3
0
mirror of https://github.com/larvit/adf-codec.git synced 2026-11-13 04:08:29 +01:00

Answer principles round 1: 0 🔴, 2 🟡; read an inline directive from the InlineSource holding its text and closer, and name the quote edges apart from the quotes passed

This commit is contained in:
2026-10-18 11:31:11 +02:00
committed by Lillem4n
parent 15f7d47fb4
commit 5f8c7cf2eb
5 changed files with 21 additions and 23 deletions
+13 -12
View File
@@ -74,7 +74,7 @@ type ContainerStack = {
open: readonly OpenContainer[]
push: (container: OpenContainer) => void
// The index in `edges` of each blockquote.
quotes: readonly number[]
quoteEdges: readonly number[]
}
type Walk = ParsedBlocks & {
@@ -114,7 +114,7 @@ function containerStack(): ContainerStack {
const depthsOf = (name: string): number[] => entryOf(directiveDepths, name, () => [])
const edges: { container: EdgeContainer; depth: number }[] = []
const open: OpenContainer[] = []
const quotes: number[] = []
const quoteEdges: number[] = []
return {
directiveDepth: (name) => directiveDepths.get(name)?.at(-1),
drop: (depth) => {
@@ -123,7 +123,7 @@ function containerStack(): ContainerStack {
if (container.kind === 'directive') depthsOf(container.name).pop()
else {
edges.pop()
if (container.kind === 'blockquote') quotes.pop()
if (container.kind === 'blockquote') quoteEdges.pop()
}
}
return dropped
@@ -134,11 +134,11 @@ function containerStack(): ContainerStack {
const depth = open.push(container) - 1
if (container.kind === 'directive') depthsOf(container.name).push(depth)
else {
if (container.kind === 'blockquote') quotes.push(edges.length)
if (container.kind === 'blockquote') quoteEdges.push(edges.length)
edges.push({ container, depth })
}
},
quotes,
quoteEdges,
}
}
@@ -168,15 +168,15 @@ function swallowsLines(leaf: OpenLeaf | undefined): boolean {
// A directive container has no continuation marker, so every line continues it.
function matchContainers(walk: Walk, line: Line): { depth: number; rest: Line } {
if (isBlankLine(line.text)) return matchBlankLine(walk, line, 0, 0)
let quotes = 0
let quotesPassed = 0
let rest = line
for (const [index, { container, depth }] of walk.stack.edges.entries()) {
const next = continuesContainer(container, rest)
if (next === undefined) return { depth, rest }
rest = next
if (container.kind !== 'blockquote') continue
quotes += 1
if (isBlankLine(rest.text)) return matchBlankLine(walk, rest, index + 1, quotes)
quotesPassed += 1
if (isBlankLine(rest.text)) return matchBlankLine(walk, rest, index + 1, quotesPassed)
}
return { depth: walk.stack.open.length, rest }
}
@@ -184,11 +184,12 @@ function matchContainers(walk: Walk, line: Line): { depth: number; rest: Line }
// A blank line continues every list item up to the next blockquote, so it is matched in one step rather than one per item.
// A list item begins with at most one blank line: an empty one gives the second up. Only the innermost item is empty:
// opening a container inside an item gives it a block.
function matchBlankLine(walk: Walk, line: Line, from: number, quote: number): { depth: number; rest: Line } {
const { edges, quotes } = walk.stack
function matchBlankLine(walk: Walk, line: Line, from: number, quotesPassed: number): { depth: number; rest: Line } {
const { edges, quoteEdges } = walk.stack
const last = edges.length - 1
const emptyItem = last >= from && edges[last]?.container.blocks.length === 0 && walk.leaf === undefined
const stop = Math.min(quotes[quote] ?? edges.length, emptyItem ? last : edges.length)
const innermost = edges[last]?.container
const emptyItem = last >= from && innermost?.kind === 'item' && innermost.blocks.length === 0 && walk.leaf === undefined
const stop = Math.min(quoteEdges[quotesPassed] ?? edges.length, emptyItem ? last : edges.length)
return { depth: edges[stop]?.depth ?? walk.stack.open.length, rest: stop === from ? line : { column: line.column, text: '' } }
}
+1 -1
View File
@@ -173,7 +173,7 @@ function readLineEnding(scan: Scan, index: number): number {
function readDirective(scan: Scan, inline: InlineSource, prefix: ClaimedPrefix): Result<number> {
const held = scan.spans.get(prefix.index)
if (held !== undefined) return pushDirective(scan, held, prefix.index)
const directive = readInlineDirective(scan.source, prefix, inline.codeSpanCloser)
const directive = readInlineDirective(inline, prefix)
if (directive.fault !== undefined) return faulted(directive.fault, scan.path)
return pushDirective(scan, directive.value, prefix.index)
}