1 Artemus 5 Templating Language Overview
2 ======================================
4 Artemus is a template toolkit. It filters text files, parsing, compiling
5 and executing code surrounded by special marks (leaving the rest
6 untouched) and concatenating everything as output. Its main purpose is
7 to filter HTML files, but it can be used for any scripting need related
8 to text filtering and substitution.
13 The Artemus 5 parser expects its code to be between the <{ and }> markers,
14 passing the rest of its input as is.
16 This will be output with no modification:
19 It includes no Art5 markup,
20 so it will pass through unmodified.
22 Artemus 5 tokens must be separated by freely distributed blanks (spaces,
23 tabs or newlines). If a single token is found, it's accepted to be a
24 template to be called. Templates can be found on disk as regular files
25 (where they will be recursively compiled), in memory as builtin operators
26 or functions (that will be discussed later), or as variables defined inside
27 the Art5 program flow.
29 Direct template file inclusion:
32 If the current directory is in the template search path and
33 a README file exists there, it will be directly included.
40 This is another example.
41 The sum of 2 plus 3 is <{add 2 3}>,
42 that will output "The sum of 2 plus 3 is 5".
44 Assignation and variable usage:
46 This is another example.
47 The TEST variable is assigned. <{= 'TEST' 'This is a test' }>
48 (Note that the above code do not generate any output).
49 And now it's printed: <{TEST}>
51 Please take note that, on assignation, the name of the variable to be
52 assigned *must* be enclosed by quotes, as if it was a string literal.
54 Any text from a # symbol to the end of the line is assumed to be a comment
58 # This won't appear in the output and will be ignored
61 A block of code, or a template invocation with arguments, must be
62 enclosed in curly brackets. The <{ and }> markers also work as code
65 Look how a `mul' (multiply) operation must be set in a code stream:
67 V and A are variables.
68 <{"Voltage: " V "Current: " A "Power: " {mul V A}}>
70 In a code block, the first argument must always be an opcode, being it a
71 builtin operator or a template name. But, if a literal is found, the
72 default opcode `?' (concatenate) is assumed. So, the following example
73 is exactly the same as the previous one:
75 <{? "Voltage: " V "Current: " A "Power: " {mul V A}}>
77 Variables, definitions and data types
78 -------------------------------------
80 Assignation to variables can be done by using the `=' operator:
82 <{= 'email' 'angel@triptico.com' # assign }>
83 Artemus author's email is <{email}>.
85 From that moment on, the `email' variable can be used as a template.
87 It's also possible to define new templates inline by using the `def'
88 operator. This code defines a `link' template that is then used:
91 # Create the 'link' template
93 ? "<a href = '" $0 "'>" $1 "</a>"
97 <{link "http://triptico.com" "Angel Ortega's Site"}>
99 Please take note that, both on asignation and template definition,
100 the name of the variable or template must be enclosed with quotes.
102 Also take note that variables and templates are essentially the same,
103 and the only difference is in the way dollar-prefixed arguments are
104 treated when the assignation or definition is done: in the first case,
105 arguments are expanded in that specific moment, but in the second one
106 the expansion is postponed until the execution.
111 Strings can be specified in two ways: by enclosing them in double quotes,
112 where backslash-prefixed codes are accepted (like \n, as in C or Perl),
113 or by enclosing in single quotes, where they are parsed verbatim.
115 <{ "This is\na test" # Output is two lines }>
116 <{ 'This is\na test' # Output is one line, \n is printed }>
118 Translateable strings
119 ~~~~~~~~~~~~~~~~~~~~~
121 A translateable string is one that will be internally translated just
122 before output. They are like double quoted strings, but prefixed by
127 The special `T' operator can be used to define sets of translateable
128 strings. For example, this code snippets translate weekday names from
134 "Wednesday" "miercoles"
141 So the <{ @"Monday" }> code above will output `lunes'.
143 The `art5' command line tool includes an option to generate translate
144 code files from a set of templates on disk. Any file matching `lang_*'
145 will be refreshed to include all translateable strings ready to be
146 edited. To start with new language file, just create an empty one.
151 Arrays can be defined by using the `&' opcode.
154 {& "Monday" "Tuesday" "Wednesday" "Thursday"
155 "Friday" "Saturday" "Sunday" }
158 Arrays can be later used in `foreach' loops and such. Each element of an
159 array can be a scalar (as in the example) or another array itself. These
160 structures can be as complicated as desired.
165 Any included template can be called with arguments. For example:
167 <{ link 'http://triptico.com/software/artemus.html' 'Artemus Home Page' }>
169 The `link' template will access its arguments as numbers prefixed by the `$'
170 sign, as in the example:
172 <{ # generate an link
173 '<a href = "' $0 '">' $1 '</a>'
176 External hash elements
177 ~~~~~~~~~~~~~~~~~~~~~~
179 When Artemus 5 is used as a library inside an application, an external hash
180 can be provided at startup. The values for this hash can be accessed by
181 prefixing them with the `%' sign. For example, in the Gruta Content
182 Management System, the external hash is filled with the CGI arguments.
184 The topic is <{%topic}>.
186 In the `art5' command line tool, though, the external hash only has a
187 key/value pair, `arch', containing the system architecture (most probably
190 The current architecture on this system is <{%arch}>.
192 Conditional and looping constructs
193 ----------------------------------
198 The `if' opcode can be used for conditional output. It has two mandatory
199 arguments, the condition and the output if true:
201 <{if accepted "Operation was accepted" # accepted should return 1 or 0 }>
203 It also accepts an optional third argument, to be output if the condition
206 Operation <{if accepted "was accepted" "was NOT accepted"}>.
208 As discussed above, if any of the three code blocks contain more than one
209 opcode or one with arguments, they must be enclosed by curly brackets:
211 Error msg: <{if {eq msg "OK"} "All OK" "Something bad happened"}>
213 <{if {eq %user "anonymous"}
214 "No user logged" {"User " %user " logged in"}
220 The `foreach' opcode can be used for looping through arrays. It accepts
221 up to 4 arguments, being mandatory just the first one, the array:
223 Concatenates the full array without separation
226 The second argument is a code block that will be called on each iteration
227 with the arguments filled with each element of the array. For arrays
228 with scalar elements, only the first ($0) element is filled.
230 Prints each array element with a heading in its own line
231 <{foreach weekdays {"Week day: " $0 "\n"}}>
233 If an element of the array is itself an array, arguments from $0 up to $9
234 will be filled with the elements of the array.
236 <{= 'dataset' {& {& 'a' 1} {& 'b' 2} {& 'c' 3}}}>
237 <{foreach dataset { "Value for element " $0 " is " $1 "\n" }}>
239 The array can be defined inline:
241 The multiplying table of 2
242 <{foreach {& 1 2 3 4 5 6 7 8 9 10} { $0 " by 2 is " {mul $0 2}}}>
244 Though, for loops like this, the `seq' opcode is more useful, as it
245 generates a sequence of numbers:
247 <{foreach {seq 1 10} { $0 " by 2 is " {mul $0 2}}}>
249 The third argument to `foreach' is a separator, that will be emitted as
250 output between each call to the main code block:
252 <{foreach {seq 1 10} $0 ", " }>
254 And the fourth one is a header; it will be emitted everytime the output
255 generated by it is different that the previous one. This can be useful
256 to generate subheaders everytime a field changes:
264 <{foreach {& {& 'a' 1} {& 'a' 2} {& 'b' 3}} { " " $1 "\n" } ""
267 It can also be used to generate a header only if the array is not empty:
275 <{foreach {& 1 2 3 4} $0 "\n" "Dataset\n" }>
277 Output will be nothing
278 <{foreach {&} $0 "\n" "Dataset\n" }>
283 The `case' opcode can be used as a multiple choice code generator. The
284 first argument is the value to be compared, followed by pairs of
285 value-output code block.
288 "Unix" { "Some Unix system (Linux, etc)" }
289 "win32" { "Some version of MS Windows" }
292 The first argument is compared sequentially until one is found, and then
293 the associated code block is emitted. If none is found, nothing is output.
295 If the number of arguments is odd, the last one is not compared, but
296 accepted as the `otherwise' clause and used as output in case no value
300 "Unix" { "Some Unix system (Linux, etc)" }
301 "win32" { "Some version of MS Windows" }
302 { "Some other strange architecture I didn't envisioned" }
305 Builtin operators and functions
306 -------------------------------
311 The `eq' and `ne' operators can be used to test for equality or inequality
314 Numerical comparisons
315 ~~~~~~~~~~~~~~~~~~~~~
317 The `gt' and `lt' operators can be used to test greater-than and lower-than
318 numerical comparisons.
323 The `and', `or' and `not' can be used as boolean operators. Both `and' and
324 `or' do not return some true or false values, but the value tested itself,
325 so they can be used as simple conditionals. For example:
327 Stores in the user variable the content of %user or,
328 if it's empty, the "anonymous" string
329 <{= user {or %user "anonymous"}}>
334 Array definitions and the `seq' operator has been seen above; other array
335 manipulation opcodes are `reverse', that does the obvious or `size', that
336 returns the number of elements in the array.
338 The `split' opcode can be used to split an array by using a separator:
340 <{foreach {split "," "1,2,3,4,5"} {$0 "\n"}}>
342 The `sort' opcode can be used to sort an array. The 1 argument version
345 Print in proper order:
346 <{foreach {sort {& 3 4 2 5 6 4 3 2 4 5 6 4}} $0 ', ' }>
348 If a second argument is used, it's assumed to be a code block to be
349 executed on each pair of arguments as a sort order criteria:
351 <{foreach {sort {& 3 4 2 5 6 4 3 2 4 5 6 4} {sub 1000 $0}} $0 ', ' }>
356 The `add', `sub', `mul' and `div' exist as their corresponding math
362 An undefined operator or template name generates a fatal error unless
363 an `AUTOLOAD' template is defined. If it is, it's called on errors
364 with the offending template name sent as the only argument. This allow
365 automatic loading from external sources, code generation on the fly
366 or simply returning the error in the output stream.
371 The `env' opcode returns the value of an environment variable; if no
372 argument is given, the full set of existing environment variables will
373 be returned as an array.
375 The `random' opcode accepts an arbitrary number of arguments and returns
376 one of them, at random.
379 Angel Ortega <angel@triptico.com>