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

Answer prose round 1: 1 🔴, 5 🟡 (0 misread); fix the comment that claimed the only ask, cut three repeating comments, and name markdown/'s root in the decision and the lint message

This commit is contained in:
2026-11-10 21:31:31 +01:00
committed by Lillem4n
parent bffeb1f7d6
commit 3479bcefca
4 changed files with 19 additions and 18 deletions
+1 -1
View File
@@ -30,7 +30,7 @@
{
"files": ["src/markdown/*.ts"],
"rules": {
"no-restricted-imports": ["error", { "patterns": [{ "group": ["**/emit/**", "**/html/**", "**/parse/**", "**/portable/**"], "message": "A root file of src/markdown/ is read by the writers and the readers and imports neither: docs/decisions.md §The source parts by ADF and format" }] }]
"no-restricted-imports": ["error", { "patterns": [{ "group": ["**/emit/**", "**/html/**", "**/parse/**", "**/portable/**"], "message": "docs/decisions.md §The source parts by ADF and format" }] }]
}
},
{
+14 -13
View File
@@ -1175,7 +1175,8 @@ is the markdown flavour's choice, not ADF's.
2026-08-27, placement 2026-09-18, `adf/`'s bar 2026-09-21, `plain/` 2026-10-03, the import
boundaries' lint 2026-10-22, the maintainer; `parse/` and `emit/` free of `portable/`,
2026-10-22; the root's imports and `emit/` free of `parse/`, 2026-11-10. Goal 2. Valid while each format has a reader and a writer through ADF.
2026-10-22; `markdown/`'s root free of `emit/`, `parse/` and `portable/`, and `emit/` free of
`parse/`, 2026-11-10. Goal 2. Valid while each format has a reader and a writer through ADF.
`src/adf/` holds ADF's own knowledge, imports no format, and is where a construct both formats read
lives: the question is answered in ADF's vocabulary — a node type, an attribute kind, a content
@@ -1202,22 +1203,22 @@ whether a list marker interrupts a paragraph — is one function there too, neve
direction, however conservative the copy would be. Where the rule is the emitter's own choice, input
consults it rather than restating it, so no fixture the emitter writes can be refused, and a
spelling the emitter refuses gives its own error rather than a second name for it. That consulting
is the only import `parse/` takes from `emit/`, through `emit/spelling-questions.ts`. The root
imports neither `emit/`, `parse/` nor `portable/`, and `emit/` does not import `parse/`. The scan in
`inline-content.ts` reports whether a spellable link opens the paragraph, and
`parse/inline-content.ts` alone asks the writer what that link needs. A read-back (`readLineBack`)
never asks the writer: the writer calls it as it spells a line, so a read-back that asked would
recurse without bound (§Nothing recurses unbounded).
is the only import `parse/` takes from `emit/`, through `emit/spelling-questions.ts`. The root of
`markdown/` imports none of `emit/`, `parse/` and `portable/`, and `emit/` does not import `parse/`.
The scan in `inline-content.ts` reports whether a spellable link opens the paragraph, and
`parse/inline-content.ts` alone asks the writer whether that link still needs its directive. A
read-back (`readLineBack`) never asks the writer: the writer calls it as it spells a line, so a
read-back that asked would recurse without bound (§Nothing recurses unbounded).
`.oxlintrc.json` enforces that limit for `markdown/parse/`, keeps `html/parse/` from importing
`html/emit/`, keeps markdown's `parse/` and `emit/` from importing `portable/`, keeps the root's files from
importing `emit/`, `parse/` and `portable/`, keeps `emit/` from importing `parse/`, keeps
`markdown/directive/` from importing `emit/` or `parse/`, keeps `markdown/` and `html/` from
`html/emit/`, keeps markdown's `parse/` and `emit/` from importing `portable/`, keeps `markdown/`'s
root files from importing `emit/`, `parse/` or `portable/`, keeps `emit/` from importing `parse/`,
keeps `markdown/directive/` from importing `emit/` or `parse/`, keeps `markdown/` and `html/` from
importing each other, and keeps `adf/` from importing either, as `no-restricted-imports` overrides.
A later override replaces an earlier one's rule, so each subdirectory's override repeats its
format's ban on the other format, and `ci.sh` probes every override. They are lint rules because the technical principles refuse a
test that scans the source, and a lint rule reads every import spelling: `from`, a bare `import`,
double quotes and a dynamic `import()`.
format's ban on the other format, and `ci.sh` probes every override. They are lint rules because the
technical principles refuse a test that scans the source, and a lint rule reads every import
spelling: `from`, a bare `import`, double quotes and a dynamic `import()`.
## The comparison tables list every ADF converter that starts and converts
+3 -3
View File
@@ -26,7 +26,7 @@ import { readTextDirective } from './directive/text.ts'
// Only a `paragraph` block takes `image`, the `mediaSingle` a lone image builds; every other container takes `nodes`, where the image is its linked alt text.
export type InlineContent = { image?: AdfNode; nodes: AdfNode[] }
// `openingSpellableLink`: a directive link opens the paragraph that CommonMark could spell; `parse/` asks the writer whether the line still needs the directive.
// `openingSpellableLink`: the paragraph opens with a directive link that CommonMark could spell.
export type OutermostContent = InlineContent & { openingSpellableLink: boolean }
// The text break leaf: it holds no marks, and stands between the nodes it parts until the outermost content checks and drops it.
@@ -132,7 +132,7 @@ export function parseInlineContent(source: string, definitions: LinkDefinitions,
return success(image === undefined ? { nodes: nodes.value, openingSpellableLink } : { image, nodes: nodes.value, openingSpellableLink })
}
// A read-back never asks the writer for anything: the writer calls it while it spells a line. The reading of a line that faults still holds what the reader took before the fault.
// The reading of a line that faults still holds what the reader took before the fault.
export function readLineBack(line: string, container: LineContainer, claims: Claims): { faulted: boolean; reading: InlineReading } {
const reading: InlineReading = { codeSpans: [], emphasis: new Map(), links: [] }
const scan = freshScan(line, { definitions: noDefinitions, path: [], reading, targets: targetMemo(line) }, { claims, container, inLink: false, offset: 0, spans: noSpans })
@@ -271,7 +271,7 @@ function directiveMarkPieces(scan: Scan, name: string, mark: AdfMark, slot: read
return success([...marked.filter((piece) => piece.kind === 'nodes'), ...besideLink(images, link)])
}
// spec/flavour.md, Marks. A link opening a paragraph may still need the directive form for the line it opens, which `parse/` asks the writer once `parseInlineContent` reports the opening.
// spec/flavour.md, Marks. A link opening a paragraph may still need the directive form for the line it opens.
function refuseLinkDirective(scan: Scan, mark: AdfMark, nodes: readonly Inline[], index: number): Result<Piece[]> | undefined {
const href = linkHref(nodeAttrs(mark))
if (href === undefined) return failure('unsupported-node-shape', hreflessLink, scan.shared.path)
+1 -1
View File
@@ -6,7 +6,7 @@ import { failure, success } from '../../result.ts'
import { openingLinkTakesDirective } from '../emit/spelling-questions.ts'
import { parseInlineContent, spellableLink } from '../inline-content.ts'
// The only place a reader asks the writer: whether a spellable link opening the paragraph still needs its directive for the line it opens (spec/flavour.md, Marks).
// The only place a reader asks the writer whether the link opening a paragraph still needs its directive (spec/flavour.md, Marks).
export function readInlineContent(source: string, definitions: LinkDefinitions, path: ConvertErrorPath, container: LineContainer, flavour: Flavour): Result<InlineContent> {
const content = parseInlineContent(source, definitions, path, container, flavour)
if (!content.ok || !content.value.openingSpellableLink) return content