mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-12 19:58:28 +01:00
Answer stability round 1: 0 🔴, 2 🟡; seed the withheld-mark carries once per line, pin the single highlight around a link
This commit is contained in:
@@ -54,7 +54,7 @@ export function openingLinkTakesDirective(nodes: readonly AdfNode[], path: Conve
|
||||
}
|
||||
|
||||
export function portableLineFallback(nodes: readonly AdfNode[], container: LineContainer, path: ConvertErrorPath): Result<PortableLineFallback | undefined> {
|
||||
const emission = lineSegments(nodes, container, path, { carried: new Set(), flavour: 'portable', openingLinkAsDirective: false })
|
||||
const emission = lineSegments(nodes, container, path, freshFallbacks(nodes, 'portable'))
|
||||
if (!emission.ok) return emission
|
||||
if (emission.value.carry !== undefined) return failure('unsupported-node-shape', 'an inline node on a portable line has no spelling but the carry', path)
|
||||
const verdict = lineVerdict(emission.value.segments, container, 'portable')
|
||||
@@ -80,7 +80,7 @@ export function tryImageLine(alt: string | undefined, url: string, link?: LinkDe
|
||||
}
|
||||
|
||||
function emitLine(nodes: readonly AdfNode[], container: LineContainer, path: ConvertErrorPath, flavour: WrittenFlavour): Result<EmittedLine> {
|
||||
const fallbacks: LineFallbacks = { carried: new Set(), flavour, openingLinkAsDirective: false }
|
||||
const fallbacks = freshFallbacks(nodes, flavour)
|
||||
// Terminates because takeFallback refuses a pass that took no new fallback.
|
||||
for (;;) {
|
||||
const emission = lineSegments(nodes, container, path, fallbacks)
|
||||
@@ -99,6 +99,16 @@ function emitLine(nodes: readonly AdfNode[], container: LineContainer, path: Con
|
||||
}
|
||||
}
|
||||
|
||||
// Seeds the withheld-mark carries once per line, so no run at any depth reads a node's marks whole.
|
||||
function freshFallbacks(nodes: readonly AdfNode[], flavour: WrittenFlavour): LineFallbacks {
|
||||
const carried = new Set<number>()
|
||||
for (const [index, node] of nodes.entries()) {
|
||||
const taken = takenMarkTypes(node)
|
||||
if (taken !== undefined && nodeMarks(node).some((mark) => !taken.includes(mark.type))) carried.add(index)
|
||||
}
|
||||
return { carried, flavour, openingLinkAsDirective: false }
|
||||
}
|
||||
|
||||
function takeFallback(fallbacks: LineFallbacks, fallback: NodeRange | 'opening-link', path: ConvertErrorPath): Result<null> {
|
||||
if (fallback === 'opening-link') {
|
||||
if (fallbacks.openingLinkAsDirective) return failure('unsupported-node-shape', 'an opening link spelled as a directive still reads as a link definition, so the line has no spelling left', path)
|
||||
@@ -221,10 +231,9 @@ function nodePath(context: InlineContext, index: number): ConvertErrorPath {
|
||||
return [...context.path, 'content', index]
|
||||
}
|
||||
|
||||
// Decides the text-node, withheld-mark and slot-fault carries up front, so a line holding many of them is emitted once.
|
||||
// Decides the text-node and slot-fault carries up front, so a line holding many of them is emitted once.
|
||||
function carries(node: AdfNode, carried: ReadonlySet<number>, index: number): boolean {
|
||||
const taken = takenMarkTypes(node)
|
||||
if (carried.has(index) || (taken !== undefined && nodeMarks(node).some((mark) => !taken.includes(mark.type)))) return true
|
||||
if (carried.has(index)) return true
|
||||
if (node.type === 'text') return !isSpellableText(node) || typeof node.text !== 'string' || node.text === ''
|
||||
const model = inlineNodeModel(node.type)
|
||||
if (model === undefined) return true
|
||||
|
||||
@@ -219,6 +219,7 @@ test('reads a == pair to the editor default highlight, Yellow200 #f8e6a0 in @atl
|
||||
assert.deepEqual(read('**==hi==** b\n'), [paragraph(text('hi', highlight, strong), text(' b'))])
|
||||
assert.deepEqual(read('==**a**_b_ `c`==\n'), [paragraph(text('a', highlight, strong), text('b', highlight, em), text(' ', highlight), text('c', code))])
|
||||
assert.deepEqual(read('==`a`==\n'), [paragraph(text('a', code))])
|
||||
assert.deepEqual(read('==[==a==](/u) b==\n'), [paragraph(text('a', { attrs: { href: '/u' }, type: 'link' }, highlight), text(' b', highlight))])
|
||||
assert.deepEqual(read('x==y==z ==a == b==, (==c==) _d_==e==\n'), [paragraph(text('x==y==z '), text('a == b', highlight), text(', ('), text('c', highlight), text(') '), text('d', em), text('e', highlight))])
|
||||
assert.deepEqual(read('😀==b== ==c==😀 é==d==\n'), [paragraph(text('😀'), text('b', highlight), text(' '), text('c', highlight), text('😀 é==d=='))])
|
||||
assert.deepEqual(read('この機能は==日本語==でのみ、中文==重点==内容、ภาษา==ไทย==ดี 𠀀==𠀁==𠀂 이 기능은 ==한국어==에서만 サーバー==停止==中 このiPhone==専用==アプリ\n'), [
|
||||
|
||||
Reference in New Issue
Block a user