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.
- data/HISTORY.txt +15 -0
- data/TEMPLATE_MANUAL.html +838 -0
- data/lib/ltdtemplate/code/call.rb +46 -0
- data/lib/ltdtemplate/code/code_block.rb +30 -0
- data/lib/ltdtemplate/code/parameters.rb +40 -0
- data/lib/ltdtemplate/code/subscript.rb +81 -0
- data/lib/ltdtemplate/code/variable.rb +77 -0
- data/lib/ltdtemplate/code.rb +102 -0
- data/lib/ltdtemplate/value/array.rb +168 -0
- data/lib/ltdtemplate/value/boolean.rb +79 -0
- data/lib/ltdtemplate/value/code_block.rb +40 -0
- data/lib/ltdtemplate/value/namespace.rb +135 -0
- data/lib/ltdtemplate/value/nil.rb +27 -0
- data/lib/ltdtemplate/value/number.rb +93 -0
- data/lib/ltdtemplate/value/string.rb +121 -0
- data/lib/ltdtemplate.rb +451 -0
- data/ltdtemplate.gemspec +16 -0
- data/test/00class.rb +20 -0
- data/test/01instance.rb +30 -0
- data/test/02tpl_literal.rb +61 -0
- data/test/03tpl_singletons.rb +48 -0
- data/test/04number.rb +36 -0
- data/test/05string.rb +30 -0
- data/test/06array.rb +34 -0
- metadata +94 -0
@@ -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
|
+
<<a href='mailto:briank@kappacs.com'>briank@kappacs.com</a>>,
|
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><<</code>"
|
52
|
+
and "<code>>></code>" that don't contain "<code><<</code>"
|
53
|
+
or "<code>>></code>" are template code; the rest is literal
|
54
|
+
text. Given a sequence of the form:</p>
|
55
|
+
|
56
|
+
<blockquote>
|
57
|
+
<code>A<<B<<C>>D<<E>>F>>G<<<H>>>I</code>
|
58
|
+
</blockquote>
|
59
|
+
|
60
|
+
<p>template code cannot begin at "<<B" because it is not allowed
|
61
|
+
to contain "<code><<</code>" or "<code>>></code>", so the
|
62
|
+
first template code is "<code><<C>></code>", the second is
|
63
|
+
"<code><<E>></code>", and the last is
|
64
|
+
"<code><<H>></code>". Everything else ("<code>A<<B</code>",
|
65
|
+
"<code>D</code>", "<code>F>>G<</code>", and "<code>>I</code>")
|
66
|
+
is treated as literal text.</p>
|
67
|
+
|
68
|
+
<p>If template code begins with "<code><<.</code>" (with a period
|
69
|
+
immediately after the second "<code><</code>"), it strips any trailing
|
70
|
+
white space from immediately preceding literal text. Likewise, if template
|
71
|
+
code ends with "<code>.>></code>", it strips any leading white space
|
72
|
+
from immediately following literal text. Template code consisting of
|
73
|
+
only "<code><<.>></code>" is considered to meet both
|
74
|
+
conditions and is equivalent to "<code><<..>></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><<>></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><<</code>"
|
82
|
+
(or "<code><<.</code>") and "<code>>></code>" (or
|
83
|
+
"<code>.>></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 '<\< '>\>
|
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—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
|
+
@['<\<weird>\>]</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>-></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>+>(</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><-</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><+(</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><=</code>, <code><</code>, <code>==</code>,
|
721
|
+
<code>!=</code>, <code>></code>, <code>>=</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><=</code>, <code><</code>, <code>==</code>,
|
802
|
+
<code>!=</code>, <code>></code>, <code>>=</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>=(11)&(n100<=(20)) }, 'th, { n10==(1) }, 'st,<br>
|
831
|
+
{ n10==(2) }, 'nd, { n10==(3) }, 'rd, 'th) })<br>
|
832
|
+
n=(-11) $.loop({ n<=(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>
|