mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-12 19:58:28 +01:00
Answer prose round 1: 0 🔴, 5 🟡; define the closer in place, and say the kept source is one per text
This commit is contained in:
+4
-4
@@ -16,10 +16,10 @@
|
||||
table cell: `[alt](href) ([image](url))`, where it wrote `[alt](url)` and dropped the link's target.
|
||||
- `losslessMarkdownToAdf` names the CommonMark spelling to write when it refuses a directive whose
|
||||
node CommonMark spells, such as `[](href)` for a linked `!adf:mediaSingle`.
|
||||
- Every reader and writer takes time linear in a text holding many `<!--`, `<?`, `<![CDATA[` or `<!`
|
||||
openers without a terminator, or many unclosed backtick runs outside a directive's `[content]`,
|
||||
where such a text took time quadratic in its length: 160000 characters of `<?` took seven seconds
|
||||
each way, now 50 ms.
|
||||
- Every reader and writer takes time linear in the text when it holds many `<!--`, `<?`,
|
||||
`<![CDATA[` or `<!` openers without a terminator, or many unclosed backtick runs outside a
|
||||
directive's `[content]`. Such a text took time quadratic in its length: 160000 characters of `<?`
|
||||
took seven seconds each way, now 50 ms.
|
||||
- The README compares the package with seven other ADF converters, each checked against its
|
||||
published version.
|
||||
|
||||
|
||||
@@ -4,9 +4,8 @@ export function backtickRun(text: string, index: number): number {
|
||||
return text.charAt(index) === '`' ? runLength(text, index) : 0
|
||||
}
|
||||
|
||||
// As `closingBacktickRun`, for `from` past the end of an opener's run, with each run's start read once by its length.
|
||||
// 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.
|
||||
// Where the first run of exactly `opener` backticks at or after `from` begins, `from` never inside a run. Ask with
|
||||
// `from` rising, so each length's cursor only moves forward and a walk stays linear; an earlier `from` rescans that length.
|
||||
export function backtickCloser(text: string): (from: number, opener: number) => number | undefined {
|
||||
const cursors = new Map<number, number>()
|
||||
const starts = new Map<number, number[]>()
|
||||
|
||||
@@ -9,7 +9,7 @@ import { losslessMarkdownToAdf } from './parse/markdown-to-adf.ts'
|
||||
|
||||
const constructs = ['<!A>', '<??>', '<![CDATA[]]>']
|
||||
|
||||
// CommonMark 0.31.2, Raw HTML: the terminator must start after the opener, and may start right after it.
|
||||
// CommonMark 0.31.2, Raw HTML: the terminator may start right after the opener, never inside it; `<!-->` and `<!--->` are whole comments.
|
||||
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) {
|
||||
|
||||
@@ -18,10 +18,10 @@ export type InlineToken =
|
||||
| { closes: boolean; kind: 'highlight'; opens: boolean; width: number }
|
||||
| { construct: string; kind: 'html' }
|
||||
|
||||
// A text and what its openers look ahead for, read once, so a walk reading a token at every index stays linear in it.
|
||||
// Build one per text and pass it to every `readInlineToken` call on that text, so a walk stays linear in the text's length.
|
||||
export type InlineSource = {
|
||||
readonly codeSpanCloser: (from: number, opener: number) => number | undefined
|
||||
// Each HTML construct terminator's last start in the text, -1 for none, read the first time an opener asks.
|
||||
// Where each HTML terminator last starts in the text, -1 for none; filled the first time an opener asks.
|
||||
readonly terminators: Map<string, number>
|
||||
readonly text: string
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
| 59 | 0.3.0 | | decision | **Group the directive grammar into `src/markdown/directive/`, move `Read<T>` to `result.ts`, and move `Flavour` and `flavourClaims` to `markdown/flavour.ts`.** | 3 | 1 | 2 | 4 | 5 | 10 by 5 | 1.5 |
|
||||
| 62 | 0.3.0 | | decision | **Move the portable flavour's reading out of `parse/` and its writing out of `emit/` into `markdown/portable/`, so `emit/` no longer imports `portable/`.** | 3 | 1 | 2 | 4 | 5 | 10 by 5 | 1.5 |
|
||||
| 73 | 0.3.0 | 33, 59, 60, 62, 91, 92, 95, 98, 100, 102, 109, 115 | | **Announce the package where someone needing an ADF converter already reads: JRACLOUD-77436, the Atlassian developer community and Stack Overflow's ADF-to-markdown questions.** | 1 | 2 | 2 | 3 | 2 | 3 by 8 | 32.0 |
|
||||
| 119 | 0.3.0 | | defect | **Read a directive's content holding many unclosed backtick runs in time linear in the text.** | 2 | 1 | 2 | 3 | 2 | 9 by 2 | 8.0 |
|
||||
| 119 | 0.3.0 | | defect | **Read a directive's content holding many unclosed backtick runs in time linear in the markdown.** | 2 | 1 | 2 | 3 | 2 | 9 by 2 | 8.0 |
|
||||
| 81 | 0.4.0 | | | **Fail the gate unless the README's error tables list exactly the codes `ConvertErrorCode` holds.** | 1 | 1 | 1 | 1 | 2 | 3 by 2 | 8.0 |
|
||||
| 45 | 0.4.0 | | defect | **Replace `isAdfDocument` with a reader returning `Result<AdfDocument>`.** | 2 | 1 | 3 | 4 | 3 | 1 by 2 | 6.0 |
|
||||
| 6 | 0.4.0 | | decision | **Specify the HTML dialect.** | 3 | 2 | 1 | 4 | 6 | | 0.0 |
|
||||
@@ -167,16 +167,15 @@ posting, set `converter-comparison/run.sh`'s pins to each package's latest versi
|
||||
its versions and its date in step with the output. We draft each post for the place it goes; the
|
||||
maintainer posts them once `0.3.0` is published. Found while planning discoverability, 2026-10-04.
|
||||
|
||||
### 119. Read a directive's content holding many unclosed backtick runs in time linear in the text.
|
||||
### 119. Read a directive's content holding many unclosed backtick runs in time linear in the markdown.
|
||||
|
||||
`readCodeSpanEnd` (`src/markdown/directive-syntax.ts`) calls `closingBacktickRun`, which searches
|
||||
the rest of the text at every opener, so backtick runs of lengths 1 to k with no closers inside an
|
||||
inline directive's `[content]` cost about k·n. Measured on 2026-10-18: 24 ms at 40k characters,
|
||||
126 ms at 160k and 1004 ms at 640k, where the same runs outside a directive take 6, 18 and 63 ms.
|
||||
The inline reader reads such runs through `backtickCloser`
|
||||
(`src/markdown/commonmark/backtick-runs.ts`), kept once per text; the directive reader would need
|
||||
them kept for the source it reads from. Delete `closingBacktickRun` once nothing calls it, so one
|
||||
reader finds a closer.
|
||||
The inline reader finds closers through one `backtickCloser` per text
|
||||
(`src/markdown/commonmark/backtick-runs.ts`); `readCodeSpanEnd` needs one built for the source it
|
||||
reads. Then delete `closingBacktickRun`, so one function finds every closer.
|
||||
|
||||
### 81. Fail the gate unless the README's error tables list exactly the codes `ConvertErrorCode` holds.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user