diff --git a/AGENTS.md b/AGENTS.md index 0f0a775..f7972af 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -306,16 +306,12 @@ someone spells it or pins it. `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 the whole point of. -- A readable spelling tried ahead of a general one — a CommonMark block, the image, the pipe - table, a pipe cell, the CommonMark link — gives way with `undefined` for every shape it cannot - spell, and fails only where the general form fails on the same node; it takes the `try` prefix, - so both arms read at the call site (20). Refusing there refuses a document the general form - spells, so a refusal the general form does not share belongs in the general form or nowhere — - save the nested list a tight spelling would swallow, whose refusal the tight-versus-blank answer - 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). +- A readable spelling tried ahead of a general one takes the `try` prefix and fails only where the + general form fails on the same node (20): refusing there refuses a document the general form + spells, so a refusal the general form does not share belongs in the general form or nowhere. 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 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 diff --git a/src/markdown/emit/adf-to-markdown.ts b/src/markdown/emit/adf-to-markdown.ts index d3e28c0..299f248 100644 --- a/src/markdown/emit/adf-to-markdown.ts +++ b/src/markdown/emit/adf-to-markdown.ts @@ -243,7 +243,7 @@ function tryList(node: AdfNode, path: ConvertErrorPath, depth: number, memo: Spe } const lines: string[] = [] 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 (headroom < 1) return tooDeep(path) 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 } -function listItemLines(blocks: readonly PlacedBlock[], marker: string): string | undefined { +function tryListItemLines(blocks: readonly PlacedBlock[], marker: string): string | undefined { const inner = joinBlocks(blocks, 'list-item') if (inner === '') return marker.trimEnd() const body = inner.split('\n') diff --git a/todo-history.md b/todo-history.md index d06e268..8ab98bd 100644 --- a/todo-history.md +++ b/todo-history.md @@ -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 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 - `tryImage` and `tryPipeTable` already return. `emitLink` is the same channel outside the - six — the CommonMark link tried ahead of the inline directive form — so it takes the prefix - with them, and the comment naming its `undefined` arm goes with the rename. §11's - readable-spelling rule carries the prefix, so the next spelling is named by the rule rather - than by the seven beside it. + `tryImage` and `tryPipeTable` already return. `emitLink` and `listItemLines` are the same + channel outside the six — the CommonMark link and the tight list item, each tried ahead of a + directive form — so they take the prefix too, and the comment naming `emitLink`'s `undefined` + arm goes with the rename. §11's readable-spelling rule carries the prefix and gave up the set + 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 `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