This is a candidate specification. Changes are unlikely, but may still be made before the final specification.
Attributes provide extra information for elements as key-value pairs. Ducktype attributes are similar to XML, except they allow certain shorthand notations.
An attribute list starts with a left square bracket and continues to the first unescaped and unquoted right square bracket.
Attribute lists can occur after, in , in
An attribute list is a space-separated list of attributes. Each attribute is a name and a value separated by an equals sign, except for certain shorthand notations.
Attribute values can be quoted with single or double quotes, or they can be unquoted if the value contains no spaces.
An attribute without an equals sign is a bare word. Bare words are shorthand attributes:
If the bare word starts with ., it is a style attribute.
If the bare word starts with #, it is an id attribute.
If the bare word starts with >>, it is an href attribute.
If the bare word starts with >, it is an xref attribute.
Otherwise, the bare word is a type attribute.
Attribute values may contain $ followed by the entity name followed by ;.references. An entity reference is
Specify that a page is a guide page:
= My Page Title [type=guide]
Specify that a page is a guide page using shorthand notation:
= My Page Title [guide]
Use an type and xref attributes:to create a guide link, using shorthand notation for the
= My Page Title @link[guide >index]
Attribute lists on style attribute on a note:share the starting bracket with the element declaration. Use a
[note style=warning] This is a warning.
Use shorthand notation for a style attribute:
[note .warning] This is a warning.
Use shorthand notation for a xref attribute in a link :
Learn more about $xref[>duck_inline](inline elements).
Attribute lists occur in four places: header attribute lists for, in , in , and in . For header, informational, and inline elements attribute lists, the attribute list starts with a left square bracket. For block attribute lists, the block declaration itself starts with a left square bracket, so the attribute list begins with the first whitespace character after the block name.
An attribute list is a space-separated list of key-value pairs in the form name=value. If the value is quoted with a single or double quote, the value finishes when that quote character is encountered. However, the quote character itself may be escaped in the value as $' or $" or using other entity values (described below). Furthermore, $ itself may be escaped as $$.
If the value is not quoted, it ends with the first whitespace character or right square bracket, unless the right square bracket is escaped as $]. An unescaped right square bracket (outside a quoted value) ends the attribute list. Unlike XML, no space is allowed around the = character.
The full attribute list may contain newlines as insignificant whitespace or as part of values. If the parser is inside the attribute list, only a square bracket may end it. Normal indentation requirements do not hold in an attribute list except for attribute lists on inline elements. Because block and inline parsing can be done in separate steps, if newlines occur in inline attribute lists, the new lines must be indented to at least the inner indent of the containing block.
In addition to regular key-value pairs, bare words are allowed in attribute lists, possibly with leading sigils, for common cases. A bare word starts either with the sigil or a non-whitespace character, and finishes at the first whitespace character or an unescaped right square bracket.
If the word starts with >>, the value is taken as the value of the href attribute.
If the word starts with >, the value is taken as the value of the xref attribute.
If the word starts with ., the value is taken as the value of the style attribute.
If the word starts with #, the value is taken as the value of the id attribute.
Otherwise, the value is taken as the value of the type attribute.
For the type and style attributes only, multiple values are joined with a space character.
Attribute values are parsed to allow character escapes and entities. If the character $ (U+0024) is followed by one of $ (U+0024), * (U+002A), = (U+003D), - (U+002D), @ (U+0040), [ (U+005B), ] (U+005D), ( (U+0028), ) (U+0029), " (U+0022), or ' (U+0027), that two-character sequence is replaced by the second character.
If the character $ (U+0024) is followed by a name and the character ; (U+003B), then the name is an entity name, and the entire entity reference is replaced according to the following rules:
If the name is a, the content of that entity is parsed as attribute value content, and the result is used. Each entity is parsed in its own subcontext, so an entity reference cannot span across multiple entities. Parsers must detect cycles in entity references and produce an error.
Otherwise, if the name is defined in, the corresponding value is used.
Otherwise, if the name consists only of characters in the ranges 0-9, a-f, and A-F, that value is interpreted as a hexadecimal number, and the Unicode character with that code point is used.
Otherwise, the entity is unrecognized, and parsers must produce an error.