20 - the prefix is the set, and §11 drops the list it enumerated
CI / gate (push) Successful in 31s
CI / publish (push) Has been skipped

This commit is contained in:
2026-09-21 21:16:26 +02:00
parent 97bf2440fd
commit cf9b12b973
3 changed files with 16 additions and 17 deletions
+6 -10
View File
@@ -306,16 +306,12 @@ someone spells it or pins it.
`matchEmphasis` transcribes the reference `process_emphasis` line for line, and its closer walk and `matchEmphasis` transcribes the reference `process_emphasis` line for line, and its closer walk and
opener search stay whole: broken into named steps they drift from the algorithm being faithful is opener search stay whole: broken into named steps they drift from the algorithm being faithful is
the whole point of. the whole point of.
- A readable spelling tried ahead of a general one — a CommonMark block, the image, the pipe - A readable spelling tried ahead of a general one takes the `try` prefix and fails only where the
table, a pipe cell, the CommonMark link — gives way with `undefined` for every shape it cannot general form fails on the same node (20): refusing there refuses a document the general form
spell, and fails only where the general form fails on the same node; it takes the `try` prefix, spells, so a refusal the general form does not share belongs in the general form or nowhere. A
so both arms read at the call site (20). Refusing there refuses a document the general form readable spelling that must spell its subtree before it can give way — the list, whose
spells, so a refusal the general form does not share belongs in the general form or nowhere — thematic-break first line and blank lines exist only spelled — hands that one walk to the general
save the nested list a tight spelling would swallow, whose refusal the tight-versus-blank answer form instead: giving way after the walk walks again at every level, doubling per level (4b).
owns (`todo.md` 2b). A readable spelling that must spell its subtree before it can give way —
the list, whose thematic-break first line and blank lines exist only spelled — hands that one
walk to the general form instead: giving way after the walk walks again at every level, doubling
per level (4b).
- Nothing recurses unbounded: the guards walk iteratively, and blocks, marks and JSON values — an - Nothing recurses unbounded: the guards walk iteratively, and blocks, marks and JSON values — an
attribute's and a carried node's alike — are all held to 500 levels, so a deep document is a attribute's and a carried node's alike — are all held to 500 levels, so a deep document is a
`Result` rather than the stack overflow that waits near 2000. A level is one block-list `Result` rather than the stack overflow that waits near 2000. A level is one block-list
+2 -2
View File
@@ -243,7 +243,7 @@ function tryList(node: AdfNode, path: ConvertErrorPath, depth: number, memo: Spe
} }
const lines: string[] = [] const lines: string[] = []
for (const [offset, item] of walked.entries()) { for (const [offset, item] of walked.entries()) {
const line = listItemLines(item.walk.blocks, ordered ? `${start + offset}. ` : '- ') const line = tryListItemLines(item.walk.blocks, ordered ? `${start + offset}. ` : '- ')
if (line === undefined) { if (line === undefined) {
if (headroom < 1) return tooDeep(path) if (headroom < 1) return tooDeep(path)
return emitDirectiveBlock(node, ordered ? blockDirectives.orderedList : blockDirectives.bulletList, path, depth, () => success({ blocks: directiveItems(walked), headroom: headroom - 1 })) return emitDirectiveBlock(node, ordered ? blockDirectives.orderedList : blockDirectives.bulletList, path, depth, () => success({ blocks: directiveItems(walked), headroom: headroom - 1 }))
@@ -265,7 +265,7 @@ function listStart(node: AdfNode, items: number): number | undefined {
return start + items - 1 > largestListMarker ? undefined : start return start + items - 1 > largestListMarker ? undefined : start
} }
function listItemLines(blocks: readonly PlacedBlock[], marker: string): string | undefined { function tryListItemLines(blocks: readonly PlacedBlock[], marker: string): string | undefined {
const inner = joinBlocks(blocks, 'list-item') const inner = joinBlocks(blocks, 'list-item')
if (inner === '') return marker.trimEnd() if (inner === '') return marker.trimEnd()
const body = inner.split('\n') const body = inner.split('\n')
+8 -5
View File
@@ -933,11 +933,14 @@ The done `todo.md` items in full, as they were written. `todo.md` keeps a one-li
directive form shares — a walk, `codeBlockText`, `emitInlineLine` — so moving it out is the directive form shares — a walk, `codeBlockText`, `emitInlineLine` — so moving it out is the
second walk 4b removed, and they take the prefix alone. `tryRule` refuses nothing, so it second walk 4b removed, and they take the prefix alone. `tryRule` refuses nothing, so it
takes the narrower type as well, `string | undefined` through `readableText`, which is what takes the narrower type as well, `string | undefined` through `readableText`, which is what
`tryImage` and `tryPipeTable` already return. `emitLink` is the same channel outside the `tryImage` and `tryPipeTable` already return. `emitLink` and `listItemLines` are the same
six — the CommonMark link tried ahead of the inline directive form — so it takes the prefix channel outside the six — the CommonMark link and the tight list item, each tried ahead of a
with them, and the comment naming its `undefined` arm goes with the rename. §11's directive form — so they take the prefix too, and the comment naming `emitLink`'s `undefined`
readable-spelling rule carries the prefix, so the next spelling is named by the rule rather arm goes with the rename. §11's readable-spelling rule carries the prefix and gave up the set
than by the seven beside it. it enumerated: the prefix is the set now, which is what stops the next spelling being named
by the eight beside it. The same rule's nested-list carve-out went with it, naming a refusal
2b's tight-versus-blank answer had already removed — `unspellable-adjacent-lists` is gone from
`result.ts` and `separationBetween` returns a `string`.
- [x] **28 — `emitLine`'s retry loop cannot spin (`0.2.0`).** `emit/inline-line.ts:67` is a - [x] **28 — `emitLine`'s retry loop cannot spin (`0.2.0`).** `emit/inline-line.ts:67` is a
`for (;;)` that re-emits the line until every unspellable node has been carried, and its `for (;;)` that re-emits the line until every unspellable node has been carried, and its
termination rests on a comment: each pass carries at least one more node, or flips termination rests on a comment: each pass carries at least one more node, or flips