diff --git a/MIGRATION.md b/MIGRATION.md new file mode 100644 index 0000000..077eab4 --- /dev/null +++ b/MIGRATION.md @@ -0,0 +1,46 @@ +# Migrating + +## From `0.1.0` to `0.2.0` + +Directives moved under the `!adf:` prefix. `0.2.0` reads markdown `0.1.0` wrote without an error +and turns every directive in it into plain text, so convert stored markdown before `0.2.0` reads +it. Stored ADF needs no change. + +### Convert stored markdown + +Read it with `0.1.0` and write it with `0.2.0`, installed side by side: + +```sh +npm install @larvit/adf-codec@0.2.0 adf-codec-0.1@npm:@larvit/adf-codec@0.1.0 +``` + +```ts +import { adfToMarkdown } from '@larvit/adf-codec' +import { markdownToAdf as markdownToAdf010 } from 'adf-codec-0.1' + +function migrateMarkdown(stored: string) { + const parsed = markdownToAdf010(stored) + return parsed.ok ? adfToMarkdown(parsed.value) : parsed +} +``` + +### Spellings + +| `0.1.0` | `0.2.0` | +| --- | --- | +| `:::panel info` … `:::`, the fence longer per nesting level | `!adf:panel info` … `!adf:/panel` at any depth | +| `::media {id=a type=file}` | `!adf:media {id=a type=file}` | +| `::paragraph`, the empty paragraph | `!adf:paragraph` then `!adf:/paragraph` | +| `:mention[@Mikael]{id=5b10a2}` | `!adf:mention[@Mikael]{id=5b10a2}` | +| the `adf` code fence and `:adf{json="…"}` | the `carry` code fence and `!adf:carry{json="…"}` | +| `\:` keeps a directive literal | `\!adf:` keeps a directive literal | + +A colon run and `:name[` are plain text now, and `adf` is an ordinary code block language. + +### Error codes + +| Input | `0.1.0` | `0.2.0` | +| --- | --- | --- | +| a leaf node given a body, `listBreak` included: `:::media {…}` … `:::`, `!adf:media {…}` … `!adf:/media` | `unsupported-node-shape` | `malformed-directive` | +| a container node with no closer: `::panel info`, `!adf:panel info` | `unsupported-node-shape` | `malformed-directive` | +| an empty paragraph with a closer: `:::paragraph` … `:::`, `!adf:paragraph` … `!adf:/paragraph` | `unsupported-node-shape` | parses | diff --git a/README.md b/README.md index 2507a25..bbb5105 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ an HTML dialect. **Status: published — the markdown round-trip (`adfToMarkdown`, `markdownToAdf`); HTML at `0.3.0`.** Plan: `todo.md`. Decisions: `AGENTS.md`. The flavour's grammar: -[`spec/flavour.md`](spec/flavour.md). +[`spec/flavour.md`](spec/flavour.md). Upgrading from `0.1.0`: [`MIGRATION.md`](MIGRATION.md). ## What it is for @@ -27,7 +27,7 @@ npm install @larvit/adf-codec ```ts import { markdownToAdf } from '@larvit/adf-codec' -const result = markdownToAdf('# Release notes\n\n:::panel info\nShipped on Tuesday.\n:::\n') +const result = markdownToAdf('# Release notes\n\n!adf:panel info\nShipped on Tuesday.\n!adf:/panel\n') if (result.ok) { send(result.value) } else { @@ -78,9 +78,9 @@ Parsing — `markdownToAdf`, and `htmlToAdf` at `0.3.0`: | Code | Fires when | What you can do | | --- | --- | --- | -| `malformed-directive` | a `:::` block or `:name[…]` inline directive the grammar cannot read — an unclosed fence or `[content]`, `{attrs}` out of order or duplicated, invalid JSON in an `adf` carry | write the spelling the message names, or escape the line — `\:::` for a block, `\:` for an inline one — to keep it literal text | +| `malformed-directive` | an `!adf:` the grammar cannot read — a prefix completing no directive, an unclosed container or `[content]`, 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 colon; the spelling itself is well formed, so a later minor may give the name meaning | +| `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.3.0` | | `unmappable-image` | an image sits inside other content, or carries a title | give the image a paragraph of its own and drop the title | diff --git a/todo.md b/todo.md index 32c4e7f..705aad5 100644 --- a/todo.md +++ b/todo.md @@ -275,12 +275,13 @@ proves 12, 13 spells 11's gaps in 12's grammar, and 12 rewrites code 4b and 4c c - [ ] **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. A round-trip fixture holds the - shape 4.2's review left refused until then: an autolink-shaped link under a directive mark - whose href holds `\:name{`. A link opening a paragraph whose opening reads as a link - reference definition, which 4.3 leaves riding the carry, takes the directive link too, with - its round-trip fixture (the maintainer, 2026-09-15). + exceptions it cures re-derived, the README's code table and its "not every document + converts back" guarantee following, and `MIGRATION.md` naming the removed code; the gap + list is empty. A round-trip fixture holds the shape 4.2's review left refused until then: + an autolink-shaped link under a directive mark whose href holds `\!adf:name{`. A link + opening a paragraph whose opening reads as a link reference definition, which 4.3 leaves + riding the carry, takes the directive link too, with its round-trip fixture (the + maintainer, 2026-09-15). - [ ] **14 — The CommonMark subset's directory (`0.2.0`).** `src/markdown/` holds 16 source files at its root and 10 adds more there. The CommonMark subset moves under `src/markdown/commonmark/` — `backtick-runs.ts`, `commonmark-grammar.ts` as `grammar.ts`,