Minimal meta-HTML DSL compiler.


Write Web pages using a minimal meta-HTML syntax — no XML cruft! Designed to be clean and clear without compromising functionality. Includes a simple, extensible templating system with support for Markdown and other external content processors.

  • Elegantly minimal meta-HTML DSL syntax
    • easily generates fully HTML5-compliant web pages
  • Flexible templating system
    • include nominal files recursively
    • include lightweight markup files using auto-executed external tool processing
  • Functions as the NomDT builder.


The Nominal file used to produce the present Web page:

@Define base = Parts                ◀ define variables 
@Define project = "Nominal"
@Define title = "Certiv Analytics - " + $project

@Include Doctype                    ◀ key expansion from HTMLDictionary
Html lang:en {                      ◀ title case tag names
  @Include $base + "certivHead.nom" ◀ include boilerplate

  Body {                            ◀ braces delimit tag scope
    Div #bodyWrapper {
      @Include $base + "certivProjSidebar.nom"

      // Main Page Content
      Section #contentWrapper .scroll-page {    ◀ '#': CSS id 
        Header .contentHeader {                 ◀ '.': CSS classes 
          Button .menuBtn #menuToggle type:button .btn .btn-default

        // Page content
        Main .content .container-fluid {
          Div .row {
            Div .col-md-10 {
              Div .prjPageLogo                  ◀ empty body
              @Include Content + ""
              @Include Content + "NominalDir.txt"
              @Include Content + ""
        @Include $base + "certivFoot.nom"
    @Include $base + "scriptStd.nom"

Quick notes:

  • title case of HTML tag names is significant.
  • order of CSS attributes is not significant.
  • whitespace around CSS attributes is not significant.
  • custom CSS attributes are specified by key:value.
  • if an attribute value has embedded whitespaces, enclose in quotes, single or double.
  • custom HTMLDictionary.json entries enable key value text expansion
  • omit empty bodies


Every tag is represented by a statement of the form

Name style* body? 
Tag Name

Tag names are the simple, title cased names of the HTML5-compliant tags.


CSS attributes are defined using these forms

Representation Description
#value specification of a CSS ID; expands to id="value" within the opening tag; if multiple instances are provided, only the last will be be present in the generated tag.
.value specification of a CSS CLASS; expands to class="value" within the opening tag; multiple instances may be provided
key:value specification of a custom attribute; expands to key="value" within the opening tag; if the value has an embedded whitespace, enclose the value in quotes, single or double; multiple instances may be provided

Other than with respect to the multiple instances of ID attributes, the order of CSS attributes is not significant.

The existence of whitespace around CSS attributes is not significant. Attributes can be chained tightly together, aligned vertically, or neatly spaced with no functional distinction.

Tag Body

The tag body defines the containment scope of the corresponding HTML5-compliant tag. A tag body is only valid for HTML5 non-void elements.

The body is specified by brace delimiters enclosing zero or more tag statements. The body is optional, and preferably omitted, if it is empty.


There are two commands, @Define and @Include.

The @Define command creates a variable of implicit typing, allowing assignment using both concatenation and arithmetic operations. The command has the general form

@Define expression ( Comma expression )*

where expression is generally of the form

( name|varRef) ( '=' ( name|varRef|string ) ( op  ( name|varRef|string ) )*)?

For a name, a new variable is created. For a varRef, the value of the variable is updated.

The @Include command includes the content of the file or value referenced directly or indirectly by the object of the include statement; the object of the include can be a string, variable reference or the RHS of an expression. That is, it has the general form

@Include  ( name | varRef | string | expressionRHS )

The object is evaluated and resolved first as a lookup key against the entries present in the HTMLDictionary. If a corresponding entry is found, the found value is returned as the literal text for inclusion.

Where there is no lookup key match, the object is then resolved, as a filename, against the filesystem. If the named file is readable, it is read and processed dependent on the filetype. Nominal files are recursively evaluated, with prior defined variables being progressively visible in subsequent recursive evaluations.

Other file types are evaluated against the HTMLDictionary to identify if a corresponding filter program is identified. If a filter exists, the content of the file is processed through the filter prior to inclusion.


Variables created using the @Define command are generally of the form

 '$'? name

Variable names are case sensitive and cannot include whitespace. References to prior defined variables are made using a '$' prefix.

There are two builtin variables: Parts and Content. These variables cannot be assignment receivers. They are referenced without using the '$' prefix.

The Parts variable is automatically assigned the path value of the ‘parts directory’ argument provided through the CLI.

The Content variable is dynamically assigned the path value of the ‘content’ subdirectory of the directory containing the Nominal file that references the variable. Even under recursive inclusion of Nominal files, the value of the Content variable is in fact logically fixed: it will always refer to the ‘content’ subdirectory relative to the file that contains that unique reference.


The HTMLDictionary is an ordinary JSON file providing a flat set of key-value pairs. Note: if the file contains any non-JSON compliant header // comment lines, they will be stripped prior to unmarshalling.

// Format is Json. Keys must be unique. Key lookup is case insensitive.
  "md-tool" : "D:/DevFiles/Go/WorkSpaces/Main/GitHub/bin/blackfriday-tool.exe",
  "md-args" : "-smartypants=true",
  "Doctype" : "<!DOCTYPE html>",

The file will generally contain two types of entries: tool entries and literal expansions. Tool entries are composed of command and argument entries; the key for the command is the filter filetype-tool; for the arguments, filter filetype-args.

For literal expansions, the entry value is the expanded text value that will be included.

Project Structure

A minimum ‘General’ Eclipse project can be used as the development Web site container. Exemplary project structure:

Workspace Root                      ◀ Eclipse workspace root directory
      └───Project Root              ◀ your Eclipse project directory
              ├───output            ◀ root dir for the generated html 
              │   ├───app           ◀ conventional app resources
              │   │   ├───css
              │   │   ├───fonts
              │   │   ├───img
              │   │   └───js
              │   ├───download      ◀ generated subdirs containing html
              │   ├───legal
              │   ├───projects
              │   └───support
              ├───source            ◀ root dir for nom files
              │   ├───content       ◀ content dir for root nom files
              │   ├───download      ◀ a subdir for nom files
              │   │   └───content   ◀ content dir for the subdir nom files
              │   ├───legal
              │   │   └───content
              │   ├───projects
              │   │   └───content
              │   └───support
              │       └───content
              └───_parts            ◀ dir containing includable nom files
                                           and the 'HTML' dictionary


Antlr Runtime 4.5.3


Antlr-standard BSD License. See the accompanying License.txt file.