Design 12 and 13: settle the !adf: grammar and split both by construct #65
@@ -185,34 +185,69 @@ proves 12, 13 spells 11's gaps in 12's grammar, and 12 rewrites code 4b and 4c c
|
|||||||
length rule go and every container opens the constant `!adf:`; block leaf `!adf:name arg
|
length rule go and every container opens the constant `!adf:`; block leaf `!adf:name arg
|
||||||
{attrs}` with no closer; inline node `!adf:name[content]{attrs}`; directive marks
|
{attrs}` with no closer; inline node `!adf:name[content]{attrs}`; directive marks
|
||||||
`!adf:border`/`subsup`/`textColor`/`underline` `[content]{attrs}`. Attributes and their
|
`!adf:border`/`subsup`/`textColor`/`underline` `[content]{attrs}`. Attributes and their
|
||||||
escaping stay `{key=value}`; the literal escape is `\!adf:`; a line opening `!adf:` claims as
|
escaping stay `{key=value}`; the literal escape is `\!adf:`. Leaf vs container is decided by
|
||||||
today's colon-run does. Leaf vs container is decided by the node's content model rather than
|
the node's content model rather than syntax — the `::`/`:::` split goes, a simplification the
|
||||||
syntax — the `::`/`:::` split and §4's name-set-independent recognition go, a simplification
|
carry makes safe (an unknown *block* node already rides the fence, not the directive). The
|
||||||
the carry makes safe (an unknown *block* node already rides the fence, not the directive).
|
carry's reserved name becomes `carry`, both spellings — the block fence info string `carry`
|
||||||
The carry's reserved name becomes `carry`, both spellings — the block fence info string
|
and the inline `!adf:carry{json="…"}` — named for what it does: it carries a node verbatim,
|
||||||
`` `carry` `` and the inline `!adf:carry{json="…"}` — named for what it does: it carries a node
|
never "unknown-node", since a known node no section spells where it stands rides it too. No
|
||||||
verbatim, never "unknown-node", since a known node no section spells where it stands rides it
|
`ConvertErrorCode` is added, removed or renamed, and the round-trip guarantee and the carry
|
||||||
too. A spelling change, not a semantic one: no `ConvertErrorCode` is added, removed or renamed,
|
both hold through it. Mechanical surface: the grammar in `spec/flavour.md`,
|
||||||
the round-trip guarantee and the carry both hold through it. Mechanical surface: the grammar in
|
`src/adf/block-directives.ts` + `inline-directives.ts`, `src/markdown/`'s
|
||||||
`spec/flavour.md`, `src/adf/block-directives.ts` + `inline-directives.ts`, `src/markdown/`'s
|
|
||||||
`directive-syntax.ts`, `opaque-carry.ts` and the `emit/` + `parse/` readers, every corpus
|
`directive-syntax.ts`, `opaque-carry.ts` and the `emit/` + `parse/` readers, every corpus
|
||||||
fixture (round-trip, normalization and `errors/`), `spec.test.ts`'s prose reader, and the
|
fixture (round-trip, normalization and `errors/`), the prose reader over `spec/flavour.md`,
|
||||||
README's examples.
|
and the README's examples.
|
||||||
- [ ] **12a — The spec and the decision.** Rewrite `spec/flavour.md` to the `!adf:` grammar, and
|
**Settled** (the maintainer, 2026-09-13):
|
||||||
record the departures in `AGENTS.md` §4 (leaf/container by content model, carry renamed
|
- A line opening `!adf:name` is a block line when a space or the line's end follows the name,
|
||||||
`carry`).
|
and a paragraph when `[` or `{` does. Claiming stays syntactic and structure comes from the
|
||||||
- [ ] **12b — The emit side.** `adfToMarkdown` spells `!adf:` / `!adf:/name` / `!adf:carry`; its
|
tables: an unknown name is `unknown-directive-name` at the opener, whatever follows it.
|
||||||
fixtures re-spelled, green.
|
- An unescaped `!adf:` claims on its own anywhere inline: one completing no directive is
|
||||||
- [ ] **12c — The parse side and the round-trip.** `markdownToAdf` reads it back; the round-trip
|
`malformed-directive`, the emitter escapes every literal `!adf:`, and `!adf:hardBreak{}`
|
||||||
corpus, the `errors/` fixtures and the CommonMark spec suite re-spelled,
|
keeps its braces. Block and inline share the one `\!adf:` escape hint.
|
||||||
`markdownToAdf(adfToMarkdown(doc))` still equals `doc`.
|
- A closer names the innermost open container, crosses no list-item or blockquote edge,
|
||||||
- [ ] **12d — The README and the sweep.** The README's examples follow; sweep docs and fixtures
|
indents as a fence does and carries nothing after the name; anything else is
|
||||||
for any stale `::`/`:name` spelling.
|
`malformed-directive`.
|
||||||
|
- A node holding no content whose content model takes some is an empty opener–closer pair,
|
||||||
|
never a leaf.
|
||||||
|
- A spelled node's content model is frozen with its spelling: changing it is MAJOR (§8).
|
||||||
|
- The colon spellings are dropped, not refused: `0.1.0` markdown reads back as prose, `adf`
|
||||||
|
is no longer a reserved language, and `MIGRATION.md` tells a consumer to convert stored
|
||||||
|
markdown through `0.1.0`'s parser and `0.2.0`'s emitter.
|
||||||
|
- Inputs moving between codes ride the break: a leaf given a body, a container missing its
|
||||||
|
closer and `listBreak` with a body are `malformed-directive`, and an empty inline-body
|
||||||
|
container parses.
|
||||||
|
- Split by construct, each sub-item both directions: 55 of 78 round-trip fixtures feed both
|
||||||
|
the emit and the read-back test, so an emit-only chunk cannot land green.
|
||||||
|
- [ ] **12a — The spec and the decision.** `spec/flavour.md` rewritten to the `!adf:` grammar and
|
||||||
|
the settled answers above, no colon directive form left in it; AGENTS.md §4's directive
|
||||||
|
bullet and prior-art line, and §8's escape hints and `::adf`/`::listBreak` examples, name
|
||||||
|
the new forms, §8 gaining the frozen content model.
|
||||||
|
- [ ] **12b — The inline form.** Inline nodes, directive marks, `text` and the inline carry
|
||||||
|
`!adf:carry{json=…}` spelled and read as `!adf:name[content]{attrs}`, with the prefix claim
|
||||||
|
and its escape; the round-trip, normalization and `errors/` fixtures holding inline forms
|
||||||
|
re-spelled, and the gate green.
|
||||||
|
- [ ] **12c — The block form.** Openers and `!adf:/name` closers, leaf vs container by content
|
||||||
|
model, empty pairs, `listBreak` and the `carry` fence, spelled and read; the fence-length
|
||||||
|
rule and the corpus test's fence nesting check deleted; the remaining fixtures re-spelled
|
||||||
|
and `errors/` re-derived under the shifted codes, and the gate green.
|
||||||
|
- [ ] **12d — The README, `MIGRATION.md` and the sweep.** The README's examples and error tables
|
||||||
|
follow, `MIGRATION.md` linked from one README line; docs and fixtures swept for any stale
|
||||||
|
`::`/`:name` spelling.
|
||||||
- [ ] **13 — The schema's gap attributes (`0.2.0`).** Spell the attributes 11b pins as gaps, in
|
- [ ] **13 — The schema's gap attributes (`0.2.0`).** Spell the attributes 11b pins as gaps, in
|
||||||
12's grammar, and empty the list. `rule`'s `color`, `style` and `weight` and
|
12's grammar, and empty the list.
|
||||||
`layoutSection`'s `columnRuleStyle` join their tables and `spec/flavour.md` bullets. `link`'s
|
**Settled** (the maintainer, 2026-09-13): a link `[text](url "title")` cannot hold takes the
|
||||||
`collection`, `id` and `occurrenceKey` have no slot in `[text](url)`, so a link carrying one
|
directive mark `!adf:link[text]{attrs}` — one carrying `collection`, `id` or `occurrenceKey`,
|
||||||
rides the inline carry whole today; the spelling it takes instead is designed here.
|
or an `href` or `title` no CommonMark escape writes — and a directive link CommonMark could
|
||||||
|
spell is `unsupported-node-shape`. That leaves `unspellable-link` no cause, so it leaves
|
||||||
|
`ConvertErrorCode` in `0.2.0`, §8 recording the removal.
|
||||||
|
- [ ] **13a — `rule` and `layoutSection`.** `rule`'s `color`, `style` and `weight` and
|
||||||
|
`layoutSection`'s `columnRuleStyle` join their tables and `spec/flavour.md` bullets, with
|
||||||
|
round-trip fixtures; their gap entries go.
|
||||||
|
- [ ] **13b — The directive link.** `link` spelled as above in both directions, with a round-trip
|
||||||
|
fixture per trigger, `spec/flavour.md`'s Marks section following; `unspellable-link` removed
|
||||||
|
from the code list, its `errors/` fixtures and the CommonMark suite's `unspellable`
|
||||||
|
exceptions it cures re-derived, and the README's code table and its "not every document
|
||||||
|
converts back" guarantee following; the gap list is empty.
|
||||||
|
|
||||||
## The ADF inventory to cover
|
## The ADF inventory to cover
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user