From 6636f01497acd85573ef096ef1d0735a4c7fe8fc Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Wed, 28 Oct 2026 14:50:05 +0100 Subject: [PATCH] =?UTF-8?q?Answer=20principles=20round=201:=200=20?= =?UTF-8?q?=F0=9F=94=B4,=200=20=F0=9F=9F=A1=20(0=20misread);=20readAsWritt?= =?UTF-8?q?en=20names=20the=20emphasis=20check,=20the=20bracket=20test=20n?= =?UTF-8?q?ames=20the=20bare=20case,=20noDefinitions=20sorts=20after=20lin?= =?UTF-8?q?kInLink?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/markdown/emit/adf-to-markdown.test.ts | 2 +- src/markdown/emit/line-escaping.ts | 8 ++++++-- src/markdown/inline-content.ts | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/markdown/emit/adf-to-markdown.test.ts b/src/markdown/emit/adf-to-markdown.test.ts index df91465..f356af2 100644 --- a/src/markdown/emit/adf-to-markdown.test.ts +++ b/src/markdown/emit/adf-to-markdown.test.ts @@ -342,7 +342,7 @@ test('escapes only text that would otherwise open a construct', () => { assert.equal(emitted('x"_y"'), 'x"\\_y"\n') }) -test('escapes every text bracket in a line where one opens link text, and every text backtick where one opens a code span', () => { +test('escapes every text bracket in a line where one opens link text, none where none does, and every text backtick where one opens a code span', () => { const emitted = (text: string): string => markdown(adfToLosslessMarkdown(document(paragraph({ text, type: 'text' })))) assert.equal(emitted('[a](b) [c]'), '\\[a](b) \\[c]\n') assert.equal(emitted('see [1] and [docs](url) [2]'), 'see \\[1] and \\[docs](url) \\[2]\n') diff --git a/src/markdown/emit/line-escaping.ts b/src/markdown/emit/line-escaping.ts index 30558cc..57b1870 100644 --- a/src/markdown/emit/line-escaping.ts +++ b/src/markdown/emit/line-escaping.ts @@ -278,14 +278,18 @@ function unspellableRuns(placed: readonly PlacedSegment[], reading: InlineReadin if (segment.highlight === 'open') highlight = { nodes: segment.nodes, start } if (segment.emphasis === 'close') { const opener = openers.pop() - const read = opener === undefined ? undefined : reading.emphasis.get(opener.start) - if (opener !== undefined && (read?.closer !== start || read.width !== segment.text.length) && opener.start > (innermost?.start ?? -1)) innermost = opener + if (opener !== undefined && !readAsWritten(reading, opener.start, start, segment.text.length) && opener.start > (innermost?.start ?? -1)) innermost = opener } if (segment.highlight === 'close' && highlight !== undefined && reading.highlights.get(highlight.start) !== start) unreadHighlights.push(highlight.nodes) } return innermost === undefined ? unreadHighlights : [innermost.nodes] } +function readAsWritten(reading: InlineReading, opener: number, closer: number, width: number): boolean { + const read = reading.emphasis.get(opener) + return read?.closer === closer && read.width === width +} + function isEscapable(escaping: InlineEscaping | undefined): boolean { return escaping === 'backslash' || escaping === 'bracketed' } diff --git a/src/markdown/inline-content.ts b/src/markdown/inline-content.ts index 7e031c8..f6199a1 100644 --- a/src/markdown/inline-content.ts +++ b/src/markdown/inline-content.ts @@ -113,8 +113,8 @@ type SharedScan = Pick const ownMarksInMark = 'move the opaque carry, or the node spelling marks=empty, out of the mark spelling: it holds its own marks' const editorHighlight: AdfMark = { attrs: { color: '#f8e6a0' }, type: 'backgroundColor' } const hreflessLink = 'the link mark spells its href: this one spells none' -const noDefinitions: LinkDefinitions = new Map() const linkInLink = 'no link wraps a link: the [content] this one marks already holds one' +const noDefinitions: LinkDefinitions = new Map() const unlinkable = 'the text of this link holds only nodes that take no link: write the link around text beside them' const spellableLink = 'link takes the directive form only where CommonMark cannot spell it: this one it can, as [text](url "title") or ' const textBreak: TextBreak = { kind: 'textBreak' }