ltdtemplate 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,838 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>LtdTemplate Manual</title>
5
+ <style type='text/css'>
6
+ table { border-collapse: collapse }
7
+ tr { border: solid 1px black }
8
+ td, th { padding-left: 1.5em; padding-right: 0.3em }
9
+ td:first-child, th:first-child { padding-left: 0.3em }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <h1 id='top'>LtdTemplate Manual<br>
14
+ <span style='font-size: smaller'>Version 0.1.0; July 12, 2013</span></h1>
15
+
16
+ <h2>Author(s)</h2>
17
+
18
+ <ul>
19
+ <li>Brian Katzung
20
+ &lt;<a href='mailto:briank@kappacs.com'>briank@kappacs.com</a>&gt;,
21
+ Kappa Computer Solutions, LLC (original author)</li>
22
+ </ul>
23
+
24
+ <h2 id='contents'>Contents</h2>
25
+
26
+ <ul>
27
+ <li><a href='#introduction'>Introduction</a></li>
28
+ <li><a href='#template_syntax'>Template Syntax</a></li>
29
+ <li><a href='#code_syntax'>Template Code Syntax</a></li>
30
+ <li><a href='#values_methods'>Values And Methods</a></li>
31
+ <li><a href='#examples'>(Some More) Examples</a></li>
32
+ </ul>
33
+
34
+ <h2 id='introduction'>Introduction</h2>
35
+
36
+ <p><a href='http://rubygems.org/gems/ltdtemplate'>LtdTemplate</a> is a
37
+ <a href='http://rugybems.org/'>Ruby Gem</a> implementing resource-limitable
38
+ templating. With proper configuration, it can be used to allow sophisticated
39
+ users to edit their own templates, e.g. for message localization, with
40
+ limited risk of infinite execution loops or other uncontrolled resource
41
+ utilization.</p>
42
+
43
+ <p>This document describes the template syntax. See the Gem documentation
44
+ for information about the programming interface.</p>
45
+
46
+ <p>[<a href='#contents'>Contents</a>]</p>
47
+
48
+ <h2 id='template_syntax'>Template Syntax</h2>
49
+
50
+ <p>A template consists of inter-mixed sections of literal text and
51
+ template code. The shortest sequences between "<code>&lt;&lt;</code>"
52
+ and "<code>&gt;&gt;</code>" that don't contain "<code>&lt;&lt;</code>"
53
+ or "<code>&gt;&gt;</code>" are template code; the rest is literal
54
+ text. Given a sequence of the form:</p>
55
+
56
+ <blockquote>
57
+ <code>A&lt;&lt;B&lt;&lt;C&gt;&gt;D&lt;&lt;E&gt;&gt;F&gt;&gt;G&lt;&lt;&lt;H&gt;&gt;&gt;I</code>
58
+ </blockquote>
59
+
60
+ <p>template code cannot begin at "&lt;&lt;B" because it is not allowed
61
+ to contain "<code>&lt;&lt;</code>" or "<code>&gt;&gt;</code>", so the
62
+ first template code is "<code>&lt;&lt;C&gt;&gt;</code>", the second is
63
+ "<code>&lt;&lt;E&gt;&gt;</code>", and the last is
64
+ "<code>&lt;&lt;H&gt;&gt;</code>". Everything else ("<code>A&lt;&lt;B</code>",
65
+ "<code>D</code>", "<code>F&gt;&gt;G&lt;</code>", and "<code>&gt;I</code>")
66
+ is treated as literal text.</p>
67
+
68
+ <p>If template code begins with "<code>&lt;&lt;.</code>" (with a period
69
+ immediately after the second "<code>&lt;</code>"), it strips any trailing
70
+ white space from immediately preceding literal text. Likewise, if template
71
+ code ends with "<code>.&gt;&gt;</code>", it strips any leading white space
72
+ from immediately following literal text. Template code consisting of
73
+ only "<code>&lt;&lt;.&gt;&gt;</code>" is considered to meet both
74
+ conditions and is equivalent to "<code>&lt;&lt;..&gt;&gt;</code>".</p>
75
+
76
+ <p>There need not be any literal text before, after, or between template
77
+ code sequences. Template code sequences between delimiters may also be empty
78
+ (<code>&lt;&lt;&gt;&gt;</code>).</p>
79
+
80
+ <p>Unless otherwise stated, the remainder of this document will refer to
81
+ template code as the code between the "<code>&lt;&lt;</code>"
82
+ (or "<code>&lt;&lt;.</code>") and "<code>&gt;&gt;</code>" (or
83
+ "<code>.&gt;&gt;</code>") without reference to the delimiters
84
+ themselves.</p>
85
+
86
+ <p>[<a href='#contents'>Contents</a>]</p>
87
+
88
+ <h2 id='code_syntax'>Template Code Syntax</h2>
89
+
90
+ <ul>
91
+ <li><a href='#comment_syntax'>Comments</a></li>
92
+ <li><a href='#strlit_syntax'>String Literals</a></li>
93
+ <li><a href='#numlit_syntax'>Numeric Literals</a></li>
94
+ <li><a href='#variable_syntax'>Variables</a></li>
95
+ <li><a href='#call_syntax'>Method Calls</a></li>
96
+ <li><a href='#assignment_syntax'>Assignments</a></li>
97
+ <li><a href='#predefined_vars'>Pre-Defined Variables</a></li>
98
+ <li><a href='#codeseq_syntax'>Code Sequences</a></li>
99
+ <li><a href='#codeblocks_syntax'>Code Blocks</a></li>
100
+ <li><a href='#subscript_syntax'>Subscripts And Code-Block Bindings</a></li>
101
+ </ul>
102
+
103
+ <h3 id='comment_syntax'>Comments</h3>
104
+
105
+ <p>Comments begin with "<code>/*</code>" and end at the nearest
106
+ "<code>*/</code>".</p>
107
+
108
+ <blockquote><code>/* this is a comment */
109
+ /* and so is /* this */</code></blockquote>
110
+
111
+ <p>[<a href='#contents'>Contents</a>] [<a href='#code_syntax'>Template Code Syntax</a>]</p>
112
+
113
+ <h3 id='strlit_syntax'>String Literals</h3>
114
+
115
+ <p>String literals are used to generate <a href='#string_values'>string
116
+ values</a>. LtdTemplate supports two forms: "short" and "regular".</p>
117
+
118
+ <p>Short string literals begin with a single quote (<code>'</code>) and
119
+ terminate before a period (<code>.</code>), comma (<code>,</code>), opening
120
+ or closing brackets, parentheses, or braces (<code>[](){}</code>), or white
121
+ space. However, any normally terminating character may be included by
122
+ preceding it with a backslash (<code>\</code>).</p>
123
+
124
+ <p>Regular string literals begin with a double quote (<code>"</code>) and
125
+ terminate at the next double quote. A double quote may be included by
126
+ preceding it with a backslash.</p>
127
+
128
+ <p>String literals may also contain other "escape sequences" like those in
129
+ Ruby double-quoted strings. Here is the full list:</p>
130
+
131
+ <table>
132
+
133
+ <tr><th>Sequence</th><th>Meaning</th></tr>
134
+
135
+ <tr><td>\M-\C-<i>x</i></td><td>meta-control-<i>x</i></td></tr>
136
+
137
+ <tr><td>\M-<i>x</i></td><td>meta-<i>x</i></td></tr>
138
+
139
+ <tr><td>\C-<i>x</i>, \C<i>x</i></td><td>control-<i>x</i></td></tr>
140
+
141
+ <tr><td>\u<i>dddd</i></td>
142
+ <td>Unicode four-digit, 16-bit hexadecimal code point <i>dddd</i></td></tr>
143
+
144
+ <tr><td>\x<i>dd</i></td><td>two-digit, 8-bit hexadecimal <i>dd</i></td></tr>
145
+
146
+ <tr><td>\<i>ddd</i></td>
147
+ <td>one, two, or three-digit, 8-bit octal <i>ddd</i></td></tr>
148
+
149
+ <tr><td>\a</td><td>alert (ASCII BEL)</td></tr>
150
+
151
+ <tr><td>\b</td><td>backspace (ASCII BS)</td></tr>
152
+
153
+ <tr><td>\e</td><td>escape (ASCII ESC)</td></tr>
154
+
155
+ <tr><td>\f</td><td>formfeed (ASCII FF)</td></tr>
156
+
157
+ <tr><td>\n</td><td>new-line/line-feed (ASCII LF)</td></tr>
158
+
159
+ <tr><td>\r</td><td>carriage return (ASCII ESC)</td></tr>
160
+
161
+ <tr><td>\s</td><td>space (ASCII SP)</td></tr>
162
+
163
+ <tr><td>\t</td><td>horizontal tab (ASCII HT)</td></tr>
164
+
165
+ <tr><td>\v</td><td>vertical tab (ASCII VT)</td></tr>
166
+
167
+ <tr><td>\<i>c</i></td>
168
+ <td>any other character <i>c </i> is just itself</td></tr>
169
+
170
+ </table>
171
+
172
+ <p>Examples, with some comments added for annotation:</p>
173
+
174
+ <blockquote><code>' /* empty */ 'short '&lt;\&lt; '&gt;\&gt;
175
+ /* escaped code delimiters */ "\"regular\" string"</code></blockquote>
176
+
177
+ <p>[<a href='#contents'>Contents</a>] [<a href='#code_syntax'>Template Code Syntax</a>]</p>
178
+
179
+ <h3 id='numlit_syntax'>Numeric Literals</h3>
180
+
181
+ <p>Numeric literals are used to generate typical integer or real (decimal)
182
+ <a href='#number_values'>numeric values</a> and consist of an optional
183
+ minus sign (<code>-</code>) followed by one or more digits, and optionally
184
+ followed by a decimal point (<code>.</code>) and one or more additional
185
+ digits.</p>
186
+
187
+ <blockquote><code>0.125 1 -2 3.0 -4.5</code></blockquote>
188
+
189
+ <p>LtdTemplate does not support numeric literals in scientific notation
190
+ or bases other than ten.</p>
191
+
192
+ <p>[<a href='#contents'>Contents</a>] [<a href='#code_syntax'>Template Code Syntax</a>]</p>
193
+
194
+ <h3 id='variable_syntax'>Variables</h3>
195
+
196
+ <p>Variables hold references to values, and can hold references to (be
197
+ bound to) different values at different times. They exist within the stack
198
+ of <a href='#namespace_values'>namespaces</a>. Referencing a variable
199
+ normally searches for it beginning in the most recent or "nearest"
200
+ namespace and works back to the first or "root" namespace until a
201
+ variable with that name is found. If the name begins with circumflex
202
+ (<code>^</code>), the search begins in the parent namespace (if there is
203
+ one) instead of the current namespace. If the name begins with at-sign
204
+ (<code>@</code>), only the root namespace is searched. If the variable
205
+ has not been <a href='#assignment_syntax'>assigned</a>, the
206
+ <a href='#nil_value'>nil</a> value is used.</p>
207
+
208
+ <p>Variable names must be in one of the following formats (unless accessed
209
+ as an <a href='#subscript_syntax'>element</a> of a specific
210
+ namespace&mdash;see last example) and are case-sensitive:</p>
211
+
212
+ <ol>
213
+ <li>A letter or an underscore (<code>_</code>), followed by zero
214
+ or more letters, numbers, or underscores</li>
215
+
216
+ <li>An at-sign or circumflex followed by one or more letters, numbers,
217
+ or underscores</li>
218
+
219
+ <li>An at-sign, circumflex, or dollar-sign (<code>$</code>) by itself</li>
220
+ </ol>
221
+
222
+ <blockquote><code>name item1 _2 ^parent @root $
223
+ @['&lt;\&lt;weird&gt;\&gt;]</code></blockquote>
224
+
225
+ <p>[<a href='#contents'>Contents</a>] [<a href='#code_syntax'>Template Code Syntax</a>]</p>
226
+
227
+ <h3 id='call_syntax'>Method Calls</h3>
228
+
229
+ <p>A method call performs an action on, or returns information about,
230
+ a value. A method call consists of a value expression followed by a
231
+ period (<code>.</code>) followed by the desired method name, optionally
232
+ followed by an open parenthesis "<code>(</code>", zero or more method
233
+ call parameters separated by commas (<code>,</code>), and a closing
234
+ parenthesis "<code>)</code>". Parameters may be positional (also called
235
+ sequential) or named (also called random-access). Use the "dot dot"
236
+ symbol (<code>..</code>) to terminate the positional parameters and begin
237
+ the named parameters.</p>
238
+
239
+ <blockquote><code>value_expression.method_name(positional_1,
240
+ </code>...<code>, positional_N .. name_1, value_1,
241
+ </code>...<code>, name_N, value_N)</code></blockquote>
242
+
243
+ <p>Method names are case-sensitive and must be in one of the following
244
+ formats:</p>
245
+
246
+ <ol>
247
+ <li>A letter or underscore (<code>_</code>) followed by zero or more
248
+ letters, numbers, or underscores</li>
249
+ <li>One or more punctuation characters that don't have any other meaning
250
+ (these are often referred to as "operators" in other syntax definitions),
251
+ such as:</li>
252
+ </ol>
253
+
254
+ <blockquote><code>+ - * / % & | ! < <= = == != >= ></code></blockquote>
255
+
256
+ <p>The parentheses are optional if no parameters are to be supplied to
257
+ the method call. The period is optional for "operator-style" method calls
258
+ if not immediately preceded by punctuation.</p>
259
+
260
+ <blockquote><code>3.type /* => number */<br>
261
+ 3.type.length /* "chained" method calls; => 6 */<br>
262
+ 1+(2,3,4) /* short for */ 1.+(2,3,4) /* => 10 */</code></blockquote>
263
+
264
+ <p>[<a href='#contents'>Contents</a>] [<a href='#code_syntax'>Template Code Syntax</a>]</p>
265
+
266
+ <h3 id='assignment_syntax'>Assignments</h3>
267
+
268
+ <p>Variables support two assignment method calls: unconditional
269
+ (<code>=</code>) and conditional (<code>?=</code>). A conditional
270
+ assignment does nothing if the variable is already bound to (holds a
271
+ reference to) a value (including the nil value). Assignments do not
272
+ render in the template output.</p>
273
+
274
+ <p>If called with a single parameter and no "dot dot" symbol, the value of
275
+ the single parameter is assigned. Otherwise, all the parameters are
276
+ assigned as an array. See also <a href='#array_values'>array values</a>.</p>
277
+
278
+ <blockquote><code>num=(5) num?=(6) /* num is still 5 */<br>
279
+ empty1= empty2=() /* empty arrays */<br>
280
+ single=(10 ..) /* one element */ double=(5, 10) /* two */<br>
281
+ matrix=($.*(1, 0), $.*(0, 1) .. 'type, 'identity)<br>
282
+ matrix[0, 0] /* => 1 */ matrix['type] /* => identity */</code></blockquote>
283
+
284
+ <p>Variables beginning with circumflex (<code>^</code>) will be created in
285
+ the parent namespace (if they do not already exist) and variables beginning
286
+ with at-sign (<code>@</code>) will be created in the root namespace. All
287
+ others will be created in the current namespace.</p>
288
+
289
+ <p>See also the <a href='#namespaces_var_method'>var</a> method for
290
+ <a href='#namespace_values'>namespaces</a>.</p>
291
+
292
+ <p>[<a href='#contents'>Contents</a>] [<a href='#code_syntax'>Template Code Syntax</a>]</p>
293
+
294
+ <h3 id='predefined_vars'>Pre-Defined Variables</h3>
295
+
296
+ <p>The following variables are pre-defined by LtdTemplate:</p>
297
+
298
+ <table>
299
+
300
+ <tr><th>Name</th><th>Description</th></tr>
301
+
302
+ <tr><td><code>$</code></td>
303
+ <td>This is the current <a href='#namespace_values'>namespace</a>. A
304
+ new namespace is automatically created each time a
305
+ <a href='#code_blocks'>code block</a> is executed and is subsequently
306
+ destroyed when the code block completes.</td></tr>
307
+
308
+ <tr><td><code>^</code></td>
309
+ <td>This variable refers to the previous namespace if there is one,
310
+ or <a href='#nil_value'>nil</a> if there isn't.</td></tr>
311
+
312
+ <tr><td><code>@</code></td>
313
+ <td>This variable refers to the first (also known as "root" or
314
+ "top-level") namespace.</td></tr>
315
+
316
+ <tr><td><code>_</code></td>
317
+ <td>This variable contains the parameters passed into the template
318
+ or current <a href='#code_block'>code block</a>.</td></tr>
319
+
320
+ </table>
321
+
322
+ <p>[<a href='#contents'>Contents</a>] [<a href='#code_syntax'>Template Code Syntax</a>]</p>
323
+
324
+ <h3 id='codeseq_syntax'>Code Sequences</h3>
325
+
326
+ <p>A code sequence refers to a sequence of zero or more template code
327
+ expressions. <a href='#template_syntax'>Templates</a>,
328
+ <a href='#call_syntax'>method call</a> parameters, and code block bodies
329
+ are all code sequences.</p>
330
+
331
+ <p>If a code sequence consists of a single, non-string value and does
332
+ not constitute the entire template code, it is retained as-is. Otherwise,
333
+ the string value of each element in the sequence, if any, is combined to
334
+ produce the result of the code sequence.</p>
335
+
336
+ <blockquote><code>'Hello $.true ", " num=(5) num-(4) " world!"<br>
337
+ /* 5 and 4 are single, non-string values in their code sequences */<br>
338
+ /* $.true and num=(5) render nothing */<br>
339
+ /* num-(4) returns the number 1 but it's string value gets used */<br>
340
+ /* => Hello, 1 world! */</code></blockquote>
341
+
342
+ <p>[<a href='#contents'>Contents</a>] [<a href='#code_syntax'>Template Code Syntax</a>]</p>
343
+
344
+ <h3 id='codeblock_syntax'>Code Blocks</h3>
345
+
346
+ <p>If you surround a <a href='#code_sequences'>code sequence</a>
347
+ by braces (<code>{</code> and <code>}</code>), you create a code
348
+ block. A code block is a value which does not render directly, but
349
+ can be called as a <a href='#method_calls'>method call</a>, executing
350
+ the code sequence within the code block.</p>
351
+
352
+ <blockquote><code>render_method=({ $.method })<br>
353
+ render_method.hi " " render_method.there
354
+ /* => hi there */</code></blockquote>
355
+
356
+ <p>[<a href='#contents'>Contents</a>] [<a href='#code_syntax'>Template Code Syntax</a>]</p>
357
+
358
+ <h3 id='subscript_syntax'>Subscripts And Code-Block Bindings</h3>
359
+
360
+ <p>Any expression that evaluates to an array (or tree of nested arrays)
361
+ may be subscripted to select a particular value or nested array from the
362
+ array. A subscript consists of an open bracket (<code>[</code>) followed
363
+ by one or more selector expressions separated by commas followed by a
364
+ closing bracket (<code>]</code>). Consecutive selector expressions are
365
+ used to traverse progressively more deeply nested arrays.</p>
366
+
367
+ <blockquote><code>array_var['items, 5] /* fetches item "5" (which
368
+ might also be an array) from array "items" in the array referenced by
369
+ array_var */<br>
370
+ array_var['items][5] /* as above - alternate syntax */</code></blockquote>
371
+
372
+ <p>If the requested item does not exist, the special value
373
+ "<a href='#nil'>nil</a>" is used instead.</p>
374
+
375
+ <p>LtdTemplate also uses subscript syntax to bind
376
+ <a href='#code_blocks'>code blocks</a> to non-array values. These can
377
+ subsequently be called like <a href='#method_calls'>methods</a>. They
378
+ never override standard methods.</p>
379
+
380
+ <blockquote><code>x['greeting]=({'hello}) /* where x is not an array
381
+ value */<br>x.greeting /* => hello */</code></blockquote>
382
+
383
+ <p>You can also bind code blocks to proxy objects to be used by all
384
+ array, boolean, number, or string values.</p>
385
+
386
+ <blockquote><code>@Array?=(') /* bind the array proxy to a unique object */<br>
387
+ @Array['list]=({ $.target.join(", ") }) /* bind the list method */<br>
388
+ $.*(1, 2, 3).list /* => 1, 2, 3 */</code></blockquote>
389
+
390
+ <p>[<a href='#contents'>Contents</a>] [<a href='#code_syntax'>Template Code Syntax</a>]</p>
391
+
392
+ <h2 id='values_methods'>Values And Methods</h2>
393
+
394
+ <ul>
395
+ <li><a href='#array_values'>Arrays</a></li>
396
+ <li><a href='#boolean_values'>Booleans (True And False)</a></li>
397
+ <li><a href='#codeblock_values'>Code Blocks</a></li>
398
+ <li><a href='#namespace_values'>Namespaces</a></li>
399
+ <li><a href='#nil_value'>Nil</a></li>
400
+ <li><a href='#number_values'>Numbers</a></li>
401
+ <li><a href='#string_values'>Strings</a></li>
402
+ </ul>
403
+
404
+ <h3 id='array_values'>Arrays</h3>
405
+
406
+ <p>LtdTemplate does not have array literals, but you can construct arrays
407
+ using the variable assignment method (see <a href='#variable_syntax'>variable
408
+ syntax</a>) or via the <a href='#namespace_star_method'>namespace anonymous
409
+ array</a> method:</p>
410
+
411
+ <blockquote><code>empty=() /* empty array */ single=(10 ..) /* one element */
412
+ double=(5, 10) /* two */<br>
413
+ matrix=($.*(1, 0), $.*(0, 1) .. 'type, 'identity)<br>
414
+ matrix[0, 0] /* => 1 */ matrix['type] /* => identity */</code></blockquote>
415
+
416
+ <p>Arrays render to the concatenation of the renderings of their sequential
417
+ (positional) elements; random-access (named) elements are ignored.</p>
418
+
419
+ <p>Standard methods:</p>
420
+
421
+ <table>
422
+
423
+ <tr><th>Method</th><th>Description</th></tr>
424
+
425
+ <tr><td><code>call</code></td><td>Same as the array itself</td></tr>
426
+
427
+ <tr><td><code>class</code></td><td>Returns the string "Array"</td></tr>
428
+
429
+ <tr><td><code>join</code></td><td>Joins sequential (positional)
430
+ elements</td></tr>
431
+
432
+ <tr><td><code>join(</code><i>separator</i><code>)</code></td><td>Join with
433
+ <i>separator</i> between elements</td></tr>
434
+
435
+ <tr><td><code>join(</code><i>two</i><code>, </code><i>first</i><code>,
436
+ </code><i>middle</i><code>, </code><i>last</i><code>)</code></td>
437
+ <td>Joins two elements with <i>two</i> as the separator or more than two
438
+ elements with <i>first</i> as the first separator, <i>last</i> as the
439
+ last separator, and <i>middle</i> for all other separators</td></tr>
440
+
441
+ <tr><td><code>pop</code>, <code>-&gt;</code></td><td>Pop the last sequential
442
+ element</td></tr>
443
+
444
+ <tr><td><code>push(</code><i>list</i><code>)</code>,
445
+ <code>+&gt;(</code><i>list</i><code>)</code></td>
446
+ <td>Adds zero or more elements in the <i>list</i> to the end of the
447
+ array</td></tr>
448
+
449
+ <tr><td><code>rnd_size</code></td><td>The number of random-access (named)
450
+ elements</td></tr>
451
+
452
+ <tr><td><code>seq_size</code></td><td>The number of sequential (positional)
453
+ elements</td></tr>
454
+
455
+ <tr><td><code>shift</code>, <code>&lt;-</code></td><td>Shift the first
456
+ sequential element</td></tr>
457
+
458
+ <tr><td><code>size</code></td><td>The total number of elements in the
459
+ array</td></tr>
460
+
461
+ <tr><td><code>type</code></td><td>Returns the string "array"</td></tr>
462
+
463
+ <tr><td><code>unshift(</code><i>list</i><code>)</code>,
464
+ <code>&lt;+(</code><i>list</i><code>)</code></td>
465
+ <td>Adds zero or more elements in the <i>list</i> to the beginning of
466
+ the array</td></tr>
467
+
468
+ </table>
469
+
470
+ <p><a href='#codeblock_syntax'>Code blocks</a> may be bound as methods for
471
+ all array values as follows:</p>
472
+
473
+ <blockquote><code>@Array?=(')
474
+ @Array['</code><i>method_name</i><code>]=({</code>
475
+ <i>code sequence</i> <code>})</code></blockquote>
476
+
477
+ <p>[<a href='#contents'>Contents</a>] [<a href='#values_methods'>Values And Methods</a>]</p>
478
+
479
+ <h3 id='boolean_values'>Booleans (True And False)</h3>
480
+
481
+ <p>LtdTemplate supports boolean values (true and false). They can be
482
+ accessed via the namespace method calls <code>$.true</code> and
483
+ <code>$.false</code>. There is only one true value and one false value,
484
+ although other values can be interpreted in boolean context (the nil
485
+ value is treated as false; all others, including the number 0 and
486
+ empty strings, are treated as true).</p>
487
+
488
+ <p>Standard methods:</p>
489
+
490
+ <table>
491
+
492
+ <tr><th>Method</th><th>Description</th></tr>
493
+
494
+ <tr><td><code>call</code></td><td>Same as the boolean itself</td></tr>
495
+
496
+ <tr><td><code>class</code></td><td>Returns the string "Boolean"</td></tr>
497
+
498
+ <tr><td><code>string</code>, <code>str</code></td>
499
+ <td>Returns the string "true" for true and "false" for false</td></tr>
500
+
501
+ <tr><td><code>type</code></td><td>Returns the string "boolean"</td></tr>
502
+
503
+ <tr><td><code>+</code>, <code>|</code>, <code>or</code></td>
504
+ <td>Returns the "logical or" of the value and any supplied call
505
+ parameters (if <b>any are true</b>, the result is true, otherwise the
506
+ result is false)</td></tr>
507
+
508
+ <tr><td><code>*</code>, <code>&</code>, <code>and</code></td>
509
+ <td>Returns the "logical and" of the value and any supplied call
510
+ parameters (if <b>all are true</b>, the result is true, otherwise the
511
+ result is false)</td></tr>
512
+
513
+ <tr><td><code>!</code>, <code>not</code></td>
514
+ <td>Returns the "logical not and" of the value and any supplied call
515
+ parameters (if <b>all are false</b>, the result is true, otherwise the
516
+ result is false)</td></tr>
517
+
518
+ </table>
519
+
520
+ <p><a href='#codeblock_syntax'>Code blocks</a> may be bound as methods
521
+ for true, false, or both boolean
522
+ values as follows:</p>
523
+
524
+ <blockquote><code>$.true['</code><i>method_name</i><code>]=({</code>
525
+ <i>code sequence</i> <code>})<br>
526
+ $.false['</code><i>method_name</i><code>]=({</code>
527
+ <i>code sequence</i> <code>})<br>
528
+ @Boolean?=(') @Boolean['</code><i>method_name</i><code>]=({</code>
529
+ <i>code sequence</i> <code>})</code></blockquote>
530
+
531
+ <p>[<a href='#contents'>Contents</a>] [<a href='#values_methods'>Values And Methods</a>]</p>
532
+
533
+ <h3 id='codeblock_values'>Code Blocks</h3>
534
+
535
+ <p>Standard methods:</p>
536
+
537
+ <table>
538
+
539
+ <tr><th>Method</th><th>Description</th></tr>
540
+
541
+ <tr><td><code>type</code></td><td>Returns the string "code"</td></tr>
542
+
543
+ </table>
544
+
545
+ <p>All other methods execute the code block in a new
546
+ <a href='#namespace_values'>namespace</a>.</p>
547
+
548
+ <p>[<a href='#contents'>Contents</a>] [<a href='#values_methods'>Values And Methods</a>]</p>
549
+
550
+ <h3 id='namespace_values'>Namespaces</h3>
551
+
552
+ <p>A namespace is a storage area for variables. A new namespace is created
553
+ each time the template is rendered or a <a href='#codeblock_values'>code
554
+ block</a> is executed. In the case of code blocks, the previously active
555
+ namespace becomes the parent (<code>^</code>) of the new namespace
556
+ (<code>$</code>).</p>
557
+
558
+ <p>Namespaces provide a number of <a href='#predefined_vars'>pre-defined
559
+ variables</a>, as well as <a href='#call_syntax'>method calls</a> for
560
+ loops and conditionals that are traditionally statements in other
561
+ programming environments.</p>
562
+
563
+ <p>Standard methods:</p>
564
+
565
+ <table>
566
+
567
+ <tr><th>Method</th><th>Description</th></tr>
568
+
569
+ <tr><td><code>array(</code><i>elements</i><code>)</code>,
570
+ <code>*(</code><i>elements</i><code>)</code></td>
571
+ <td>Returns an anonymous array (see <a href='#array_values'>array
572
+ values</a>)</td></tr>
573
+
574
+ <tr><td><code>false</code></td><td>Returns the boolean false value</td></tr>
575
+
576
+ <tr><td><code>if(</code><i>condition_1</i><code>,
577
+ </code><i>return_1</i><code>,</code> ...<code>,</code>
578
+ <i>condition_N</i><code>,</code> <i>return_N</i><code>,</code>
579
+ <i>default</i><code>)</code></td>
580
+ <td>Processes each condition in turn. The return value
581
+ corresponding to the first condition that evaluates to true is
582
+ returned. If none of the conditions evaluate to true, the optional
583
+ <i>default</i> value (or the nil value, in the case of an even number
584
+ of parameters) is returned. Parameters can be supplied as
585
+ <a href='#codeblock_syntax'>code blocks</a> to avoid execution unless
586
+ and until needed.</td></tr>
587
+
588
+ <tr><td><code>loop(</code><i>before</i><code>,</code>
589
+ <i>body</i><code>,</code> <i>after</i><code>)</code></td>
590
+ <td>If the <i>before</i> condition evaluates to true, the
591
+ <i>body</i> is executed and the optional <i>after</i> condition is
592
+ evaluated. If the <i>after</i> condition is absent or evaluates to
593
+ true, the loop starts over with the <i>before</i> condition. The
594
+ <i>body</i> and non-constant conditions should be supplied as
595
+ <a href='#codeblock_syntax'>code blocks</a>. Returns an
596
+ <a href='#array_values'>array</a> of <i>body</i> results
597
+ (one element per loop iteration).</td></tr>
598
+
599
+ <tr><td><code>method</code></td><td>Returns the method name used to
600
+ call a <a href='#codeblock_syntax'>code block</a>, or "render" for
601
+ top-level template code</td></tr>
602
+
603
+ <tr><td><code>nil</code></td><td>Returns the nil value</td></tr>
604
+
605
+ <tr><td><code>target</code></td><td>Returns the target object in
606
+ a <a href='#codeblock_syntax'>code block</a> being called as
607
+ part of an object binding</td></tr>
608
+
609
+ <tr><td><code>true</code></td><td>Returns the boolean true value</td></tr>
610
+
611
+ <tr><td><code>use(</code><i>name</i><code>)</code></td>
612
+ <td>Calls the template loader to load resource <i>name</i></td></tr>
613
+
614
+ <tr><td id='namespaces_var_method'><code>var(</code><i>name_1</i><code>,</code> ...<code>,</code>
615
+ <i>name_N</i> <code>..</code> <i>set_1</i><code>,</code>
616
+ <i>value_1</i><code>,</code> ...<code>,</code> <i>set_N</i><code>,</code>
617
+ <i>value_N</i><code>)</code></td>
618
+ <td>Creates and (re-)sets variables named by the supplied strings. The
619
+ variables in the sequential parameters section, <i>name_1</i> through
620
+ <i>name_N</i>, are assigned the nil value. The variables in the
621
+ random-access section, <i>set_1</i> through <i>set_N</i>, are assigned
622
+ the corresponding values from <i>value_1</i> through
623
+ <i>value_N</i>.</td></tr>
624
+
625
+ </table>
626
+
627
+ <p>[<a href='#contents'>Contents</a>] [<a href='#values_methods'>Values And Methods</a>]</p>
628
+
629
+ <h3 id='nil_value'>Nil</h3>
630
+
631
+ <p>LtdTemplate supports a "nil" value to represent the lack of another
632
+ value. It can be accessed via the namespace method call
633
+ <code>$.nil</code>. There is only one nil value.</p>
634
+
635
+ <p>Standard methods:</p>
636
+
637
+ <table>
638
+
639
+ <tr><th>Method</th><th>Description</th></tr>
640
+
641
+ <tr><td><code>type</code></td><td>Returns the string "nil"</td></tr>
642
+
643
+ </table>
644
+
645
+ <p><a href='#codeblock_syntax'>Code blocks</a> may be bound as methods
646
+ for the nil value as follows:</p>
647
+
648
+ <blockquote><code>$.nil['</code><i>method_name</i><code>]=({</code>
649
+ <i>code sequence</i> <code>})</code></blockquote>
650
+
651
+ <p>[<a href='#contents'>Contents</a>] [<a href='#values_methods'>Values And Methods</a>]</p>
652
+
653
+ <h3 id='number_values'>Numbers</h3>
654
+
655
+ <p>Standard methods:</p>
656
+
657
+ <table>
658
+
659
+ <tr><th>Method</th><th>Description</th></tr>
660
+
661
+ <tr><td><code>abs</code></td>
662
+ <td>Returns the absolute value of the number</td></tr>
663
+
664
+ <tr><td><code>call</code></td><td>Returns the number itself</td></tr>
665
+
666
+ <tr><td><code>ceil</code></td><td>Returns the closest greater or equal
667
+ integer</td></tr>
668
+
669
+ <tr><td><code>class</code></td><td>Returns the string "Number"</td></tr>
670
+
671
+ <tr><td><code>floor</code></td><td>Returns the closest lesser or equal
672
+ integer</td></tr>
673
+
674
+ <tr><td><code>flt, float</code></td><td>Returns the number as a
675
+ floating-point number</td></tr>
676
+
677
+ <tr><td><code>int</code></td><td>Returns the number as an integer</td></tr>
678
+
679
+ <tr><td><code>str</code>, <code>string</code></td>
680
+ <td>Returns the number as a string</td></tr>
681
+
682
+ <tr><td><code>type</code></td><td>Returns the string "number"</td></tr>
683
+
684
+ <tr><td><code>+(</code><i>list</i><code>)</code></td>
685
+ <td>Returns the sum of the number and numeric items in
686
+ <i>list</i></td></tr>
687
+
688
+ <tr><td><code>-</code></td>
689
+ <td>With no parameters, returns the negative of the number</td></tr>
690
+
691
+ <tr><td><code>-(</code><i>list</i><code>)</code></td>
692
+ <td>Returns the difference of the number and the sum of numeric
693
+ items in the non-empty <i>list</i></td></tr>
694
+
695
+ <tr><td><code>*(</code><i>list</i><code>)</code></td>
696
+ <td>Returns the product of the number and the numeric items in
697
+ <i>list</i></td></tr>
698
+
699
+ <tr><td><code>/(</code><i>list</i><code>)</code></td>
700
+ <td>Returns the quotient of the number and the numeric items in
701
+ <i>list</i></td></tr>
702
+
703
+ <tr><td><code>%(</code><i>list</i><code>)</code></td>
704
+ <td>Returns the progressive remainder of the number and the
705
+ numeric items in <i>list</i></td></tr>
706
+
707
+ <tr><td><code>&(</code><i>list</i><code>)</code></td>
708
+ <td>Returns the bit-wise "AND" of the number and the numeric items
709
+ in <i>list</i></td></tr>
710
+
711
+ <tr><td><code>|(</code><i>list</i><code>)</code></td>
712
+ <td>Returns the bit-wise "OR" of the number and the numeric items
713
+ in <i>list</i></td></tr>
714
+
715
+ <tr><td><code>^(</code><i>list</i><code>)</code></td>
716
+ <td>Returns the bit-wise "exclusive OR" of the number and the numeric
717
+ items in <i>list</i></td></tr>
718
+
719
+ <tr><td><i>op</i> or <i>op</i><code>(</code><i>value</i><code>)</code> for
720
+ <i>op</i> in <code>&lt;=</code>, <code>&lt;</code>, <code>==</code>,
721
+ <code>!=</code>, <code>&gt;</code>, <code>&gt;=</code></td>
722
+ <td>Returns whether the number is less than or equal to, less than,
723
+ equal to, not equal to, greater than, or greater than or equal to,
724
+ <i>value</i>. If <i>value</i> is not supplied or is not numeric, zero
725
+ is used.</td></tr>
726
+
727
+ </table>
728
+
729
+ <p>[<a href='#contents'>Contents</a>] [<a href='#values_methods'>Values And Methods</a>]</p>
730
+
731
+ <h3 id='string_values'>Strings</h3>
732
+
733
+ <p>Standard methods:</p>
734
+
735
+ <table>
736
+
737
+ <tr><th>Method</th><th>Description</th></tr>
738
+
739
+ <tr><td><code>call</code></td><td>Returns the string itself</td></tr>
740
+
741
+ <tr><td><code>class</code></td><td>Returns the string "String"</td></tr>
742
+
743
+ <tr><td><code>flt</code>, <code>float</code></td>
744
+ <td>Returns the floating-point value of the string</td></tr>
745
+
746
+ <tr><td><code>idx(</code><i>target</i><code>,
747
+ </code><i>offset</i><code>)</code>,
748
+ <code>index(</code><i>target</i><code>,
749
+ </code><i>offset</i><code>)</code></td>
750
+ <td>Search for <i>target</i> left-to-right in the string beginning at
751
+ position <i>offset</i> (default 0) and return the offset from the start
752
+ of the string at which found (or -1 if not found)</td></tr>
753
+
754
+ <tr><td><code>int</code></td>
755
+ <td>Returns the integer value of the string</td></tr>
756
+
757
+ <tr><td><code>len</code>, <code>length</code></td>
758
+ <td>Returns the length of the string</td></tr>
759
+
760
+ <tr><td><code>ridx(</code><i>string</i><code>,
761
+ </code><i>offset</i><code>)</code>,
762
+ <code>rindex(</code><i>string</i><code>,
763
+ </code><i>offset</i><code>)</code></td>
764
+ <td>Search for <i>target</i> right-to-left in the string beginning at
765
+ position <i>offset</i> (the end of the string by default) and return
766
+ the offset from the start of the string at which found (or -1 if not
767
+ found)</td></tr>
768
+
769
+ <tr><td><code>rng(</code><i>begin</i><code>,
770
+ </code><i>end</i><code>)</code>,
771
+ <code>range(</code><i>begin</i><code>,
772
+ </code><i>end</i><code>)</code></td>
773
+ <td>Returns characters <i>begin</i> through <i>end</i> of the string,
774
+ inclusive, counting from zero. Either may be negative, in which case
775
+ counting is backwards from the end of the string.</td></tr>
776
+
777
+ <tr><td><code>slc(</code><i>begin</i><code>,
778
+ </code><i>length</i><code>)</code>,
779
+ <code>slice(</code><i>begin</i><code>,
780
+ </code><i>length</i><code>)</code></td>
781
+ <td>Returns <i>length</i> characters beginning at <i>begin</i>,
782
+ counting from zero. <i>Begin</i> may be negative, in which case
783
+ counting is backwards from the end of the string.</td></tr>
784
+
785
+ <tr><td><code>str</code>, <code>string</code></td>
786
+ <td>Returns the string itself</td></tr>
787
+
788
+ <tr><td><code>type</code></td><td>Returns the string "string"</td></tr>
789
+
790
+ <tr><td><code>+(</code><i>list</i><code>)</code></td>
791
+ <td>Returns the concatenation of the string and the items in
792
+ <i>list</i></td></tr>
793
+
794
+ <tr><td><code>*(</code><i>value</i><code>)</code></td>
795
+ <td>Returns the concatenation of the string repeated <i>value</i>
796
+ times. If <i>value</i> is negative, the reverse of the string repeated
797
+ -<i>value</i> times is returned. If <i>value</i> is omitted or
798
+ not numeric, an empty string is returned.</td></tr>
799
+
800
+ <tr><td><i>op</i> or <i>op</i><code>(</code><i>value</i><code>)</code> for
801
+ <i>op</i> in <code>&lt;=</code>, <code>&lt;</code>, <code>==</code>,
802
+ <code>!=</code>, <code>&gt;</code>, <code>&gt;=</code></td>
803
+ <td>Returns whether the string is less than or equal to, less than,
804
+ equal to, not equal to, greater than, or greater than or equal to,
805
+ <i>value</i>. If <i>value</i> is not supplied, the empty string
806
+ is used.</td></tr>
807
+
808
+ </table>
809
+
810
+ <p>[<a href='#contents'>Contents</a>] [<a href='#values_methods'>Values And Methods</a>]</p>
811
+
812
+ <h2 id='examples'>(Some More) Examples</h2>
813
+
814
+ <p>This example binds a list method to arrays to include commas and "and"
815
+ between elements:</p>
816
+
817
+ <blockquote><code>@Array?=(') @Array['list]=({<br>
818
+ $.target.join(" and ", ", ", ", ", ", and ") })<br>
819
+ $.*('Ruby).list /* => Ruby */<br>
820
+ $.*('Perl, 'Ruby).list /* => Perl and Ruby */<br>
821
+ $.*('Perl, 'PHP, 'Python, 'Ruby).list /* => Perl, PHP, Python, and Ruby */
822
+ </code></blockquote>
823
+
824
+ <p>This example binds a method called "en_nth" on number values to return
825
+ the English "nth" for the number (e.g. 1st for 1, 2nd for 2, 3rd for 3,
826
+ etc.) and then generates them from -11 to 24:</p>
827
+
828
+ <blockquote><code>@Number?=(') @Number['en_nth]=({<br>
829
+ $.var(.. 'n, $.target) $.var(.. 'n10, n.abs%(10), 'n100, n.abs%(100))<br>
830
+ n $.if({ n100&gt;=(11)&(n100&lt;=(20)) }, 'th, { n10==(1) }, 'st,<br>
831
+ { n10==(2) }, 'nd, { n10==(3) }, 'rd, 'th) })<br>
832
+ n=(-11) $.loop({ n&lt;=(24) }, { n.en_nth n=(n+(1)) }).join(", ")
833
+ </code></blockquote>
834
+
835
+ <p>[<a href='#contents'>Contents</a>]</p>
836
+
837
+ </body>
838
+ </html>