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:
@@ -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
|
||||
|
||||
@@ -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('')
|
||||
|
||||
@@ -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][] => {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user