35b - review: runs as a non-empty tuple, no item for a stray child reducing to nothing, 42 filed
This commit is contained in:
@@ -38,7 +38,7 @@ type LineAttempt = { fallback: NodeRange | 'opening-link'; line?: undefined } |
|
|||||||
|
|
||||||
type LineFallbacks = { carried: Set<number>; flavour: Flavour; openingLinkAsDirective: boolean }
|
type LineFallbacks = { carried: Set<number>; flavour: Flavour; openingLinkAsDirective: boolean }
|
||||||
|
|
||||||
export type PlainLineFallback = { kind: 'claimed-line'; line: number; text: string } | { kind: 'opening-link' } | { kind: 'unspellable-run'; run: MarkRun; runs: MarkRun[] }
|
export type PlainLineFallback = { kind: 'claimed-line'; line: number; text: string } | { kind: 'opening-link' } | { kind: 'unspellable-run'; runs: [MarkRun, ...MarkRun[]] }
|
||||||
|
|
||||||
export function emitInlineLine(nodes: readonly AdfNode[], container: LineContainer, path: ConvertErrorPath, flavour: Flavour): Result<string> {
|
export function emitInlineLine(nodes: readonly AdfNode[], container: LineContainer, path: ConvertErrorPath, flavour: Flavour): Result<string> {
|
||||||
const emitted = emitLine(nodes, container, path, flavour)
|
const emitted = emitLine(nodes, container, path, flavour)
|
||||||
@@ -120,7 +120,7 @@ function lineSegments(nodes: readonly AdfNode[], container: LineContainer, path:
|
|||||||
function attemptLine(segments: readonly InlineSegment[], container: LineContainer, path: ConvertErrorPath, flavour: Flavour): Result<LineAttempt> {
|
function attemptLine(segments: readonly InlineSegment[], container: LineContainer, path: ConvertErrorPath, flavour: Flavour): Result<LineAttempt> {
|
||||||
const verdict = lineVerdict(segments, container, flavour)
|
const verdict = lineVerdict(segments, container, flavour)
|
||||||
if (verdict.kind === 'opening-link') return success({ fallback: 'opening-link' })
|
if (verdict.kind === 'opening-link') return success({ fallback: 'opening-link' })
|
||||||
if (verdict.kind === 'unspellable-run') return success({ fallback: verdict.run })
|
if (verdict.kind === 'unspellable-run') return success({ fallback: verdict.runs[0] })
|
||||||
if (verdict.kind === 'claimed-line') return failure('unspellable-line-start', `block parsing would claim the emitted line ${JSON.stringify(verdict.text)}`, path)
|
if (verdict.kind === 'claimed-line') return failure('unspellable-line-start', `block parsing would claim the emitted line ${JSON.stringify(verdict.text)}`, path)
|
||||||
return success({ line: verdict.text })
|
return success({ line: verdict.text })
|
||||||
}
|
}
|
||||||
@@ -129,8 +129,8 @@ function attemptLine(segments: readonly InlineSegment[], container: LineContaine
|
|||||||
function lineVerdict(segments: readonly InlineSegment[], container: LineContainer, flavour: Flavour): PlainLineFallback | { kind: 'line'; text: string } {
|
function lineVerdict(segments: readonly InlineSegment[], container: LineContainer, flavour: Flavour): PlainLineFallback | { kind: 'line'; text: string } {
|
||||||
const assembled = assembleInlineLine(segments, container, flavour)
|
const assembled = assembleInlineLine(segments, container, flavour)
|
||||||
if (assembled.openingLinkAsDirective) return { kind: 'opening-link' }
|
if (assembled.openingLinkAsDirective) return { kind: 'opening-link' }
|
||||||
const [run] = assembled.unspellableRuns
|
const [run, ...others] = assembled.unspellableRuns
|
||||||
if (run !== undefined) return { kind: 'unspellable-run', run, runs: assembled.unspellableRuns }
|
if (run !== undefined) return { kind: 'unspellable-run', runs: [run, ...others] }
|
||||||
const lines = assembled.line.split('\n')
|
const lines = assembled.line.split('\n')
|
||||||
const claimed = container === 'paragraph' ? lines.findIndex((single, index) => claimsLine(single, index === 0 ? 'first' : 'later')) : -1
|
const claimed = container === 'paragraph' ? lines.findIndex((single, index) => claimsLine(single, index === 0 ? 'first' : 'later')) : -1
|
||||||
return claimed === -1 ? { kind: 'line', text: assembled.line } : { kind: 'claimed-line', line: claimed, text: lines[claimed] ?? '' }
|
return claimed === -1 ? { kind: 'line', text: assembled.line } : { kind: 'claimed-line', line: claimed, text: lines[claimed] ?? '' }
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ function reduceTaskList(node: AdfNode, reduction: Reduction): Result<AdfNode[]>
|
|||||||
const reduced = isTask(child) ? reduceTask(child, at) : reduceStanding(child, at)
|
const reduced = isTask(child) ? reduceTask(child, at) : reduceStanding(child, at)
|
||||||
if (!reduced.ok) return reduced
|
if (!reduced.ok) return reduced
|
||||||
if (!regular) {
|
if (!regular) {
|
||||||
const standsAlone = !isTask(child) && child.type !== 'taskList'
|
const standsAlone = !isTask(child) && child.type !== 'taskList' && reduced.value.length > 0
|
||||||
for (const block of standsAlone ? [{ content: reduced.value, type: 'listItem' }] : reduced.value) tasks.push(block)
|
for (const block of standsAlone ? [{ content: reduced.value, type: 'listItem' }] : reduced.value) tasks.push(block)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,10 @@
|
|||||||
paragraph of 2000 × `un` plus `**-r**`: each run its flanking cannot spell re-emits the whole line
|
paragraph of 2000 × `un` plus `**-r**`: each run its flanking cannot spell re-emits the whole line
|
||||||
before riding the carry, quadratic in the runs (Goal 9), and the plain reduction's
|
before riding the carry, quadratic in the runs (Goal 9), and the plain reduction's
|
||||||
`spellableLine` drops one mark per re-emit the same way. Make both linear.
|
`spellableLine` drops one mark per re-emit the same way. Make both linear.
|
||||||
|
- **42 — Trim a text leaf's trailing blanks in linear time.** `plain-inline.ts`'s `leafEdges` finds
|
||||||
|
the trail with an unanchored `/[ \t]*$/`, quadratic in a run of blanks inside one leaf: a
|
||||||
|
paragraph of `a`, 80 000 spaces, `b` takes 6.5 s in `adfToPlainMarkdown` (Goal 9). Scan backward,
|
||||||
|
as the expand title's trim does.
|
||||||
- **34 — Read emphasis flanking by the whole character beside an astral symbol.** Check whether
|
- **34 — Read emphasis flanking by the whole character beside an astral symbol.** Check whether
|
||||||
`line-escaping.ts`'s `charAt` and the parser's flanking read one UTF-16 unit beside an astral
|
`line-escaping.ts`'s `charAt` and the parser's flanking read one UTF-16 unit beside an astral
|
||||||
symbol — a lone surrogate is neither punctuation nor symbol, where CommonMark reads `😀` as
|
symbol — a lone surrogate is neither punctuation nor symbol, where CommonMark reads `😀` as
|
||||||
|
|||||||
Reference in New Issue
Block a user