diff --git a/spec.txt b/spec.txt index 6204443b..d22a7b9f 100644 --- a/spec.txt +++ b/spec.txt @@ -5944,6 +5944,576 @@ Multiple spaces

Multiple spaces

. +# Extensions + +This section contains extensions to the Core Markdown syntax described above. They don't need to be implemented to conform to this spec. However, if an implementation includes an extension with the same purpose as one of the extensions described here, this spec strongly recommends to implement the syntax described here. + + +## Attributes + +Certain elements may carry an attribute block. The following subsections list all elements that may contain attributes, see those for examples. + +- For inlines, the attribute block must immediately follow the element without any characters between the end of the inline and the start of the attribute block. +- For horizontal rules, headers, fenced code blocks and reference links, there must be one or more space characters preceding the attribute block and any trailing whitespace is non-significant. +- For paragraphs, block quotes and tight lists, the attribute block must start on a line that immediately follows the corresponding block. (Attributes on list items are not supported.) +- For loose lists, the attribute block must start on a line that either immediately follows the list or is separated from it by only one blank line. + +For the last two points in the above list the following must hold: the line(s) on which the attribute block resides must not contain any other characters except for leading spaces (i.e. indentation), which may be significant in determining to which element the attribute block belongs, but the start of the attribute block must be indented by exactly the same amount as the corresonding block itself. Trailing whitespace is non-significant. + +An attribute block consists of a sequence of zero or more characters, between an unescaped opening LEFT CURLY BRACKET (`{`) and an unescaped closing RIGHT CURLY BRACKET (`}`), that includes curly brackets only if they are part of a balanced pair of unescaped double-quote or single-quote characters. The characters between the opening and closing brackets form zero or more attributes which are separated by one or more whitespace characters (and may contain non-significant leading and trailing whitespace). The order of the attributes is not significant. An attribute consists of (a) a key-value pair, (b) an id-identifier or (c) a class-identifier. + +- a) A key-value pair consists of a key, immediately followed by an EQUALS SIGN (`=`) which is immediately followed by the value. The key follows the syntax of [raw HTML attribute names](#attribute-name). The value consists of either + + - a sequence of zero or more characters that does not include ASCII space or control characters, or + - a sequence of zero or more characters between straight double-quote characters (`"`), including a `"` character only if it is backslash-escaped, or + - a sequence of zero or more characters between straight single-quote characters (`'`), including a `'` character only if it is backslash-escaped. + +- b) An id-identifier consists of a NUMBER SIGN — also known as a hash — (`#`) immediately followed by one or more characters that does neither include ASCII space or control characters nor curly brackets. `{#myId}` is syntactic sugar for `{id=myId}`. + +- c) A class-identifier consists of a FULL STOP (`.`) immediately followed by one or more characters that does neither include ASCII space or control characters nor curly brackets. `{.myClass}` is syntactic sugar for `{class=myClass}`. + +Markdown authors shouldn't write multiple key-value pairs with the same key in an attribute block. However, to ease the burden of implementation, the behaviour in such cases is left undefined—although most implementations will probably parse the attributes sequentially and insert them into a map, which would result in a last-one-wins semantic. + +If there are curly brackets that contain characters which don't follow the rules outlined above and below, the curly brackets and the containing characters are not considered an attribute block but regular text and are to be interpreted accordingly. + + +### Horizontal rules + +. +--- {#myId .myClass key=val key2="val 2"} +. +
+. + +There must be one or more space characters in front of the attribute block: + +. +---{.myClass} +. +

---{.myClass}

+. + +. +--- {#myId .myClass key=val key2="val 2"} +. +
+. + +Any whitespace (not only spaces) separate the attributes: + +. +--- {#myId .myClass +key=val} +. +
+. + +Any characters (except unescaped quotes of the same kind) are allowed in quoted attributes: + +. +--- {key="Hello \"World\"!" key2='Hello "World"!' key3="even new +lines and special chars like '=' or '`' are allowed"} +. +
+. + + +### ATX headers + +. +### foo {#myId .myClass key=val key2="val 2"} +. +

foo

+. + +Or with a closing header sequence: + +. +### foo ### {#myId} +. +

foo

+. + + +### Setext headers + +. +Foo {#myId} +=========== +. +

Foo

+. + + +### Fenced code blocks + +. +``` {.language-ruby #code1} +x = 1 +``` +. +
x = 1
+
+. + +[Info strings](#info-string) are syntactic sugar for classes, i.e. the following two fenced code blocks are identical: + + ```ruby + x = 1 + ``` + + ``` {.language-ruby} + x = 1 + ``` + +As the attribute block must be preceded by a space, this may be surprising: + +. +```{.foo} +x = 1 +``` +. +
x = 1
+
+. + +### Reference Links + +There must be one or more space characters preceding the attribute block in a reference link as well: + +. +[foo][bar] + +[bar]: /url "title" {.myClass} +. +

foo

+. + +. +[foo][bar] + +[bar]: /url "title"{.no-attribute} +. +

[foo][bar]

+

[bar]: /url "title"{.no-attribute}

+. + +. +[foo][bar] + +[bar]: /url{.no-attribute} +. +

foo +

+. + + +### Paragraphs + +Attribute blocks must start on a line following the paragraph. + +. +Paragraph with attributes. +{.myPar} +. +

Paragraph with attributes.

+. + +. +Paragraph with attributes. +{.myPar +#myId} +. +

Paragraph with attributes.

+. + +. +Paragraph {.nope} +. +

Paragraph {.nope}

+. + +. +Paragraph + +{.nope} +. +

Paragraph

+

{.nope}

+. + +Attribute blocks for paragraphs must be indented exactly as much as the first line of the paragraph itself: + +. +Paragraph + {.nope} +. +

Paragraph {.nope}

+. + + +### Block quotes + +. +> Blockquote with attributes. +{.myBlockquote} +. +
+

Blockquote with attributes.

+
+. + +. +> Paragraph with attributes +> inside a block quote. +> {.myPar} +. +
+

Paragraph with attributes inside a block quote.

+
+. + +Attribute blocks for block quotes must be indented exactly as much as the `>` which is part of the [block quote marker](#block-quote-marker): + +. + > Blockquote with attributes. + {.myBlockquote} +. +
+

Blockquote with attributes.

+
+. + +. +> Blockquote without attributes. + {.nope} +. +
+

Blockquote without attributes. {.nope}

+
+. + +. +> Blockquote with +lazy continuation +{.myBlockquote} +. +
+

Blockquote with lazy continuation.

+
+. + +. +> Blockquote with +lazy continuation + {.nope} +. +
+

Blockquote with lazy continuation {.nope}

+
+. + + +### Lists + +. +- list with +- attributes +{.myList} +. + +. + +. +- tight list without +- attributes + +{.nope} +. + +

{.nope}

+. + +Attribute blocks for lists must be indented exactly as much as the [list markers](#list-marker): + +. +- a tight list +- without attributes + {.nope} +. + +. + +. +- a tight list +- without attributes + {.nope} +. + +. + +. +- one 1 +- two 2 + - 2.1 + {.myList} +. + +. + +. +- a loose list + +- with attributes + +{.myList} +. + +. + +. +- loose list + +- with attributes +{.myList} +. + +. + +. +- a loose list + +- without attributes + + +{.nope} +. + +

{.nope}

+. + +. +- a loose list where + +- the last paragraph has attributes. + Note that the indentation of the + attribute block is significant. + {.myPar} +. + +. + +Attribute blocks themselves do not obey the lazy continuation rules. They can be used with lazy continuation paragraphs, however it is not recommended since it gets quickly confusing. + +. +- a loose list + +- with lazy +continuation +{.myList} +. + +. + +. +- a tight list +{.nope} +- with lazy +continuation + {.nope} +. + +. + +. +- a loose list + +- with lazy +continuation + {.myPar} +. + +. + +A list of blockquotes: + +. +- > a list where each + > item is a blockquote + > {.myPar} + +- > to see what is possible + > {.myPar} + {.myBlockquote} +{.myList} +. + +. + +Note that list items themselves cannot have attributes. + + +### Code span + +An attribute block follows the closing code span backtick immediately: + +. +`foo`{.myClass} +. +

foo

+. + +. +`foo` {.no-attribute} +. +

foo {.no-attribute}

+. + + +### Emphasis and strong emphasis + +An attribute block follows any closing emphasis character immediately: + +. +_foo_{.myClass} +. +

foo

+. + +. +**foo**{.myClass} +. +

foo

+. + + +### Inline Links + +An attribute block follows a link's right parenthesis (`)`) immediately: + +. +[link](/uri){.myClass} +. +

link

+. + + +### Images + +As images are defined as links preceded by an exclamation mark (`!`), the behaviour is already well-defined. + +. +![foo](/url){.myClass} +. +

foo

+. + + +### Spans + +A span consists of + +- an opening `[`, followed by +- zero or more characters parsed as inline (where neither the first nor the last character is an ASCII space or control character), followed by +- a closing `]`, immediately followed by +- a mandatory attribute block. + +. +[foo _bar_]{#myId} +. +

foo bar

+. + +Spaces before or after the span are not required: + +. +this[foo]{#myId}works +. +

thisfooworks

+. + +But the span content mustn't start or end with whitespace: + +. +[ does not]{} work +. +

[ does not]{} work

+. + +. +[does not ]{} work +. +

[does not ]{} work

+. + +Empty attribute blocks are generally allowed: + +. +[foo]{} +. +

foo

+. + +As are empty spans: + +. +[]{.glyphicon} +. +

+. + + # Appendix A: A parsing strategy {-}