From e680927e372fc93c657c59905d948ca99b0d46bc Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Wed, 14 Oct 2026 22:31:24 +0200 Subject: [PATCH] =?UTF-8?q?Answer=20prose=20round=201:=200=20=F0=9F=94=B4,?= =?UTF-8?q?=203=20=F0=9F=9F=A1;=20disambiguate=20the=20README=20fallback,?= =?UTF-8?q?=20reword=20item=20117's=20citation=20and=20item=20118's=20tagl?= =?UTF-8?q?ine,=20record=20the=20writer=20panel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 2 +- CHANGELOG.md | 2 +- README.md | 2 +- docs/decisions.md | 18 ++++++++++-------- src/markdown/portable/inline-reduction.ts | 2 +- todo.md | 10 +++++----- 6 files changed, 19 insertions(+), 17 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7f61130..75c6227 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,7 +30,7 @@ In `docs/decisions.md`: - An image reads as an image only alone in its paragraph, else as its alt text linked; a link text of hard breaks alone reads as its destination, then the breaks - A mark skips a node that cannot hold it, and a directive mark wrapping only such nodes is refused, as is a `[text](url)` link unless its text is hard breaks alone - A linked image is written `[![alt](url)](href)`, a captioned image as its directive -- A linked image standing inline in portable markdown is written `[alt](href) ([image](url))` +- A linked image standing inline in portable markdown, its link to another target, is written `[alt](href) ([image](url))` - Ids stay site-local - Portable task ids come from position - A block a task item cannot hold stands after its task list diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fa5eb9..b981785 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ around only code spans is `unsupported-node-shape`. `adfToLosslessMarkdown` writes code text holding another mark as `!adf:carry{json="…"}`, and `adfToPortableMarkdown` drops that mark. - `adfToPortableMarkdown` keeps both targets of a linked external image standing inline, as in a - table cell: `[alt](href) ([image](url))`, where it wrote `[alt](url)` and dropped the link. + table cell: `[alt](href) ([image](url))`, where it wrote `[alt](url)` and dropped the link's target. - `losslessMarkdownToAdf` names the CommonMark spelling to write when it refuses a directive whose node CommonMark spells, such as `[![alt](url)](href)` for a linked `!adf:mediaSingle`. - The README compares the package with seven other ADF converters, each checked against its diff --git a/README.md b/README.md index 8fed5e3..aaac336 100644 --- a/README.md +++ b/README.md @@ -374,7 +374,7 @@ saving what this pair read replaces mentions, attachments and macros with text. | `backgroundColor` | `==text==` | `==text==` on one line, the text touching both delimiters, bounded outside by whitespace, punctuation or a line edge, or touching a Han, Hangul, Hiragana, Katakana, Thai, Lao, Khmer or Myanmar character on either side, in the editor's default highlight `#f8e6a0` | | `decisionList` | a bullet list | — | | `expand`, `nestedExpand` | Obsidian's folded callout, `> [!NOTE]- Title` | `-` or `+` after any word, the rest of the marker's line the title; a link reads `text (target)`, or its text alone where the text is the target with or without `mailto:`; an expand inside an expand is a `nestedExpand` | -| external `media` | in a block `![alt](url)`, or `[![alt](url)](href)` where a link marks it; inline `[alt](url)`, or `[alt](href) ([image](url))` where a link to another target marks it, the link text `href` where `alt` is empty, or `url` where both are | — | +| external `media` | in a block `![alt](url)`, or `[![alt](url)](href)` where a link marks it; inline `[alt](url)`, or `[alt](href) ([image](url))` where a link to another target marks it; an empty `alt` gives way to `href`, then `url` | — | | `inlineCard`, `blockCard`, `embedCard` | a link to the card's URL, else its name | — | | `layoutSection`, `bodiedExtension`, `bodiedSyncBlock`, `multiBodiedExtension`, `extensionFrame`, `caption`, a node this version does not know | its blocks or its text | — | | `mention`, `status`, `emoji`, `date` | their text: `@` kept, a mention with none `@` and its id, an emoji its `shortName` without, a date `2026-09-13` in UTC | — | diff --git a/docs/decisions.md b/docs/decisions.md index 443395f..d406671 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -283,16 +283,18 @@ each reader expected before seeing the options. A captioned image keeps the `!ad directive: each reader read `![alt](url "title")` as hover text, not a caption. Every reader still reads that title as the caption; `todo.md` item 100 puts that reading back to a reader panel. -## A linked image standing inline in portable markdown is written `[alt](href) ([image](url))` +## A linked image standing inline in portable markdown, its link to another target, is written `[alt](href) ([image](url))` -2026-10-14, a reader panel of the export tool, the LLM pipeline and a support agent, 3 of 3. Goals 6 -and 7. Valid while the portable reader reads an image inside a link as the link's text. +2026-10-14, a reader panel of the export tool, the LLM pipeline and a support agent, and a writer +panel of a product manager, an engineer and that support agent, 3 of 3 each. Goals 6 and 7. Valid +while the portable reader reads an image inside a link as its alt text, linked. Where `adfToPortableMarkdown` writes an external image inline, as in a table cell, and a link to another target marks it, the link keeps its target and the image follows as a link reading `image`. -With no alt text, the link text is the link's target, as `[](href)` reads. Every reader first wrote -`[![alt](url)](href)`, which reads back as `[alt](href)` and so breaks the byte-for-byte rewrite. -Each then picked this over `[alt](url)` and `[alt](href)`, which drop a target. +With no alt text, the link text is the link's target, which is how the reader reads `[](href)`, so +the rewrite holds. Every seat first wrote `[![alt](url)](href)`, which reads back as `[alt](href)` +and so breaks the byte-for-byte rewrite. Each then picked this over `[alt](url)` and `[alt](href)`, +which drop a target. ## Ids stay site-local @@ -354,8 +356,8 @@ past `[x]`/`[ ]`, and lifting bare URLs, `@name`, `:shortcode:` or ISO dates int ## The portable reader refuses what GFM's reading would drop 2026-10-14, the maintainer. Goals 4 and 7. Valid while a refusal is a result and the caller can -fix the markdown it sent, and until `todo.md` item 117 settles whether Goal 4, which ranks above -Goal 7, reads such a row instead. +fix the markdown it sent. `todo.md` item 117 settles whether Goal 4, which outranks Goal 7, has +`portableMarkdownToAdf` read a row wider than its header as GFM does. Where GFM's reading of a shape drops content, `portableMarkdownToAdf` refuses the shape. A pipe table row holding more cells than its header is `malformed-pipe-table`, where GFM cuts the extra diff --git a/src/markdown/portable/inline-reduction.ts b/src/markdown/portable/inline-reduction.ts index 0638c09..f796adc 100644 --- a/src/markdown/portable/inline-reduction.ts +++ b/src/markdown/portable/inline-reduction.ts @@ -80,7 +80,7 @@ function idMention(id: unknown): string | undefined { return typeof id === 'string' && id !== '' ? `@${id}` : undefined } -// An image standing inline is a link to it: CommonMark's inline image reads back as no node, and one inside a link as the link's text. +// An image standing inline is a link to it: CommonMark's inline image reads back as no node, and one inside a link as its alt text, linked. function mediaLeaves(attrs: Readonly, marks: readonly AdfMark[], container: LineContainer): AdfNode[] { const alt = nonEmpty(attrs['alt']) const url = nonEmpty(attrs['url']) diff --git a/todo.md b/todo.md index fadfd54..ee648d5 100644 --- a/todo.md +++ b/todo.md @@ -62,7 +62,7 @@ | 56 | 0.5.0 | principle | **Give each piece of `blocks.ts`'s block-walk state and `inline-content.ts`'s `Scan` one owner that returns what it changes.** | 4 | 5 | 8 | 2 | 4 | 1 | 6.8 | | 76 | 0.5.0 | principle | **State the files the package does not ship once, so the build, the lint ceiling and the coverage exclusions cannot drift apart.** | 2 | 2 | 3 | 1 | 3 | 1 | 5.5 | | 82 | 0.5.0 | principle | **Give the directive tests and fixtures random UUID v7 ids in place of `a-1`, `a`, `x` and `h`.** | 1 | 3 | 1 | 1 | 2 | 1 | 4.2 | -| 118 | 0.5.0 | principle | **Spell a portable link's title through `oneLine`, as the text beside it is.** | 1 | 1 | 1 | 1 | 2 | 6 | 2.5 | +| 118 | 0.5.0 | principle | **Spell a portable link's title through `oneLine`.** | 1 | 1 | 1 | 1 | 2 | 6 | 2.5 | | 57 | 0.5.0 | principle | **Make each `ci.sh` leg build what it reads, so one leg run alone tests the current tree.** | 2 | 3 | 3 | 1 | 3 | 8 | 0.6 | | 58 | 0.5.0 | principle | **Port `ci.sh`, `publish.sh` and `docker-runner.sh` to standalone Python scripts.** | 4 | 6 | 4 | 1 | 2 | 8 | -2.6 | | 8 | 0.6.0 | | **Ship a CLI.** | 3 | 7 | 5 | 7 | 6 | 3 | 18.6 | @@ -275,9 +275,9 @@ unminified: tarball 60.4 kB, unpacked 221.5 kB, JS gzipped 45.6 kB. ### 117. Read a GFM pipe-table row holding more cells than its header as GFM does, or name the goal that outranks Goal 4 in refusing it. -`docs/decisions.md` §The portable reader refuses what GFM's reading would drop refuses such a row as -`malformed-pipe-table` by Goal 7, which ranks below Goal 4: a bot whose model writes an over-wide row -gets an error where GitHub renders a table. The maintainer either reads the row as GFM does, cutting +`portableMarkdownToAdf` refuses such a row as `malformed-pipe-table` by Goal 7 (`docs/decisions.md` +§The portable reader refuses what GFM's reading would drop). Goal 4 ranks above Goal 7, and by it a +bot whose model writes an over-wide row gets an error where GitHub renders a table. The maintainer either reads the row as GFM does, cutting the cells, or states the goal that outranks Goal 4 here and cites it in the entry. Found by the principles audit of item 99, 2026-10-14. @@ -379,7 +379,7 @@ agree. Found by the technical-principles audit, 2026-10-04. Technical principle: tests use random UUID v7 ids; `portable-markdown-to-adf.test.ts` already does. Found by the technical-principles audit of item 78, 2026-10-05. -### 118. Spell a portable link's title through `oneLine`, as the text beside it is. +### 118. Spell a portable link's title through `oneLine`. `portableLink` (`src/markdown/portable/inline-reduction.ts`) repeats `oneLine`'s replacements by hand, so a change to what a portable line drops would miss link titles. Technical principle: DRY.