diff --git a/src/markdown/parse/inline-content.ts b/src/markdown/parse/inline-content.ts index 5b25084..d138545 100644 --- a/src/markdown/parse/inline-content.ts +++ b/src/markdown/parse/inline-content.ts @@ -52,7 +52,7 @@ type Resolved = ImageLink | Nodes type HighlightDelimiter = { closes: boolean; holder: AdfNode; index: number; opens: boolean; position: number; stretch: number } -// `index` is the bracket's piece, `start` the index of the source its text starts at. +// `index` is the bracket's position in `pieces`; `start` is where its text starts in `source`. type OpenBracket = { image: boolean; index: number; start: number } type Pairing = EmphasisPairing @@ -78,7 +78,7 @@ type Scan = { definitions: LinkDefinitions // Whether this content is an `!adf:link`'s text, where an image reads as its plain alt text. inLink: boolean - // A link opener at this index of `brackets` or above is active; one below it stood open while a link closed, and no link holds another. + // Link openers below this index of `brackets` were open when a link closed, so they stay literal: no link holds another. linkOpenersFrom: number openingSpellableLink: boolean path: ConvertErrorPath @@ -392,7 +392,7 @@ function closeBracket(scan: Scan, index: number): Result { const inner = scan.pieces.slice(open.index + 1) // A link closing, or one inside these brackets, leaves every link opener still open literal. if (!open.image) scan.linkOpenersFrom = scan.brackets.length - // Ahead of the own-marks guard in `linkPieces`: brackets going literal put the carry inside no mark for it to refuse. + // Before `linkPieces`' own-marks guard: brackets that go literal mark nothing, so a carry inside them is no error. if (!open.image && holdsLink(inner)) return success(unopened(scan, open, index)) const closed = open.image ? imagePieces(scan, inner, target.definition) : linkPieces(scan, inner, target.definition) if (!closed.ok) return closed @@ -401,7 +401,7 @@ function closeBracket(scan: Scan, index: number): Result { return success(index + 1 + target.length) } -// Every close takes the innermost bracket off the stack, whether it closes a link, an image or nothing. +// A close that builds nothing still pops its bracket, so no later close walks past it. function popBracket(scan: Scan): (OpenBracket & { active: boolean }) | undefined { const open = scan.brackets.pop() if (open === undefined) return undefined diff --git a/src/markdown/parse/markdown-to-adf.test.ts b/src/markdown/parse/markdown-to-adf.test.ts index 1ce6886..094c411 100644 --- a/src/markdown/parse/markdown-to-adf.test.ts +++ b/src/markdown/parse/markdown-to-adf.test.ts @@ -1076,7 +1076,7 @@ test('reads the reference links a definition resolves, and leaves the rest liter assert.deepEqual(content(losslessMarkdownToAdf('[][]\n')), [paragraph('[][]')]) }) -test('reads link text past 999 characters as no label, in every reader', () => { +test('leaves a link label past 999 characters literal, an escape counting as two, in every reader', () => { const longest = `foo${' '.repeat(993)}bar` const tooLong = `foo${' '.repeat(994)}bar` const escaped = '\\*'.repeat(499)