Hold the lazy-continuation fence, and fault a colon run that closes nothing
CI / gate (push) Successful in 5s
CI / gate (push) Successful in 5s
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@ One directory per contract kind, each landing with its milestone:
|
|||||||
|
|
||||||
- `round-trip/` — `<name>.json` + `<name>.md`: the markdown `adfToMarkdown` must emit for that
|
- `round-trip/` — `<name>.json` + `<name>.md`: the markdown `adfToMarkdown` must emit for that
|
||||||
document, byte for byte, and that `markdownToAdf` must read back to it (AGENTS.md §2). Grouped
|
document, byte for byte, and that `markdownToAdf` must read back to it (AGENTS.md §2). Grouped
|
||||||
by node family, `combinations/` holding what crosses them.
|
by what the fixture exercises.
|
||||||
- `normalization/` — `<name>.md` + `<name>.json`: markdown input, and the document
|
- `normalization/` — `<name>.md` + `<name>.json`: markdown input, and the document
|
||||||
`markdownToAdf` must build from it. One-way; the markdown is not canonical.
|
`markdownToAdf` must build from it. One-way; the markdown is not canonical.
|
||||||
- `errors/` — `<name>.md`: markdown input that must not convert. A `<name>.error` beside it
|
- `errors/` — `<name>.md`: markdown input that must not convert. A `<name>.error` beside it
|
||||||
|
|||||||
@@ -5,33 +5,6 @@
|
|||||||
"panelType": "info"
|
"panelType": "info"
|
||||||
},
|
},
|
||||||
"content": [
|
"content": [
|
||||||
{
|
|
||||||
"content": [
|
|
||||||
{
|
|
||||||
"text": ":::",
|
|
||||||
"type": "text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"type": "paragraph"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": [
|
|
||||||
{
|
|
||||||
"text": "::: x",
|
|
||||||
"type": "text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"type": "paragraph"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": [
|
|
||||||
{
|
|
||||||
"text": "::",
|
|
||||||
"type": "text"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"type": "paragraph"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"content": [
|
"content": [
|
||||||
{
|
{
|
||||||
@@ -64,6 +37,33 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"type": "blockquote"
|
"type": "blockquote"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"text": ":::",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "paragraph"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"text": "::: x",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "paragraph"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"text": "::",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "paragraph"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"type": "panel"
|
"type": "panel"
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
:::panel info
|
:::panel info
|
||||||
|
- \:::
|
||||||
|
|
||||||
|
> \:::
|
||||||
|
|
||||||
\:::
|
\:::
|
||||||
|
|
||||||
\::: x
|
\::: x
|
||||||
|
|
||||||
\::
|
\::
|
||||||
|
|
||||||
- \:::
|
|
||||||
|
|
||||||
> \:::
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
\:::
|
\:::
|
||||||
|
|||||||
+3
-1
@@ -86,7 +86,8 @@ function fenceNestingFault(markdown: string): string | undefined {
|
|||||||
const run = colons[1]?.length ?? 0
|
const run = colons[1]?.length ?? 0
|
||||||
const enclosing = open[open.length - 1]
|
const enclosing = open[open.length - 1]
|
||||||
if (colons[2] === '') {
|
if (colons[2] === '') {
|
||||||
if (enclosing !== undefined && run < enclosing) return `${JSON.stringify(line)} is shorter than the ${enclosing} colons it would close`
|
if (enclosing === undefined) return `${JSON.stringify(line)} closes no open container`
|
||||||
|
if (run < enclosing) return `${JSON.stringify(line)} is shorter than the ${enclosing} colons it would close`
|
||||||
open.pop()
|
open.pop()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -101,6 +102,7 @@ test('the fence nesting check catches a fence a container cannot hold', () => {
|
|||||||
assert.equal(fenceNestingFault(':::panel info\n- - :::panel warning\n B\n :::\n:::'), '"- - :::panel warning" sits in a container fenced with 3 colons')
|
assert.equal(fenceNestingFault(':::panel info\n- - :::panel warning\n B\n :::\n:::'), '"- - :::panel warning" sits in a container fenced with 3 colons')
|
||||||
assert.equal(fenceNestingFault(':::panel info\n10. :::panel warning\n B\n :::\n:::'), '"10. :::panel warning" sits in a container fenced with 3 colons')
|
assert.equal(fenceNestingFault(':::panel info\n10. :::panel warning\n B\n :::\n:::'), '"10. :::panel warning" sits in a container fenced with 3 colons')
|
||||||
assert.equal(fenceNestingFault('::::panel info\n:::\n::::'), '":::" is shorter than the 4 colons it would close')
|
assert.equal(fenceNestingFault('::::panel info\n:::\n::::'), '":::" is shorter than the 4 colons it would close')
|
||||||
|
assert.equal(fenceNestingFault('Text\n:::\n'), '":::" closes no open container')
|
||||||
assert.equal(fenceNestingFault('::::panel info\n- - :::panel warning\n B\n :::\n::::'), undefined)
|
assert.equal(fenceNestingFault('::::panel info\n- - :::panel warning\n B\n :::\n::::'), undefined)
|
||||||
assert.equal(fenceNestingFault(':::tableCell\n```text\n:::::::panel warning\n:::\n```\n:::'), undefined)
|
assert.equal(fenceNestingFault(':::tableCell\n```text\n:::::::panel warning\n:::\n```\n:::'), undefined)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -84,8 +84,8 @@ detail is settled at its own milestone.
|
|||||||
attribute fallback 2e owes, since the reservation leaves that node no other spelling
|
attribute fallback 2e owes, since the reservation leaves that node no other spelling
|
||||||
whatever 1d decides for its `localId`.
|
whatever 1d decides for its `localId`.
|
||||||
- [ ] **2e — Carve-outs and combinations.** Fixtures and emitter together, into
|
- [ ] **2e — Carve-outs and combinations.** Fixtures and emitter together, into
|
||||||
`corpus/round-trip/combinations/` — the documents that cross what 2a–2d isolated.
|
`corpus/round-trip/combinations/`.
|
||||||
- [ ] **2e1 — The carve-outs and the claimed line.** The directory opens: the three carve-outs
|
- [ ] **2e1 — The carve-outs and the claimed line.** The three carve-outs
|
||||||
and their escapes, and a paragraph line inside a container body shaped like a closing
|
and their escapes, and a paragraph line inside a container body shaped like a closing
|
||||||
fence (`:::`, `::: x`). Guard `fenceNestingFault`'s bare-run pop here too — a run shorter
|
fence (`:::`, `::: x`). Guard `fenceNestingFault`'s bare-run pop here too — a run shorter
|
||||||
than the open fence is a fault, not a close — which today's emitter cannot reach.
|
than the open fence is a fault, not a close — which today's emitter cannot reach.
|
||||||
@@ -117,7 +117,8 @@ detail is settled at its own milestone.
|
|||||||
and it is provable without one. It also settles the emitter's one known approximation:
|
and it is provable without one. It also settles the emitter's one known approximation:
|
||||||
delimiter flanking is exact, but CommonMark's *matching* — the multiple-of-3 rule and the
|
delimiter flanking is exact, but CommonMark's *matching* — the multiple-of-3 rule and the
|
||||||
way a run splits across several openers — is not modelled. No reachable violation has been
|
way a run splits across several openers — is not modelled. No reachable violation has been
|
||||||
found by hand; the property test is what decides it.
|
found by hand; the property test is what decides it, and 2e1's `carve-out-strike` pins a
|
||||||
|
second backslash only flanking-without-matching emits.
|
||||||
- [ ] **2f — The attributes CommonMark cannot hold.** 1d's settled answer: the block nodes
|
- [ ] **2f — The attributes CommonMark cannot hold.** 1d's settled answer: the block nodes
|
||||||
CommonMark spells — `blockquote`, `bulletList`, `codeBlock`, `heading`, `listItem`,
|
CommonMark spells — `blockquote`, `bulletList`, `codeBlock`, `heading`, `listItem`,
|
||||||
`orderedList`, `paragraph`, `rule` — get directive sections in `spec/flavour.md` carrying
|
`orderedList`, `paragraph`, `rule` — get directive sections in `spec/flavour.md` carrying
|
||||||
@@ -140,7 +141,10 @@ detail is settled at its own milestone.
|
|||||||
assumes — CommonMark flanking, as for `*` — which `spec/flavour.md` does not yet pin, and
|
assumes — CommonMark flanking, as for `*` — which `spec/flavour.md` does not yet pin, and
|
||||||
the precedence between a directive and the constructs a raw attribute value opens inside it —
|
the precedence between a directive and the constructs a raw attribute value opens inside it —
|
||||||
a code span, an entity, raw HTML — which one directive alone already reaches until 2e's
|
a code span, an entity, raw HTML — which one directive alone already reaches until 2e's
|
||||||
escape lands.
|
escape lands. Whether a claimed line interrupts a paragraph is pinned for the plain case and
|
||||||
|
unstated for the lazy one: a closing fence on the line after a blockquote's open paragraph is
|
||||||
|
lazy continuation in CommonMark, which would swallow the fence and leave the container
|
||||||
|
unclosed. 2e1's `closing-fence-line` orders its blockquote away from that edge meanwhile.
|
||||||
`src/` gets its hierarchy at the same split — `adf/`,
|
`src/` gets its hierarchy at the same split — `adf/`,
|
||||||
`markdown/`, `html/`, the grammar module shared inside `markdown/` — while the rename is
|
`markdown/`, `html/`, the grammar module shared inside `markdown/` — while the rename is
|
||||||
still mechanical. Three files do not move whole: `block-directives.ts` and
|
still mechanical. Three files do not move whole: `block-directives.ts` and
|
||||||
|
|||||||
Reference in New Issue
Block a user