Nominal
Minimal meta-HTML DSL compiler.
Summary
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.
Example
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 + "Nominal.md"
@Include Content + "NominalDir.txt"
@Include Content + "NominalRem.md"
}
}
}
@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
Tags
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.
Style
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.
Commands
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
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.
HTMLDictionary
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
Requirements
Antlr Runtime 4.5.3
License
Antlr-standard BSD License. See the accompanying License.txt file.