4.3: a paragraph line reading as a link reference definition escapes its opening bracket

This commit is contained in:
2026-09-15 20:45:07 +02:00
parent ec5c92d4fd
commit 4735933d61
6 changed files with 95 additions and 6 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ import {
} from '../commonmark-grammar.ts'
import { directiveLineEscape, malformedDirective, readDirectiveLine } from '../directive-syntax.ts'
import { barePipeCells, isDelimiterRow, isPipeAlignment, isPipeDelimiter, malformedPipeTable, pipeCells } from '../pipe-table-syntax.ts'
import { readLinkDefinitions } from './link-reference-definitions.ts'
import { readLinkDefinitions } from '../link-reference-definitions.ts'
export type Block = { position: SourcePosition } & (
| { argument: string | undefined; attributes: DirectiveAttributes; blocks: Block[] | undefined; kind: 'directive'; name: string }
@@ -1,47 +0,0 @@
import type { LinkDefinition, LinkPart } from '../link-syntax.ts'
import { normalizeLabel, readDestination, readLabel, readTitle, skipLinkWhitespace } from '../link-syntax.ts'
type ReadDefinition = { definition: LinkDefinition; label: string; length: number }
const restOfLine = /^[ \t]*(?:\n|$)/
export function readLinkDefinitions(definitions: Map<string, LinkDefinition>, text: string): string {
let rest = text
let read = readDefinition(rest)
while (read !== undefined) {
if (!definitions.has(read.label)) definitions.set(read.label, read.definition)
rest = rest.slice(read.length)
read = readDefinition(rest)
}
return rest
}
function readDefinition(text: string): ReadDefinition | undefined {
const label = readLabel(text, 0)
if (label === undefined || text.charAt(label.length) !== ':') return undefined
const name = normalizeLabel(label.value)
if (name === '') return undefined
const afterLabel = skipLinkWhitespace(text, label.length + 1)
const destination = readDestination(text, afterLabel)
if (destination === undefined) return undefined
const afterDestination = afterLabel + destination.length
const titled = readTitledEnd(text, afterDestination)
if (titled !== undefined) return { definition: { destination: destination.value, title: titled.value }, label: name, length: titled.length }
const plain = endOfLine(text, afterDestination)
if (plain === undefined) return undefined
return { definition: { destination: destination.value }, label: name, length: plain }
}
function readTitledEnd(text: string, offset: number): LinkPart | undefined {
const afterSpace = skipLinkWhitespace(text, offset)
if (afterSpace === offset) return undefined
const title = readTitle(text, afterSpace)
if (title === undefined) return undefined
const end = endOfLine(text, afterSpace + title.length)
return end === undefined ? undefined : { length: end, value: title.value }
}
function endOfLine(text: string, offset: number): number | undefined {
const rest = restOfLine.exec(text.slice(offset))?.[0]
return rest === undefined ? undefined : offset + rest.length
}