diff --git a/spec.txt b/spec.txt index c06f750c..fa483c4a 100644 --- a/spec.txt +++ b/spec.txt @@ -473,7 +473,7 @@ An [ATX header](#atx-header) consists of a string of characters, parsed as inline content, between an opening sequence of 1--6 unescaped `#` characters and an optional closing sequence of any number of `#` characters. The opening sequence -of `#` characters cannot be followed directly by a nonspace character. +of `#` characters cannot be followed directly by a non-space character. The closing `#` characters may be followed by spaces only. The opening `#` character may be indented 0-3 spaces. The raw contents of the header are stripped of leading and trailing spaces before being parsed @@ -599,7 +599,7 @@ Spaces are allowed after the closing sequence:
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, and that does not contain a blank line. 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"} +. +---{.myClass}
+. + +. +--- {#myId .myClass key=val key2="val 2"} +. +--- {#myId
+.myClass}
+. + +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"} +. +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][bar]
+
+[bar]: /url "title"{.no-attribute}
+.
+[foo][bar]
+[bar]: /url "title"{.no-attribute}
+. + +. +[foo][bar] + +[bar]: /url{.no-attribute} +. + +. + + +### 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} +. +++. + +. +> Paragraph with attributes +> inside a block quote. +> {.myPar} +. +Blockquote with attributes.
+
++. + +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} +. +Paragraph with attributes inside a block quote.
+
++. + +. +> Blockquote without attributes. + {.nope} +. +Blockquote with attributes.
+
++. + +. +> Blockquote with +lazy continuation +{.myBlockquote} +. +Blockquote without attributes. {.nope}
+
++. + +. +> Blockquote with +lazy continuation + {.nope} +. +Blockquote with lazy continuation.
+
++. + + +### Lists + +. +- list with +- attributes +{.myList} +. +Blockquote with lazy continuation {.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 loose list
with attributes
loose list
with attributes
a loose list
without attributes
{.nope}
+. + +. +- a loose list where + +- the last paragraph has attributes. + Note that the indentation of the + attribute block is significant. + {.myPar} +. +a loose list where
the last paragraph has attributes
a loose list
with lazy continuation
a loose list
with lazy continuation
++a list where each item is a blockquote
+
++to see what is possible
+
foo
foo
{.no-attribute}
foo
+. + +. +**foo**{.myClass} +. +foo
+. + + +### Inline Links + +An attribute block follows a link's right parenthesis (`)`) immediately: + +. +[link](/uri){.myClass} +. + +. + + +### Images + +As images are defined as links preceded by an exclamation mark (`!`), the behaviour is already well-defined. + +. +![foo](/url){.myClass} +. + +. + + +### 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} +. ++. + +Note that [reference links](#reference-links) have their attributes in the reference part, thus this span is not to be confused with a reference link: + +. +a paragraph with [no reflink]{.myClass} + +[no reflink]: http://test.com +. +
a paragraph with no reflink
+. + + # Appendix A: A parsing strategy {-}