diff --git a/src/adf/inline-nodes.ts b/src/adf/inline-nodes.ts index a731403..38322b5 100644 --- a/src/adf/inline-nodes.ts +++ b/src/adf/inline-nodes.ts @@ -38,7 +38,7 @@ export function inlineNodeModel(type: string): InlineNodeModel | undefined { return Object.hasOwn(inlineNodes, type) ? inlineNodes[type] : undefined } -// Undefined means every mark: the table lists only types the schema restricts. Text is code text, or formatted text, which withholds `border`. +// Undefined means every mark: a node type outside this module's tables, which the schema restricts nowhere. export function takenMarkTypes(node: AdfNode): readonly string[] | undefined { if (node.type === 'text') return nodeMarks(node).some((mark) => mark.type === 'code') ? codeTextMarkTypes : formattedTextMarkTypes return inlineNodeModel(node.type)?.markTypes diff --git a/src/markdown/emit/inline-line.ts b/src/markdown/emit/inline-line.ts index 55bbfde..3c33740 100644 --- a/src/markdown/emit/inline-line.ts +++ b/src/markdown/emit/inline-line.ts @@ -63,9 +63,10 @@ export function openingLinkTakesDirective(nodes: readonly AdfNode[], path: Conve } export function portableLineFallback(nodes: readonly AdfNode[], container: LineContainer, path: ConvertErrorPath): Result { - const emission = lineSegments(nodes, container, path, withheldMarkFallbacks(nodes, 'portable')) + const fallbacks = withheldMarkFallbacks(nodes, 'portable') + const emission = lineSegments(nodes, container, path, fallbacks) if (!emission.ok) return emission - if (emission.value.carries !== undefined) return failure('unsupported-node-shape', 'an inline node on a portable line has no spelling but the carry', path) + if (fallbacks.carried.size > 0 || emission.value.carries !== 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', { kind: 'drop', nodes }) return success(verdict.kind === 'line' ? undefined : verdict) } diff --git a/src/markdown/portable/adf-to-portable-markdown.test.ts b/src/markdown/portable/adf-to-portable-markdown.test.ts index 7cdef22..4b0f3c5 100644 --- a/src/markdown/portable/adf-to-portable-markdown.test.ts +++ b/src/markdown/portable/adf-to-portable-markdown.test.ts @@ -416,8 +416,10 @@ test('gives up every highlight run whose own delimiter cannot flank in one fallb }) test('refuses a portable line holding a node only the carry spells, at the line', () => { - const refused = portableLineFallback([text('x', { attrs: { a: 1 }, type: 'em' })], 'paragraph', ['content', 0]) - assert.deepEqual(refused.ok ? refused : [refused.error.code, refused.error.path], ['unsupported-node-shape', ['content', 0]]) + for (const mark of [{ attrs: { a: 1 }, type: 'em' }, { type: 'odd' }]) { + const refused = portableLineFallback([text('x', mark)], 'paragraph', ['content', 0]) + assert.deepEqual(refused.ok ? refused : [refused.error.code, refused.error.path], ['unsupported-node-shape', ['content', 0]]) + } }) test('breaks a line at a newline and trims whitespace at every edge CommonMark strips', () => {