Definition lists and abbreviations
Terms and descriptions, abbreviation definitions and the document levels that may declare them.
Generated from resources/examples/edge-cases.md and resources/examples/core.md - edit the cases there, not here. Each case links the conformance fixture it produces.
Abbreviation matches on word boundaries only
1 conformance fixture
A defined abbreviation is expanded only as a whole word — it is not substituted inside a longer word.
*[HTML]: HyperText Markup Language
HTML and XHTMLish.<p><abbr title="HyperText Markup Language">HTML</abbr> and XHTMLish.</p>Abbreviation definition interrupts a paragraph
1 conformance fixture
An abbreviation definition is an invisible construct (§10): on the line directly after prose it is consumed and applied, with no blank line needed.
The HTML spec is long.
*[HTML]: HyperText Markup Language<p>The <abbr title="HyperText Markup Language">HTML</abbr> spec is long.</p>Abbreviation definition separator must be a space
1 conformance fixture
Abbreviation definitions follow the rule too: *[label]: must be followed by a literal space. A tab keeps the line as a paragraph and no abbreviation is registered.
*[HTML]: Hyper
The HTML<p>*[HTML]: Hyper</p>
<p>The HTML</p>Definition list as a first-class block opener
4 conformance fixtures
A :: term definition-list opener is a block opener like every other (quote, heading, fence, table) under the content-column rule (PART 9 §24 C3): it interrupts an open list item at column 0, and nests at the item's content column. The two-line :: /: marker is recognized by look-ahead; only the :: term line opens the block.
At the content column, the definition list nests inside the item.
- one
:: term
: def<ul>
<li>one
<dl>
<dt>term</dt>
<dd>def</dd>
</dl>
</li>
</ul>At column 0 (below the content column), it interrupts: the list ends and the definition list parses at document level.
- one
:: term
: def<ul>
<li>one</li>
</ul>
<dl>
<dt>term</dt>
<dd>def</dd>
</dl>Below the content column but not at column 0, it folds in as lazy item text.
- one
:: term
: def<ul>
<li>one
:: term
: def</li>
</ul>A blank line before a nested definition list keeps the outer item tight (§17), like any other nested sub-block.
- one
:: t
: d<ul>
<li>one
<dl>
<dt>t</dt>
<dd>d</dd>
</dl>
</li>
</ul>Abbreviation title escapes its markup characters
1 conformance fixture
An abbreviation's expansion becomes the title attribute, so &, <, > and " in it are entity-escaped like any attribute value.
*[HTML]: Hyper & Text < Markup > "quoted"
The HTML spec.<p>The <abbr title="Hyper & Text < Markup > "quoted"">HTML</abbr> spec.</p>Under-indented definition attaches, over-indented definition folds
3 conformance fixtures
A : def line is a lenient definition-list entry (PART 9 §24 C3): it attaches as a fresh <dd> to its open :: term when its column is at or below the term's, even under the item's content column. Only a definition line indented above the term folds into the term text as a lazy continuation.
Under-indented (below the content column, still above column 0): the definition attaches.
- one
:: term
: def<ul>
<li>one
<dl>
<dt>term</dt>
<dd>def</dd>
</dl>
</li>
</ul>At column 0, the definition still attaches: the : marker is a lenient exception to the column-0 interrupt rule, so it does not end the item and orphan the definition.
- one
:: term
: def<ul>
<li>one
<dl>
<dt>term</dt>
<dd>def</dd>
</dl>
</li>
</ul>Over-indented (above the term): the line folds into the term, preserving its over-indent whitespace.
- one
:: term
: def<ul>
<li>one
<dl>
<dt>term
: def</dt>
</dl>
</li>
</ul>Wrapped definition term continuation below the content column strips leading whitespace
2 conformance fixtures
A :: term line inside a list item may be continued by a wrapped line. When that continuation sits below the item content column it is a lazy continuation, so - like a lazy paragraph or blockquote continuation - its leading whitespace is stripped before it folds into the <dt>. (A continuation above the content column instead folds with its residual indent preserved; a continuation at or above the content column is dedented rather than stripped.)
At column 1, one below the content column 2: the leading space is stripped before the fold.
- one
:: term
wrapped<ul>
<li>one
<dl>
<dt>term
wrapped</dt>
</dl>
</li>
</ul>At column 0, flush left: the continuation still folds into the term, byte-identically.
- one
:: term
wrapped<ul>
<li>one
<dl>
<dt>term
wrapped</dt>
</dl>
</li>
</ul>Two abbreviation definitions
1 conformance fixture
Nothing about the second definition is special - it is here because a document with TWO of them is what tells the engines apart. The HTML says nothing about how the definitions were spelled, so a formatter that joined them differently stayed invisible until the canonical-Carve target was compared across engines (carve-php#682).
*[HTML]: HyperText Markup Language
*[CSS]: Cascading Style Sheets
HTML and CSS.<p><abbr title="HyperText Markup Language">HTML</abbr> and <abbr title="Cascading Style Sheets">CSS</abbr>.</p>An abbreviation definition is recognized only at document level
1 conformance fixture
*[TERM]: expansion defines an abbreviation only as a direct child of the document. Inside a block quote, a list item or a div the line is ordinary paragraph text: it defines nothing and it is preserved as written. An abbreviation is the only definition kind with no marker at the use site, so a definition carried in quoted material would otherwise rewrite every occurrence of its term in the quoting document.
> *[HTML]: Hyper Text
The HTML spec.<blockquote><p>*[HTML]: Hyper Text</p></blockquote>
<p>The HTML spec.</p>A list item does not define an abbreviation either
1 conformance fixture
The same rule holds for every container, not just the block quote: the definition line stays visible text and expands nothing.
- *[HTML]: Hyper Text
The HTML spec.<ul>
<li>*[HTML]: Hyper Text</li>
</ul>
<p>The HTML spec.</p>A div does not define an abbreviation either
1 conformance fixture
The rule names three containers - a block quote, a list item and a div - and the first two were pinned while the third was not. A div is the one of the three that renders its children unchanged, so a definition inside it is the case where the line looks most like a document-level one, and the use below it still gets no <abbr>.
:::
*[HTML]: Hyper Text
The HTML spec.
:::<div>
<p>*[HTML]: Hyper Text</p>
<p>The HTML spec.</p>
</div>A definition below every content column folds as text
1 conformance fixture
A definition is not block-shaped, but §24 C3's "every other line" covers it too: below every open content column it folds into the item paragraph as literal text and registers nothing, so a reference to it elsewhere stays literal. The failure this guards against is not a wrong shape but a disappearance - a definition that falls past the fold branch lands at the item's own column 0, where it is skipped as already-extracted and renders as nothing at all.
- - a
[^f]: x<ul>
<li>
<ul>
<li>a
[^f]: x</li>
</ul>
</li>
</ul>An abbreviation at a list item's content column is still not a definition
2 conformance fixtures
*[TERM]: expansion is recognized only at document level - NORMATIVE, and already pinned inside a block quote and on a list item's MARKER line. The position that was missing is the one where the other definition kinds do the opposite: an item's CONTENT COLUMN, on a continuation line. There the line is item text and defines nothing, so the reference below it renders without an <abbr>.
- a
*[HTML]: Hyper Text
The HTML spec.<ul>
<li>a
*[HTML]: Hyper Text</li>
</ul>
<p>The HTML spec.</p>The contrast is the point: a REFERENCE definition written at that same column IS the item's block, so it renders nothing and resolves. Three definition kinds, one column, two answers - and until now nothing measured the difference at this position.
- a
[r]: /u
see [t][r]<ul>
<li>a</li>
</ul>
<p>see <a href="/u">t</a></p>An abbreviation definition in an item body is paragraph text
5 conformance fixtures
324-an-abbreviation-definition-in-an-item-body-is-paragraph-text324-an-abbreviation-definition-in-an-item-body-is-paragraph-text-2324-an-abbreviation-definition-in-an-item-body-is-paragraph-text-3324-an-abbreviation-definition-in-an-item-body-is-paragraph-text-4324-an-abbreviation-definition-in-an-item-body-is-paragraph-text-5
PART 12 §7 says an abbreviation_definition is one only as a direct child of the document: written inside a block quote, a list item or a div, "the line is not a definition at all: it is ordinary paragraph text, it defines nothing, and it is preserved as the text the author typed". So the looseness question §17 L1 asks - does the item hold a blank-line-separated second paragraph - has an answer that follows from §7 rather than from a rule about abbreviations: the line renders, so it IS that paragraph, and the item is loose.
- a
*[A]: a<ul>
<li><p>a</p>
<p>*[A]: a</p>
</li>
</ul>Nothing changes when a sublist follows it. The definition-shaped line is already the second paragraph, and §17 L2's attached sub-block cannot take that back:
- a
*[A]: a
- b<ul>
<li><p>a</p>
<p>*[A]: a</p>
<ul>
<li>b</li>
</ul>
</li>
</ul>Looseness is a property of the LIST, so a sibling item is wrapped too:
- a
*[A]: a
- b
- c<ul>
<li><p>a</p>
<p>*[A]: a</p>
<ul>
<li>b</li>
</ul>
</li>
<li><p>c</p></li>
</ul>The control is the definition kind that IS collected at that column. A link reference definition inside the item renders nothing, resolves for the rest of the document, and leaves the item tight - which is what makes the abbreviation's answer a consequence of §7 rather than an inconsistency:
- a
[r]: /u
See [x][r].<ul>
<li>a</li>
</ul>
<p>See <a href="/u">x</a>.</p>At document level the abbreviation is collected, renders nothing of its own, and expands its term - the behavior the container position does not get:
*[A]: alpha
A here<p><abbr title="alpha">A</abbr> here</p>A : description line needs a term above it
1 conformance fixture
A definition list is a term plus its descriptions, so a : line with no term above it opens nothing - the line is ordinary paragraph text, and anything on it stays text too.
: [r]: /u
see [t][r]<p>: [r]: /u</p>
<p>see [t][r]</p>A tab as the first character of a definition term
1 conformance fixture
A tab right after the marker's separator space is a different question from the previous one: the separator itself is a literal space, and it is present, so the marker is satisfied and a term forms. The tab is the first character of the term's content, not part of the separator - ordinary leading whitespace there, stripped the same way a bullet's own extra separator spaces never reach the item's text. It is not protected by the tabs-in-code verbatim rule, which covers fenced code content and inline code spans only (carve#698).
:: x<dl>
<dt>x</dt>
</dl>An abbreviation term is one ASCII alphanumeric word
2 conformance fixtures
abbreviation_term = (letter | digit)+, and letter is enumerated as a..z plus A..Z. So the term is case-blind, may start with a digit, and may be a digit alone - every corpus abbreviation before this one was an uppercase multi-letter word, which is the one shape that hides all of those.
*[dl]: definition list
*[3D]: three dimensional
*[9]: nine
A dl, a 3D one, and 9.<p>A <abbr title="definition list">dl</abbr>, a <abbr title="three dimensional">3D</abbr> one, and <abbr title="nine">9</abbr>.</p>A term outside that alphabet is not a definition, and the line stays as written rather than being dropped. An abbreviation has no marker at the use site, so a definition swallowed here would take its whole line of prose with it and leave nothing behind to explain the loss.
*[ß]: sharp s
*[e.g.]: for example
*[HTTP API]: an interface
Text about ss and eg below.<p>*[ß]: sharp s
*[e.g.]: for example
*[HTTP API]: an interface</p>
<p>Text about ss and eg below.</p>A definition inside a definition-list dd is collected, and the entry keeps no trace
2 conformance fixtures
A <dd> continues like a list item (§17, definition_body) and is one of the block-level contexts §17 L6 names: a definition written as its content is collected into the document-wide table and the entry renders empty, exactly as a list item or block quote does. This holds the same way for both definition kinds a <dd> can hold - a link reference definition and a footnote definition - so a fix for one is not a fix for only one (carve#666).
:: term
: [r]: /u
see [t][r]<dl>
<dt>term</dt>
<dd></dd>
</dl>
<p>see <a href="/u">t</a></p>:: term
: [^f]: x
see[^f]<dl>
<dt>term</dt>
<dd></dd>
</dl>
<p>see<a id="fnref1" href="#fn1" role="doc-noteref"><sup>1</sup></a></p>
<section role="doc-endnotes">
<hr>
<ol>
<li id="fn1">
<p>x<a href="#fnref1" role="doc-backlink">↩</a></p>
</li>
</ol>
</section>An empty abbreviation term is not a definition
1 conformance fixture
abbreviation_term = (letter | digit)+ needs at least one character, so *[]: opens nothing and the line stays paragraph text.
*[]: expansion
Text.<p>*[]: expansion</p>
<p>Text.</p>A definition body continuation indented past its column is lazy text
3 conformance fixtures
definition_indent (resources/grammar.ebnf, PART 2) is a whitespace run REACHING the body's column - the one : establishes. REACHING it is what makes a line the body's own content; going past it does not make the line something else, because there is nothing past that column for indentation to mean. So a line indented further is a continuation of the body's OPEN PARAGRAPH, its content is inline, and a > on it is a greater-than sign rather than a block quote opener.
The alternative reading - extra indentation opens a nested block, the way it does inside a list item - makes indentation depth mean two different things one line apart: the line above continues a paragraph lazily and this one would open a block. carve-js and carve-php read it that way and both move (carve#918).
The two documents after it are CONTROLS. They pin the columns on either side of the boundary, which do not change and are not what was ruled: at the body's own column a block opener still opens a block, and flush left the body ends and the quote is its sibling. Without them the rule above reads as "an indented > is never a quote", which is not what it says.
:: t
: body
> q<dl>
<dt>t</dt>
<dd>body
> q</dd>
</dl>CONTROL, at the body's column. Three spaces reach column 3, so the line is the body's own block content and the quote opens.
:: t
: body
> q<dl>
<dt>t</dt>
<dd>
<p>body</p>
<blockquote><p>q</p></blockquote>
</dd>
</dl>CONTROL, flush left. Column 0 does not reach the body's column at all, so the body ends and the quote is a sibling of the list.
:: t
: body
> q<dl>
<dt>t</dt>
<dd>body</dd>
</dl>
<blockquote><p>q</p></blockquote>An abbreviation expands inside an inline container
5 conformance fixtures
PART 9R R3 matches a term in RENDERED TEXT at word boundaries. The container the text sits in does not change that: an ordinary span, a compact semantic span and the :name[…] extension form all expand, exactly as emphasis and a link do.
The corpus had one case here - the explicit-abbr row, which every engine agreed on - so every neighbouring row was unpinned, and two engines kept opposite defects for months with no red test: carve-rs dropped the expansion inside a span, carve-js dropped it inside :name[…] (markup-carve/carve#1151).
*[HTML]: Long Form
The [HTML]{.x} key.<p>The <span class="x"><abbr title="Long Form">HTML</abbr></span> key.</p>A compact semantic span is the same question, and PART 9 §10 made this spelling a documented feature - so a dropped expansion here is silent loss inside a construct the docs teach.
*[HTML]: Long Form
The [HTML]{kbd} key.<p>The <kbd><abbr title="Long Form">HTML</abbr></kbd> key.</p>The :name[…] form takes the generic fallback in a core render, and the term still expands inside it.
*[HTML]: Long Form
The :kbd[HTML] key.<p>The <span class="ext-kbd"><abbr title="Long Form">HTML</abbr></span> key.</p>The controls: emphasis and a link already agreed across engines, and they pin that the containers above are not special-cased in one direction.
*[HTML]: Long Form
Both *HTML* and [HTML](/u) expand.<p>Both <strong><abbr title="Long Form">HTML</abbr></strong> and <a href="/u"><abbr title="Long Form">HTML</abbr></a> expand.</p>An explicit abbr attribute is the one exception (markup-carve/carve#1127): the authored expansion wins and the definition does not apply on top of it.
*[HTML]: Long Form
The [HTML]{abbr="Custom"} key.<p>The <abbr title="Custom">HTML</abbr> key.</p>Definition lists
1 conformance fixture
A definition list also does not interrupt a paragraph - a :: line directly under prose folds into that paragraph, so a list needs a blank line before it.
A blank line may separate a term from its definition (or one definition from the next) for readability - a following : line still attaches to the entry:
:: term
: the definition<dl>
<dt>term</dt>
<dd>the definition</dd>
</dl>A definition (<dd>) ends at a blank line that is followed by neither an indented continuation nor a : definition, at a new :: term, or at a block opener.
Attributes attach to the whole <dl> via a preceding block-attribute line ({.class} on the line before the first :: term). There is deliberately no per-<dt> / per-<dd> attribute form: unlike a list item (-{.c}) or a table row (| … |{.c}), a term or definition takes no glued marker attributes. Style individual terms/definitions with CSS descendant selectors (dl.gloss dt), or put the attributes on the <dl>.