Skip to content

Latest commit

 

History

History
123 lines (68 loc) · 4.51 KB

domex-lang.md

File metadata and controls

123 lines (68 loc) · 4.51 KB

The Domex Language

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.

Grammar

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.

DOM Expressions

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 )

Attribute Expressions

Attrs   ::=     A  Attrs

A   ::=     attr-name      |     attr-name = V

V   ::=     text     |     $     |     %

Operator Precedence

Semantics

DOM Expressions denote render functions that take structured data as input to a list of DOM Nodes as output.

Primitives

  • 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.

Attributes

  • E.class — adds class to the class attribute of the last element of E.
  • E#id — sets the id 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

Child and Sibling Combinators

  • 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.

Decomposition :=: Selection and Iteration

  • 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.

Append operator

  • 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?

Named expressions

  • 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 E1En in the evaluation of E.

Conditionals

  • 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.

Some Axioms

  • 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 %)*.