3
0
mirror of https://github.com/larvit/adf-codec.git synced 2026-11-12 19:58:28 +01:00

Answer prose round 1: the parsing codes list each reader, the CommonMark guarantee splits into three bullets, the migration row and two decisions read once

This commit is contained in:
2026-10-09 02:53:55 +02:00
parent e3919c3165
commit 5fc877e28e
5 changed files with 26 additions and 24 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ Each call names the markdown it reads or writes:
| --- | --- | | --- | --- |
| `adfToMarkdown` | `adfToLosslessMarkdown` | | `adfToMarkdown` | `adfToLosslessMarkdown` |
| `markdownToAdf`, for markdown `adfToMarkdown` wrote, edited since or not | `losslessMarkdownToAdf` | | `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 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 an error, turning each directive into text and each carried node into an `adf` code block. Before
+20 -18
View File
@@ -10,10 +10,10 @@ products store as ADF.
- **Lossless:** `adfToLosslessMarkdown` and `losslessMarkdownToAdf` give back the document they - **Lossless:** `adfToLosslessMarkdown` and `losslessMarkdownToAdf` give back the document they
started from — panels, mentions, statuses and node types this version does not know included. 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 - **Markdown in:** `portableMarkdownToAdf` reads a bot's or a model's markdown, including `~~` and
whose every row opens with a pipe included; `commonMarkToAdf` reads markdown known to be strict pipe tables whose every row opens with a pipe. `commonMarkToAdf` reads strict CommonMark as its
CommonMark as its spec says, nothing in it becoming a table, task or panel. Both apart from raw spec says: nothing becomes a table, task or panel. Both refuse raw HTML and the exceptions
HTML and the exceptions [The guarantees](#the-guarantees) lists. [The guarantees](#the-guarantees) lists.
- **Portable markdown, lossy:** `adfToPortableMarkdown` and `portableMarkdownToAdf` convert to and - **Portable markdown, lossy:** `adfToPortableMarkdown` and `portableMarkdownToAdf` convert to and
from the markdown that GitHub, GitLab and Obsidian render — GitHub Flavored Markdown's alerts, 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. 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 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 }`. 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`; Parsing. Every reader also raises `unsupported-nesting-depth` from the "Either direction" table,
`portableMarkdownToAdf` those and `malformed-pipe-table`; `losslessMarkdownToAdf` every row; and 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 - `commonMarkToAdf`: `not-a-string`, `unmappable-html` and `unmappable-image`.
"Either direction" table: - `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 | | 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 - 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 `0.3.0`, well-formed HTML means what the HTML standard says, read or written. The bullets below
name every exception. name every exception.
- CommonMark is valid input to every reader apart from the raw HTML `unmappable-html` names, with - 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 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. 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 — - `commonMarkToAdf` claims nothing else. `losslessMarkdownToAdf` claims four shapes: literal text
literal text matching directive, pipe-table or strikethrough syntax, and a code fence whose info matching directive, pipe-table or strikethrough syntax, and a code fence whose info string opens
string opens `adf:`, are claimed (each can be kept literal — `spec/flavour.md`) — and `adf:`. Each can be kept literal (`spec/flavour.md`). `portableMarkdownToAdf` claims what
`portableMarkdownToAdf` claims what [Portable markdown](#portable-markdown) lists. Converting a [Portable markdown](#portable-markdown) lists.
read document back with `adfToLosslessMarkdown` yields the library's canonical spelling, which - A document any reader built, written back with `adfToLosslessMarkdown`, takes the library's
round-trips byte-identically. canonical spelling, which round-trips byte-identically.
- Four CommonMark spellings parse without an error and build a document the reference - Four CommonMark spellings parse without an error and build a document the reference
implementation renders differently: `[](/url)` and `[]()` stay literal text against CommonMark's 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 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 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 document read-only; saving markdown you could not produce is the loss the round-trip exists to
stop. 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, 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 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. trailing pipe is canonical output, optional in input.
+4 -3
View File
@@ -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 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 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` 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 ## 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 Each example is a named error or markdown `commonMarkToAdf` reads to a document that
`adfToLosslessMarkdown` writes and `losslessMarkdownToAdf` reads back deep-equal, since CommonMark `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 has no writer of its own. The example's reference HTML's text, tags stripped and entities decoded,
parsed document's; and its elements count the marks and nodes they map to. The fixpoint alone 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 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 exception is the maintainer's to add, and valid CommonMark parsing to a document
`adfToLosslessMarkdown` refuses is a bug to fix, never an exception. `adfToLosslessMarkdown` refuses is a bug to fix, never an exception.
-1
View File
@@ -15,7 +15,6 @@ export type Claims = {
taskMarkers: boolean taskMarkers: boolean
} }
// The writer spells pipe tables and `~~` in every flavour it writes.
type WrittenClaims = Claims & { pipeTables: true; strikethrough: true } type WrittenClaims = Claims & { pipeTables: true; strikethrough: true }
// Directives exclude alerts and highlights: an expand directive leaves `inExpand` unset and a directive's slot reads `==`. // Directives exclude alerts and highlights: an expand directive leaves `inExpand` unset and a directive's slot reads `==`.
+1 -1
View File
@@ -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 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 `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 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. ### 80. Name the node's path and the attribute key when `not-an-adf-document` refuses a node inside the document.