Ecmarkup is a number of custom elements and a toolchain suitable for specifying semantics for ECMAScript and other programming languages.
Ecmarkup offers the following conveniences (among many others):
This document is itself written using Ecmarkup. Its source can be viewed on github.
npm install -g ecmarkup ecmarkup --help ecmarkup spec.html out.html
Build options and document options can be passed in via the command line or specified in the front-matter of your document.
Option | Description |
---|---|
watch | Rebuild when files change |
verbose | Print verbose logging info |
biblio | Emit a biblio file to the specified location |
assets | "none" for no css/js, "inline" for inline css/js |
css-out | Emit the Ecmarkup CSS file to the specified location |
js-out | Emit the Ecmarkup JS file to the specified location |
Option | Description |
---|---|
title | Title of specification, for example ECMAScript 2016 or Async Functions . |
status | Status of specification. Can be proposal , draft , or standard . Default is proposal . |
stage | Stage of proposal. Must be a number if provided, but is optional. Sets version to Stage N Draft , but can be overridden. |
version | Version of specification, for example 6<sup>th</sup> Edition or Draft 1 . Optional. |
date | Date the spec was generated. Used for various pieces of boilerplate that include dates. Defaults to today's date. |
shortname | Shortname of specification, for example ECMA-262 or ECMA-402 . |
location | URL of this specification. Use in conjunction with the biblio file to enable external specs to reference this one. |
copyright | Emit copyright and software license information. Boolean, default true. |
contributors | Contributors to this specification, ie. those who own the copyright. If your proposal includes text from any Ecma specification, you should include "Ecma International" in this list. |
toc | Emit table of contents. Boolean, default true. |
old-toc | Emit the old style of table of contents. Boolean, default false. |
ecma-262-biblio | Load the ECMA-262 biblio file. Boolean, default true. |
Ecmarkup requires css styles and, if you're using the sidebar table of contents, javascript as well. By default CSS and JS dependencies are inlined into the document. You can override this by setting assets to "none" (for example if you want to manually link to external assets). Passing cssOut and jsOut will write the respective files to disk at the given location.
There are a large number of features in Ecmarkup. Detailed documentation can be found in later sections. This section provides a high-level overview of what capabilities are available and when to use them.
Notational Convention | Ecmarkup Functionality |
---|---|
Clauses | |
Algorithms | |
Notes | |
Figures (such as images) | emu-caption |
Tables | emu-caption |
Examples | emu-caption |
Grammar | |
Cross-references |
There are also a number of elements and corresponding Ecmarkdown syntax to give inline styles to various parts of your document in accordance with ECMAScript conventions. More detail on Ecmarkdown syntax can be found on its readme.
Notational Convention | Ecmarkdown Syntax | Ecmarkup Functionality |
---|---|---|
Variables, such as those in defined in algorithms, parameters in |
_variable_ |
<var>variable</var> |
ECMAScript Language Type Values, eg. |
*TypeError* |
<emu-val>TypeError</emu-val> |
Specification types and their instances, eg. |
~throw~ |
<emu-const>throw<emu-const> |
Source Code, eg. Function.prototype . |
`code` |
<code>code</code> |
Non-terminal references, eg. as |
|FunctionExpression| |
<emu-nt>FunctionExpression</emu-nt> |
There are a number of settings that allow customizations or enable generation of boilerplate. Metadata can be included in the document and passed on the command line, for example --no-toc --title "Document 1"
. Metadata given on the command line takes precedence.
To add metadata to your document, use yaml syntax inside a <pre class=metadata>
element somewhere in the root of your document.
All of the command line options can be provided in the metadata block. See --help
).
<pre class=metadata>
Title: Document 1
toc: false
</pre>
Clauses are referenced using their id and are numbered automatically based on document position. Ecmarkdown syntax can be used in descendent text nodes as well. Text nodes are parsed as Ecmarkdown Fragments.
Non-normative introductory information.
id: Clause id. Must be unique.
aoid: Abstract operation ID. A unique name identifying this clause as an abstract operation. Algorithm steps will auto-link calls to this abstract operation to this clause. If left blank, the aoid will be set to the id of this clause.
Normative clause.
id: Clause id. Must be unique.
aoid: Abstract operation ID. A unique name identifying this clause as an abstract operation. Algorithm steps will auto-link calls to this abstract operation to this clause. If left blank, the aoid will be set to the id of this clause.
Annex clause.
normative: If present, annex is normative. Default is non-normative.
id: Clause id. Must be unique.
aoid: Abstract operation ID. A unique name identifying this clause as an abstract operation. Algorithm steps will auto-link calls to this abstract operation to this clause. If left blank, the aoid will be set to the id of this clause.
Algorithm steps. Should not contain any HTML. The node's textContent is parsed as an Ecmarkdown document. Additionally, calls to
<emu-alg aoid="EmuAlgExample">
1. let _clauseAbstractOp_ be the result of calling EmuAlg()
2. Step 2
1. let _recurse_ be the result of calling EmuAlgExample(`true`)
2. Return the result of evaluating this |NonTerminalProduction|
</emu-alg>
true
)Algorithms may be specified to replace a labeled step, in which case the algorithm will adopt the numbering of that step. For example:
<emu-alg>
1. Step.
1. Step 2.
1. [id="replace-me"] Replaced.
1. Substep.
</emu-alg>
<p>The following is an alernative definition of step <emu-xref href="#replace-me"></emu-xref>.</p>
<emu-alg replaces-step="replace-me">
1. Replacement.
1. Substep.
</emu-alg>
The following is an alernative definition of step
An equation, similar to those found in ES6
aoid: Required: the abstract operation id that this equation defines.
id: Optional id. If present, links will go directly to the eqn definition. Otherwise, links go to the parent clause.
Non-normative explanatory text. Comes in two flavors - regular notes and Editor's notes. Regular notes are intended for the implementers and end users of this specification. Editor's notes are notes to and from the Editors and will generally be removed prior to a specification being finalized and ratified.
type: The type of note, either blank or "editor".
For authentication only, servers and clients MUST support SASL Salted Challenge Response Authentication Mechanism [SCRAM].
Cross-reference another clause, production, note, example, abstract operation, or labeled step. If the text content of this element is empty, a suitable default is used. The title
attribute controls this default - when present, clauses are referred to using their title rather than number. This also applies to examples which are indexed first by their containing clause and then their example number.
Cross-references to an id check for clauses, productions, examples, and steps in this order. For each type, the local document is consulted before looking for external sources including the default ES6 biblio.
href: Optional: URL of the target clause, production, or example to cross-reference.
title: Optional: If present, xref will be filled in with the referenced clause's title. Otherwise, the clause's section number is used.
aoid: Optional: aoid of an abstract operation to reference.
One of aoid or href must be specified.
<p>The clause element is specified in <emu-xref href="#emu-clause"></emu-xref>.</p>
<p>See <emu-xref href="#emu-note" title></emu-xref> for information on the emu-note element.</p>
<p>The <emu-xref href="#emu-biblio">biblio element</emu-xref> supports xref to external specs.</p>
<p><emu-xref aoid="Get"></emu-xref> is an abstract operation from ES6</p>
<p><emu-alg>1. [id="example-step-label"] Example labeled step.</emu-alg></p>
<p>You can reference step <emu-xref href="#example-step-label"></emu-xref> like this</p>
Result
The clause element is specified in
See
The
You can reference step
Suppresses automatic linking to definitions.
<div id="not-ref-section-1">
<p>An <dfn>example</dfn> is used for illustrative purposes.</p>
</div>
<div id="not-ref-section-2">
<p>When a word defined in another section (or algorithm step) is used, as in this example, it is normally automatically linked to the section containing the definition.</p>
<p>When such a word should not be automatically linked, for <emu-not-ref>example</emu-not-ref> when using its colloquial definition, it can be wrapped with this tag to surpress the automatic linking.</p>
</div>
Result
An example is used for illustrative purposes.
When a word defined in another section (or algorithm step) is used, as in this
When such a word should not be automatically linked, for
Creates a figure that can be xrefed by ID using the emu-xref
element. Add a caption using a child emu-caption
element.
informative: Optional: If present, the figure is informative. Otherwise it is normative.
<emu-figure>
<emu-caption>Example figure<emu-caption>
[[insert some awesome graphic here, maybe something like figure 2]]
</emu-figure>
Creates a table that can be xrefed by ID using the emu-xref
element. Add a caption using a child emu-caption
element.
caption: Optional: Caption for the example
informative: Optional: If present, the table is informative. Otherwise it is normative.
<emu-table>
<emu-caption>Example table<emu-caption>
<table>
<tr><th>Column 1</th><th>Column 2</th></tr>
<tr><td>Value</td><td>Value 2</td></tr>
<tr><td>Value</td><td>Value 2</td></tr>
<tr><td>Value</td><td>Value 2</td></tr>
<tr><td>Value</td><td>Value 2</td></tr>
</table>
</emu-table>
Column 1 | Column 2 |
---|---|
Value | Value 2 |
Value | Value 2 |
Value | Value 2 |
Value | Value 2 |
Creates an informative example. Examples are numbered based on how many are present in the example's containing clause. Can be xrefed by ID using emu-xref
.
caption: Optional: Caption for the example
<emu-example caption="Example Example">
This is an example.
</emu-example>
<emu-example caption="Another Example Example">
This is also an example.
</emu-example>
Links a bibliography file. The bibliography file is a JSON document containing URLs for referenced documents along with any algorithms they define.
href: Required: URL to the biblio file.
{
"https://tc39.github.io/ecma262/": [
{
"type": "op",
"id": "sec-returnifabrupt",
"aoid": "ReturnIfAbrupt"
},
{
"type": "op",
"id": "sec-get-o-p",
"aoid": "Get"
}
]
}
spec.emu
<emu-biblio href="./biblio.json"></emu-biblio>
<emu-alg>
1. let _res_ be Get(_obj_, _key_).
2. ReturnIfAbrupt(_res_)
</emu-alg>
Result
There are two ways to specify grammar in Ecmarkup: using the emu-production element and related elements, or by using the emu-grammar element which allows specifying grammar using a plaintext format.
<emu-production name="WhileStatement">
<emu-rhs>while ( <emu-nt>Expression</emu-nt> ) <emu-nt>Statement</emu-nt></emu-rhs>
</emu-production>
<emu-production name="ArgumentList">
<emu-rhs><emu-nt>AssignmentExpression</emu-nt></emu-rhs>
<emu-rhs><emu-nt>ArgumentList</emu-nt> , <emu-nt>AssignmentExpression</emu-nt></emu-rhs>
</emu-production>
<emu-production name="IterationStatement">
<emu-rhs>for ( <emu-nt>LexicalDeclaration</emu-nt> ; <emu-nt optional>Expression</emu-nt> ;
<emu-nt optional>Expression</emu-nt> ) <emu-nt>Statement</emu-nt></emu-rhs>
</emu-production>
<emu-production name="Identifier" type="lexical">
<emu-rhs><emu-nt>IdentifierName</emu-nt> <emu-gmod>but not
<emu-nt>ReservedWord</emu-nt></emu-gmod></emu-rhs>
</emu-production>
<emu-production name="SourceCharacter" type="lexical">
<emu-rhs><emu-gprose>any Unicode code point</emu-gprose></emu-rhs>
</emu-production>
<emu-production name="ExpressionStatement" params="Yield">
<emu-rhs>
<emu-gann>lookahead ∉ {
<emu-t>{</emu-t>,
<emu-t>function</emu-t>,
<emu-t>class</emu-t>,
<emu-t>let [</emu-t>
}</emu-gann>
</emu-rhs>
</emu-production>
<emu-production name="DecimalDigit" type="lexical" oneof>
<emu-rhs>0 1 2 3 4 5 6 7 8 9</emu-rhs>
</emu-production>
<emu-production name="StatementList" params="Return, In">
<emu-rhs constraints="~Return"><emu-nt>ReturnStatement</emu-nt></emu-rhs>
<emu-rhs><emu-nt>ExpressionStatement</emu-nt></emu-rhs>
</emu-production>
Text inside emu-grammar elements is parsed using Grammarkdown. The syntax is essentially identical to the notational conventions in ECMAScript (minus formatting). See the Grammarkdown readme.
Grammar will be displayed as an "inline" element flowing with text unless it is the immediate child of an emu-clause-like element.
collapsed: If present, production is displayed in collapsed format with LHS and RHS on the same line.
collapsed: If present, production is displayed in collapsed format with LHS and RHS on the same line.
This is the top level element that contains all grammar productions. Each production MUST include at least one right-hand side (see emu-rhs).
The production will be displayed as an "inline" element flowing with text unless it is the immediate child of an emu-clause-like element or if its containing emu-grammar element is an immediate child of an emu-clause-like element.
Name: Required. Name of the production (i.e. the non-terminal on the LHS).
Params: Parameters for this production. Multiple parameters separated by commas.
Type: Type of production, either "lexical" or "regexp". Default is blank (normal).
oneof: If present, production is a one-of production. See DecimalDigit example above.
collapsed: If present, production is displayed in collapsed format with LHS and RHS on the same line.
Describes one right-hand-side alternative of a production. Text nodes inside of an rhs are split on each space and turned into terminals. For example,
<emu-rhs>a b c</emu-rhs>is semantically equivalent to
<emu-rhs><emu-t>a</emu-t> <emu-t>b</emu-t> <emu-t>c</emu-t>
constraints: any constraints for this RHS. Multiple constraints separated by commas. See StatementList example above.
a: Optional alternative id used to reference a particular RHS via emu-prodref
. Must be unique for all emu-rhs
elements inside an emu-production. Example might be `
Non-terminal. Alpha characters only.
Params: Parameters for this production. Multiple parameters separated by commas.
oneof: If present, production is a one-of production (see DecimalDigit example above).
Terminal. No attributes available. Mostly don't need to create these elements manually as they are created automatically inside emu-rhs elements.
Contains well-known modifiers to a right-hand side of a production. The only well-known modifier at present is the "but not" modifier. See the Identifier example above.
Contains well-known annotations to to a right-hand side of a production. The only well-known modifiers at present are "lookahead" and "empty". See the ExpressionStatement example above. Any text inside a gann element is wrapped in square brackets.
Contains any prose text that describes a production. See SourceCharacter example above.
References a production defined elsewhere in the document. Ecmarkup will insert either the entire production or a particular RHS depending on attributes.
name: Required. Name of the production to reference.
a: Optional. If present, specified a particular alternative ID to reference.
HTML Imports are treated specially in an ecmarkup document. Every import is inlined into its parent document at the location of the import tag. This is useful for breaking your spec document up into many smaller pieces.
Old IDs for any element can be stored as a comma-separated list inside an oldids attribute, allowing links using them to continue working as expected.
The ins
and del
HTML tags can be used to mark insertions and deletions respectively. When adding or removing block content (such as entire list items, paragrpahs, clauses, grammar RHSes, etc.), use a class of "block".
ECMAScript <del>6</del><ins>2015</ins> <del>will be ratified</del><ins>was ratified</ins> in June, 2015.
ECMAScript 62015 will be ratifiedwas ratified in June, 2015.
<p>|HoistableDeclaration| is modified as follows:</p>
<emu-production name="HoistableDeclaration">
<emu-rhs><emu-nt>FunctionDeclaration</emu-nt></emu-rhs>
<emu-rhs><emu-nt>GeneratorDeclaration</emu-nt></emu-rhs>
<ins class="block"><emu-rhs><emu-nt>AsyncFunctionDeclaration</emu-nt></emu-rhs></ins>
</emu-production>
Create a code listing using <pre><code>
. The code
element takes a class of javascript
, html
, or any other language provided by highlightjs. Ecmarkup will trim any leading blank lines and also normalize the indentation based on the indentation of the first line.