29: the README states the raw HTML rule once #115

Merged
lilleman merged 1 commits from readme-raw-html into main 2026-09-20 23:26:28 +02:00
3 changed files with 30 additions and 25 deletions
+14 -15
View File
@@ -29,9 +29,9 @@ In priority order.
2. **Three formats, ADF the hub.** ADF, one markdown flavour, one HTML dialect, markdown↔HTML
composing through ADF — four conversions to keep correct, never a fifth, and never a fourth
format.
3. **Plain CommonMark is input.** Markdown written for something else converts — the three
carve-outs and the one gap below are the whole of the exception — and every spelling the
flavour claims on top of CommonMark is escapable, so the flavour is opt-in.
3. **Plain CommonMark is input.** Markdown written for something else converts — the exceptions
below are the whole of them — and every spelling the flavour claims on top of CommonMark is
escapable, so the flavour is opt-in.
4. **Output a person can edit.** A node CommonMark can spell gets that spelling; the directive
form carries only what CommonMark cannot hold.
5. **Failures are values.** Nothing throws, and `code` is a closed list — as much a contract as
@@ -118,7 +118,7 @@ Parsing — `markdownToAdf`, and `htmlToAdf` at `0.2.0`:
| `malformed-directive` | an `!adf:` the grammar cannot read — a prefix completing no directive, an unclosed container, `[content]` or `{attrs}`, a closer with no container of its name open, a leaf given a body, `{attrs}` out of order or duplicated, invalid JSON in a `carry` | write the spelling the message names, or escape the prefix — `\!adf:`, block and inline alike — to keep it literal text |
| `malformed-pipe-table` | a pipe row that is no pipe table — a missing or ragged `---` delimiter row, an alignment colon in it, or a row not opening with a pipe | open every row with a pipe and give the delimiter row the header's cell count; to keep the lines literal text instead, escape the leading pipe of every one — escaping a single row leaves the next to open a fresh table and fail the same way |
| `unknown-directive-name` | a directive whose name is no node or mark this version spells | check the name in `spec/flavour.md`, or escape the prefix as `\!adf:`; the spelling itself is well formed, so a later minor may give the name meaning |
| `unmappable-html` | the markdown holds a raw HTML tag, comment or processing instruction | remove it or write it in the flavour — ADF holds no raw-HTML node, and the element mapping lands at `0.2.0` |
| `unmappable-html` | the input holds an HTML construct the documented element set does not map, a comment and a processing instruction among them — at this version that is every raw HTML construct in markdown, the element set landing at `0.2.0` | remove the construct, or write what it holds in the flavour |
| `unmappable-image` | an image sits inside other content that is not another image's description, or carries a title | give the image a paragraph of its own and drop the title |
Emitting — `adfToMarkdown`, and `adfToHtml` at `0.2.0`:
@@ -144,13 +144,13 @@ emit refuses:
- `markdownToAdf(adfToMarkdown(doc))` equals `doc` — unknown node types included, carried opaquely
(AGENTS.md §3).
- Plain CommonMark is valid input to `markdownToAdf` apart from the raw HTML below, 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 its own
title-less paragraph; mid-text and titled images are error results, save an image inside
another's description, which flattens into the alt text. Converting back yields the
library's canonical spelling, which round-trips byte-identically — where it converts back at
all: a parse succeeding is no promise of that, so keep the source until the way back succeeds.
- 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
syntax is claimed (escapable — `spec/flavour.md`) — and one gap: a CommonMark image fits only as
its own title-less paragraph; mid-text and titled images are error results, save an image inside
another's description, which flattens into the alt text. Converting back yields the library's
canonical spelling, which round-trips byte-identically — where it converts back at all: a parse
succeeding is no promise of that, so keep the source until the way back succeeds.
``` ` `` ` ``` reads cleanly and then refuses.
- Four CommonMark spellings parse without an error and build a document the reference
implementation renders differently: `[](/url)` and `[]()` stay literal text against CommonMark's
@@ -160,8 +160,6 @@ emit refuses:
text, which the spec requires and the reference itself breaks, nesting one `<a>` in the other.
The first three are pinned `pending` in `corpus/commonmark-spec/exceptions.json`; the suite
holds no example of the fourth.
- Raw HTML in markdown input is an error result, never a silent drop — a tag, a comment and a
processing instruction alike. ADF holds no raw-HTML node; the element mapping ships at `0.2.0`.
- Not every document converts back: `adfToMarkdown` is partial on valid ADF — a text node holding
a carriage return, or a paragraph line beginning with a code span whose backticks read back as a
fence. Show the refusal and keep the document read-only; saving markdown you could not produce
@@ -175,8 +173,9 @@ emit refuses:
- A document nested deeper than 500 levels is an error result, not a stack overflow.
- The emitted formats are semver surface (AGENTS.md §8).
- **`0.2.0`** — `htmlToAdf(adfToHtml(doc))` equals `doc`; fidelity HTML cannot express rides
`data-*` attributes. Foreign HTML maps a documented element set, an unmappable element is an
error, and well-formed HTML only — no tag-soup recovery.
`data-*` attributes. Foreign HTML maps a documented element set, which markdown's raw HTML reads
through as well, and a construct outside it is an error; well-formed HTML only — no tag-soup
recovery.
## The package
+15
View File
@@ -928,6 +928,21 @@ The done `todo.md` items in full, as they were written. `todo.md` keeps a one-li
directive-spelled opening link leaves the first segment with no node range for `escape` to
ask about — so both are uncovered branches like the repo's other guards, 98.92% to 98.84%
against the floor of 98.
- [x] **29 — The README reads raw HTML as refused for good (`0.2.0`).** §Goals 3 says "the three
carve-outs and the one gap below are the whole of the exception" and §The guarantees says
"Raw HTML in markdown input is an error result", both reading as settled, where
`spec/flavour.md` §Raw HTML in input says the opposite: `markdownToAdf` routes each construct
through the foreign HTML element mapping, and only a construct without one is refused. The
spec stands — commonplace markdown is accepted, and every tool writes some HTML (the
maintainer, 2026-09-20). So rewrite the two README texts to name the exception that survives
6 and 7, a construct outside the documented element set, and state it in one place, since
three already spell this one rule. `markdown-to-adf.ts:73` and `inline-content.ts:158` are
the whole of the refusal and already say "at this version"; 7 is what makes them route.
**Done** (2026-09-20): the rule has one home, the `unmappable-html` row, naming the element
set and what its absence covers at this version; §Goals 3 bounds the exceptions without
listing them, the standalone raw-HTML guarantee goes, and the `0.2.0` guarantee says
markdown's raw HTML reads the same set. That guarantee's "never a silent drop" went with it:
6 settled that `<script>` and `<style>` drop whole, so the claim does not survive 7.
## 5 — Ship `0.1.0`
+1 -10
View File
@@ -40,16 +40,6 @@ panel says the next reader pays for.
29 and 30 come from 17's prose pass (2026-09-20). 29 reads first because every goal is what a later
ask is settled against, 19's included; 30 sits beside 25, the other chunk rereading AGENTS.md.
- [ ] **29 — The README reads raw HTML as refused for good (`0.2.0`).** §Goals 3 says "the three
carve-outs and the one gap below are the whole of the exception" and §The guarantees says
"Raw HTML in markdown input is an error result", both reading as settled, where
`spec/flavour.md` §Raw HTML in input says the opposite: `markdownToAdf` routes each construct
through the foreign HTML element mapping, and only a construct without one is refused. The
spec stands — commonplace markdown is accepted, and every tool writes some HTML (the
maintainer, 2026-09-20). So rewrite the two README texts to name the exception that survives
6 and 7, a construct outside the documented element set, and state it in one place, since
three already spell this one rule. `markdown-to-adf.ts:73` and `inline-content.ts:158` are
the whole of the refusal and already say "at this version"; 7 is what makes them route.
- [ ] **30 — AGENTS.md says each thing once (`0.2.0`).** §15's ask protocol — name the class, cite
the earlier asks of it, never "A or B?" — is the rule reviewers cite most and has no heading,
two thirds down a 50-line section in a file with no index. Give it one. §15 also offers "the
@@ -302,6 +292,7 @@ ask is settled against, 19's included; 30 sits beside 25, the other chunk reread
- [x] **17 — A machine-enforced size ratchet (`0.2.0`).**
- [x] **18 — The subtree the directive spelling asks about (`0.2.0`).**
- [x] **28 — `emitLine`'s retry loop cannot spin (`0.2.0`).**
- [x] **29 — The README reads raw HTML as refused for good (`0.2.0`).**
## The ADF inventory to cover