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

Answer prose round 1: the README drops the parse-path sentence and the comments say what stands in and why

This commit is contained in:
2026-10-11 12:01:26 +02:00
committed by Lillem4n
parent be3ac4af22
commit cc40fb95f2
5 changed files with 7 additions and 8 deletions
+1 -2
View File
@@ -174,8 +174,7 @@ and may change in any release. A parse always names a position, so the three mar
alone; one handler typed on `ConvertError` takes both, which is what the calls between markdown and
HTML hand back. `path` is the node's place from the document root, alternating `'content'` and an
index, so `path.map((step) => '/' + step).join('')` is a JSON Pointer at the node — the empty path
being the document itself. A parse's path points into the document the call returns once the
refusal is fixed.
being the document itself.
A call reports the first refusal in document order and stops, so a document with several surfaces
them one per call. Every refusal is deterministic — there is no I/O anywhere — so a retry returns
+3 -3
View File
@@ -225,12 +225,12 @@ function bulletBlocks(items: readonly Block[][], reading: Reading, path: Convert
type Refusal = { block: ReadBlock; next: ReadBlock | undefined; path: ConvertErrorPath; reading: Reading; task: AdfNode; tasks: readonly AdfNode[] }
// splitTaskList moves a task's children, so a refusal in `block` names where its node would stand: in place of the node, the split places a stand-in of its type.
// splitTaskList moves a task's children, so the path names where the refused block's node will stand: the split runs with a stand-in of that node's type.
function splitPath(refused: ConvertErrorPath, { block, next, path, reading, task, tasks }: Refusal): ConvertErrorPath {
const [, offset, ...within] = refused.slice(path.length + 2)
const listIndex = path.at(-1)
if (typeof offset !== 'number' || typeof listIndex !== 'number') return refused
// A nested task list reads as a task list, then a block the split moves out, so a node past its first stands outside the task.
// A nested task list reads as a task list, then the blocks its own split moved out; a bulletList stands in for each of those, since the split moves it out too.
const before = Array.from({ length: offset }, (_, at): AdfNode => ({ type: at === 0 ? 'taskList' : 'bulletList' }))
const node: AdfNode & { content: [AdfNode] } = { content: [{ text: '', type: 'text' }], type: offset === 0 ? childType(block, reading) : 'bulletList' }
const after = next === undefined ? [] : [{ type: childType(next, reading) }]
@@ -241,7 +241,7 @@ function splitPath(refused: ConvertErrorPath, { block, next, path, reading, task
return [...path.slice(0, -1), listIndex + blockIndex, ...steps, ...within]
}
// A task keeps only paragraphs and task lists, so another block's kind stands in for its node's type.
// The split tells only paragraphs and task lists from other blocks, so any other block's kind serves as its type; a paragraph may read as another node.
function childType(block: ReadBlock, reading: Reading): string {
if (block.kind === 'bulletList') return taskItems(block.items) === undefined ? 'bulletList' : 'taskList'
if (block.kind !== 'paragraph') return block.kind === 'taskParagraph' ? 'paragraph' : block.kind
@@ -180,7 +180,7 @@ test('stands a block a task item cannot hold, and what follows it in the item, a
])
})
test('names the place a refused block would stand once the task list moves it', () => {
test('names where a refused block stands after the task list splits', () => {
const refused = (markdown: string): string => {
const parsed = portableMarkdownToAdf(markdown)
return parsed.ok ? 'read' : parsed.error.path.map((step) => '/' + step).join('')
+1 -1
View File
@@ -19,7 +19,7 @@ export function splitTaskList(list: AdfNode): AdfNode[] {
return blocks
}
// Where `node`, a child of one of the list's tasks, stands among the blocks splitTaskList returns; a lone paragraph, holding its inline node, stands as its taskItem.
// Where `node`, a child of one of the list's tasks, stands among the blocks splitTaskList returns; a task's lone paragraph becomes a taskItem, found by the paragraph's first inline node.
export function splitPlace(list: AdfNode, node: AdfNode & { content: [AdfNode] }): [number, ...ConvertErrorPath] | undefined {
const [inline] = node.content
const places = splitTaskList(list).flatMap((block, index): [number, ...ConvertErrorPath][] => {
+1 -1
View File
@@ -122,7 +122,7 @@ commonmark.js avoids the backtick cost by caching backtick runs by length.
### 92. Lower the reading cost of the files a chunk reads most before its first commit.
The last five chunks' median is 168135 new input tokens before their first commit, the five before
them 97329. Read most over the last five, opens and searches: `docs/decisions.md` 28, `README.md`
them 97329. Files read most over the last five chunks, counting opens and searches: `docs/decisions.md` 28, `README.md`
23, `todo.md` 23, `CHANGELOG.md` 19, `src/markdown/parse/blocks.ts` 15,
`src/markdown/portable/adf-to-portable-markdown.ts` 12, `spec/flavour.md` 10,
`src/markdown/emit/line-escaping.ts` 9, `src/markdown/parse/markdown-to-adf.test.ts` 8,