Domex is an algebraic expression language for creating DOM trees from input data. It can be used as a template language for HTML, but it is quite different from traditional template languages. It has characteristics of a specification– or a data description language.
The abstract syntax of Domex is given by the following grammar. The grammar consists of two main categories: DOM expressions E and AttributeList expressions Attrs, where the latter makes use of attribute expressions A and attribute-value expressions V.
E ::=
tag-name | text | @
ref | $
| %
E .
class | E #
id | E [
Attrs]
E >
E | E +
E | E |
E
E *
| E ~
prop
E @
name | E1 ;
… ;
En ;
E
E :
test | E ::
type-test
(
E )
Attrs ::= A Attrs
A ::= attr-name | attr-name =
V
V ::= text | $
| %
…
DOM Expressions denote render functions that take structured data as input to a list of DOM Nodes as output.
- tag-name — creates a singleton list with a single tag-name-element.
- text — creates a singleton list with a single text-node.
@
ref — refers to an expression with the name ref in scope.$
— creates a singleton list with the key of the current input as a text-node.%
— creates a singleton list with the current input converted to a text-node.
- E
.
class — adds class to theclass
attribute of the last element of E. - E
#
id — sets theid
attribute of the last element of E to id. - E
[
name=
value]
— adds an attribute named name with value value to the last element of the result of E.
Note: I am still looking at the design of the attribute operators. The question is, should they indeed only 'apply to the last element'? ==> NO
- E1
>
E2 — adds E2 as children to all element in E1. - E1
+
E2 — adds E2 as siblings to E1. - E1
|
E2 — the or–else operator – equivalent to E2 if E1 evaluates to an empty list; otherwise equivalent to E1.
- E
*
— evaluates E against each key-value pair in the current input and combines the results into a list of siblings. - E
~
name — evaluates E against the property named name of the input data.
Shorthands:
- The notation
%
name may be used as a shorthand for%
~
name. - Likewise, E
%
name may be used for E%
~
name. - Likewise, E
*
name is a shorthand for E*
~
name.
- E text — appends text to all elements in E.
- E
$
— Appends the key of the current input as a textnode to all elements in E. - E
%
— Appends a string representation of the current input to all elements in E.
Note: The design of the append operator with dynamic content (i.e. the last two items) is still somewhat problematic and may require some changes. Naïvely E %
is a shorthand for (E >
%
), however the ~
operator is made to distribute over >
, e.g. span ~name > %
is equivalent to (span > %) ~name
. Thus the question is, what should the semantics of e.g. div ~prop %
be?
- E
@
name — assigns the expression E the name name. Used in declarations and in recursive expressions. - E1
;
…;
En;
E – declaration list; use the named expressions in E1 … En in the evaluation of E.
- E
:
test — runs a test named test against the current input and evaluates E if true, or returns an empty sequence otherwise. - E
::
test — runs a type-test named test against the current input and results in E if true, or in the empty sequence otherwise.
- E1
*
>
E2 = (E1>
E2)*
- E1
*
text = (E1>
text)*
- E1
*
$
= (E1>
$
)*
- E1
*
%
= (E1>
%
)*
For example, dl > di* > dt $ + dd %
is equivalent with dl > (di > dt $ + dd %)*
.