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"], "files": ["src/markdown/*.ts"],
"rules": { "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 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/`, 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 `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 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 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 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 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 is the only import `parse/` takes from `emit/`, through `emit/spelling-questions.ts`. The root of
imports neither `emit/`, `parse/` nor `portable/`, and `emit/` does not import `parse/`. The scan in `markdown/` imports none of `emit/`, `parse/` and `portable/`, and `emit/` does not import `parse/`.
`inline-content.ts` reports whether a spellable link opens the paragraph, and 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`) `parse/inline-content.ts` alone asks the writer whether that link still needs its directive. A
never asks the writer: the writer calls it as it spells a line, so a read-back that asked would read-back (`readLineBack`) never asks the writer: the writer calls it as it spells a line, so a
recurse without bound (§Nothing recurses unbounded). read-back that asked would recurse without bound (§Nothing recurses unbounded).
`.oxlintrc.json` enforces that limit for `markdown/parse/`, keeps `html/parse/` from importing `.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 `html/emit/`, keeps markdown's `parse/` and `emit/` from importing `portable/`, keeps `markdown/`'s
importing `emit/`, `parse/` and `portable/`, keeps `emit/` from importing `parse/`, keeps root files from importing `emit/`, `parse/` or `portable/`, keeps `emit/` from importing `parse/`,
`markdown/directive/` from importing `emit/` or `parse/`, keeps `markdown/` and `html/` from 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. 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 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 format's ban on the other format, and `ci.sh` probes every override. They are lint rules because the
test that scans the source, and a lint rule reads every import spelling: `from`, a bare `import`, technical principles refuse a test that scans the source, and a lint rule reads every import
double quotes and a dynamic `import()`. spelling: `from`, a bare `import`, double quotes and a dynamic `import()`.
## The comparison tables list every ADF converter that starts and converts ## 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. // 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[] } 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 } 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. // 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 }) 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 } { export function readLineBack(line: string, container: LineContainer, claims: Claims): { faulted: boolean; reading: InlineReading } {
const reading: InlineReading = { codeSpans: [], emphasis: new Map(), links: [] } 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 }) 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)]) 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 { function refuseLinkDirective(scan: Scan, mark: AdfMark, nodes: readonly Inline[], index: number): Result<Piece[]> | undefined {
const href = linkHref(nodeAttrs(mark)) const href = linkHref(nodeAttrs(mark))
if (href === undefined) return failure('unsupported-node-shape', hreflessLink, scan.shared.path) 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 { openingLinkTakesDirective } from '../emit/spelling-questions.ts'
import { parseInlineContent, spellableLink } from '../inline-content.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> { export function readInlineContent(source: string, definitions: LinkDefinitions, path: ConvertErrorPath, container: LineContainer, flavour: Flavour): Result<InlineContent> {
const content = parseInlineContent(source, definitions, path, container, flavour) const content = parseInlineContent(source, definitions, path, container, flavour)
if (!content.ok || !content.value.openingSpellableLink) return content if (!content.ok || !content.value.openingSpellableLink) return content