diff --git a/readme.md b/readme.md index d87a4e2..94c3cb1 100644 --- a/readme.md +++ b/readme.md @@ -1,16 +1,14 @@ -# ![MDAST][logo] +# ![mdast][logo] **M**ark**d**own **A**bstract **S**yntax **T**ree. * * * -**MDAST** discloses markdown as an abstract syntax tree. -_Abstract_ means not all information is stored in this tree and an exact -replica of the original document cannot be re-created. -_Syntax Tree_ means syntax **is** present in the tree, thus an exact syntactic -document can be re-created. - -**MDAST** is a subset of [unist][], and implemented by [remark][]. +**mdast** is a specification for representing markdown in a +[syntax tree][syntax-tree]. +It implements the [**unist**][unist] spec. +It can represent several flavours of [Markdown][], such as [CommonMark][], +and [GitHub Flavored Markdown][gfm] extensions. This document may not be released. See [releases][] for released documents. @@ -18,7 +16,11 @@ The latest released version is [`2.2.0`][latest]. ## Table of Contents -* [AST](#ast) +* [Introduction](#introduction) + * [Where this specification fits](#where-this-specification-fits) +* [Nodes](#nodes) + * [Parent](#parent) + * [Literal](#literal) * [Root](#root) * [Paragraph](#paragraph) * [Blockquote](#blockquote) @@ -45,18 +47,83 @@ The latest released version is [`2.2.0`][latest]. * [FootnoteReference](#footnotereference) * [Definition](#definition) * [FootnoteDefinition](#footnotedefinition) - * [TextNode](#textnode) + * [Text](#text) +* [Mixin](#mixin) + * [Resource](#resource) + * [Association](#association) + * [Reference](#reference) + * [Alternative](#alternative) +* [Enumeration](#enumeration) + * [alignType](#aligntype) + * [referenceType](#referencetype) +* [Content](#content) + * [TopLevelContent](#toplevelcontent) + * [BlockContent](#blockcontent) + * [FrontmatterContent](#frontmattercontent) + * [DefinitionContent](#definitioncontent) + * [ListContent](#listcontent) + * [TableContent](#tablecontent) + * [RowContent](#rowcontent) + * [PhrasingContent](#phrasingcontent) + * [StaticPhrasingContent](#staticphrasingcontent) +* [Glossary](#glossary) * [List of Utilities](#list-of-utilities) -* [Related](#related) +* [References](#references) * [Contribute](#contribute) * [Acknowledgments](#acknowledgments) * [License](#license) -## AST +## Introduction -### `Root` +This document defines a format for representing [Markdown][] as an +[abstract syntax tree][syntax-tree]. +Development of mdast started in July 2014, in [**remark**][remark], before +[unist][] existed. +This specification is written in a [Web IDL][webidl]-like grammar. + +### Where this specification fits + +mdast extends [unist][], a format for syntax trees, to benefit from its +[ecosystem of utilities][utilities]. + +mdast relates to [JavaScript][] in that it has a rich [ecosystem of +utilities][list-of-utilities] for working with compliant syntax trees in +JavaScript. +However, mdast is not limited to JavaScript and can be used in other +programming languages. + +mdast relates to the [unified][] and [remark][] projects in that mdast syntax +trees are used throughout their ecosystems. + +## Nodes + +### `Parent` + +```idl +interface Parent <: UnistParent { + children: [Content]; +} +``` + +**Parent** ([**UnistParent**][dfn-unist-parent]) represents a node in mdast +containing other nodes (said to be [_children_][term-child]). + +Its content is limited to only other mdast [**content**][dfn-content]. + +### `Literal` + +```idl +interface Literal <: UnistLiteral { + value: string; +} +``` + +**Literal** ([**UnistLiteral**][dfn-unist-literal]) represents a node in mdast +containing a value. -`Root` ([`Parent`][parent]) houses all nodes. +Its `value` field is a `string`. + +### `Root` ```idl interface Root <: Parent { @@ -64,26 +131,39 @@ interface Root <: Parent { } ``` -### `Paragraph` +**Root** ([**Parent**][dfn-parent]) represents a document. -`Paragraph` ([`Parent`][parent]) represents a unit of discourse dealing with a -particular point or idea. +**Root** can be used as the [_root_][term-root] of a [_tree_][term-tree], never +as a [_child_][term-child]. +Its content model is not limited to [**top-level**][dfn-top-level-content] +content, but can contain any [**content**][dfn-content] with the restriction +that all content must be of the same category. + +### `Paragraph` ```idl interface Paragraph <: Parent { type: "paragraph"; + children: [PhrasingContent] } ``` +**Paragraph** ([**Parent**][dfn-parent]) represents a unit of discourse dealing +with a particular point or idea. + +**Paragraph** can be used where [**block**][dfn-block-content] content is +expected. +Its content model is [**phrasing**][dfn-phrasing-content] content. + For example, the following markdown: -```md +```markdown Alpha bravo charlie. ``` Yields: -```js +```javascript { type: 'paragraph', children: [{type: 'text', value: 'Alpha bravo charlie.'}] @@ -92,23 +172,29 @@ Yields: ### `Blockquote` -`Blockquote` ([`Parent`][parent]) represents a quote. - ```idl interface Blockquote <: Parent { type: "blockquote"; + children: [BlockContent] } ``` +**Blockquote** ([**Parent**][dfn-parent]) represents a section quoted from +somewhere else. + +**Blockquote** can be used where [**block**][dfn-block-content] content is +expected. +Its content model is also [**block**][dfn-block-content] content. + For example, the following markdown: -```md +```markdown > Alpha bravo charlie. ``` Yields: -```js +```javascript { type: 'blockquote', children: [{ @@ -120,25 +206,32 @@ Yields: ### `Heading` -`Heading` ([`Parent`][parent]), just like with HTML, with a level greater than -or equal to 1, lower than or equal to 6. - ```idl interface Heading <: Parent { type: "heading"; - depth: 1 <= uint32 <= 6; + depth: 1 <= number <= 6; + children: [PhrasingContent]; } ``` +**Heading** ([**Parent**][dfn-parent]) represents a heading of a section. + +**Heading** can be used where [**block**][dfn-block-content] content is +expected. +Its content model is [**phrasing**][dfn-phrasing-content] content. + +A `depth` field must be present. +A value of `1` is said to be the highest rank and `6` the lowest. + For example, the following markdown: -```md +```markdown # Alpha ``` Yields: -```js +```javascript { type: 'heading', depth: 1, @@ -148,28 +241,38 @@ Yields: ### `Code` -`Code` ([`Text`][text]) occurs at block level (see [`InlineCode`][inlinecode] -for code spans). -The value after the opening of fenced code can be followed by a language tag, -and then optionally white-space followed by the meta value. - ```idl -interface Code <: Text { +interface Code <: Literal { type: "code"; - lang: string | null; - meta: string | null; + lang: string?; + meta: string?; } ``` +**Code** ([**Literal**][dfn-literal]) represents a block of preformatted text, +such as ASCII art or computer code. + +**Code** can be used where [**block**][dfn-block-content] content is expected. +Its content is represented by its `value` field. + +This node relates to the [**phrasing**][dfn-phrasing-content] content concept +[**InlineCode**][dfn-inline-code]. + +A `lang` field can be present. +It represents the language of computer code being marked up. + +If the `lang` field is present, a `meta` field can be present. +It represents custom information relating to the node. + For example, the following markdown: -```md +```markdown foo() ``` Yields: -```js +```javascript { type: 'code', lang: null, @@ -180,8 +283,8 @@ Yields: And the following markdown: -````md -```js highlight-line="2" +````markdown +```javascript highlight-line="2" foo() bar() baz() @@ -190,10 +293,10 @@ baz() Yields: -```js +```javascript { type: 'code', - lang: 'js', + lang: 'javascript', meta: 'highlight-line="2"', value: 'foo()\nbar()\nbaz()' } @@ -201,46 +304,52 @@ Yields: ### `InlineCode` -`InlineCode` ([`Text`][text]) occurs inline (see [`Code`][code] for blocks). -Inline code does not sport `lang` or `meta` properties. - ```idl -interface InlineCode <: Text { +interface InlineCode <: Literal { type: "inlineCode"; } ``` +**InlineCode** ([**Literal**][dfn-literal]) represents a fragment of computer +code, such as a file name, computer program, or anything a computer could parse. + +**InlineCode** can be used where [**phrasing**][dfn-phrasing-content] content +is expected. +Its content is represented by its `value` field. + +This node relates to the [**block**][dfn-block-content] content concept +[**Code**][dfn-code]. + For example, the following markdown: -```md +```markdown `foo()` ``` Yields: -```js +```javascript {type: 'inlineCode', value: 'foo()'} ``` ### `YAML` -`YAML` ([`Text`][text]) can occur at the start of a document, and contains -embedded YAML data. - ```idl -interface YAML <: Text { +interface YAML <: Literal { type: "yaml"; } ``` -> **Note**: YAML used to be available through the core of remark and thus -> is specified here. Support for it now moved to -> [`remark-frontmatter`][frontmatter], and the definition here may be removed -> in the future. +**YAML** ([**Literal**][dfn-literal]) represents a collection of metadata for +the document in the [YAML][] data serialisation language. + +**YAML** can be used where [**frontmatter**][dfn-frontmatter-content] content is +expected. +Its content is represented by its `value` field. For example, the following markdown: -```md +```markdown --- foo: bar --- @@ -248,61 +357,74 @@ foo: bar Yields: -```js +```javascript {type: 'yaml', value: 'foo: bar'} ``` ### `HTML` -`HTML` ([`Text`][text]) contains embedded HTML. - ```idl -interface HTML <: Text { +interface HTML <: Literal { type: "html"; } ``` +**HTML** ([**Literal**][dfn-literal]) represents a fragment of raw [HTML][]. + +**HTML** can be used where [**block**][dfn-block-content] or +[**phrasing**][dfn-phrasing-content] content is expected. +Its content is represented by its `value` field. + For example, the following markdown: -```md +```markdown
``` Yields: -```js +```javascript {type: 'html', value: '
'} ``` ### `List` -`List` ([`Parent`][parent]) contains [`ListItem`s][listitem]. -No other nodes may occur in lists. - -The `start` property contains the starting number of the list when -`ordered: true`; `null` otherwise. - -When all list items have `loose: false`, the list’s `loose` property is also -`false`. Otherwise, `loose: true`. - ```idl interface List <: Parent { type: "list"; - ordered: true | false; - start: uint32 | null; - loose: true | false; + ordered: boolean?; + start: number?; + loose: boolean?; + children: [ListContent]; } ``` +**List** ([**Parent**][dfn-parent]) represents a list of items. + +**List** can be used where [**block**][dfn-block-content] content is expected. +Its content model is [**list**][dfn-list-content] content. + +An `ordered` field can be present. +It represents that the items have been intentionally ordered (when true), or +that the order of items is not important (when `false` or not present). + +If the `ordered` field is `true`, a `start` field can be present. +It represents the starting number of the node. + +A `loose` field can be present. +It represents that any of its items is separated by a blank line from its +[siblings][term-sibling] or contains two or more [_children_][term-child] +(when `true`), or not (when `false` or not present). + For example, the following markdown: -```md +```markdown 1. [x] foo ``` Yields: -```js +```javascript { type: 'list', ordered: true, @@ -311,7 +433,6 @@ Yields: children: [{ type: 'listItem', checked: true, - loose: false, children: [{ type: 'paragraph', children: [{type: 'text', value: 'foo'}] @@ -322,48 +443,67 @@ Yields: ### `ListItem` -`ListItem` ([`Parent`][parent]) is a child of a [`List`][list]. - -Loose `ListItem`s often contain more than one block-level elements. - -A checked property exists on `ListItem`s, set to `true` (when checked), `false` -(when unchecked), or `null` (when not containing a checkbox). -See [Task Lists on GitHub][task-list] for information. - ```idl interface ListItem <: Parent { type: "listItem"; - checked: true | false | null; - loose: true | false; + checked: boolean?; + children: [BlockContent]; } ``` -For an example, see the definition of [`List`][list]. +**ListItem** ([**Parent**][dfn-parent]) represents an item in a +[**List**][dfn-list]. -### `Table` +**ListItem** can be used where [**list**][dfn-list-content] content is expected. +Its content model is [**block**][dfn-block-content] content. -`Table` ([`Parent`][parent]) represents tabular data, with alignment. -Its children are [`TableRow`][tablerow]s, the first of which acts as a table -header row. +A `checked` field can be present. +It represents whether the item is done (when `true`), not done (when `false`), +or indeterminate or not applicable (when `null` or not present). -`table.align` represents the alignment of columns. +For example, the following markdown: -```idl -interface Table <: Parent { - type: "table"; - align: [alignType]; +```markdown +* [x] bar +``` + +Yields: + +```javascript +{ + type: 'listItem', + checked: true, + children: [{ + type: 'paragraph', + children: [{type: 'text', value: 'bar'}] + }] } ``` +### `Table` + ```idl -enum alignType { - "left" | "right" | "center" | null; +interface Table <: Parent { + type: "table"; + align: [alignType]?; + children: [TableContent]; } ``` +**Table** ([**Parent**][dfn-parent]) represents two-dimensional data. + +**Table** can be used where [**block**][dfn-block-content] content is expected. +Its content model is [**table**][dfn-table-content] content. + +The [_head_][term-head] of the node represents the labels of the columns. + +An `align` field can be present. +If present, it must be a list of [**alignType**s][dfn-enum-align-type]. +It represents how cells in columns are aligned. + For example, the following markdown: -```md +```markdown | foo | bar | | :-- | :-: | | baz | qux | @@ -371,7 +511,7 @@ For example, the following markdown: Yields: -```js +```javascript { type: 'table', align: ['left', 'center'], @@ -408,34 +548,43 @@ Yields: ### `TableRow` -`TableRow` ([`Parent`][parent]). -Its children are always [`TableCell`][tablecell]. - ```idl interface TableRow <: Parent { type: "tableRow"; + children: [RowContent]; } ``` -For an example, see the definition of `Table`. +**TableRow** ([**Parent**][dfn-parent]) represents a row of cells in a table. -### `TableCell` +**TableRow** can be used where [**table**][dfn-table-content] content is +expected. +Its content model is [**row**][dfn-row-content] content. -`TableCell` ([`Parent`][parent]). -Contains a single tabular field. +If the node is a [_head_][term-head], it represents the labels of the columns +for its parent [**Table**][dfn-table]. + +For an example, see [**Table**][dfn-table]. + +### `TableCell` ```idl interface TableCell <: Parent { type: "tableCell"; + children: [PhrasingContent]; } ``` -For an example, see the definition of [`Table`][table]. +**TableCell** ([**Parent**][dfn-parent]) represents a header cell in a +[**Table**][dfn-table], if its parent is a [_head_][term-head], or a data +cell otherwise. -### `ThematicBreak` +**TableCell** can be used where [**row**][dfn-row-content] content is expected. +Its content model is [**phrasing**][dfn-phrasing-content] content. + +For an example, see [**Table**][dfn-table]. -A `ThematicBreak` ([`Node`][node]) represents a break in content, often shown -as a horizontal rule, or by two HTML section elements. +### `ThematicBreak` ```idl interface ThematicBreak <: Node { @@ -443,38 +592,50 @@ interface ThematicBreak <: Node { } ``` +**ThematicBreak** ([**Node**][dfn-node]) represents a thematic break, such as a +scene change in a story, a transition to another topic, or a new document. + +**ThematicBreak** can be used where [**block**][dfn-block-content] content is +expected. +It has no content model. + For example, the following markdown: -```md +```markdown *** ``` Yields: -```js +```javascript {type: 'thematicBreak'} ``` ### `Break` -`Break` ([`Node`][node]) represents an explicit line break. - ```idl interface Break <: Node { type: "break"; } ``` -For example, the following markdown (interpuncts represent spaces): +**Break** ([**Node**][dfn-node]) represents a line break, such as in poems or +addresses. + +**Break** can be used where [**phrasing**][dfn-phrasing-content] content is +expected. +It has no content model. -```md +For example, the following markdown: + +```markdown foo·· bar ``` Yields: -```js +```javascript { type: 'paragraph', children: [ @@ -487,23 +648,29 @@ Yields: ### `Emphasis` -`Emphasis` ([`Parent`][parent]) represents slight emphasis. - ```idl interface Emphasis <: Parent { type: "emphasis"; + children: [PhrasingContent]; } ``` +**Emphasis** ([**Parent**][dfn-parent]) represents stress emphasis of its +contents. + +**Emphasis** can be used where [**phrasing**][dfn-phrasing-content] content is +expected. +Its content model is also [**phrasing**][dfn-phrasing-content] content. + For example, the following markdown: -```md +```markdown *alpha* _bravo_ ``` Yields: -```js +```javascript { type: 'paragraph', children: [ @@ -522,23 +689,29 @@ Yields: ### `Strong` -`Strong` ([`Parent`][parent]) represents strong emphasis. - ```idl interface Strong <: Parent { type: "strong"; + children: [PhrasingContent]; } ``` +**Strong** ([**Parent**][dfn-parent]) represents strong importance, seriousness, +or urgency for its contents. + +**Strong** can be used where [**phrasing**][dfn-phrasing-content] content is +expected. +Its content model is also [**phrasing**][dfn-phrasing-content] content. + For example, the following markdown: -```md +```markdown **alpha** __bravo__ ``` Yields: -```js +```javascript { type: 'paragraph', children: [ @@ -557,23 +730,29 @@ Yields: ### `Delete` -`Delete` ([`Parent`][parent]) represents text ready for removal. - ```idl interface Delete <: Parent { type: "delete"; + children: [PhrasingContent]; } ``` +**Delete** ([**Parent**][dfn-parent]) represents contents that are no longer +accurate or no longer relevant. + +**Delete** can be used where [**phrasing**][dfn-phrasing-content] content is +expected. +Its content model is also [**phrasing**][dfn-phrasing-content] content. + For example, the following markdown: -```md +```markdown ~~alpha~~ ``` Yields: -```js +```javascript { type: 'delete', children: [{type: 'text', value: 'alpha'}] @@ -582,25 +761,32 @@ Yields: ### `Link` -`Link` ([`Parent`][parent]) represents the humble hyperlink. - ```idl interface Link <: Parent { type: "link"; - url: string; - title: string | null; + children: [StaticPhrasingContent]; } + +Link includes Resource; ``` +**Link** ([**Parent**][dfn-parent]) represents a hyperlink. + +**Link** can be used where [**phrasing**][dfn-phrasing-content] content is +expected. +Its content model is [**static phrasing**][dfn-static-phrasing-content] content. + +**Link** includes the mixin [**Resource**][dfn-mxn-resource]. + For example, the following markdown: -```md +```markdown [alpha](http://example.com "bravo") ``` Yields: -```js +```javascript { type: 'link', url: 'http://example.com', @@ -611,26 +797,33 @@ Yields: ### `Image` -`Image` ([`Node`][node]) represents the figurative figure. - ```idl interface Image <: Node { type: "image"; - url: string; - title: string | null; - alt: string | null; } + +Image includes Resource; +Image includes Alternative; ``` +**Image** ([**Node**][dfn-node]) represents an image. + +**Image** can be used where [**phrasing**][dfn-phrasing-content] content is +expected. +It has no content model, but is described by its `alt` field. + +**Image** includes the mixins [**Resource**][dfn-mxn-resource] and +[**Alternative**][dfn-mxn-alternative]. + For example, the following markdown: -```md +```markdown ![alpha](http://example.com/favicon.ico "bravo") ``` Yields: -```js +```javascript { type: 'image', url: 'http://example.com', @@ -641,24 +834,29 @@ Yields: ### `Footnote` -`Footnote` ([`Parent`][parent]) represents an inline marker, whose content -relates to the document but is outside its flow. - ```idl interface Footnote <: Parent { type: "footnote"; + children: [PhrasingContent]; } ``` +**Footnote** ([**Parent**][dfn-parent]) represents content relating to the +document that is outside its flow. + +**Footnote** can be used where [**phrasing**][dfn-phrasing-content] content is +expected. +Its content model is also [**phrasing**][dfn-phrasing-content] content. + For example, the following markdown: -```md +```markdown [^alpha bravo] ``` Yields: -```js +```javascript { type: 'footnote', children: [{type: 'text', value: 'alpha bravo'}] @@ -667,36 +865,35 @@ Yields: ### `LinkReference` -`LinkReference` ([`Parent`][parent]) represents a humble hyperlink, its `url` -and `title` defined somewhere else in the document by a -[`Definition`][definition]. - -`referenceType` is needed to detect if a reference was meant as a reference -(`[foo][]`) or just unescaped brackets (`[foo]`). - ```idl interface LinkReference <: Parent { type: "linkReference"; - identifier: string; - referenceType: referenceType; + children: [StaticPhrasingContent]; } -``` -```idl -enum referenceType { - "shortcut" | "collapsed" | "full"; -} +LinkReference includes Reference; ``` +**LinkReference** ([**Parent**][dfn-parent]) represents a hyperlink through +association, or its original source if there is no association. + +**LinkReference** can be used where [**phrasing**][dfn-phrasing-content] content +is expected. +Its content model is [**static phrasing**][dfn-static-phrasing-content] content. + +**LinkReference** includes the mixin [**Reference**][dfn-mxn-reference]. + +**LinkReferences** should be associated with a [**Definition**][dfn-definition]. + For example, the following markdown: -```md +```markdown [alpha][bravo] ``` Yields: -```js +```javascript { type: 'linkReference', identifier: 'bravo', @@ -707,31 +904,36 @@ Yields: ### `ImageReference` -`ImageReference` ([`Node`][node]) represents a figurative figure, its `url` and -`title` defined somewhere else in the document by a [`Definition`][definition]. - -`referenceType` is needed to detect if a reference was meant as a reference -(`![foo][]`) or just unescaped brackets (`![foo]`). -See [`LinkReference`][linkreference] for the definition of `referenceType`. - ```idl interface ImageReference <: Node { type: "imageReference"; - identifier: string; - referenceType: referenceType; - alt: string | null; } + +ImageReference includes Reference; +ImageReference includes Alternative; ``` +**ImageReference** ([**Node**][dfn-node]) represents an image through +association, or its original source if there is no association. + +**ImageReference** can be used where [**phrasing**][dfn-phrasing-content] +content is expected. +It has no content model, but is described by its `alt` field. + +**ImageReference** includes the mixins [**Reference**][dfn-mxn-reference] and +[**Alternative**][dfn-mxn-alternative]. + +**ImageReference** should be associated with a [**Definition**][dfn-definition]. + For example, the following markdown: -```md +```markdown ![alpha][bravo] ``` Yields: -```js +```javascript { type: 'imageReference', identifier: 'bravo', @@ -742,26 +944,35 @@ Yields: ### `FootnoteReference` -`FootnoteReference` ([`Node`][node]) is like [`Footnote`][footnote], but its -content is already outside the documents flow: placed in a -[`FootnoteDefinition`][footnotedefinition]. - ```idl interface FootnoteReference <: Node { type: "footnoteReference"; - identifier: string; } + +FootnoteReference includes Association; ``` +**FootnoteReference** ([**Node**][dfn-node]) represents a marker through +association. + +**FootnoteReference** can be used where [**phrasing**][dfn-phrasing-content] +content is expected. +It has no content model. + +**FootnoteReference** includes the mixin [**Association**][dfn-mxn-association]. + +**FootnoteReference** should be associated with a +[**FootnoteDefinition**][dfn-footnote-definition]. + For example, the following markdown: -```md +```markdown [^alpha] ``` Yields: -```js +```javascript { type: 'footnoteReference', identifier: 'alpha' @@ -770,28 +981,37 @@ Yields: ### `Definition` -`Definition` ([`Node`][node]) represents the definition (as in, location and -title) of a [`LinkReference`][linkreference] or an -[`ImageReference`][imagereference]. - ```idl interface Definition <: Node { type: "definition"; - identifier: string; - url: string; - title: string | null; } + +Definition includes Association; +Definition includes Resource; ``` +**Definition** ([**Node**][dfn-node]) represents a resource. + +**Definition** can be used where [**definition**][dfn-definition-content] +content is expected. +It has no content model. + +**Definition** includes the mixins [**Association**][dfn-mxn-association] and +[**Resource**][dfn-mxn-resource]. + +**Definition** should be associated with +[**LinkReferences**][dfn-link-reference] and +[**ImageReferences**][dfn-image-reference]. + For example, the following markdown: -```md +```markdown [alpha]: http://example.com ``` Yields: -```js +```javascript { type: 'definition', identifier: 'alpha', @@ -802,25 +1022,37 @@ Yields: ### `FootnoteDefinition` -`FootnoteDefinition` ([`Parent`][parent]) represents the definition (as in, -content) of a [`FootnoteReference`][footnotereference]. - ```idl interface FootnoteDefinition <: Parent { type: "footnoteDefinition"; - identifier: string; + children: [BlockContent]; } + +FootnoteDefinition includes Association; ``` +**FootnoteDefinition** ([**Parent**][dfn-parent]) represents content relating +to the document that is outside its flow. + +**FootnoteDefinition** can be used where +[**definition**][dfn-definition-content] content is expected. +Its content model is [**block**][dfn-block-content] content. + +**FootnoteDefinition** includes the mixin +[**Association**][dfn-mxn-association]. + +**FootnoteDefinition** should be associated with +[**FootnoteReferences**][dfn-footnote-reference]. + For example, the following markdown: -```md +```markdown [^alpha]: bravo and charlie. ``` Yields: -```js +```javascript { type: 'footnoteDefinition', identifier: 'alpha', @@ -831,48 +1063,253 @@ Yields: } ``` -### `TextNode` - -`TextNode` ([`Text`][text]) represents everything that is just text. -Note that its `type` property is `text`, but it is different from -[`Text`][text]. +### `Text` ```idl -interface TextNode <: Text { +interface Text <: Literal { type: "text"; } ``` +**Text** ([**Literal**][dfn-literal]) represents everything that is just text. + +**Text** can be used where [**phrasing**][dfn-phrasing-content] content is +expected. +Its content is represented by its `value` field. + For example, the following markdown: -```md +```markdown Alpha bravo charlie. ``` Yields: -```js +```javascript {type: 'text', value: 'Alpha bravo charlie.'} ``` +## Mixin + +### `Resource` + +```idl +interface mixin Resource { + url: string; + title: string?; +} +``` + +**Resource** represents a reference to resource. + +A `url` field must be present. +It represents a URL to the referenced resource. + +A `title` field can be present. +It represents advisory information for the resource, such as would be +appropriate for a tooltip. + +### `Association` + +```idl +interface mixin Association { + identifier: string; +} +``` + +**Association** represents an internal relation from one node to another. + +An `identifier` field must be present. +It can match an `identifier` field on another node. + +Whether the value of `identifier` is expected to be a unique identifier or not +depends on the type of node including the **Association**. +An example of this is that `identifier` on [**Definition**][dfn-definition] +should be a unique identifier, whereas multiple +[**LinkReference**][dfn-link-reference]s can have the same `identifier` and be +associated with one definition. + +### `Reference` + +```idl +interface mixin Reference { + referenceType: string; +} + +Reference includes Association; +``` + +**Reference** represents a marker that is [**associated**][dfn-mxn-association] +to another node. + +A `referenceType` field must be present. +Its value must be a [**referenceType**][dfn-enum-reference-type]. +It represents the explicitness of the reference. + +### `Alternative` + +```idl +interface mixin Alternative { + alt: string?; +} +``` + +**Alternative** represents a node with a fallback + +An `alt` field should be present. +It represents equivalent content for environments that cannot represent the +node as intended. + +## Enumeration + +### `alignType` + +```idl +enum alignType { + "left" | "right" | "center" | null; +} +``` + +**alignType** represents how phrasing content is aligned. + +* **left**: See the [`left`][css-left] value of the `text-align` CSS property +* **right**: See the [`right`][css-right] value of the `text-align` CSS + property +* **center**: See the [`center`][css-center] value of the `text-align` CSS + property +* **null**: phrasing content is aligned as defined by the host environment + +### `referenceType` + +```idl +enum referenceType { + "shortcut" | "collapsed" | "full"; +} +``` + +**referenceType** represents the explicitness of a reference. + +* **shortcut**: the reference is implicit, its identifier inferred from its + content +* **collapsed**: the reference is explicit, its identifier inferred from its + content +* **full**: the reference is explicit, its identifier explicitly set + +## `Content` + +```idl +type Content = + TopLevelContent | PhrasingContent | TableContent | RowContent | ListContent; +``` + +Each node in mdast falls into one or more categories of **Content** that group +nodes with similar characteristics together. + +### `TopLevelContent` + +```idl +type TopLevelContent = BlockContent | FrontmatterContent | DefinitionContent; +``` + +**Top-level** content represent the sections of document (**block** content), +and metadata such as frontmatter and definitions. + +### `BlockContent` + +```idl +type BlockContent = + HTML | Blockquote | Paragraph | Heading | Code | List | Table | ThematicBreak; +``` + +**Block** content represent the sections of document. + +### `FrontmatterContent` + +```idl +type FrontmatterContent = YAML; +``` + +**Frontmatter** content represent out-of-band information about the document. + +If frontmatter is present, it must be limited to one node in the +[_tree_][term-tree], and can only exist as a [_head_][term-head]. + +### `DefinitionContent` + +```idl +type DefinitionContent = Definition | FootnoteDefinition; +``` + +**Definition** content represents out-of-band information that typically +affects the document through [**Association**][dfn-mxn-association]. + +### `ListContent` + +```idl +type ListContent = ListItem; +``` + +**List** content represent the items in a list. + +### `TableContent` + +```idl +type TableContent = TableRow; +``` + +**Table** content represent the rows in a table. + +### `RowContent` + +```idl +type RowContent = TableCell; +``` + +**Row** content represent the cells in a row. + +### `PhrasingContent` + +```idl +type PhrasingContent = StaticPhrasingContent | Link | LinkReference; +``` + +**Phrasing** content represent the text in a document, and its markup. + +### `StaticPhrasingContent` + +```idl +type StaticPhrasingContent = + HTML | InlineCode | Break | Emphasis | Strong | Delete | Image | + ImageReference | Footnote | FootnoteReference | Text; +``` + +**StaticPhrasing** content represent the text in a document, and its +markup, that is not intended for user interaction. + +## Glossary + +See the [unist glossary][glossary]. + ## List of Utilities +See the [unist list of utilities][utilities] for more utilities. + * [`mdast-util-assert`](https://github.com/syntax-tree/mdast-util-assert) - — Assert MDAST nodes + — Assert nodes * [`mdast-add-list-metadata`](https://gitlab.com/staltz/mdast-add-list-metadata) — Enhances the metadata of list and listItem nodes * [`mdast-comment-marker`](https://github.com/syntax-tree/mdast-comment-marker) — Parse a comment marker * [`mdast-util-compact`](https://github.com/syntax-tree/mdast-util-compact) - — Make an MDAST tree compact + — Make a tree compact * [`mdast-util-definitions`](https://github.com/syntax-tree/mdast-util-definitions) — Find definition nodes * [`mdast-flatten-listitem-paragraphs`](https://gitlab.com/staltz/mdast-flatten-listitem-paragraphs) — Flatten listItem and (nested) paragraph into one listItem node * [`mdast-flatten-nested-lists`](https://gitlab.com/staltz/mdast-flatten-nested-lists) - — Transforms an MDAST tree to avoid lists inside lists + — Transforms a tree to avoid lists inside lists * [`mdast-util-heading-range`](https://github.com/syntax-tree/mdast-util-heading-range) — Markdown heading as ranges * [`mdast-util-heading-style`](https://github.com/syntax-tree/mdast-util-heading-style) @@ -885,39 +1322,68 @@ Yields: — Flatten paragraph and image into one image node * [`mdast-move-images-to-root`](https://gitlab.com/staltz/mdast-move-images-to-root) — Moves image nodes up the tree until they are strict children of the root -* [`mdast-normalize-headings`](https://github.com/eush77/mdast-normalize-headings) +* [`mdast-normalize-headings`](https://github.com/syntax-tree/mdast-normalize-headings) — Ensure at most one top-level heading is in the document -* [`mdast-squeeze-paragraphs`](https://github.com/eush77/mdast-squeeze-paragraphs) +* [`mdast-squeeze-paragraphs`](https://github.com/syntax-tree/mdast-squeeze-paragraphs) — Remove empty paragraphs * [`mdast-util-toc`](https://github.com/BarryThePenguin/mdast-util-toc) — Generate a Table of Contents from a tree * [`mdast-util-to-hast`](https://github.com/syntax-tree/mdast-util-to-hast) - — Transform MDAST to HAST + — Transform to HAST * [`mdast-util-to-nlcst`](https://github.com/syntax-tree/mdast-util-to-nlcst) - — Transform MDAST to NLCST + — Transform to NLCST * [`mdast-zone`](https://github.com/syntax-tree/mdast-zone) — HTML comments as ranges or markers -## Related - -* [remark][] -* [unist][] -* [nlcst][] -* [vfile][] +## References + +* **unist**: + [Universal Syntax Tree][unist]. + T. Wormer; et al. +* **Markdown**: + [Markdown][]. + J. Gruber. +* **CommonMark**: + [CommonMark][]. + J. MacFarlane; et al. +* **GFM**: + [GitHub Flavored Markdown][gfm]. + GitHub. +* **HTML**: + [HTML Standard][html], + A. van Kesteren; et al. + WHATWG. +* **CSSTEXT**: + [CSS Text][css-text], + CSS Text, E. Etemad, K. Ishii. + W3C. +* **JavaScript** + [ECMAScript Language Specification][javascript]. + Ecma International. +* **YAML**: + [YAML Ain’t Markup Language][yaml], + O. Ben-Kiki, C. Evans, I. döt Net. +* **Web IDL**: + [Web IDL][webidl], + C. McCormack. + W3C. ## Contribute -**mdast** is built by people just like you! Check out -[`contributing.md`][contributing] for ways to get started. +**mdast** is built by people just like you! +Check out [`contributing.md`][contributing] for ways to get started. -This project has a [Code of Conduct][coc]. By interacting with this repository, -organisation, or community you agree to abide by its terms. +This project has a [Code of Conduct][coc]. +By interacting with this repository, organisation, or community you agree to +abide by its terms. -Want to chat with the community and contributors? Join us in [Gitter][chat]! +Want to chat with the community and contributors? +Join us in [Gitter][chat]! -Have an idea for a cool new utility or tool? That’s great! If you want -feedback, help, or just to share it with the world you can do so by creating -an issue in the [`syntax-tree/ideas`][ideas] repository! +Have an idea for a cool new utility or tool? +That’s great! +If you want feedback, help, or just to share it with the world you can do so by +creating an issue in the [`syntax-tree/ideas`][ideas] repository! ## Acknowledgments @@ -938,7 +1404,8 @@ Thanks to [**@rhysd**](https://github.com/rhysd), [**@Sarah-Seo**](https://github.com/Sarah-Seo), [**@sethvincent**](https://github.com/sethvincent), and -[**@simov**](https://github.com/simov) for contributing commits since! +[**@simov**](https://github.com/simov) for contributing to mdast and related +projects! ## License @@ -946,64 +1413,126 @@ Thanks to -[logo]: https://cdn.rawgit.com/syntax-tree/mdast/6205835/logo.svg +[contributing]: contributing.md -[unist]: https://github.com/syntax-tree/unist +[coc]: code-of-conduct.md -[remark]: https://github.com/wooorm/remark +[license]: https://creativecommons.org/licenses/by/4.0/ -[nlcst]: https://github.com/syntax-tree/nlcst +[author]: http://wooorm.com -[vfile]: https://github.com/vfile/vfile +[logo]: https://cdn.rawgit.com/syntax-tree/mdast/6205835/logo.svg + +[ideas]: https://github.com/syntax-tree/ideas + +[chat]: https://gitter.im/remarkjs/remark [releases]: https://github.com/syntax-tree/mdast/releases [latest]: https://github.com/syntax-tree/mdast/releases/tag/2.2.0 -[node]: https://github.com/syntax-tree/unist#node +[dfn-node]: https://github.com/syntax-tree/unist#node -[parent]: https://github.com/syntax-tree/unist#parent +[dfn-unist-parent]: https://github.com/syntax-tree/unist#parent -[text]: https://github.com/syntax-tree/unist#text +[dfn-unist-literal]: https://github.com/syntax-tree/unist#literal -[task-list]: https://help.github.com/articles/writing-on-github/#task-lists +[dfn-parent]: #parent -[inlinecode]: #inlinecode +[dfn-literal]: #literal -[code]: #code +[dfn-code]: #code -[list]: #list +[dfn-inline-code]: #inlinecode -[listitem]: #listitem +[dfn-list]: #list -[table]: #table +[dfn-table]: #table -[tablerow]: #tablerow +[dfn-link-reference]: #linkreference -[tablecell]: #tablecell +[dfn-image-reference]: #imagereference -[definition]: #definition +[dfn-footnote-reference]: #footnotereference -[linkreference]: #linkreference +[dfn-definition]: #definition -[imagereference]: #imagereference +[dfn-footnote-definition]: #footnotedefinition -[footnote]: #footnote +[term-tree]: https://github.com/syntax-tree/unist#tree -[footnotereference]: #footnotereference +[term-child]: https://github.com/syntax-tree/unist#child -[footnotedefinition]: #footnotedefinition +[term-sibling]: https://github.com/syntax-tree/unist#sibling -[frontmatter]: https://github.com/wooorm/remark-frontmatter +[term-root]: https://github.com/syntax-tree/unist#root -[contributing]: contributing.md +[term-head]: https://github.com/syntax-tree/unist#head -[coc]: code-of-conduct.md +[dfn-mxn-resource]: #resource -[ideas]: https://github.com/syntax-tree/ideas +[dfn-mxn-association]: #association -[chat]: https://gitter.im/wooorm/remark +[dfn-mxn-reference]: #reference -[license]: https://creativecommons.org/licenses/by/4.0/ +[dfn-mxn-alternative]: #alternative -[author]: http://wooorm.com +[dfn-enum-align-type]: #aligntype + +[dfn-enum-reference-type]: #referencetype + +[dfn-content]: #content + +[dfn-top-level-content]: #toplevelcontent + +[dfn-block-content]: #blockcontent + +[dfn-frontmatter-content]: #frontmattercontent + +[dfn-definition-content]: #frontmattercontent + +[dfn-list-content]: #listcontent + +[dfn-table-content]: #tablecontent + +[dfn-row-content]: #rowcontent + +[dfn-phrasing-content]: #phrasingcontent + +[dfn-static-phrasing-content]: #staticphrasingcontent + +[list-of-utilities]: #list-of-utilities + +[unist]: https://github.com/syntax-tree/unist + +[syntax-tree]: https://github.com/syntax-tree/unist#syntax-tree + +[yaml]: http://yaml.org + +[html]: https://html.spec.whatwg.org/multipage/ + +[css-text]: https://drafts.csswg.org/css-text/ + +[css-left]: https://drafts.csswg.org/css-text/#valdef-text-align-left + +[css-right]: https://drafts.csswg.org/css-text/#valdef-text-align-right + +[css-center]: https://drafts.csswg.org/css-text/#valdef-text-align-center + +[javascript]: https://www.ecma-international.org/ecma-262/9.0/index.html + +[webidl]: https://heycam.github.io/webidl/ + +[markdown]: https://daringfireball.net/projects/markdown/ + +[commonmark]: https://commonmark.org + +[gfm]: https://github.github.com/gfm/ + +[glossary]: https://github.com/syntax-tree/unist#glossary + +[utilities]: https://github.com/syntax-tree/unist#list-of-utilities + +[unified]: https://github.com/unifiedjs/unified + +[remark]: https://github.com/remarkjs/remark