5b3: name the alignment form the bare shape claims, record the reserved names' codes
CI / gate (push) Successful in 9s

This commit is contained in:
2026-09-03 19:23:48 +02:00
parent 9215c1cbdc
commit aa177d1f8e
7 changed files with 113 additions and 10 deletions
+9 -2
View File
@@ -100,7 +100,10 @@ reuses a code where one fits; the list is complete at `0.1.0`. A code names the
cause; where one cause recurs across node types, across one mark's attributes or across cause; where one cause recurs across node types, across one mark's attributes or across
directions, one code covers them all and directions, one code covers them all and
`path` and `message` say which — `unsupported-nesting-depth` is the 500-level guard whichever `path` and `message` say which — `unsupported-nesting-depth` is the 500-level guard whichever
direction hits it, `unspellable-link` the destination and the title alike. A claim code names the spelling claimed, never the node that spelling would have built: direction hits it, `unspellable-link` the destination and the title alike. Where two codes stay
apart, the line between them is what they name: `unspellable-character` is a character CommonMark
rewrites wherever text holds it, `unspellable-whitespace` the newline no inline directive's
content slot spans, in either direction. A claim code names the spelling claimed, never the node that spelling would have built:
a malformed `:::table` is a `malformed-directive`, and an alignment colon a `malformed-pipe-table` a malformed `:::table` is a `malformed-directive`, and an alignment colon a `malformed-pipe-table`
the flavour's own delimiter row is `-` runs, so the grammar refuses the colon rather than ADF's the flavour's own delimiter row is `-` runs, so the grammar refuses the colon rather than ADF's
missing column model doing it. A refusal no spelling recovers from is a gap in the flavour rather missing column model doing it. A refusal no spelling recovers from is a gap in the flavour rather
@@ -108,7 +111,11 @@ than a code: give the flavour the spelling and the code goes, which the freeze i
for. A cause the carry answers gets no code: a mark no for. A cause the carry answers gets no code: a mark no
spelling writes rides the carry with its node. A directive whose name reads back to no node is spelling writes rides the carry with its node. A directive whose name reads back to no node is
`unknown-directive-name` rather than a claim code — the spelling is well formed, and telling that `unknown-directive-name` rather than a claim code — the spelling is well formed, and telling that
apart from a typo is what a consumer switches on when a later MINOR gives the name meaning. What apart from a typo is what a consumer switches on when a later MINOR gives the name meaning. A
reserved name is a known name, so never that code, and the two the flavour reserves part on form:
a form the grammar does not have is a claim code — `::adf`, whose carry is the fence — and a
well-formed form in the wrong place is `unsupported-node-shape`, `::listBreak` parting anything
but two adjacent lists of one type. What
the grammar itself refuses stays a claim code, key order among it; a well-formed directive the the grammar itself refuses stays a claim code, key order among it; a well-formed directive the
node tables refuse — an attribute a node does not hold or spells elsewhere, a value outside its node tables refuse — an attribute a node does not hold or spells elsewhere, a value outside its
kind or its canonical spelling, an argument or a body its content model does not take — is kind or its canonical spelling, an argument or a body its content model does not take — is
@@ -127,6 +127,54 @@
} }
], ],
"type": "panel" "type": "panel"
},
{
"content": [
{
"content": [
{
"content": [
{
"content": [
{
"content": [
{
"text": "Head",
"type": "text"
}
],
"type": "paragraph"
}
],
"type": "listItem"
}
],
"type": "bulletList"
},
{
"content": [
{
"content": [
{
"content": [
{
"text": "Tail",
"type": "text"
}
],
"type": "paragraph"
}
],
"type": "listItem"
}
],
"type": "bulletList"
}
],
"type": "listItem"
}
],
"type": "bulletList"
} }
], ],
"type": "doc", "type": "doc",
@@ -15,3 +15,9 @@
::listBreak ::listBreak
- Right - Right
::: :::
- - Head
::listBreak
- Tail
@@ -0,0 +1,38 @@
{
"content": [
{
"content": [
{
"text": "Part | Qty",
"type": "text"
},
{
"type": "hardBreak"
},
{
"text": "--- | ---",
"type": "text"
}
],
"type": "paragraph"
},
{
"content": [
{
"text": "Part | Qty",
"type": "text"
},
{
"type": "hardBreak"
},
{
"text": ":--- | ---:",
"type": "text"
}
],
"type": "paragraph"
}
],
"type": "doc",
"version": 1
}
@@ -0,0 +1,5 @@
Part | Qty\
\--- | ---
Part | Qty\
\:--- | ---:
+5 -4
View File
@@ -26,7 +26,8 @@ normalizes to it through the round-trip.
second list on merges instead: ADF records no tightness, so one `- ` spelling reads two second list on merges instead: ADF records no tightness, so one `- ` spelling reads two
adjacent lists of a kind back as one. The leaf `::listBreak` parts them, taking the separation adjacent lists of a kind back as one. The leaf `::listBreak` parts them, taking the separation
any directive block takes where it sits. It builds no node, and it reads only between two any directive block takes where it sits. It builds no node, and it reads only between two
adjacent lists of one type: elsewhere, or carrying an argument or `{attrs}`, it is a named error. adjacent lists of one type: elsewhere, or carrying an argument, `{attrs}` or a body, it is a
named error.
- Blockquotes prefix lines with `> `; a blank line inside a blockquote is a bare `>`. - Blockquotes prefix lines with `> `; a blank line inside a blockquote is a bare `>`.
- ATX headings (`#``######`); setext input normalizes to ATX. - ATX headings (`#``######`); setext input normalizes to ATX.
- Code fences ``` with the node's language as info string, the fence lengthened past any backtick - Code fences ``` with the node's language as info string, the fence lengthened past any backtick
@@ -296,9 +297,9 @@ takes the directive form instead. A pipe table parses back to exactly that shape
Claiming at block level, symmetric with directives: a line opening with an unescaped `|` is Claiming at block level, symmetric with directives: a line opening with an unescaped `|` is
claimed and must parse as part of a pipe table, else it is a named error — escape the pipe claimed and must parse as part of a pipe table, else it is a named error — escape the pipe
(`\|`) to keep it literal text. The shape a missing leading pipe leaves is claimed too: a line (`\|`) to keep it literal text. The shape a missing leading pipe leaves is claimed too: a line
holding an unescaped `|`, followed inside one paragraph by a line whose cells are all `-` runs holding an unescaped `|`, followed inside one paragraph by a line whose cells are all `-` runs,
and match it in count — GFM's table without the outer pipes — is a named error rather than the an alignment colon among them, and match it in count — GFM's table without the outer pipes — is
prose it reads as. A pipe table is a header row, a delimiter row whose cells are a named error rather than the prose it reads as. A pipe table is a header row, a delimiter row whose cells are
runs of one or more `-` (canonical `---`), and body rows; rows follow code-fence indentation. runs of one or more `-` (canonical `---`), and body rows; rows follow code-fence indentation.
Cells split on unescaped `|` before inline parsing — `\|` stays in the cell text, and the Cells split on unescaped `|` before inline parsing — `\|` stays in the cell text, and the
inline layer's ordinary CommonMark escaping yields the pipe; each cell is the inline content of inline layer's ordinary CommonMark escaping yields the pipe; each cell is the inline content of
+2 -4
View File
@@ -1,5 +1,3 @@
const name = 'listBreak' export const listBreakName = 'listBreak'
export const listBreakName = name export const listBreakSpelling = `::${listBreakName}`
export const listBreakSpelling = `::${name}`