This repository contains the CommonMark specification, along with tools for running conformance tests and creating HTML and PDF versions of the spec.
Overview
The reference implementations live in separate repositories:
- cmark (C)
- commonmark.js (JavaScript)
There is also a list of third-party libraries in a dozen different languages.
Running tests against the spec
The spec contains over 500 embedded examples which serve as conformance tests. To run the tests using an executable $PROG:
python3 test/spec_tests.py --program $PROG
To extract the raw test data from the spec without running the tests, use:
python3 test/spec_tests.py --dump-tests
This outputs the tests as JSON. JavaScript developers may find it more convenient to use the commonmark-spec npm package, which is published from this repository. It exports an array named tests of JSON objects in this format:
{
"markdown": "Foo\nBar\n---\n",
"html": "<h2>Foo\nBar</h2>\n",
"section": "Setext headings",
"number": 65
}
The specification
The source of the spec is spec.txt. It is basically a Markdown file, with code examples written in a shorthand form:
```````````````````````````````` example
Markdown source
.
expected HTML output
````````````````````````````````
To build an HTML version of the spec, run make spec.html. To build a PDF version, run make spec.pdf. Both require the Lua rock lcmark. After installing Lua and LuaRocks, install it with luarocks install lcmark. Building the PDF also requires xelatex.
The spec is written from the point of view of the human writer, not the computer reader. It is a declarative description of what counts as a block quote, a code block, and each of the other structural elements that can make up a Markdown document—not an algorithm or an English translation of a computer program.
Because John Gruber's canonical syntax description leaves many aspects of syntax undetermined, writing a precise spec requires many decisions, some somewhat arbitrary. In making them, the authors considered existing conventions, simplicity, readability, expressive power, and consistency. They aimed to make “normal” documents in the many incompatible Markdown implementations render as their authors intended, as far as possible, and to make the rules for different elements work together harmoniously.
Where different decisions could have been made—for example, the rules governing list indentation—the spec explains the rationale. In a few cases it departs slightly from the canonical syntax description in ways intended to further Markdown's stated goals.
For the most part, the spec is limited to the basic elements in Gruber's description, leaving out extensions such as footnotes and definition lists. It includes visible syntax for line breaks and fenced code blocks.
Differences from original Markdown
There are only a few places where this spec contradicts the canonical syntax description:
- It allows all punctuation symbols to be backslash-escaped, not just symbols with special meanings in Markdown. The authors found it too hard to remember which symbols could be escaped.
- It introduces an alternative syntax for hard line breaks: a backslash at the end of the line, supplementing the two-spaces-at-the-end-of-the-line rule. This addresses persistent complaints about the “invisible” two-space rule.
- Link syntax is more predictable in a backwards-compatible way. For example,
Markdown.plallows single quotes around a title in inline links but not reference links; the spec allows single quotes in both contexts. - The rule for HTML blocks differs, though in most real cases it should not matter. (See the section on HTML Blocks for details.) The proposal makes it easy to include Markdown inside HTML block-level tags, or to exclude it, and makes parsing easier by avoiding expensive backtracking.
- It does not collapse adjacent bird-track blocks into a single blockquote:
> these are two > blockquotes > this is a single > > blockquote with two paragraphs - Rules for content in lists differ in a few respects. As with HTML blocks, most lists in existing documents should still render as intended. The subsection of List Items entitled Motivation discusses the choices and differences. The authors believe the proposal renders lists as a human writer or reader would intuitively understand them, including examples that many existing implementations handle poorly.
- Changing bullet characters, or changing from bullets to numbers or vice versa, starts a new list. The authors think this is almost always the writer's intent.
- The number that begins an ordered list item may be followed by either
.or). Changing the delimiter style starts a new list. - The start number of an ordered list is significant.
- Fenced code blocks are supported, delimited by either backticks (
```) or tildes (~~~).
Contributing
There is a forum for discussing CommonMark; use it for questions and open-ended discussions. Use the GitHub issue tracker only for simple, clear, actionable issues.