aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 6c5e4dbb07b6be139f3544d1970f0c32966c32e3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# csma

csma is a tiny superset of CSS, with the goal of making rules more organizeable and modular than ever.

## How to use

Currently the only preprocessor is "preproc.awk":

```bash
awk -f preproc.awk styles.csma styles.csma
```

Remember to pass the csma file **twice**

## Language reference

The syntactical additions to CSS are two:

- macro name
- macro definition

The concept is inspired from C-like macros.
There is no **CSS modification**, you can only really move around rules (and text).

### (Standalone) Macro name

A macro name is a string in the form:

```
<LETTERS>
```

where LETTERS can be any combination and length of letters, excluding `>`, `&` and newlines.

A macro name can be placed almost anywhere in a CSS file and it will be replaced by some value.

### Macro definition

That value is specified via macro definitions, a macro name followed by curly braces:

```
<NAME> {
    VALUE
}
```

Now, every time you have a standalone `<NAME>`, it will be replaced with `VALUE`.
The curly brace can be anywhere after the macro name, even after multiple new lines, but there must only be blank characters between them.

Let's look at an example:

```
<Number>
<Number> { 5 }
```

The resulting file will be:

```
5
```

As you can see, the definitions are parsed before (standalone) macro names, so it doesn't matter if the standalone name is before or after the definition.

Multiple definitions with the same macro name are concatenated, so with:

```
<Number>
<Number> { 5 }
<Number> { 6 }
```

you'll get:

```
56
```

Newlines inner empty lines are preserved, so this:

```
<Number>
<Number> {

  5

}
<Number> {
  6

}
```

results into:

```

5

6

```

### Inner macro definitions

You are also allowed to put definitions inside other definitions:

```
<Color> {
  <Text> { black }
  <Body> { white }
}
```

#### Nested macro's name

Inner definitions come with a trick: their name is accessed by prepending their parent and "/".
So, this **won't** result in anyting:

```
<Color> {
  <Text> { black }
  <Body> { white }
}
<Text>
```

however this **will** result in the word "black":

```
<Color> {
  <Text> { black }
  <Body> { white }
}
<Colors/Text>
```

It's important to note that this changes the **entire name** of the macro and every macro is globally accessible.
There is no actual tree-like structure behind it, so the syntax:

```
<A> {
  <B1> { ... }
  <B2> { ... }
  ...
  <BN> { ... }
}
```

is (almost) equivalent to:

```
<A> {
}
<A/B1> { ... }
<A/B2> { ... }
...
<A/BN> { ... }
```

You can nest as much as you like, and for every paren't you get another "name/" prepended, in this:

```
<A> {
  <B> {
    <C> {
      89
    }
  }
}
```

you have three macros: `<A>`, `<A/B>` and `<A/B/C>`.

#### Nested macro replacement

Nested macro definitions are also automatically replaced in their parent.
So here:

```
<A> {
  rule1
  <B> {
    rule2
  }
}

<A>

<A/B>
```

you'll get:

```

rule1
rule2

rule2
```

So nested definitions:

```
<A> {
  <B1> { ... }
  <B2> { ... }
  ...
  <BN> { ... }
}
```

are "spiritually" equivalent to:

```
<A> {
  <B1>
  <B1> { ... }
  <B2>
  <B2> { ... }
  ...
  <BN>
  <BN> { ... }
}
```

But **only when actually nested!**
So if we rewrite the example from above like:

```
<A> {
  rule1
}
<A/B> {
  rule2
}

<A>

<A/B>
```

the result will be:

```

rule1

rule2
```

#### Nested macro concatenation

Since multiple definitions are concatenated, there is no problem in doing:

```
<A/B>
<A> {
  <B> {}
}
<A/B> { 1 }
<A> {
  <B> { 5 }
}
```

the result will be:

```
15
```

### Inner standalone macro names

Replacement of standalone macro names also happens inside definitions.
This:

```
<A>
<A> {
  <B>
}
<B> {
  rule
}
```

results into:

```
rule
```

This also allows us to kinda do the nested macro replacement without actually nesting the entire macro definition:

```
<A> {
  rule1
  <A/B>
}
<A/B> {
  rule2
}

<A>

<A/B>
```

the result is:

```

rule1
rule2

rule2
```

## How to use effectively in CSS

Image the following scenario, you have a website with:

- header with website logo, links to pages and a hidden menu bar, for mobile devices
- page with text and picture contents
- image reel
- footer with social links, a map with your business address and disclaimers

The CSS rules can stack up very quickly, and it can be difficult to maintain.
One way in which you can use CSMA is by representing your site structure with different macros and dividing everything into them:

```
<Page>

<Page> {
  body { ... }

  <Page/Header>
  <Page/Contents>
  <Page/Footer>
}

<Page/Header> {
  header { ... }

  <Link> {
    .header-link {
      ...
    }
    .header-link:hover() {
      ...
    }
  }

  <Logo> {
    .header-logo {
      ...
    }
  }
}

<Page/Contents> {
  article {
    ...
  }
  <Image reel>
  a {
    ...
  }
  b {
    ...
  }
}

<Page/Footer> {
  ...
}
```

But this is just an example.

You may want to have even more macros that mostly contain other macros (like with `<Page>`).
This way you can very easily turn on or off a feature, and rules are easily discoverable (for example, try finding the rule for the header logo).