diff --git a/MIGRATION.md b/MIGRATION.md index 7d4be34..2c7b5bc 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -8,7 +8,7 @@ Each call names the markdown it reads or writes: | --- | --- | | `adfToMarkdown` | `adfToLosslessMarkdown` | | `markdownToAdf`, for markdown `adfToMarkdown` wrote, edited since or not | `losslessMarkdownToAdf` | -| `markdownToAdf`, for markdown no `adfToMarkdown` output went into | `portableMarkdownToAdf`, which keeps GFM's pipe tables and `~~` and reads alerts, callouts, task markers and `==` as nodes ([Portable markdown](README.md#portable-markdown)); or `commonMarkToAdf`, which reads all of them, a directive and an `adf:` fence as CommonMark does, as text and code | +| `markdownToAdf`, for markdown no `adfToMarkdown` output went into | `portableMarkdownToAdf`, which reads GFM's pipe tables and `~~`, and reads alerts, callouts, task markers and `==` as nodes ([Portable markdown](README.md#portable-markdown)). Or `commonMarkToAdf`, which reads every one of those, and a directive and an `adf:` fence, as CommonMark does: as text and code | Directives moved under the `!adf:` prefix. `losslessMarkdownToAdf` reads `0.1.0`'s spelling without an error, turning each directive into text and each carried node into an `adf` code block. Before diff --git a/README.md b/README.md index f2bfd4b..2a50dc3 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,10 @@ products store as ADF. - **Lossless:** `adfToLosslessMarkdown` and `losslessMarkdownToAdf` give back the document they started from — panels, mentions, statuses and node types this version does not know included. -- **Markdown in:** `portableMarkdownToAdf` reads a bot's or a model's markdown, `~~` and pipe tables - whose every row opens with a pipe included; `commonMarkToAdf` reads markdown known to be strict - CommonMark as its spec says, nothing in it becoming a table, task or panel. Both apart from raw - HTML and the exceptions [The guarantees](#the-guarantees) lists. +- **Markdown in:** `portableMarkdownToAdf` reads a bot's or a model's markdown, including `~~` and + pipe tables whose every row opens with a pipe. `commonMarkToAdf` reads strict CommonMark as its + spec says: nothing becomes a table, task or panel. Both refuse raw HTML and the exceptions + [The guarantees](#the-guarantees) lists. - **Portable markdown, lossy:** `adfToPortableMarkdown` and `portableMarkdownToAdf` convert to and from the markdown that GitHub, GitLab and Obsidian render — GitHub Flavored Markdown's alerts, task lists and pipe tables, Obsidian Flavored Markdown's callouts and highlights. @@ -184,11 +184,13 @@ UTF-16 code unit, a JavaScript string index rather than a codepoint or a byte of or before the refusal — currently the start of the line the enclosing block begins on; a later minor may narrow that, never widen it. For `not-a-string` it is `{ line: 1, offset: 0 }`. -Parsing — `commonMarkToAdf` raises `not-a-string`, `unmappable-html` and `unmappable-image`; -`portableMarkdownToAdf` those and `malformed-pipe-table`; `losslessMarkdownToAdf` every row; and -`htmlToAdf`, at `0.3.0`, the rows its dialect reaches. Every reader also raises -`unsupported-nesting-depth`, and `losslessMarkdownToAdf` `unsupported-node-shape`, from the -"Either direction" table: +Parsing. Every reader also raises `unsupported-nesting-depth` from the "Either direction" table, +and: + +- `commonMarkToAdf`: `not-a-string`, `unmappable-html` and `unmappable-image`. +- `portableMarkdownToAdf`: those and `malformed-pipe-table`. +- `losslessMarkdownToAdf`: every row below, and `unsupported-node-shape`. +- `htmlToAdf`, at `0.3.0`: the rows its dialect reaches. | Code | Fires when | What you can do | | --- | --- | --- | @@ -228,15 +230,15 @@ Serves Goals 1, 4 and 5. - Markdown this library reads, and markdown it writes, means what the CommonMark spec says; from `0.3.0`, well-formed HTML means what the HTML standard says, read or written. The bullets below name every exception. -- CommonMark is valid input to every reader apart from the raw HTML `unmappable-html` names, with - one gap: a CommonMark image fits only as its own title-less paragraph; mid-text and titled images +- CommonMark is valid input to every reader, apart from the raw HTML `unmappable-html` names 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. - `commonMarkToAdf` reads it as its spec says. `losslessMarkdownToAdf` has four carve-outs — - literal text matching directive, pipe-table or strikethrough syntax, and a code fence whose info - string opens `adf:`, are claimed (each can be kept literal — `spec/flavour.md`) — and - `portableMarkdownToAdf` claims what [Portable markdown](#portable-markdown) lists. Converting a - read document back with `adfToLosslessMarkdown` yields the library's canonical spelling, which - round-trips byte-identically. +- `commonMarkToAdf` claims nothing else. `losslessMarkdownToAdf` claims four shapes: literal text + matching directive, pipe-table or strikethrough syntax, and a code fence whose info string opens + `adf:`. Each can be kept literal (`spec/flavour.md`). `portableMarkdownToAdf` claims what + [Portable markdown](#portable-markdown) lists. +- A document any reader built, written back with `adfToLosslessMarkdown`, takes the library's + canonical spelling, which round-trips byte-identically. - Four CommonMark spellings parse without an error and build a document the reference implementation renders differently: `[](/url)` and `[]()` stay literal text against CommonMark's empty link, a list continuing past a marker change stays one list against CommonMark's two, a @@ -249,7 +251,7 @@ Serves Goals 1, 4 and 5. levels, and the node shapes the `unsupported-node-shape` row lists. Show the refusal and keep the document read-only; saving markdown you could not produce is the loss the round-trip exists to stop. -- The pipe table `losslessMarkdownToAdf` and `portableMarkdownToAdf` read narrows GFM's twice: every +- The pipe table that `losslessMarkdownToAdf` and `portableMarkdownToAdf` read narrows GFM's twice: every row opens with a pipe, so GFM's bare form is an error result rather than the prose it reads as, and an alignment colon in the delimiter row is an error too — ADF holds no column alignment. The trailing pipe is canonical output, optional in input. diff --git a/docs/decisions.md b/docs/decisions.md index fbd9f94..a6bc805 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -181,7 +181,8 @@ opener nests by itself and leaf versus container falls out of the node's content CommonMark is a subset of the lossless flavour, with carve-outs (`spec/flavour.md`): literal text shaped like a directive, a pipe table or a `~~` pair is claimed, and so is a code fence whose info string opens `adf:` (§The carry fence names the node type) — plus one image gap, which `todo.md` -item 65 ends. `commonMarkToAdf` claims none of them (§Each call names its flavour). +item 65 ends. `commonMarkToAdf` claims none of the carve-outs; the image gap holds there too (§Each call names +its flavour). ## Tables @@ -556,8 +557,8 @@ suite's answers are HTML ADF cannot be compared against. Each example is a named error or markdown `commonMarkToAdf` reads to a document that `adfToLosslessMarkdown` writes and `losslessMarkdownToAdf` reads back deep-equal, since CommonMark -has no writer of its own; its reference HTML's text, tags stripped and entities decoded, equals the -parsed document's; and its elements count the marks and nodes they map to. The fixpoint alone +has no writer of its own. The example's reference HTML's text, tags stripped and entities decoded, +equals the parsed document's; and its elements count the marks and nodes they map to. The fixpoint alone passes a parser returning the empty document, the text alone one dropping every emphasis. An exception is the maintainer's to add, and valid CommonMark parsing to a document `adfToLosslessMarkdown` refuses is a bug to fix, never an exception. diff --git a/src/markdown/portable/conventions.ts b/src/markdown/portable/conventions.ts index 83e0a7e..971556d 100644 --- a/src/markdown/portable/conventions.ts +++ b/src/markdown/portable/conventions.ts @@ -15,7 +15,6 @@ export type Claims = { taskMarkers: boolean } -// The writer spells pipe tables and `~~` in every flavour it writes. type WrittenClaims = Claims & { pipeTables: true; strikethrough: true } // Directives exclude alerts and highlights: an expand directive leaves `inExpand` unset and a directive's slot reads `==`. diff --git a/todo.md b/todo.md index 0a12573..681f883 100644 --- a/todo.md +++ b/todo.md @@ -189,7 +189,7 @@ candidates are `@atlaskit/editor-markdown-transformer`, `adf-to-markdown`, `adf- Models write `|:---|` delimiter rows and tables without a leading pipe; both are `malformed-pipe-table` today, and `portableMarkdownToAdf` is the bot's reader. ADF holds no column alignment, so the portable reader drops it (Goal 7: form, never content). The lossless reader keeps -§Tables' narrowing. Found by the product-owner review of item 43, 2026-10-09. +§Tables' narrowing. ### 80. Name the node's path and the attribute key when `not-an-adf-document` refuses a node inside the document.