Answer the architecture review: one interrupt rule both directions read
CI / gate (push) Successful in 8s

This commit is contained in:
2026-08-30 19:50:41 +02:00
parent e73de651be
commit a09b80e65d
9 changed files with 67 additions and 21 deletions
@@ -267,6 +267,7 @@ test('parts a nested list the tight spelling would swallow from the block above
const outer = (...content: AdfNode[]): AdfDocument => document({ content: [item(...content)], type: 'bulletList' })
const ordered: AdfNode = { attrs: { order: 2 }, content: [item(text('b'))], type: 'orderedList' }
assert.equal(markdown(adfToMarkdown(outer(text('a'), ordered))), '- a\n\n 2. b\n')
assert.equal(markdown(adfToMarkdown(outer(text('a'), { ...ordered, attrs: { order: 1 } }))), '- a\n 1. b\n')
assert.equal(markdown(adfToMarkdown(outer(text('a'), { content: [item()], type: 'bulletList' }))), '- a\n\n -\n')
assert.equal(markdown(adfToMarkdown(outer(text('a'), { content: [item(text('b'))], type: 'bulletList' }))), '- a\n - b\n')
})
@@ -381,6 +382,9 @@ test('refuses a document nested deeper than the emitter carries', () => {
let node: AdfNode = paragraph({ text: 'x', type: 'text' })
for (let depth = 0; depth < 600; depth += 1) node = { content: [node], type: 'blockquote' }
assert.equal(code(adfToMarkdown(document(node))), 'unsupported-nesting-depth')
let carried: AdfNode = paragraph({ text: 'x', type: 'text' })
for (let depth = 0; depth < 500; depth += 1) carried = { content: [carried], type: 'blockquote' }
assert.ok(adfToMarkdown(document(carried)).ok)
})
test('emits an empty list item without trailing whitespace', () => {
+5 -3
View File
@@ -7,7 +7,7 @@ import { carriesOnly, isAdfDocument } from '../../adf/document.ts'
import { emitInlineLine } from './inline-line.ts'
import { failure, success, type ConvertErrorPath, type Result } from '../../result.ts'
import { fencedCodeBlock } from '../backtick-runs.ts'
import { holdsControlCharacter, holdsEntityReference, holdsNullCharacter, isThematicBreak } from '../commonmark-grammar.ts'
import { holdsControlCharacter, holdsEntityReference, holdsNullCharacter, isThematicBreak, markerInterruptsParagraph } from '../commonmark-grammar.ts'
import { largestNesting } from '../../nesting.ts'
import { spellDirectiveHeader } from './block-directive-spelling.ts'
import { tryImage } from './image.ts'
@@ -72,8 +72,10 @@ function separationBetween(previous: PlacedBlock, next: PlacedBlock, container:
}
function interruptsParagraph(node: AdfNode): boolean {
if (node.type === 'orderedList') return false
return ((node.content ?? [])[0]?.content ?? []).length > 0
const items = node.content ?? []
const empty = (items[0]?.content ?? []).length === 0
if (node.type !== 'orderedList') return markerInterruptsParagraph(undefined, empty)
return markerInterruptsParagraph(listStart(node, items.length) ?? 0, empty)
}
function emitBlock(node: AdfNode, path: ConvertErrorPath, depth: number): Result<EmittedBlock> {