Ecmarkup

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.

1Getting Started

npm install -g ecmarkup
ecmarkup --help
ecmarkup spec.html out.html
  

2Options

Build options and document options can be passed in via the command line or specified in the front-matter of your document.

Table 1: Build options
OptionDescription
watchRebuild when files change
verbosePrint verbose logging info
biblioEmit a biblio file to the specified location
assets"none" for no css/js, "inline" for inline css/js
css-outEmit the Ecmarkup CSS file to the specified location
js-outEmit the Ecmarkup JS file to the specified location
Table 2: Document options
OptionDescription
titleTitle of specification, for example ECMAScript 2016 or Async Functions.
statusStatus of specification. Can be proposal, draft, or standard. Default is proposal.
stageStage of proposal. Must be a number if provided, but is optional. Sets version to Stage N Draft, but can be overridden.
versionVersion of specification, for example 6<sup>th</sup> Edition or Draft 1. Optional.
dateDate the spec was generated. Used for various pieces of boilerplate that include dates. Defaults to today's date.
shortnameShortname of specification, for example ECMA-262 or ECMA-402.
locationURL of this specification. Use in conjunction with the biblio file to enable external specs to reference this one.
copyrightEmit copyright and software license information. Boolean, default true.
contributorsContributors 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.
tocEmit table of contents. Boolean, default true.
old-tocEmit the old style of table of contents. Boolean, default false.

3Stylesheets and Scripts

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.

4Editorial Conventions

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.

Table 3: Structuring your Ecmarkup document
Notational ConventionEcmarkup Functionality
Clausesemu-clause, emu-intro, and emu-annex
Algorithmsemu-alg with Ecmarkdown (see also Table 4). Equations such as Year Number use emu-eqn
Notesemu-note
Figures (such as images)emu-figure and emu-caption
Tablesemu-table and emu-caption
Examplesemu-example and emu-caption
Grammaremu-grammar using Grammarkdown syntax or emu-production and child elements
Cross-referencesemu-xref (can reference clauses, productions, abstract operations, tables, figuers, and examples)

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.

Table 4: Inline styles/conventions
Notational Convention Ecmarkdown Syntax Ecmarkup Functionality
Variables, such as those in defined in algorithms, parameters in abstract operations, etc. _variable_ <var>variable</var>
ECMAScript Language Type Values, eg. undefined, true, 1, "string", TypeError, etc. *TypeError* <emu-val>TypeError</emu-val>
Specification types and their instances, eg. throw and empty. ~throw~ <emu-const>throw<emu-const>
Source Code, eg. Function.prototype. `code` <code>code</code>
Non-terminal references, eg. as FunctionDeclaration and FunctionExpression. |FunctionExpression| <emu-nt>FunctionExpression</emu-nt>

5Metadata

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 Table 1 and Table 2 for a list (or consult --help).

Example document with metadata

<pre class=metadata>
Title: Document 1
toc: false
</pre>

6Clauses

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.

6.1emu-intro

Non-normative introductory information.

Attributes

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.

6.2emu-clause

Normative clause.

Attributes

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.

6.3emu-annex

Annex clause.

Attributes

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.

7emu-alg

Algorithm steps. Should not contain any HTML. The node's textContent is parsed as an Ecmarkdown document. Additionally, calls to abstract operations inside algorithm steps are automatically linked to their definitions by first checking for any clauses or algorithms with the appropriate "aoid" in the current spec, and afterwards checking any linked bibliography files.

Example

Note
The emu-alg clause has an aoid of "EmuAlg".

Element

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

Result

  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

8emu-eqn

An equation, similar to those found in ES6 20.3.1.3.

Attributes

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.

9emu-note

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.

Attributes

type: The type of note, either blank or "editor".

Example

For authentication only, servers and clients MUST support SASL Salted Challenge Response Authentication Mechanism [SCRAM].

Note
But we know you won't.
Editor's Note
This joke brought to you by RFC6919.

10emu-xref

Cross-reference another clause, production, note, example, or abstract operation. 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, and examples in this order. For each type, the local document is consulted before looking for external sources including the default ES6 biblio.

Attributes

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.

Example

<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>
Result

The clause element is specified in 6.2.

See emu-note for information on the emu-note element.

The biblio element will eventually support xref to external specs.

Get is an abstract operation from ES6

11emu-figure

Creates a figure that can be xrefed by ID using the emu-xref element. Add a caption using a child emu-caption element.

Attributes

informative: Optional: If present, the figure is informative. Otherwise it is normative.

Example

<emu-figure>
  <emu-caption>Example figure<emu-caption>
  [[insert some awesome graphic here, maybe something like figure 2]]
</emu-figure>
Figure 1: Example figure [[insert some awesome graphic here, maybe something like figure 2]]

12emu-table

Creates a table that can be xrefed by ID using the emu-xref element. Add a caption using a child emu-caption element.

Attributes

caption: Optional: Caption for the example

informative: Optional: If present, the table is informative. Otherwise it is normative.

Example

<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>
Table 5: Example table
Column 1Column 2
ValueValue 2
ValueValue 2
ValueValue 2
ValueValue 2

13emu-example

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.

Attributes

caption: Optional: Caption for the example

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>
Example 1 (Informative): Example Example
This is an example.
Example 2 (Informative): Another Example Example
This is also an example.

14emu-biblio

Links a bibliography file. The bibliography file is a JSON document containing URLs for referenced documents along with any algorithms they define.

Attributes

href: Required: URL to the biblio file.

Example

biblio.json
{
  "https://tc39.github.io/ecma262/": [
    {
      "type": "op",
      "aoid": "ReturnIfAbrubt"
    }
  ]
}
spec.emu
<emu-biblio href="./biblio.json"></emu-biblio>
<emu-alg>
1. let _res_ be some value.
2. ReturnIfAbrupt(_res_)
</emu-alg>
Result
  1. let res be Get(obj, key).
  2. ReturnIfAbrupt(res);

15Specifying Grammar

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.

Examples

WhileStatement
<emu-production name="WhileStatement">
  <emu-rhs>while ( <emu-nt>Expression</emu-nt> ) <emu-nt>Statement</emu-nt></emu-rhs>
</emu-production>
WhileStatement:while(Expression)Statement ArgumentList
<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>
ArgumentList:AssignmentExpression ArgumentList,AssignmentExpression IterationStatement
<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>
IterationStatement:for(LexicalDeclaration;Expressionopt;Expressionopt)Statement Identifier
<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>
Identifier::IdentifierNamebut not ReservedWord SourceCharacter
<emu-production name="SourceCharacter" type="lexical">
  <emu-rhs><emu-gprose>any Unicode code point</emu-gprose></emu-rhs>
</emu-production>
SourceCharacter::any Unicode code point ExpressionStatement
<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>
ExpressionStatement[Yield]:[lookahead ∉ { {, function, class, let [ }] DecimalDigit
<emu-production name="DecimalDigit" type="lexical" oneof>
  <emu-rhs>0 1 2 3 4 5 6 7 8 9</emu-rhs>
</emu-production>
DecimalDigit::one of0123456789 StatementList
<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>
StatementList[Return, In]:[~Return]ReturnStatement ExpressionStatement

15.1emu-grammar

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.

Attributes

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.

15.2emu-production

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.

Attributes

Attributes

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.

15.3emu-rhs

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>

Attributes

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

15.4emu-nt

Non-terminal. Alpha characters only.

Attributes

Params: Parameters for this production. Multiple parameters separated by commas.

oneof: If present, production is a one-of production (see DecimalDigit example above).

15.5emu-t

Terminal. No attributes available. Mostly don't need to create these elements manually as they are created automatically inside emu-rhs elements.

15.6emu-gmod

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.

15.7emu-gann

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.

15.8emu-gprose

Contains any prose text that describes a production. See SourceCharacter example above.

15.9emu-prodref

References a production defined elsewhere in the document. Ecmarkup will insert either the entire production or a particular RHS depending on attributes.

Attributes

name: Required. Name of the production to reference.

a: Optional. If present, specified a particular alternative ID to reference.

16Imports

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.

17Other Styles & Conventions

17.1ins & del

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

Inline Example:

ECMAScript <del>6</del><ins>2015</ins> <del>will be ratified</del><ins>was ratified</ins> in June, 2015.

Result:

ECMAScript 62015 will be ratifiedwas ratified in June, 2015.

Block Example:

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

Result:

HoistableDeclaration is modified as follows:

HoistableDeclaration:FunctionDeclaration GeneratorDeclaration AsyncFunctionDeclaration

17.2Code Listings

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.