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

Have closeBracket return what the bracket becomes and apply it to the scan in one caller

This commit is contained in:
2026-11-09 01:32:02 +01:00
committed by Lillem4n
parent 19c1a53dcc
commit 2efce5f91f
3 changed files with 44 additions and 40 deletions
+13
View File
@@ -792,3 +792,16 @@ Read most (opens and searches):
- `package.json` 1
- `src/markdown/commonmark/backtick-runs.ts` 1
- `src/markdown/commonmark/grammar.ts` 1
## Reading cost, chunk ca685f64bce7, finished 2026-11-09T00:27:56Z
85473 new input tokens before the first commit.
Read most (opens and searches):
- `src/markdown/inline-content.ts` 8
- `todo.md` 5
- `README.md` 3
- `AGENTS.md` 1
- `ci.sh` 1
- `docs/decisions.md` 1
+31 -32
View File
@@ -177,7 +177,8 @@ function readToken(scan: Scan, inline: InlineSource, index: number, token: Inlin
scan.pieces.push({ image: token.image, kind: 'open' })
return success(end)
case 'bracket-close':
return closeBracket(scan, index)
flush(scan, false)
return applyClosing(scan, closeBracket(scan, index), index)
case 'code-span':
flush(scan, false)
record(scan.shared, { at: scan.offset + index, kind: 'codeSpans' })
@@ -416,42 +417,40 @@ function linkedText(text: string, scheme: string): AdfNode {
return { marks: [{ attrs: { href: `${scheme}${text}` }, type: 'link' }], text, type: 'text' }
}
function closeBracket(scan: Scan, index: number): Result<number> {
flush(scan, false)
const open = popBracket(scan)
if (open === undefined) return success(literalClose(scan, index))
const target = open.active ? resolveTarget(scan, open.start, index) : undefined
if (target === undefined) return success(unopened(scan, open, index))
// What a `]` makes of the innermost open bracket, decided without writing to the scan. `closesLink` is whether a link closes here, or one inside these brackets did, which leaves every link opener still open literal.
type Closing =
| { closesLink: boolean; kind: 'literal'; open: OpenBracket | undefined }
| { closesLink: boolean; end: number; kind: 'built'; open: OpenBracket; pieces: Result<Piece[]> }
function closeBracket(scan: Scan, index: number): Closing {
const open = scan.brackets.at(-1)
if (open === undefined) return { closesLink: false, kind: 'literal', open }
const target = open.image || scan.brackets.length > scan.linkOpenersFrom ? resolveTarget(scan, open.start, index) : undefined
if (target === undefined) return { closesLink: false, kind: 'literal', open }
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
// 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))
record(scan.shared, { at: scan.offset + open.start - 1, kind: 'links' })
const closed = open.image ? imagePieces(scan, inner, target.definition()) : linkPieces(scan, inner, target.definition())
if (!closed.ok) return closed
scan.pieces.length = open.index
for (const piece of closed.value) scan.pieces.push(piece)
return success(index + 1 + target.length)
if (!open.image && holdsLink(inner)) return { closesLink: true, kind: 'literal', open }
const pieces = open.image ? imagePieces(scan, inner, target.definition()) : linkPieces(scan, inner, target.definition())
return { closesLink: !open.image, end: index + 1 + target.length, kind: 'built', open, pieces }
}
// 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
const active = open.image || scan.brackets.length >= scan.linkOpenersFrom
scan.linkOpenersFrom = Math.min(scan.linkOpenersFrom, scan.brackets.length)
return { ...open, active }
}
function literalClose(scan: Scan, index: number): number {
scan.pending += ']'
return index + 1
}
function unopened(scan: Scan, open: OpenBracket, index: number): number {
scan.pieces[open.index] = { kind: 'nodes', nodes: bracketNodes(open) }
return literalClose(scan, index)
function applyClosing(scan: Scan, closing: Closing, index: number): Result<number> {
const { closesLink, open } = closing
if (open !== undefined) {
scan.brackets.pop()
scan.linkOpenersFrom = closesLink ? scan.brackets.length : Math.min(scan.linkOpenersFrom, scan.brackets.length)
}
if (closing.kind === 'literal') {
if (open !== undefined) scan.pieces[open.index] = { kind: 'nodes', nodes: bracketNodes(open) }
scan.pending += ']'
return success(index + 1)
}
record(scan.shared, { at: scan.offset + closing.open.start - 1, kind: 'links' })
if (!closing.pieces.ok) return closing.pieces
scan.pieces.length = closing.open.index
for (const piece of closing.pieces.value) scan.pieces.push(piece)
return success(closing.end)
}
function bracketNodes(bracket: Bracket | OpenBracket): AdfNode[] {
-8
View File
@@ -13,7 +13,6 @@
| ID | Release | Blocked by | Exempt | Item | L | E | I | R | S | Moves | Score |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 153 | 0.4.0 | | question | **Decide whether `src/markdown/` root may import `emit/`, `parse/` or `portable/`, and hold the answer in `.oxlintrc.json` and §The source parts by ADF and format.** | 1 | 2 | 2 | 3 | 2 | code health by 3 | 26.2 |
| 155 | 0.4.0 | | | **Have `closeBracket` return the link, image or literal bracket it builds, and apply it to the scan in one caller.** | 2 | 1 | 2 | 3 | 4 | code health by 4 | 17.4 |
| 162 | 0.4.0 | | | **Pin each rule of the emphasis sweep with a hand-worked line, so every mutant that lets a pair fall where the one-run-per-pass reference keeps it fails a test.** | 2 | 1 | 1 | 2 | 4 | code health by 4 | 17.4 |
| 175 | 0.4.0 | | | **Delete the guards in `tryTaskList` that `reduceToPortable` makes unreachable, once a test shows `adfToPortableMarkdown` reaches none of them.** | 1 | 1 | 1 | 1 | 2 | code health by 2 | 17.4 |
| 45 | 0.4.0 | | defect | **Replace `isAdfDocument` with a reader returning `Result<AdfDocument>`.** | 2 | 1 | 3 | 4 | 3 | 1 by 2 | 13.1 |
@@ -73,13 +72,6 @@ a paragraph opening with a spellable `!adf:link` (§Nothing recurses unbounded).
`src/markdown/**` bans only `html/`; banning `emit/`, `parse/` and `portable/` for the root's own
files, with its `ci.sh` probe, extends the decision.
### 155. Have `closeBracket` return the link, image or literal bracket it builds, and apply it to the scan in one caller.
A comprehension seat found `src/markdown/inline-content.ts` `closeBracket` hard: it writes
`scan.pieces`, the link openers and the reading, and calls `unopened`, `literalClose` and
`popBracket`, which write `scan.pieces`, `scan.pending` and the link openers. Make that place
easier to read.
### 162. Pin each rule of the emphasis sweep with a hand-worked line, so every mutant that lets a pair fall where the one-run-per-pass reference keeps it fails a test.
About 20 mutants of `src/markdown/emit/unspellable-runs.ts` survive the gate. Each lets a pair fall