View difference between Paste ID: CmQzHhym and kjCFv6QQ
SHOW: | | - or go back to the newest paste.
1
[/=============================================================================
2
3
    Gaea text template language!
4
5
    Thanks to hkaiser, VeXocide and heller !!! on Spirit IRC
6
    Thanks to Daniel James, Matias Capeletto and Dave Abrahams
7
    for added comments and suggestions (Boost Docs List).
8
9
==============================================================================]
10
11
Reserved tokens:
12
  [
13
  ]
14
  [u
15
  [def
16
  [decl
17
  [lambda
18
  [import
19
  [namespace
20
  [/
21
  [^
22
  ["
23
  [""
24
  ""]
25
  \[
26
  \]
27
28
  (the last 2 is for escaping [ and ])
29
30
Comments:
31
32
  [/ comments. ]
33
  [/ nested [/ nested comments] comments. ]
34
  [/ balanced square braces [ and ] (i.e starts with [ and ends with ] and
35
     with equal number of [ and ]), are allowed inside comments. This is a
36
     good way to comment out code. ]
37
38
Markups:
39
40
  [*This is a markup]
41
  [orderedlist [a][b][c]]
42
43
Markups are always significant, except inside escapes (see ["" Escapes
44-
below). Like HTML/XML spaces are coalesced unless they are inside the
44+
below) and except for list elements (see List). Like HTML/XML spaces
45-
preformatted markup (see [^ Preformatted below).
45+
are coalesced unless they are inside the preformatted markup
46
(see [^ Preformatted below).
47
48
Markup Identifiers:
49
50
Identifiers consist of one or more letters, digits and extended
51
characters: ! $ % & * + - . : < = > ? @ _ ` # ' that
52
cannot begin a number and cannot conflict with a reserved token.
53
54
Examples:
55
56
  This-is-an-identifier
57
  ?
58
  *
59
  ==
60
  ?WTH
61
62
Simple Strings:
63
64
  This is a string
65
66
  Jack and Jill went up the hill to fetch a pail of water.
67
  Jack fell down and broke his crown, and Jill came tumbling after.
68
69
  123 is a numeric string
70
71
Grouped String:
72
73
  ["This is grouped a string]
74
75-
of grouped strings are allowed *ONLY* as list elements
75+
76-
(see List below).
76+
of grouped strings are allowed *ONLY* as list (see List below)
77
elements:
78
79
  [This grouped string is allowed *ONLY* as list element]
80
81
The double quote is not necessary because bare markups are not
82
allowed as list elements. If you need markups in list elements,
83
put them in braces:
84
85
  [[*A marked-up list element]]
86
87
Marked up Strings:
88
89
  This string [*contains] a markup. '*' should better be a
90
  template, otherwise this is an error.
91
92
  [*This] string contains a markup. '*' should better be a
93
  template, otherwise this is an error.
94
95
Lists:
96-
A list may contain one or grouped-string or nested list.
96+
97
A list may contain one or grouped-string or nested list, but
98
not bare markups.
99
100
Examples:
101
102
  [[a][b][c]]     [/ 1st ]
103
  [[a][[b][c]]]   [/ 2nd ]
104
105
Lists can form linear or hierarchical data structures. 1st is a
106
3-element list [a][b][c]. 2nd is a 2-element list where the first
107
element is [a] and the second is a 2-element list [b][c].
108
109
Formatting makes it clear:
110
111
  1st:
112
113
    [
114
      [a][b][c]
115
    ]
116
117
  2nd:
118
119
    [
120
      [a]
121
      [
122
        [b][c]
123
      ]
124
    ]
125
126
This is an erroneous list:
127
128
  [[a][b][c] duh!]     [/ not a list ]
129
130
There should never be "naked" list elements (those without
131
braces). That one above is not a list. It is a grouped string;
132
and so is this:
133
134
  [duh! [a][b][c]]     [/ not a list ]
135
136
It is important to keep in mind that lists may not contain bare
137
markups. This:
138
139
  [[dup x][dup y]]
140
141
will *NOT* expand the 'dup' templates. If you need markups expanded
142
in list elements, put them in braces:
143
144
  [[[dup x]][[dup y]]]
145
146
Strings as lists:
147
148
A string is just a special form of list with single character elements.
149
150
List elements:
151
152
  [
153
    [This is grouped a string]
154
155
    [[*This is a markup]]
156
157
    [[a][b][c]]                         [/ A nested list ]
158
159
    [This string [*contains] a markup]
160
161
    [[*this] is still a string.]
162
163
    [[this is a single element list!]]
164
165
    ["[this is *not* a nested list!]]   [/ the double quote " prevents this from
166
                                           becoming a list (see Protect below)]
167
  ]
168
169
Nil:
170
171
    []
172
173
A nil can be an empty string or an empty list.
174
175
Unicode Code Points:
176
177
  [u2018]                     [/ Generates unicode code point (hexadecimal). ]
178
179
Escapes:
180
181
  \[                          [/ Escapes the open bracket]
182
  \]                          [/ Escapes the close bracket]
183
  [""x""]                     [/ Escapes all occurances of [ and ] in x. ]
184
185
Preformatted:
186
187
  [^ some-text]               [/ Make spaces, tabs and newlines significant ]
188
189
Protect:
190
191
  ["* blah]                   [/ Don't expand * regardless if * is
192
                                 a template (or not) ]
193
  ["[x][y][z]]                [/ Don't make this a list ]
194
195
Protect ["* blah] is not really the same as [""* blah""]. Only the
196
template * is not expanded. For example, ["* [bar]] will still expand
197
bar, while [""* [bar]""] will not evaluate both * and bar.
198
199
Template:
200
Forward declarations:
201
202
  [decl [foo]]
203
204
  [decl [dup a]]
205
206
Forward declarations are good for recursion and is always perfect
207
for documenting templates.
208
209
Definitions:
210
211
  [def [pi] 3.14159265]       [/ nullary template def ]
212
213
  [def pi 3.14159265]         [/ short for nullary template def ]
214
215
  [def [dup a] [a][a]]        [/ arguments always need to be evaluated, e.g. [a] ]
216
217
  [def [cat a b] [a][b]]
218
219
Template expansion:
220
221
  [pi]                        [/ nullary template ]
222
223
  [dup apple pie]             [/ unary template. argument is a string. ]
224
225
  [dup [apple pie]]           [/ unary template. argument is a 1-element list. ]
226
227
  [cat [apple][pie]]          [/ 2 arguments. argument is a 2-element list. ]
228
229
Optional Named Arguments:
230
231
Any argument can be made optional by preceding the formal argument
232
name with the tilde '~'. Example:
233
234
  [decl [$ path ~width ~height]]
235
236
The $ template above can be used this way:
237
238
  [$image.jpg [~width 200px] [~height 200px]]
239
240
Optional arguments can be placed anywhere in the template expansion.
241
Order does not matter:
242
243
  [$[~width 200px] image.jpg [~height 200px]]   [/ OK]
244
  [$[~height 200px] [~width 200px] image.jpg]   [/ OK]
245
246
Notice too that image.jpg need not be placed inside braces. All optional
247
arguments are gathered and what's left should conform to the rules for
248
template expansion above; hence becomes:
249
250
  [$image.jpg]                [/ nullary template ]
251
252
Of course you can place them all inside braces if you want:
253
254
  [$[image.jpg] [~width 200px] [~height 200px]]
255
256
Variable args:
257
258
Example:
259
260-
Again, the list may contain one or more markup, grouped-string or nested
260+
261-
list.
261+
262
The dot '.' before the last formal argument signifies variable
263
number of arguments. It is only allowed before the final formal
264
argument. The actual arguments passed are collected in one list.
265
266
Example invocation:
267
268
  [table [~title My First Table]
269
      [[Heading 1] [Heading 2] [Heading 3]]
270
      [[R0-C0]     [R0-C1]     [R0-C2]]
271
  ]
272
273
Again, the list may contain one or more grouped-string or nested list.
274
275
Intrinsics:
276
277
  [decl [head x]]             [/ Get first element from x. ]
278
  [decl [tail x]]             [/ Return a list or string without the first element of x. ]
279
  [decl [empty x]]            [/ Return 1 if x is empty else 0. ]
280
  [decl [at x n]]             [/ Return the nth element of x. ]
281
  [decl [size x]]             [/ Return size of x. ]
282
  [decl [append x e]]         [/ Append e to x. ]
283
  [decl [insert x e n]]       [/ Insert e to x at position n. ]
284
  [decl [reverse x]]          [/ Reverse x. ]
285
  [decl [join x y]]           [/ Join x and y as one longer list. ]
286
287
  [decl [fold x s f]]         [/ For a list x, initial state s, and binary function f,
288
                                 fold returns the result of the repeated application of
289
                                 [f e s] for each element e of list x, to the result
290
                                 of the previous f invocation (s if it is the first call). ]
291
292
Many list operations can be implemented using fold. Yet, for the sake
293
of efficiency, we provide these common operations as intrinsics.
294
295
  [decl [transform x f]]      [/ For a list x and function f, transform returns a new
296
                                 list with elements created by applying [f e] to each
297
                                 element e of x. ]
298
299
Since strings are just special forms of lists, all functions that accept
300
lists can also accept strings.
301
302
  [decl [load file]]          [/ Loads file. ]
303
  [decl [save file x]]        [/ Saves x to file. ]
304
305
load processes files (i.e. markups are significant). If you want to load
306
files verbatim, enclose it in the escape markup. Example:
307
308
  [""[load text.gia]""]
309
310
Load works similarly to C #include. It is possible to load a file inside
311
a template body. All the templates in the loaded file will be available
312
in the scope where it is loaded.
313
314
  [decl [add a b]]            [/ Add a and b. both a and b are numeric integer strings. ]
315
  [decl [subt a b]]           [/ Subract a and b. both a and b are numeric integer strings. ]
316
  [decl [mult a b]]           [/ Multiply a and b. both a and b are numeric integer strings. ]
317
  [decl [div a b]]            [/ Divide a and b. both a and b are numeric integer strings. ]
318
  [decl [mod a b]]            [/ Remainder of a / b. both a and b are numeric integer strings. ]
319
320
  [decl [eq a b]]             [/ Returns 1 if a == b. ]
321
  [decl [lt a b]]             [/ Returns 1 if a is less than b. ]
322
  [decl [and a b]]            [/ Returns a and b (boolean logic). ]
323
  [decl [or a b]]             [/ Returns a or b (boolean logic). ]
324
  [decl [if cond then else]]  [/ Returns then if cond is 1, otherwise returns else. ]
325
326
Other comparisons and booleans can be synthesized from the basics above.
327
For example not can be defined as:
328
329
  [def [not x] [if [x][0][1]]]
330
331
ne (not-equal) can be defined as:
332
333
  [def [ne a b] [not [eq [a][b]]]], etc.
334
335
Lambda Functions:
336
337
Functions are first class and can be passed to and returned from other
338
functions. For example, the transform intrinsic requires a lambda function
339
for its last (f) argument.
340
341
Here's an example of a lambda function:
342
343
  [lambda [x] [dup [x]]]
344
345
Its syntax resembles a function definition.
346
347
Here's a sample invocation of transform:
348
349
  [transform [[a][b][c]] [lambda [x] [dup [x]]]]
350
351
This doubles all elements of the list:
352
353
  [[aa][bb][cc]]
354
355
Function arguments:
356
357
If the arity of the function argument is the same as the one expected,
358
the argument (e.g. Transform expects its f argument to be a unary
359
function. Likewise, dup is also a unary function), the function can
360
be passed as-is. Example:
361
362
  [transform [[a][b][c]][dup]]
363
364
Hence:
365
366
  [dup]
367
368
is a shorthand equivalent to:
369
370
  [lambda [x] [dup [x]]]
371
372
Scopes:
373
374
Templates can be placed inside a namespace. Example:
375
376
  [namespace ns
377
378
    [decl [foo x]]
379
    [decl [bar x]]
380
  ]
381
382
The template x can be referenced in other scopes using the
383
dot notation. Example:
384
385
  [ns.foo hello, world!]
386
387
You may import names from other scopes this way:
388
389
  [import [ns][foo][bar]]   [/ Import foo and bar from ns ]
390
391
Then you can use foo and bar without qualification:
392
393
  [foo hello, world!]
394
395
You may also import a whole namespace:
396
397
  [import ns]               [/ Import all templates in ns ]
398
399
All the intrinsics are declared in namespace "std". There is an
400
implicit
401
402
  [import std]
403
404
before anything else. In case of ambiguity (when template names clash),
405
you can use explicit qualification. Example:
406
407
  [std.plus [1][2]]
408
409
410
411