3
0
mirror of https://github.com/larvit/adf-codec.git synced 2026-11-13 04:08:29 +01:00

Answer architecture round 5: 0 🔴, 0 🟡 (0 misread); shownImage returns no textless state, item 143 and the card rule name their whole reach

This commit is contained in:
2026-10-26 12:58:17 +01:00
parent 93a912db81
commit 9b43cb4fe9
6 changed files with 23 additions and 19 deletions
+7 -5
View File
@@ -432,13 +432,15 @@ the shown code keeps the class its code block's own element takes.
Inside a carry element, an image marked by a link to another target shows as portable markdown
writes it inline (§A linked image standing inline in portable markdown, its link to another target,
is written `[alt](href) ([image](url))`), so both targets stay; Goal 7 counts them as content. A link
marking a node that shows a note goes around the note. Recorded 2026-10-24 without a panel of its
own: it joins the second panel's `<a>` to that portable spelling.
marking a node that shows a note goes around the note, and an image's own `text`, outside Atlassian's
schema, shows first, as every carried node's does. Recorded 2026-10-24 without a panel of its own:
it joins the second panel's `<a>` to that portable spelling.
Inside a carry element, a card a link marks links to the link's target, and shows its own URL as its
text where it has one, so both stay. A card showing only its name keeps its URL in `data-adf` alone,
until `todo.md` item 133 writes inline cards as their own elements, in 0.3.0. Recorded 2026-10-24
without a panel of its own: it puts the second panel's `<a>` around the text a card shows.
text where it has one, so both stay. A card showing only its name keeps its URL in `data-adf` alone.
Atlassian's schema gives no card a link mark, so only a hand-built document meets this;
`todo.md` item 133 ends it for inline cards, in 0.3.0. Recorded 2026-10-24 without a panel of its
own: it puts the second panel's `<a>` around the text a card shows.
## No runtime dependencies
+2 -2
View File
@@ -48,9 +48,9 @@ test('shows an image a link to another target marks by its alt, else the target,
assert.deepEqual(shownImage({ attrs: { type: 'external', url: moon }, type: 'media' }, ' '), { after: moon, link: undefined, text: moon })
})
test('shows an image with no URL by its alt, else by no text, a note standing in its place', () => {
test('shows an image with no URL by its alt, else nothing, a note standing in its place', () => {
assert.deepEqual(shownImage({ attrs: { alt: 'The moon', type: 'file' }, type: 'media' }, target), { after: undefined, link: undefined, text: 'The moon' })
assert.deepEqual(shownImage({ attrs: { type: 'file' }, type: 'mediaInline' }, undefined), { after: undefined, link: undefined, text: undefined })
assert.equal(shownImage({ attrs: { type: 'file' }, type: 'mediaInline' }, undefined), undefined)
assert.deepEqual(shownImage({ attrs: { alt: 'The moon', type: 'external', url: ' ' }, type: 'media' }, undefined), { after: undefined, link: undefined, text: 'The moon' })
})
+3 -3
View File
@@ -39,11 +39,11 @@ export function referenceName(node: AdfNode): string | undefined {
}
}
// What an image shows in place of itself, `href` the target of the link marking it, if any: `text`, else a note; `link`, its URL, which `text` links to where no link marks it; `after`, its URL, shown after a link going elsewhere.
export function shownImage(media: AdfNode, href: string | undefined): { after: string | undefined; link: string | undefined; text: string | undefined } {
// What an image shows in place of itself, `href` the target of the link marking it, if any: `text`; `link`, its URL, which `text` links to where no link marks it; `after`, its URL, shown after a link going elsewhere. `undefined` where it shows no text, so a note stands in its place.
export function shownImage(media: AdfNode, href: string | undefined): { after: string | undefined; link: string | undefined; text: string } | undefined {
const alt = visibleText(nodeAttrs(media)['alt'])
const url = shownUrl(media)
if (url === undefined) return { after: undefined, link: undefined, text: alt }
if (url === undefined) return alt === undefined ? undefined : { after: undefined, link: undefined, text: alt }
if (href === undefined) return { after: undefined, link: url, text: alt ?? url }
if (href === url) return { after: undefined, link: undefined, text: alt ?? url }
return { after: url, link: undefined, text: alt ?? visibleText(href) ?? url }
+4 -4
View File
@@ -55,11 +55,11 @@ function shownPiece(node: AdfNode, lineFeed: string): string {
return linkedText(node, shownText(node), shownUrl(node), lineFeed)
}
// As portable markdown writes it inline, except that a link around a note stays (docs/decisions.md §The HTML dialect).
// As portable markdown writes it inline, except that a link around a note stays and an image's own `text`, outside ADF's schema, shows first (docs/decisions.md §The HTML dialect).
function linkedImage(media: AdfNode, lineFeed: string): string {
const { after, link, text } = shownImage(media, shownLink(media)?.href)
const shown = linkedText(media, text, link, lineFeed)
return after === undefined ? shown : `${shown} (${linked('image', { href: after })})`
const image = shownImage(media, shownLink(media)?.href)
const shown = linkedText(media, image?.text, image?.link, lineFeed)
return image?.after === undefined ? shown : `${shown} (${linked('image', { href: image.after })})`
}
function linkedText(node: AdfNode, standIn: string | undefined, url: string | undefined, lineFeed: string): string {
+5 -3
View File
@@ -59,14 +59,16 @@ function cardLeaves(card: AdfNode, marks: readonly AdfMark[], container: LineCon
return linkedLeaves(shownText(card) ?? href, href, marks, container)
}
function linkedLeaves(text: string | undefined, href: string, marks: readonly AdfMark[], container: LineContainer): AdfNode[] {
function linkedLeaves(text: string, href: string, marks: readonly AdfMark[], container: LineContainer): AdfNode[] {
return textLeaves(text, [...marks.filter((mark) => mark.type !== 'link'), { attrs: { href }, type: 'link' }], container)
}
// An image standing inline is a link to it: the reader builds no node for an inline image, reading it as its alt text linked, and inside a link as the link's text, then (image).
function mediaLeaves(media: AdfNode, marks: readonly AdfMark[], container: LineContainer): AdfNode[] {
const { after, link, text } = shownImage(media, shownLink(media)?.href)
const shown = link === undefined ? textLeaves(text, marks, container, referenceName(media)) : linkedLeaves(text, link, marks, container)
const image = shownImage(media, shownLink(media)?.href)
if (image === undefined) return textLeaves(undefined, marks, container, referenceName(media))
const { after, link, text } = image
const shown = link === undefined ? textLeaves(text, marks, container) : linkedLeaves(text, link, marks, container)
return after === undefined ? shown : [...shown, ...imageAside((word) => linkedLeaves(word, after, marks, container))]
}
+2 -2
View File
@@ -29,7 +29,7 @@
| 68 | 0.4.0 | | defect | **Carry a non-text inline node holding `content` or `text`, a block holding `text`, and a leaf block holding `content`.** | 2 | 1 | 2 | 3 | 3 | 1 by 2 | 13.1 |
| 127 | 0.4.0 | | principle | **Hold what `entity-references.test.ts`, `json-text.test.ts` and `result.test.ts` check by asserting outcomes, so none reads source text.** | 2 | 2 | 1 | 3 | 3 | code health by 2 | 13.1 |
| 144 | 0.4.0 | | | **Give every container `docker-runner.sh` and `publish.sh` start a memory limit and an equal swap limit, sized from the largest a gate leg measurably needs.** | 1 | 1 | 1 | 1 | 2 | code health by 1 | 8.7 |
| 143 | 0.4.0 | | defect | **Keep the link around a note in `adfToPortableMarkdown`, so a linked stored image with no alt writes its note linked.** | 2 | 1 | 2 | 3 | 3 | 7 by 1 | 6.5 |
| 143 | 0.4.0 | | defect | **Keep, in `adfToPortableMarkdown`, the link around a note and the target of a link marking a card, so a linked stored image or card writes every target.** | 2 | 1 | 2 | 3 | 3 | 7 by 1 | 6.5 |
| 112 | 0.4.0 | | | **Pad a GFM pipe table's short rows with empty cells, read its body rows holding no pipe, and read a one-column table without leading pipes in `portableMarkdownToAdf`.** | 2 | 1 | 2 | 3 | 3 | 4 by 4 | 6.2 |
| 80 | 0.4.0 | | | **Name the node's path and the attribute key when `not-an-adf-document` refuses a node inside the document.** | 2 | 1 | 2 | 3 | 3 | 6 by 4 | 6.0 |
| 81 | 0.4.0 | | | **Fail the gate unless the README's error tables list exactly the codes `ConvertErrorCode` holds.** | 1 | 1 | 1 | 1 | 2 | 3 by 2 | 4.2 |
@@ -221,7 +221,7 @@ item 60, 2026-10-22.
strings near V8's longest, about 512 MB each, so measure each leg's peak before picking the limit:
one too small fails the gate.
### 143. Keep the link around a note in `adfToPortableMarkdown`, so a linked stored image with no alt writes its note linked.
### 143. Keep, in `adfToPortableMarkdown`, the link around a note and the target of a link marking a card, so a linked stored image or card writes every target.
`noteLeaves` (`src/markdown/portable/inline-reduction.ts`) drops the node's marks, so a stored
image a link marks writes `_(image not included)_` without the link's target, which Goal 7 counts as