Until I can spec this out properly, I’ll quote an old post:
TPP stands for either Text Pre-Parser or Template Pre-Parser. The original design derived from the C pre-processor and a simplified Eiffel version. Having encountered StringTemplate, however, I thought of doing a Lua interpretation of that instead. (Maybe with a more readable syntax.)
Preprocessor
Conditionals
Leaving aside operator precedence for a moment, this is the EBNF for
all conditional expressions in an ifdef and ifndef
condition ::= SYMBOL
| condition ( boolop condition )+
| "!" condition
| "(" condition ")"
boolop ::= "&&" | "||"
SYMBOL ::= [A-Z][A-Z0-9a-z_]*
Directives
define
#define <symbol>
error
#error "<msg>"
undefine
#undefine <symbol>
ifdef
#ifdef <condition>
...
#else
...
#endif [<condition>]
ifndef
#ifndef <condition>
...
#else
...
#endif [<condition>]
include
#include "<path>"
warning
#warning "<msg>"
Template Language
While the Preprocessor simply acts on flags, the Template Language processes a data model to generate HTML, code, or anything else.
It incorporates the commands of the Preprocessor, plus those listed below.
The Data Model
TODO
- Array
- Boolean
truefalse
- Integer
- BigInt
- SmallInt
- Number
- BigDecimal
- Float
NaNInf-Inf
- Object
- String
null- undefined
True and False
TODO
{}[]""NaNfalsenull- undefined
Notably, 0 and 0.0 are treated as true, although NaN is considered
false.
Expressions
Ignoring the blurry line between syntax and functions in the Lisp-like expression language, here’s the syntax for expressions:
expr ::= boolexpr | cntexp | ifexpr | funcall | path | const | "(" expr ")"
const ::= STRING | INTEGER | NUMBER | "true" | "false" | "null"
boolexp ::= expr boolop expr
boolop ::= "&&" | "||" | "!"
| "==" | "!=" | "<" | "<=" | ">" | ">="
| "??" | "!?"
cntexp ::= "#" path
ifexpr ::= boolexpr "?" expr ":" expr
funcall ::= fcnname "(" expr* ")"
fcnname ::= SYMBOL
path ::= SYMBOL ( ( "." SYMBOL ) | ( "[" expr "]" ) )*
SYMBOL ::= [A-Za-z][A-Za-z0-9_]*
STRING ::= "\"" ( [^"]* | "\\"" )* "\""
INTEGER ::= "0" | [+-][1-9][0-9]*
NUMBER ::= INTEGER ( "." [0-9]* )? ( [eE] [+-]? [0-9]+ )?
VAR ::= SYMBOL | "_"
WS ::= ( " " | "\t" )*
Substitutions
${<path>}
TODO
$(<expr>)
TODO
Directives
if
#if <expr>
...
#elseif <expr>
...
#else
...
#endif
TODO
foreach (Array)
#foreach <symbol> <array-expr>
...
#else
...
#endfor
TODO
foreach (Object)
#foreach <var> <var> <object-expr>
...
#else
...
#endfor
TODO
Syntax
and
expr && expr ⇒ Boolean
TODO
count
# array ⇒ Integer
Count the number of elements in an Array.
# object ⇒ Integer
Count the number of keys in an Object.
# string ⇒ Integer
Count the number of characters in an Array or Object.
defined
?? symbol ⇒ Boolean
TODO
?? expr ⇒ Boolean
TODO
eq
expr == expr ⇒ Boolean
TODO
ge
expr >= expr ⇒ Boolean
TODO
gt
expr > expr ⇒ Boolean
TODO
if
boolexpr ? expr1 : expr2
If boolexpr evaluates to true, evaluate and substitute expr1. Otherwise, evaluate and substitute expr2.
le
expr <= expr ⇒ Boolean
TODO
lt
expr < expr ⇒ Boolean
TODO
neq
expr != expr ⇒ Boolean
TODO
not
! expr ⇒ Boolean
TODO
or
expr || expr ⇒ Boolean
TODO
undefined
?! symbol ⇒ Boolean
TODO
?! expr ⇒ Boolean
TODO
Functions
TODO
A future release may allow users to define their own functions. Until then, add function results to the data model and refer to that.
join
join (<str>, <array-or-object>) ⇒ String
Join the elements of an array or object into a single string, separated by the string object.
tojson
tojson (<expr>) ⇒ String
Convert the expression to a JSON string.