From 050364dbdc1960194c96794778bde8d3ea44d9b0 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Fri, 9 Oct 2026 03:52:24 +0200 Subject: [PATCH] Answer stability round 2: a link slot keeps a linked image linked, so the link-in-link refusal holds --- src/markdown/parse/inline-content.ts | 4 ++-- src/markdown/parse/markdown-to-adf.test.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/markdown/parse/inline-content.ts b/src/markdown/parse/inline-content.ts index 7d1c97e..a25d06a 100644 --- a/src/markdown/parse/inline-content.ts +++ b/src/markdown/parse/inline-content.ts @@ -299,7 +299,7 @@ function pushNode(scan: Scan, node: AdfNode): void { } function assemble(scan: Scan): Result { - const nodes = resolveNodes(scan.inLink ? scan.pieces : scan.pieces.map(linkedAlt), scan, true) + const nodes = resolveNodes(scan.pieces.map((piece) => (scan.inLink && piece.kind === 'image' && piece.link === undefined ? piece : linkedAlt(piece))), scan, true) if (!nodes.ok) return nodes const [only] = scan.pieces return success(scan.pieces.length === 1 && only?.kind === 'image' ? { image: mediaSingle(only), nodes: nodes.value } : { nodes: nodes.value }) @@ -549,7 +549,7 @@ function mergeReadText(items: readonly Inline[]): Inline[] { return merged } -// The image arm is an image inside an image's description or a link's text, which reads as its plain alt text: `assemble` links every other. +// The image arm is an image inside an image's description or a link's text, which reads as its plain alt text. // A highlight delimiter holds an empty text node until it pairs, so the emphasis around it marks it. function pieceNodes(piece: Piece): Inline[] { switch (piece.kind) { diff --git a/src/markdown/parse/markdown-to-adf.test.ts b/src/markdown/parse/markdown-to-adf.test.ts index 0e5812f..bafa2c8 100644 --- a/src/markdown/parse/markdown-to-adf.test.ts +++ b/src/markdown/parse/markdown-to-adf.test.ts @@ -985,6 +985,7 @@ test('reads a lone image as the media the flavour spells for it', () => { assert.deepEqual(content(losslessMarkdownToAdf('![](/u)\n')), [image('/u')]) assert.deepEqual(content(losslessMarkdownToAdf('![*a*](/u)\n')), [image('/u', 'a')]) assert.deepEqual(content(losslessMarkdownToAdf('- ![a](/u)\n')), [bulletList(item(image('/u', 'a')))]) + assert.deepEqual(content(losslessMarkdownToAdf('> ![a](/u)\n')), [quote(image('/u', 'a'))]) }) test('flattens the description of a lone image to the plain text alt holds', () => { @@ -1040,6 +1041,7 @@ test('reads an image inside a link not alone in its paragraph as plain alt text const unspellable = { attrs: { href: 'a\nb' }, type: 'link' } assert.deepEqual(firstContent('!adf:link[b ![a](/u)]{href="a\\nb"}\n'), [marked('b a', unspellable)]) assert.deepEqual(firstContent('!adf:link[!adf:underline[![a](/u)]]{href="a\\nb"}\n'), [marked('a', unspellable, { type: 'underline' })]) + assert.equal(content(losslessMarkdownToAdf('!adf:link[x [![a](/u)](/v)]{href="a\\nb"}\n')), 'unsupported-node-shape: no link wraps a link: the [content] this one marks already holds one') }) test('carries the mark a spelling nested inside its own kind names once', () => {