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

Keep a node's empty marks array where a run would span it

This commit is contained in:
2026-10-31 04:13:17 +01:00
committed by Lillem4n
parent 320e5debbf
commit bed322fbef
3 changed files with 9 additions and 2 deletions
+1 -1
View File
@@ -566,7 +566,7 @@ carrying an identical mark, attributes included, at that depth: `attrs: {}` diff
and a directive spells it `{attrs=empty}`. A run breaks at every node the emitter carries, so no
emitted carry sits inside a mark spelling. An `em`, `strike`, `strong` or `link` run also spans a
node between two of its nodes when that node cannot hold the run's mark. It does so only where the
spanned line reads back to the same marks; otherwise the run breaks there. So `_One\` then `Two_`
spanned line reads back to the same nodes; otherwise the run breaks there. So `_One\` then `Two_`
is one `em` run over two texts, the hard break between them unmarked, and
``**Run `npm ci` first**`` is one `strong` run around unmarked code. `adfToPortableMarkdown` spans
hard breaks and code spans the same way.
@@ -914,6 +914,8 @@ test('spells an emphasis or link run once across the hard breaks between two nod
const link: AdfMark = { attrs: { href: '/u' }, type: 'link' }
const marked = (text: string, ...marks: AdfMark[]): AdfNode => ({ marks, text, type: 'text' })
const hardBreak: AdfNode = { type: 'hardBreak' }
assert.equal(readsBack(document(paragraph(marked('a', em), { marks: [], type: 'hardBreak' }, marked('b', em)))), '_a_!adf:hardBreak{marks=empty}_b_\n')
assert.equal(readsBack(document(paragraph(marked('a', em), { attrs: { id: 'x', text: '@A' }, marks: [], type: 'mention' }, marked('b', em)))), '_a_!adf:mention[@A]{id=x marks=empty}_b_\n')
assert.equal(readsBack(document(paragraph(marked('One', em), hardBreak, marked('Two', em)))), '_One\\\nTwo_\n')
assert.equal(readsBack(document(paragraph(marked('a', link), hardBreak, marked('b', link)))), '[a\\\nb](/u)\n')
assert.equal(readsBack(document(paragraph(marked('a', em, link), hardBreak, marked('b', em)))), '_[a](/u)\\\nb_\n')
+6 -1
View File
@@ -47,7 +47,12 @@ function heldMark(spanned: readonly AdfNode[], index: number, depth: number, car
function skipsMark(spanned: readonly AdfNode[], index: number, mark: AdfMark, carries: Carries): boolean {
const node = spanned[index]
const kind = markSpelling(mark.type)?.kind
return node !== undefined && (kind === 'emphasis' || kind === 'link') && !carries(node, index) && !takesMark(node, mark.type)
return node !== undefined && (kind === 'emphasis' || kind === 'link') && !carries(node, index) && !takesMark(node, mark.type) && !holdsEmptyMarks(node)
}
// An empty marks array is spelled `marks=empty`, which a lent mark would erase.
function holdsEmptyMarks(node: AdfNode): boolean {
return Array.isArray(node.marks) && node.marks.length === 0
}
function withMark(node: AdfNode, mark: AdfMark, depth: number): AdfNode {