mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-12 19:58:28 +01:00
Keep both targets of a linked external image standing inline in adfToPortableMarkdown
This commit is contained in:
@@ -30,6 +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 `[](href)`, a captioned image as its directive
|
||||
- A linked image standing inline in portable markdown 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
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
schema requires: ``**`npm ci`**`` now reads as plain code, and a directive mark other than a link
|
||||
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.
|
||||
- `losslessMarkdownToAdf` names the CommonMark spelling to write when it refuses a directive whose
|
||||
node CommonMark spells, such as `[](href)` for a linked `!adf:mediaSingle`.
|
||||
- The README compares the package with seven other ADF converters, each checked against its
|
||||
|
||||
@@ -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 ``, or `[](href)` where a link marks it; inline `[alt](url)` | — |
|
||||
| external `media` | in a block ``, or `[](href)` where a link marks it; inline `[alt](url)`, or `[alt](href) ([image](url))` where a link marks it | — |
|
||||
| `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 | — |
|
||||
|
||||
@@ -283,6 +283,16 @@ each reader expected before seeing the options. A captioned image keeps the `!ad
|
||||
directive: each reader read `` 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))`
|
||||
|
||||
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.
|
||||
|
||||
Where `adfToPortableMarkdown` writes an external image inline, as in a table cell, a link marking it
|
||||
keeps its target and the image follows as a link reading `image`. Every reader first wrote
|
||||
`[](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
|
||||
|
||||
2026-08-23, the maintainer. Goal 1. Valid while ADF ids are minted per site.
|
||||
|
||||
@@ -4,6 +4,7 @@ import test from 'node:test'
|
||||
import type { AdfAttributes, AdfDocument, AdfMark, AdfNode } from '../../adf/document.ts'
|
||||
import { adfToPortableMarkdown, reduceToPortable } from './adf-to-portable-markdown.ts'
|
||||
import { largestNesting } from '../../nesting.ts'
|
||||
import { portableMarkdownToAdf } from '../parse/markdown-to-adf.ts'
|
||||
|
||||
const code: AdfMark = { type: 'code' }
|
||||
const em: AdfMark = { type: 'em' }
|
||||
@@ -239,6 +240,17 @@ test('keeps the target of a link marking an external image', () => {
|
||||
assert.equal(portable(linked('')), '[](<> "Docs")\n')
|
||||
})
|
||||
|
||||
test('keeps both targets of a linked external image standing inline, the image last as a link reading image', () => {
|
||||
const linked = (href: string, alt?: string): AdfNode => ({ attrs: { ...(alt === undefined ? {} : { alt }), type: 'external', url: 'https://example.com/moon.png' }, marks: [{ attrs: { href, title: 'Docs' }, type: 'link' }], type: 'media' })
|
||||
const table = (...content: AdfNode[]): AdfNode => node('table', {}, row(cell('tableHeader', said('h'))), row(cell('tableCell', ...content)))
|
||||
const inCell = portable(table(node('mediaSingle', {}, linked('https://example.com/docs', 'Moon'))))
|
||||
assert.equal(inCell, '| h |\n| --- |\n| [Moon](https://example.com/docs "Docs") ([image](https://example.com/moon.png)) |\n')
|
||||
const read = portableMarkdownToAdf(inCell)
|
||||
assert.equal(read.ok && portableDocument(read.value), inCell)
|
||||
assert.equal(portable(table(said('See'), node('mediaSingle', {}, linked('https://example.com/docs')))), '| h |\n| --- |\n| See [https://example.com/moon.png](https://example.com/docs "Docs") ([image](https://example.com/moon.png)) |\n')
|
||||
assert.equal(portable(paragraph(text('See '), linked('https://example.com/moon.png', 'Moon'))), 'See [Moon](https://example.com/moon.png "Docs")\n')
|
||||
})
|
||||
|
||||
test('keeps an external image wherever it stands and spells a stored file as its alt text, else a note', () => {
|
||||
const media = (attrs: AdfAttributes): AdfNode => ({ attrs, type: 'media' })
|
||||
const caption: AdfNode = node('caption', {}, text('The moon.'))
|
||||
|
||||
@@ -85,7 +85,10 @@ function mediaLeaves(attrs: Readonly<AdfAttributes>, marks: readonly AdfMark[],
|
||||
const alt = nonEmpty(attrs['alt'])
|
||||
const url = nonEmpty(attrs['url'])
|
||||
if (attrs['type'] !== 'external' || url === undefined) return textLeaves(alt, marks, container, 'image')
|
||||
return linkedLeaves(alt ?? url, url, marks, container)
|
||||
const href = nodeAttrs(marks.find((mark) => mark.type === 'link') ?? {})['href']
|
||||
if (href === url) return textLeaves(alt ?? url, marks, container)
|
||||
if (typeof href !== 'string') return linkedLeaves(alt ?? url, url, marks, container)
|
||||
return [...textLeaves(alt ?? url, marks, container), textLeaf(' (', []), ...linkedLeaves('image', url, marks, container), textLeaf(')', [])]
|
||||
}
|
||||
|
||||
function noteLeaves(name: string): AdfNode[] {
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
| ID | Release | Exempt | Item | R | S | C | A | G | Goals | Score |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| 73 | 0.3.0 | | **Announce the package where someone needing an ADF converter already reads: JRACLOUD-77436, the Atlassian developer community and Stack Overflow's ADF-to-markdown questions.** | 1 | 2 | 1 | 6 | 8 | 3 | 23.0 |
|
||||
| 99 | 0.3.0 | defect | **Write a linked external image standing inline or in a table cell in the spelling a reader panel picks, in `adfToPortableMarkdown`.** | 3 | 3 | 5 | 6 | 7 | 7 | 12.9 |
|
||||
| 115 | 0.3.0 | defect | **Build text holding no `border` mark in `losslessMarkdownToAdf`, and have `adfToLosslessMarkdown` carry text holding one.** | 3 | 3 | 3 | 4 | 6 | 4 | 12.3 |
|
||||
| 91 | 0.3.0 | | **Spell an emphasis once across the code spans, an emphasis or link once across the hard breaks, dates, emoji, inline cards, mentions and statuses between two nodes it marks, and an emphasis across inline media, in both writers.** | 5 | 5 | 8 | 6 | 6 | 6 | 11.0 |
|
||||
| 100 | 0.3.0 | decision | **Put the reading of an image's title as its caption back to a reader panel, now that a writer panel reads a title as hover text.** | 3 | 3 | 3 | 4 | 5 | 4, 6 | 10.9 |
|
||||
@@ -77,14 +76,6 @@ posting, set `converter-comparison/run.sh`'s pins to each package's latest versi
|
||||
its versions and its date in step with the output. We draft each post for the place it goes; the
|
||||
maintainer posts them once `0.3.0` is published. Found while planning discoverability, 2026-10-04.
|
||||
|
||||
### 99. Write a linked external image standing inline or in a table cell in the spelling a reader panel picks, in `adfToPortableMarkdown`.
|
||||
|
||||
`mediaLeaves` (`src/markdown/portable/inline-reduction.ts`) writes such an image `[alt](url)`, dropping
|
||||
the link's `href`; README §Portable markdown says link targets stay (Goal 7). `[](href)`
|
||||
there reads back as `[alt](href)`, breaking the byte-for-byte rewrite, so only one of `url` and
|
||||
`href` can survive; a reader panel picks which. If it picks `url`, the README names the dropped
|
||||
`href` where it says link targets stay.
|
||||
|
||||
### 115. Build text holding no `border` mark in `losslessMarkdownToAdf`, and have `adfToLosslessMarkdown` carry text holding one.
|
||||
|
||||
`!adf:border[x]{color="#091e42" size=2}` builds text holding `border`, which
|
||||
|
||||
Reference in New Issue
Block a user