Markdown syntax
Examples
Example 1
This Markdown code:
## Foo
Lorem ipsum.
### `bar`s
- Hello
- There
...parses to this syntax tree:
Document
Heading level=2
Text text="Foo"
Paragraph
Text text="Lorem ipsum."
Heading level=3
CodeInline text="bar"
Text text="s"
List
ListItem
Text text="Hello"
ListItem
Text text="There"
...which can be rendered to this HTML fragment:
<h2>Foo</h2>
<p>Lorem ipsum.</p>
<h3><code>bar</code>s</h3>
<ul>
<li>Hello</li>
<li>There</li>
</ul>
Glossary
section: a Heading plus all subsequent nodes up until there's any Heading with a level that is at least as significant.
About this page
This page is released under CC BY-SA 4.0.
This page seeks to (1) introduce Markdown syntax, and (2) define another "15th standard" for Markdown ASTs (with language extensions)
This builds upon:
- CommonMark Spec (CC BY-SA 4.0)
- GitHub Flavored Markdown Spec (CC BY-SA 4.0)
- cmark-gfm library (these permissive licenses)
- mdast (CC BY 4.0)
- swift-docc (Apache 2)
Disclaimer: I am also the author of MarkdownMesh, and this is the syntax tree schema that I am using in that project.
Overview of nodes
Properties from language extensions are indicated via: (+ foo
)
Node | Properties |
---|---|
Document | children , (+ frontmatter_props ) |
Heading | children , level (+ is_details_section , open ) |
Paragraph | children |
Text | text |
Html | text |
Comment | text |
CodeBlock | text , lang , meta |
CodeInline | text , (+ lang , meta ) |
HorizontalRule | ( β¦ HTML:<hr /> ) |
Link | url , title , ref_id , ref_label , children |
Image | url , title , ref_id , ref_label , alt |
LinkRefDef | url , title , def_id , def_label |
Emphasis | children |
Strong | children |
Blockquote | children |
List | children , spread , ordered , start |
ListItem | children , spread , (+ checked ) |
Nodes for extensions beyond CommonMark:
Name | |
---|---|
FootnoteRef | ref_id , ref_label |
FootnoteDef | def_id , def_label , children (content) |
Table | children ([ head, body ]), align |
TableHead | children ([ row ]) |
TableBody | children ([ ...rows ]) |
TableRow | children ([ ...cells ]) |
TableCell | children (content) |
TabNavigator | children ([ ...tabs ]) |
Tab | children (content), label |
LayoutRow | children ([ ...columns ]) |
LayoutColumn | children (content) |
What about math nodes?
e.g. for (MD:$A \cap B$
) β¦ (HTML:<math>β¦</math>
or HTML:<span class="katex">β¦</span>
)
Instead of defining MathBlock
/MathInline
nodes, math expressions are simply syntactic sugar for CodeBlock/CodeInline nodes where lang="math"
.
See also:
- GitHub Docs: Writing mathematical expressions
- MarkdownMesh plugins : math
(Disclaimer: I wrote this)
Syntax options
For some node types, CommonMark offers multiple forms of syntax for expressing them.
This page will focus on the forms to which Prettier normalizes. For the rest, see the CommonMark spec.
In addition, there are many language extensions with new types of nodes. This page covers some of them.
Nodes
Document
This is the root node.
Children: the top-level block nodes of your document (Paragraphs, Tables, etc)
Attributes:
frontmatter_props
: a dictionary of properties from the optional blob-of-YAML-between-two----
-lines at the top of your document
WARNING: never parse YAML without security-auditing your parser! π±
Heading
(MD:## Foo
) β¦ (HTML:<h2>Foo</h2>
)
Children: inline nodes
Standard attributes:
level
: 1 - 6
Non-standard attributes re: <details>
/<summary>
-ifying sections
<details>
/<summary>
-ifying sectionsNon-standard optional attributes re: <details>
/<summary>
-ifying this Heading's section:
is_details_section
: boolopen
: bool
Extensions/plugins related to that:
- MarkdownMesh plugins : details-summary-from-section (Disclaimer: I wrote this)
Paragraph
(MD: text/etc surrounded by enough space) β¦ (HTML <p>β¦</p>
)
Text
This node wraps a string of text.
Attributes: text
Html
This node wraps a string of raw HTML.
Attributes: text
Comment
This node wraps a comment (<!-- ... -->
)
Attributes: text
, with the trimmed interior of the comment (...
)
CodeBlock
Attributes:
text
: the code (all text after the"```py\n"
and before the"\n```"
))lang
meta
lang
, meta
, and info_string
A CodeBlock always has an
lang
meta
Special case: lang="math"
See "Β§ What about math nodes?"
Example 1 for lang
/meta
/info_string
```py βΆοΈcode ; result
[f(x) for x in arr]
```
β
lang
:py
meta
:βΆοΈcode ; result
text
:[f(x) for x in arr]
CodeInline
(MD:`...`
) β¦ (HTML:<code>...</code>
)
If you need to express backticks within the code, there are options:
(MD:`` ...`... ``
)
β¦ (HTML:<code>...`...</code>
)
Attributes:
text
: the codelang
: null, except with some language extensionsmeta
: null, except with some language extensions
Language extensions that can lead to non-null lang
/meta
attributes:
- Math syntax
- MarkdownMesh plugins : codeinline-info-string (Disclaimer: I wrote this)
HorizontalRule
(MD:---
) β¦ (HTML:<hr />
)
Link
e.g. (MD:[About `Foo`](#foo "bar")
) β¦ (HTML:<a href="#foo" title="bar">About <code>Foo</code></a>
)
Note: don't confuse the title
with the "link text" / content being linked.
Attributes:
url
title
: optional string, β HTML:title="β¦"
ref_id
: e.g.foo
for the ref-based link[...][Foo]
ref_label
: e.g.Foo
for the ref-based link[...][Foo]
Either both of { ref_id
, ref_label
} are specified or neither are. These join exactly one LinkRefDef on link.ref_id
= lrd.def_id
.
When a Link use a LinkRefDef, a copy of the url
and title
properties from that LinkRefDef get included in the Link node.
Image
(MD:![](foo.png)
) β¦ (HTML: <p><img src="foo.png" /></p>
)
(MD:![desc](foo.png "title")
) β¦ (HTML: <p><img alt="desc" title="title" src="foo.png" /></p>
)
Note: don't confuse the title
with the alt text.
Children: zero or more inline nodes whose combined text content, if any, forms the alt="β¦"
tag value.
Attributes:
url
title
: optional string, β¦ (HTML:title="β¦"
)ref_id
: e.g.foo
for the ref-based link (MD:[...][Foo]
)ref_label
: e.g.Foo
for the ref-based link (MD:[...][Foo]
)
Either both of { ref_id
, ref_label
} are specified or neither are. These join exactly one LinkRefDef on link.ref_id
= lrd.def_id
.
When a Link use a LinkRefDef, a copy of the url
and title
properties from that LinkRefDef get included in the Link node.
LinkRefDef
e.g. (MD:[Foo]: https://example.org/ "title"
) β¦ (AST: LinkRefDef{ url, title, def_id, def_label }
node), for use by other Markdown nodes
Attributes:
url
title
def_id
: e.g.foo
in the above exampledef_label
: e.g.Foo
in the above example
Emphasis
Emphasis{}
β content
e.g. (MD:_Lorem ipsum_
) β¦ (HTML:<em>Lorem ipsum</em>
), which usually gets styled as italic.
Strong
Strong{}
β content
e.g. (MD:**Lorem ipsum**
) β¦ (HTML:<strong>Lorem ipsum</strong>
), which usually gets styled as bold.
Blockquote
Blockquote{}
β nodes
e.g. (MD:> ...
) β¦ (HTML:<blockquote>...</blockquote>
)
List
List{ children, spread, ordered, start }
β ListItem-list
ListItem
ListItem{ spread, checked }
β content
Nodes for tables
Table
Table{ align }
β [TableHead, TableBody]
align
: (null | "left" | "right" | "center")-list, with one element per column
TableHead
TableHead{}
β TableRow-list with exactly one element
TableBody
TableBody{}
β TableRow-list with zero or more elements
TableRow
TableRow{}
β TableCell-list with one element per column
TableCell
TableCell{}
β content
Nodes for footnotes
FootnoteRef
e.g. (MD:...lorem ipsum[^foo].
) β¦ (HTML:TODO
)
FootnoteDef
e.g. (MD:[^foo]: et other stuff.
) β¦ (HTML:TODO
)
Example 1 for footnotes
TODO
Nodes for tab navigators
TabNavigator
TabNavigator{}
node β Tab nodes
Tab
Tab{ label }
node β content
Example 1 (for tab navigators)
TabNavigator
Tab label="Foo"
...
Tab label="Bar"
...
TODO: (extended) Markdown code + notes
TabNavigators without JavaScript
When generating a web page that includes a TabNavigator, please don't use any JavaScript β you don't need it!
With HTML/CSS there are plenty of options:
<a href="#tab1">
HTML +:target
/etc CSS, if you want the URL to update like that on tab selection- ...or if you don't, then
<input type="radio">
HTML +[type=radio]:checked
/etc CSS
Nodes for grid layout
LayoutRow
LayoutRow
node β LayoutColumn
nodes
LayoutColumn
LayoutColumn
node β content
Example 1 (for grid layout)
LayoutRow
LayoutColumn
...
LayoutColumn
...
TODO: (extended) Markdown code + notes