mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-13 04:08:29 +01:00
Answer architecture round 4: 0 🔴, 1 🟡 (0 misread); one image rule in shown-text for both writers, a link mark's href kept past a bad title, the card rule recorded
This commit is contained in:
@@ -149,11 +149,12 @@ test('shows a carried node\'s content after a block it holds as a paragraph of i
|
||||
assert.equal(shown(html(adfToHtml(document({ content: [paragraph(text('a')), text('b')], type: 'panel' })))), '<p>a</p><p>b</p>')
|
||||
})
|
||||
|
||||
test('shows text a link marks in a carried node as a link', () => {
|
||||
test('shows text a link marks in a carried node as a link, leaving out a title that is no string', () => {
|
||||
const link: AdfMark = { attrs: { href: 'https://spec.commonmark.org/', title: 'The spec' }, type: 'link' }
|
||||
const panel: AdfNode = { content: [paragraph(text('Read the '), text('CommonMark spec', link), text(' first.'))], type: 'panel' }
|
||||
assert.equal(shown(html(adfToHtml(document(panel)))), '<p>Read the <a href="https://spec.commonmark.org/" title="The spec">CommonMark spec</a> first.</p>')
|
||||
assert.equal(shown(html(adfToHtml(document(paragraph(text('x', { type: 'underline' }, link)))))), '<a href="https://spec.commonmark.org/" title="The spec">x</a>')
|
||||
assert.equal(shown(html(adfToHtml(document(paragraph(text('x', { attrs: { href: 'https://spec.commonmark.org/', title: 5 }, type: 'link' })))))), '<a href="https://spec.commonmark.org/">x</a>')
|
||||
})
|
||||
|
||||
test('shows a hard break, and a line feed in carried text outside a code block, as a line break', () => {
|
||||
@@ -219,8 +220,11 @@ test('shows a carried image marked by a link to another target as that link, the
|
||||
assert.equal(image({ alt: 'The moon', type: 'external', url: 'https://example.com/' }), '<p><a href="https://example.com/">The moon</a></p>')
|
||||
const blank = shown(html(adfToHtml(document({ attrs: { layout: 'wide' }, content: [{ attrs: { type: 'external', url: 'https://example.com/moon.jpg' }, marks: [{ attrs: { href: ' ' }, type: 'link' }], type: 'media' }], type: 'mediaSingle' }))))
|
||||
assert.equal(blank, '<p><a href=" ">https://example.com/moon.jpg</a> (<a href="https://example.com/moon.jpg">image</a>)</p>')
|
||||
const inline: AdfNode = { attrs: { alt: 'The moon', type: 'external', url: 'https://example.com/moon.jpg' }, marks: [link], type: 'mediaInline' }
|
||||
assert.equal(shown(html(adfToHtml(document(paragraph(inline))))), '<a href="https://example.com/">The moon</a> (<a href="https://example.com/moon.jpg">image</a>)')
|
||||
const texted = shown(html(adfToHtml(document({ attrs: { layout: 'wide' }, content: [{ attrs: { alt: 'The moon', type: 'external', url: 'https://example.com/moon.jpg' }, marks: [link], text: 'Moon', type: 'media' }], type: 'mediaSingle' }))))
|
||||
assert.equal(texted, '<p><a href="https://example.com/">Moon</a> (<a href="https://example.com/moon.jpg">image</a>)</p>')
|
||||
const inline = (mark: AdfMark): string => shown(html(adfToHtml(document(paragraph({ attrs: { alt: 'The moon', type: 'external', url: 'https://example.com/moon.jpg' }, marks: [mark], type: 'mediaInline' })))))
|
||||
assert.equal(inline(link), '<a href="https://example.com/">The moon</a> (<a href="https://example.com/moon.jpg">image</a>)')
|
||||
assert.equal(inline({ attrs: { href: 'https://example.com/', title: 5 }, type: 'link' }), '<a href="https://example.com/">The moon</a> (<a href="https://example.com/moon.jpg">image</a>)')
|
||||
})
|
||||
|
||||
test('links a carried card a link marks to that link\'s target alone', () => {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { AdfNode } from '../../adf/document.ts'
|
||||
import type { LinkAttrs } from '../../adf/mark-attributes.ts'
|
||||
import { anchorOpener, jsonValue, languageClass, shownValue } from './escaping.ts'
|
||||
import { carriedJson } from '../../adf/carried-json.ts'
|
||||
import { largestNesting } from '../../nesting.ts'
|
||||
import { linkAttrs, type LinkAttrs } from '../../adf/mark-attributes.ts'
|
||||
import { nodeAttrs, nodeContent, nodeMarks } from '../../adf/document.ts'
|
||||
import { partsShownText, referenceName, shownText, shownUrl, visibleText } from '../../adf/shown-text.ts'
|
||||
import { nodeAttrs, nodeContent } from '../../adf/document.ts'
|
||||
import { partsShownText, referenceName, shownImage, shownLink, shownText, shownUrl } from '../../adf/shown-text.ts'
|
||||
import { success, type ConvertErrorPath, type Result } from '../../result.ts'
|
||||
|
||||
// The content a carry element shows of one block; `code` the code block holding it, if any.
|
||||
@@ -51,23 +51,25 @@ function shownBlocks(root: AdfNode, codeLineFeed: string): ShownBlock[] {
|
||||
// The node's own part of what its carry element shows.
|
||||
function shownPiece(node: AdfNode, lineFeed: string): string {
|
||||
if (node.type === 'hardBreak') return '<br>'
|
||||
const mark = nodeMarks(node).find((held) => held.type === 'link')
|
||||
const target = mark === undefined ? undefined : linkAttrs(nodeAttrs(mark))
|
||||
const url = shownUrl(node)
|
||||
if (['media', 'mediaInline'].includes(node.type) && target !== undefined && url !== undefined && target.href !== url) return linkedImage(node, target, url, lineFeed)
|
||||
const link = target ?? (url === undefined ? undefined : { href: url })
|
||||
const text = node.text ?? shownText(node)
|
||||
if (['media', 'mediaInline'].includes(node.type)) return linkedImage(node, lineFeed)
|
||||
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).
|
||||
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 })})`
|
||||
}
|
||||
|
||||
function linkedText(node: AdfNode, standIn: string | undefined, url: string | undefined, lineFeed: string): string {
|
||||
const link = shownLink(node) ?? (url === undefined ? undefined : { href: url })
|
||||
const text = node.text ?? standIn
|
||||
if (text !== undefined) return linked(shownValue(text, lineFeed), link)
|
||||
const name = referenceName(node)
|
||||
return name === undefined ? '' : linked(`<em>(${shownValue(name, lineFeed)})</em>`, link)
|
||||
}
|
||||
|
||||
// As portable markdown writes it inline (docs/decisions.md §The HTML dialect).
|
||||
function linkedImage(media: AdfNode, target: LinkAttrs, url: string, lineFeed: string): string {
|
||||
const text = visibleText(nodeAttrs(media)['alt']) ?? visibleText(target.href) ?? url
|
||||
return `${linked(shownValue(text, lineFeed), target)} (${linked('image', { href: url })})`
|
||||
}
|
||||
|
||||
// The shown HTML inside an `<a>` where it links and HTML can hold the link.
|
||||
function linked(shown: string, link: LinkAttrs | undefined): string {
|
||||
const anchor = link === undefined ? undefined : anchorOpener(link)
|
||||
|
||||
Reference in New Issue
Block a user