3
0
mirror of https://github.com/larvit/adf-codec.git synced 2026-11-12 19:58:28 +01:00

Answer stability round 1: 0 🔴, 4 🟡; pin each HTML terminator boundary the readers keep

This commit is contained in:
2026-10-18 10:50:49 +02:00
committed by Lillem4n
parent a674df9b75
commit 26446c0b89
2 changed files with 10 additions and 5 deletions
+3 -3
View File
@@ -8,7 +8,7 @@ export function backtickRun(text: string, index: number): number {
// Readers ask with `from` rising, which keeps each length's cursor moving forward, so asking at every opener stays
// linear in the text; an ask behind the cursor restarts that length from its first run.
export function backtickCloser(text: string): (from: number, opener: number) => number | undefined {
const asked = new Map<number, number>()
const cursors = new Map<number, number>()
const starts = new Map<number, number[]>()
for (let start = text.indexOf('`'); start !== -1; ) {
const length = runLength(text, start)
@@ -20,10 +20,10 @@ export function backtickCloser(text: string): (from: number, opener: number) =>
return (from, opener) => {
const runs = starts.get(opener)
if (runs === undefined) return undefined
let at = asked.get(opener) ?? 0
let at = cursors.get(opener) ?? 0
if ((runs[at - 1] ?? -1) >= from) at = 0
while ((runs[at] ?? Infinity) < from) at += 1
asked.set(opener, at)
cursors.set(opener, at)
return runs[at]
}
}
+7 -2
View File
@@ -9,8 +9,13 @@ import { losslessMarkdownToAdf } from './parse/markdown-to-adf.ts'
const constructs = ['<!A>', '<??>', '<![CDATA[]]>']
test('an HTML construct whose terminator starts right after its opener reads as HTML', () => {
for (const construct of constructs) assert.equal(readInlineToken(inlineSource(`a ${construct}`), 2, flavourClaims.commonmark).kind, 'html', construct)
// CommonMark 0.31.2, Raw HTML: the terminator must start after the opener, and may start right after it.
test('an HTML opener reads as HTML only where its terminator starts after it', () => {
const cases: [string, string][] = [...constructs.map((text): [string, string] => [text, 'html']), ['<!---->', 'html'], ['?> <? ?>', 'html'], ['?> <?', 'text'], ['<?>', 'text']]
for (const [text, kind] of cases) {
const at = text.lastIndexOf('<')
assert.equal(readInlineToken(inlineSource(`a ${text}`), at + 2, flavourClaims.commonmark).kind, kind, text)
}
})
test('text spelling such a construct round-trips', () => {