Permalink
Fetching contributors…
Cannot retrieve contributors at this time
executable file 518 lines (319 sloc) 10.8 KB
EBNF
====
Program
-------
The template language starts with the non-terminal token: "Program".
::
Program ::= Version NewLine Code EOF
Version ::= '{?' 'ezt' 'version' '=' '"' FloatLiteral '"' '}'
Code ::= ( Text | Block )*
Text ::= TextBlock
| LiteralBlock
| DelimiterBlock
Block ::= CommentBlock
| DeclarationBlock
| ModifyingBlock
| OutputBlock
| LiteralBlock
| CycleBlock
| LoopBlock
| CodeFlowBlock
| CustomBlock
Text blocks
-----------
::
TextBlock ::= ( ~'{' | '\'! '{' )*
LiteralBlock ::= '{' 'literal' '}' Graphic* '{' '/literal' '}'
DelimiterBlock :== '{ldelim}' | '{rdelim}'
Blocks
------
::
CommentBlock ::= '{*' Graphic* '*}'
DeclarationBlock ::= '{' 'var' SubDefineBlock '}'
| '{' 'cycle' SubDefineBlock '}'
| '{' 'use' SubDefineBlock '}'
SubDefineBlock ::= PrimaryVariable ( '=' Expression )? ( ',' SubDefineBlock )?
ModifyingBlock ::= '{' SubAssignBlock (',' SubAssignBlock)* '}'
SubAssignBlock ::= AssignmentExpr | IncrementExpr | DecrementExpr
AssignmentExpr ::= PrimaryVariable ( '=' | CombinedAssignment) Expression
IncrementExpr ::= ( ( '++' PrimaryVariable ) | ( PrimaryVariable '++' ) )
DecrementExpr ::= ( ( '--' PrimaryVariable ) | ( PrimaryVariable '--' ) )
OutputBlock ::= '{' Expression '}'
CycleBlock ::= '{' 'increment' PrimaryVariable ( ',' PrimaryVariable )* '}'
| '{' 'decrement' PrimaryVariable ( ',' PrimaryVariable )* '}'
| '{' 'reset' PrimaryVariable ( ',' PrimaryVariable )* '}'
Loop control
------------
::
LoopBlock ::= ForeachStatement
| WhileStatement
ForeachStatement ::= '{' 'foreach' Expression 'as' PrimaryVariable ('=>' PrimaryVariable)? (Cycle)* (OffsetAndLimit)? '}' Code '{' '/foreach' '}'
WhileStatement ::= '{' 'while' Expression '}' Code '{' '/while' '}'
Cycle ::= ('increment' | 'decrement') PrimaryVariable (',' PrimaryVariable)*
OffsetAndLimit ::= ('offset' Expression)? ('limit' Expression)?
Code flow control
-----------------
::
CodeFlowBlock ::= IfStatement
| SwitchStatement
| IncludeStatement
| DelimiterStatement
| '{break}'
| '{skip}'
| '{continue}'
| ReturnStatement
IfStatement ::= '{' 'if' Expression '}' Code (ElseIf)* (Else)? '{' '/if' '}'
ElseIf ::= '{' 'elseif' Expression '}' Code
Else ::= '{' 'else' '}' Code
SwitchStatement ::= '{' 'switch' Expression '}' (Case)* (DefaultCase)? '{' '/switch' '}'
Case ::= '{' 'case' Literal ( ',' Literal)* '}' Code '{' '/case' '}'
DefaultCase ::= '{' 'default' '}' Code '{' '/default' '}'
IncludeStatement ::= '{' 'include' Expression ('send' ExprAsPrimVarList)? ('receive' PrimVarAsPrimVarList)? '}'
DelimiterStatement ::= '{' 'delimiter' (modulo Expression ('is' Expression)? )? '}' Code '{' '/delimiter' '}'
ReturnStatement ::= '{' 'return' ExprAsPrimVarList '}'
ExprAsPrimVarList ::= ( Expression 'as' PrimaryVariable | PrimaryVariable ) (',' ExprAsPrimVarList)?
PrimVarAsPrimVarList::= PrimaryVariable ('as' PrimaryVariable)? (',' PrimVarAsPrimVarList)?
Custom block
------------
::
CustomBlock ::= '{' Identifier ( Expression )? ( CustomArgument )* '}' (Code '{' '/'Identifier '}')?
CustomArgument ::= Identifier ( ('=')? Expression)?
Expression
----------
::
Expression ::= PreUnaryExpression (BinaryOperator Expression)?
PreUnaryExpression ::= '++' PrimaryVariable
| '--' PrimaryVariable
| UnaryExpression
| Expression 'instanceof' Identifier
| ArrayDeclaration
ArrayDeclaration ::= 'array' '(' ( (Expression '=>')? Expression ( ',' Expression )* (',')? )? ')'
| Expression '..' Expression
UnaryExpression ::= ( UnaryOperator )* PostFixExpression
PostFixExpression ::= PrimaryVariable ( '++' | '--' )?
| Literal
| FunctionCall
| '(' Expression ')'
PrimaryVariable ::= '$' Identifier ( '[' Expression ']' | '->' Expression )*
FunctionCall ::= Identifier '(' (ParameterList)? ')'
ParameterList ::= Expression ( ',' Expression )*
Identifier ::= Letter ( Letter | Digit | '_' )*
Basic literals
--------------
::
Literal ::= NumeralLiteral
| StringLiteral
| BooleanLiteral
| NullLiteral
NumeralLiteral ::= HexLiteral | OctLiteral | FloatLiteral
HexLiteral ::= '0x' HexDigit+
OctLiteral ::= '0' OctDigit+
FloatLiteral ::= NonZeroDigit Digit* ( '.' Digit+ )? (('e'|'E') ('+'|'-')? Digit+)?
StringLiteral ::= '"' Graphic* '"'
| "'" Graphic* "'"
BooleanLiteral ::= 'true'
| 'false'
NullLiteral ::= 'null'
Lexicon
-------
::
Comment ::= '//' Graphic* ( EOL | '}' )
| '/*' Graphic* '*/'
Graphic ::= Digit | Letter | Blank | Operators | Assignment | CombinedAssignment | RemainingCharSet
EOL ::= end-of-line
EOF ::= end-of-file
Blank ::= Tab | Space
NewLine ::= '\n'
Space ::= ' '
Tab ::= '\t'
Letter ::= 'a' ... 'z' | 'A' ... 'Z'
Hexdigit ::= '0' .. '9' | 'A' .. 'F'
Octdigit ::= '0' .. '8'
NonZeroDigit ::= '1' .. '9'
Digit ::= '0' | NonZeroDigit
Assignment ::= '='
CombinedAssignment ::= '+=' | '-=' | '*=' | '/=' | '%=' | '.='
Operators ::= BinaryOperator | UnaryOperator | '++' | '--'
BinaryOperator ::= ArithmeticOperator | ComparisonOperator | BooleanOperator | StringOperator
ArithmeticOperator ::= '+' | '-' | '*' | '/' | '%'
ComparisonOperator ::= '==' | '===' | '!=' | '!==' | '<' | '<=' | '>' | '>='
BooleanOperator ::= '&&' | '||'
StringOperator ::= '.' | '.='
UnaryOperator ::= '+' | '-' | '!'
RemainingCharSet ::= '.' | ':' | ';' | ',' | '~' | '(' | ')' | '[' | ']' | '{' | '}' | '_' | '|' | "'" | '"' | '`' | '#' | '$' | '@'
Examples
========
Text
----
Normal text output
^^^^^^^^^^^^^^^^^^
The next example writes "hello world"::
{?ezt version="1.0" }
Hello world
Using ldelim and rdelim
^^^^^^^^^^^^^^^^^^^^^^^
Template::
{?ezt version="1.0" }
{ldelim}?ezt version="1.0"{rdelim}
writes {?ezt version="1.0"} to the output.
Comments
--------
Block comments
^^^^^^^^^^^^^^
The following template::
{?ezt version="1.0"}
{* Hello *} world
will only output "world".
Inline comments
^^^^^^^^^^^^^^^
::
{ // Hello } world
{ // Hello
} earth
outputs::
world
earth
c-comment
^^^^^^^^^
::
{ /* Hello */ "world" }
outputs::
world
Foreach
-------
Foreach-ing over an array
^^^^^^^^^^^^^^^^^^^^^^^^^
::
{var $colors = array( "red" => "#FF0000", "green" => "#00FF00" )}
{foreach $colors as $name => $value}
<font color="{$value}">$name</font>
{/foreach}
Counting from 1 to 10
^^^^^^^^^^^^^^^^^^^^^
Using a function::
{foreach array_range(1, 10) as $value}
Iteration number: {$value}
{/foreach}
Or the short notation::
{foreach 1..10 as $value}
Iteration number: {$value}
{/foreach}
Using the cycle
^^^^^^^^^^^^^^^
::
{* Declaring the $blackAndWhite cycle *}
{cycle $blackAndWhite = array( '#00000', '#FFFFFF' )}
{foreach 1..10 as $value increment $blackAndWhite}
<font color="{$blackAndWhite}">Numbers: {$value}</font>
{/foreach}
Using offset and limit
^^^^^^^^^^^^^^^^^^^^^^
::
{var $hugeArray = 1..1000
{*show number 50 to 100 *}
{foreach $hugeArray as $value offset 50 limit 50}
My favourite numbers are: {$value}
{/foreach}
While
-----
Counting from 1 to 10
^^^^^^^^^^^^^^^^^^^^^
::
{var $i = 0}
{while $i <= 10}
Number: {$i}
{$i++}
{/while}
Using the cycle
^^^^^^^^^^^^^^^
For the while loop, you have to do the cycling yourself. Note that the
while loop is used rarely.
::
{var $i = 0}
{cycle $oddOrEven = array("odd", "even")}
{while $i <= 10}
Number {$i} is {$oddOrEven}
{increment $oddOrEven}
{$i++}
{/while}
If
--
::
{var $i = 10}
{if $i % 2 == 0}
The number is even.
{elseif $i % 2 == 1}
The number is odd.
{else}
The number is neither odd nor even. Which is a tiny bit strange.
{/if}
Switch
------
::
{var $number = 4}
{switch $number}
{case 1}
One
{/case}
{case 2}
Two
{/case}
{case 3,4,5}
Three, Four, or Five
{/case}
{default}
Any number except 1 to 5.
{/default}
{/switch}
Properties
----------
Use
^^^
The nodes: $node and $optionalNode come from the application, and need therefore be known in the template code.
If the $optionalNode is not set, it will get the default value "false"::
{use $node, $optionalNode = false}
Accessing a property
^^^^^^^^^^^^^^^^^^^^
::
{use $node, $optionalNode = false}
Impressive title: {$node->impressiveTitle}
Norwegian title: {$node->titles["norwegian"]}
{if $optionalNode != false}
Extra title: {$optionalNode->titles["norwegian"]}
{/if}
Dynamic names
^^^^^^^^^^^^^
::
{use $node}
{$property = "impressive" . "Title"}
Impressive title: {$node->$property}
Delimiter
---------
::
{var $columns = 4}
<table>
<tr>
{foreach 1..12 as $nr}
<td>{$nr}</td>
{delimiter modulo $columns /* is 0 */ }
</tr><tr>
{/delimiter}
{/foreach}
</tr>
Including templates
-------------------
::
{use $currentNode}
{* Call the template with the variable $node that contains the value $currentNode *}
{include 'showAndAlterNode.tpl'
send $currentNode as $node
receive $node as $alteredNode}
{* The template returns a $node, but we rename it to $alteredNode *}
{* Rename the $alteredNode to $currentNode *}
{return $alteredNode as $currentNode}
..
Local Variables:
mode: rst
fill-column: 79
End:
vim: et syn=rst tw=79