36a - review: README links the decision log, premises that can lapse, citations fixed
This commit was merged in pull request #134.
This commit is contained in:
@@ -172,16 +172,16 @@ functions, and a branch floor that only ever moves upward. It sits below 100 bec
|
|||||||
compared against `undefined` — have a half no valid document reaches.
|
compared against `undefined` — have a half no valid document reaches.
|
||||||
|
|
||||||
The size ratchet is the other such number, `.oxlintrc.json`'s single rule over the files
|
The size ratchet is the other such number, `.oxlintrc.json`'s single rule over the files
|
||||||
`tsconfig.build.json` builds — `oxlint`, since TypeScript 7 is a native compiler publishing no
|
`tsconfig.build.json` builds, measured by `oxlint` since TypeScript 7 is a native compiler
|
||||||
in-process parser, only the `unstable/` AST surface an out-of-process handshake reaches: a
|
publishing no in-process parser, only the `unstable/` AST surface an out-of-process handshake
|
||||||
per-function line ceiling, set at that set's worst and moving only downward. It covers the built
|
reaches. It is a per-function line ceiling, set at that set's worst and moving only downward. It
|
||||||
files alone, since one ceiling over the tests too would have to be their worst, loosening the guard
|
covers the built files alone, since one ceiling over the tests too would have to be their worst,
|
||||||
over the shipped code. It guards against drift and never drives a refactor, so no cyclomatic rule
|
loosening the guard over the shipped code. It guards against drift and never drives a refactor, so
|
||||||
and no second lint rule join it: neither measure picked out what nine readers found hard (the
|
no cyclomatic rule and no second lint rule join it: neither measure picked out what nine readers
|
||||||
comprehension panel, 2026-09-20). Three switches guard a silent green: `IIFEs: true`, since oxlint
|
found hard (the comprehension panel, 2026-09-20). Three switches guard a silent green: `IIFEs:
|
||||||
exempts an IIFE otherwise; an explicit `-c`, so a config gone missing fails the leg instead of
|
true`, since oxlint exempts an IIFE otherwise; an explicit `-c`, so a config gone missing fails the
|
||||||
falling back to oxlint's own defaults; and `--deny-warnings`, since a rule from a category this
|
leg instead of falling back to oxlint's own defaults; and `--deny-warnings`, since a rule from a
|
||||||
config never names arrives as a warning it exits 0 on.
|
category this config never names arrives as a warning it exits 0 on.
|
||||||
|
|
||||||
The corpus, all checked in: hand-built fixtures per node and combination; real ADF Atlassian's
|
The corpus, all checked in: hand-built fixtures per node and combination; real ADF Atlassian's
|
||||||
editor wrote; the CommonMark spec suite against `markdownToAdf` and `markdownToHtml`.
|
editor wrote; the CommonMark spec suite against `markdownToAdf` and `markdownToHtml`.
|
||||||
@@ -372,8 +372,9 @@ The verdict lands in the item it settles (the maintainer, 2026-09-25).
|
|||||||
### Rules the loop has settled (the maintainer, 2026-09-18)
|
### Rules the loop has settled (the maintainer, 2026-09-18)
|
||||||
|
|
||||||
- A finding inside the chunk's item is fixed in the chunk. Outside it, a new `todo.md` item, always
|
- A finding inside the chunk's item is fixed in the chunk. Outside it, a new `todo.md` item, always
|
||||||
in a release, weighed against every item on that release by the personas and Goals 1 and 2 — an
|
in a release, weighed against every item on that release by the personas and `docs/decisions.md`
|
||||||
item it outweighs moves later. A weighing no rule decides is asked as a gap.
|
§Plain markdown is a flavour of the grammar through §Names stay text — an item it outweighs moves
|
||||||
|
later. A weighing no rule decides is asked as a gap.
|
||||||
- A stated number — 500 levels, the branch floor — is kept; a chunk that cannot keep it asks,
|
- A stated number — 500 levels, the branch floor — is kept; a chunk that cannot keep it asks,
|
||||||
naming the number it can reach. A number the code needs and no rule states is a gap.
|
naming the number it can reach. A number the code needs and no rule states is a gap.
|
||||||
- An earliest release with no items left and nothing shipped toward it is planned as the chunk:
|
- An earliest release with no items left and nothing shipped toward it is planned as the chunk:
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ an HTML dialect.
|
|||||||
|
|
||||||
**Status: published — the markdown round-trip (`adfToMarkdown`, `markdownToAdf`); HTML at
|
**Status: published — the markdown round-trip (`adfToMarkdown`, `markdownToAdf`); HTML at
|
||||||
`0.2.0`.**
|
`0.2.0`.**
|
||||||
Plan: `todo.md`. Decisions: `AGENTS.md`. Changes:
|
Plan: `todo.md`. Decisions:
|
||||||
|
[`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md). Changes:
|
||||||
[`CHANGELOG.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/CHANGELOG.md). The lossless flavour's grammar:
|
[`CHANGELOG.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/CHANGELOG.md). The lossless flavour's grammar:
|
||||||
[`spec/flavour.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/spec/flavour.md).
|
[`spec/flavour.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/spec/flavour.md).
|
||||||
Upgrading from `0.1.0`: [convert your markdown first](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/MIGRATION.md).
|
Upgrading from `0.1.0`: [convert your markdown first](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/MIGRATION.md).
|
||||||
@@ -143,7 +144,7 @@ saving what this pair read replaces mentions, attachments and macros with text.
|
|||||||
## The errors
|
## The errors
|
||||||
|
|
||||||
An ADF node type this version does not know is not an error: it is carried opaquely and restores
|
An ADF node type this version does not know is not an error: it is carried opaquely and restores
|
||||||
unchanged (`docs/decisions.md §Unknown nodes ride the carry`).
|
unchanged ([`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md#unknown-nodes-ride-the-carry)).
|
||||||
|
|
||||||
`ConvertError` is `{ code, message, path, position? }`. `code` is the exported `ConvertErrorCode`,
|
`ConvertError` is `{ code, message, path, position? }`. `code` is the exported `ConvertErrorCode`,
|
||||||
stable across minors and safe to `switch` on exhaustively with no `default`; `message` is free text
|
stable across minors and safe to `switch` on exhaustively with no `default`; `message` is free text
|
||||||
@@ -195,7 +196,7 @@ emit refuses:
|
|||||||
## The guarantees
|
## The guarantees
|
||||||
|
|
||||||
- `markdownToAdf(adfToMarkdown(doc))` equals `doc` — unknown node types included, carried opaquely
|
- `markdownToAdf(adfToMarkdown(doc))` equals `doc` — unknown node types included, carried opaquely
|
||||||
(`docs/decisions.md §Unknown nodes ride the carry`).
|
([`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md#unknown-nodes-ride-the-carry)).
|
||||||
- Plain CommonMark is valid input to `markdownToAdf` apart from the raw HTML `unmappable-html`
|
- Plain CommonMark is valid input to `markdownToAdf` apart from the raw HTML `unmappable-html`
|
||||||
names, with three carve-outs — literal text matching directive, pipe-table or strikethrough
|
names, with three carve-outs — literal text matching directive, pipe-table or strikethrough
|
||||||
syntax is claimed (escapable — `spec/flavour.md`) — and one gap: a CommonMark image fits only as
|
syntax is claimed (escapable — `spec/flavour.md`) — and one gap: a CommonMark image fits only as
|
||||||
@@ -234,4 +235,5 @@ emit refuses:
|
|||||||
ESM only, no runtime dependencies, public npmjs. Built JavaScript with `.d.ts` beside it.
|
ESM only, no runtime dependencies, public npmjs. Built JavaScript with `.d.ts` beside it.
|
||||||
Pure ECMAScript at an ES2022 baseline, reaching for no host API; the test suite runs under Node,
|
Pure ECMAScript at an ES2022 baseline, reaching for no host API; the test suite runs under Node,
|
||||||
Deno and Bun, and a headless Firefox converts the corpus through the built entrypoint.
|
Deno and Bun, and a headless Firefox converts the corpus through the built entrypoint.
|
||||||
Contract: `docs/decisions.md`.
|
Contract: [`docs/decisions.md`](https://gitea.larvit.se/larvit/adf-codec/src/branch/main/docs/decisions.md#any-es2022-engine), §Any
|
||||||
|
ES2022 engine to §Public on npm.
|
||||||
|
|||||||
+8
-7
@@ -40,7 +40,7 @@ array the absent key — the only domain markdown can restore.
|
|||||||
## Unknown nodes ride the carry
|
## Unknown nodes ride the carry
|
||||||
|
|
||||||
2026-08-23, extended to misplaced known nodes 2026-08-26, the maintainer. Goal 1. Valid while ADF
|
2026-08-23, extended to misplaced known nodes 2026-08-26, the maintainer. Goal 1. Valid while ADF
|
||||||
gains node types faster than this library spells them.
|
holds nodes, or node positions, this library does not spell.
|
||||||
|
|
||||||
An unknown ADF node is carried opaquely — raw JSON rides a dedicated syntax in both formats and
|
An unknown ADF node is carried opaquely — raw JSON rides a dedicated syntax in both formats and
|
||||||
restores to a deep-equal node. The round-trip holds for documents newer than the library. So does
|
restores to a deep-equal node. The round-trip holds for documents newer than the library. So does
|
||||||
@@ -76,7 +76,7 @@ opener nests by itself and leaf versus container falls out of the node's content
|
|||||||
|
|
||||||
## CommonMark is a subset
|
## CommonMark is a subset
|
||||||
|
|
||||||
2026-08-23, the maintainer. Goal 3. Valid while the carve-outs stay the flavour's only claims.
|
2026-08-23, the maintainer. Goal 3. Valid while prose rarely writes the shapes the carve-outs claim.
|
||||||
|
|
||||||
Plain CommonMark is a subset, with carve-outs (`spec/flavour.md`): literal text shaped like a
|
Plain CommonMark is a subset, with carve-outs (`spec/flavour.md`): literal text shaped like a
|
||||||
directive, a pipe table or a `~~` pair is claimed — plus one image gap.
|
directive, a pipe table or a `~~` pair is claimed — plus one image gap.
|
||||||
@@ -117,7 +117,8 @@ for what HTML cannot express, text always escaped. No stylesheet ships.
|
|||||||
|
|
||||||
## No runtime dependencies
|
## No runtime dependencies
|
||||||
|
|
||||||
2026-08-23, the maintainer. Goal 7. Valid while Goal 7 names no runtime dependencies.
|
2026-08-23, the maintainer. Goal 7. Valid while ~20 lines of own code, or a vendored table, do each
|
||||||
|
job a dependency would.
|
||||||
|
|
||||||
`dependencies` is empty. A runtime dependency enters only through an entry here stating why ~20
|
`dependencies` is empty. A runtime dependency enters only through an entry here stating why ~20
|
||||||
lines of own code cannot do the job, who maintains it, and what auditing it costs. So the CommonMark
|
lines of own code cannot do the job, who maintains it, and what auditing it costs. So the CommonMark
|
||||||
@@ -125,8 +126,8 @@ and HTML parsers are written in this repo.
|
|||||||
|
|
||||||
## Standards ship as data
|
## Standards ship as data
|
||||||
|
|
||||||
2026-08-30, the CommonMark suite 2026-09-05 and ADF's schemas 2026-09-13, the maintainer. Goals 1
|
2026-08-30, the CommonMark suite 2026-09-05 and ADF's schemas 2026-09-13, the maintainer. Goals 1,
|
||||||
and 7. Valid while each table's upstream package is CommonJS-only or heavy.
|
3 and 7. Valid while each table is fixed data a dependency would only wrap.
|
||||||
|
|
||||||
A table a standard fixes is data rather than a dependency: HTML5's 2125 semicolon-terminated
|
A table a standard fixes is data rather than a dependency: HTML5's 2125 semicolon-terminated
|
||||||
character references ship packed in their own module, so entity decoding is complete without one.
|
character references ship packed in their own module, so entity decoding is complete without one.
|
||||||
@@ -163,7 +164,7 @@ never the higher one those repo-only tools want.
|
|||||||
|
|
||||||
## ESM only
|
## ESM only
|
||||||
|
|
||||||
2026-08-23, the maintainer. Goal 7. Valid while every supported engine loads ES modules.
|
2026-08-23, the maintainer. Goal 7. Valid while the audience's toolchains all import ES modules.
|
||||||
|
|
||||||
No CommonJS build, no dual-package hazard.
|
No CommonJS build, no dual-package hazard.
|
||||||
|
|
||||||
@@ -177,7 +178,7 @@ an npm consumer.
|
|||||||
|
|
||||||
## Public on npm
|
## Public on npm
|
||||||
|
|
||||||
2026-08-23, the maintainer. Goal 7 and the Audience. Valid while the audience installs from public
|
2026-08-23, the maintainer. The Audience. Valid while the audience installs from public
|
||||||
npm.
|
npm.
|
||||||
|
|
||||||
Published to public npmjs as `@larvit/adf-codec`. Public source: the Gitea repo goes public,
|
Published to public npmjs as `@larvit/adf-codec`. Public source: the Gitea repo goes public,
|
||||||
|
|||||||
+11
-11
@@ -156,13 +156,13 @@ naming no open container or a node other than the innermost open one, a leaf giv
|
|||||||
unparseable or duplicate-keyed attrs, invalid JSON in an opaque carry. Never a silent literal-text
|
unparseable or duplicate-keyed attrs, invalid JSON in an opaque carry. Never a silent literal-text
|
||||||
fallback — a typo that reparses as prose is the silent loss the round-trip refuses.
|
fallback — a typo that reparses as prose is the silent loss the round-trip refuses.
|
||||||
|
|
||||||
## The opaque carry (`docs/decisions.md` §Unknown nodes ride the carry)
|
## The opaque carry
|
||||||
|
|
||||||
A node no section spells where it stands — an unknown type, or a known one whose spelling belongs to
|
A node no section spells where it stands (`docs/decisions.md` §Unknown nodes ride the carry) — an
|
||||||
the other position — rides as its raw JSON and restores to a deep-equal node. A carry may hold a
|
unknown type, or a known one whose spelling belongs to the other position — rides as its raw JSON
|
||||||
node the emitter spells natively: it restores unreinterpreted, and the next emit spells it
|
and restores to a deep-equal node. A carry may hold a node the emitter spells natively: it restores
|
||||||
canonically (`docs/decisions.md` §The round-trip is the product). Block and inline positions
|
unreinterpreted, and the next emit spells it canonically (`docs/decisions.md` §The round-trip is the
|
||||||
canonicalize differently, each fitting where it sits:
|
product). Block and inline positions canonicalize differently, each fitting where it sits:
|
||||||
|
|
||||||
- **Block position**: a fenced code block with info string `carry`, body = the node's JSON —
|
- **Block position**: a fenced code block with info string `carry`, body = the node's JSON —
|
||||||
two-space indent, object keys sorted.
|
two-space indent, object keys sorted.
|
||||||
@@ -490,11 +490,11 @@ the directive form, open to no literal reading, is a named error.
|
|||||||
|
|
||||||
A spelling adds its mark to every inline node it wraps, and nesting is the marks array in order,
|
A spelling adds its mark to every inline node it wraps, and nesting is the marks array in order,
|
||||||
outermost first: `_!adf:underline[x]_` gives marks `[em, underline]`, `!adf:underline[_x_]` the
|
outermost first: `_!adf:underline[x]_` gives marks `[em, underline]`, `!adf:underline[_x_]` the
|
||||||
reverse.
|
reverse. `adfToMarkdown` nests in the order the array holds rather than sorting it —
|
||||||
`adfToMarkdown` nests in the order the array holds rather than sorting it — §2's equality
|
`docs/decisions.md` §Equality is editor-normal restores the array, not a set — and opens each
|
||||||
restores the array, not a set — and opens each spelling once over the longest run of adjacent
|
spelling once over the longest run of adjacent inline nodes carrying an identical mark, attributes
|
||||||
inline nodes carrying an identical mark, attributes included, at that depth. A run breaks at every
|
included, at that depth. A run breaks at every node the emitter carries, so no emitted carry sits
|
||||||
node the emitter carries, so no emitted carry sits inside a mark spelling.
|
inside a mark spelling.
|
||||||
|
|
||||||
An inline node whose marks no nesting spells — a mark type not listed here, an attrs key its
|
An inline node whose marks no nesting spells — a mark type not listed here, an attrs key its
|
||||||
spelling does not list, a value that is not the spelling's type, an attribute the spelling needs
|
spelling does not list, a value that is not the spelling's type, an attribute the spelling needs
|
||||||
|
|||||||
Reference in New Issue
Block a user