Answer the stability pass: the slot a line ending reached, and the text an image description dropped
CI / gate (push) Successful in 8s
CI / gate (push) Successful in 8s
This commit is contained in:
@@ -10,6 +10,7 @@ import { failure, faulted, success, type ConvertErrorPath, type Result } from '.
|
||||
import { inlineDirective } from '../../adf/inline-directives.ts'
|
||||
import { marksAttribute, readMarkValues } from '../block-directive-marks.ts'
|
||||
import { readVocabulary } from './directive-attributes.ts'
|
||||
import { slotLineEndingFault } from '../directive-syntax.ts'
|
||||
|
||||
export type BlockDirectiveNode = { contentModel: BlockDirective['contentModel']; node: AdfNode }
|
||||
|
||||
@@ -56,6 +57,8 @@ export function readInlineDirectiveNode(
|
||||
if (slot !== undefined && content !== undefined) {
|
||||
const text = slotText(content)
|
||||
if (text === undefined) return failure('unsupported-node-shape', `the ${name} content slot holds one unmarked text node`, path)
|
||||
const spans = slotLineEndingFault(name, text)
|
||||
if (spans !== undefined) return faulted(spans, path)
|
||||
attrs.value[slot] = text
|
||||
}
|
||||
return success(namedNode(name, attrs.value, undefined))
|
||||
|
||||
@@ -6,6 +6,7 @@ import { backslashEscape, decodeTextEscapes, inlineHtmlConstruct, readBracketedA
|
||||
import { backtickRun, closingBacktickRun } from '../backtick-runs.ts'
|
||||
import { delimiterFlags, matchEmphasis, runLength } from '../emphasis-matching.ts'
|
||||
import { failure, faulted, success, type ConvertErrorPath, type Result } from '../../result.ts'
|
||||
import { inlineDirective } from '../../adf/inline-directives.ts'
|
||||
import { mergeAdjacentText } from '../../adf/editor-normal.ts'
|
||||
import { normalizeLabel, readInlineTarget, readLabel } from '../link-syntax.ts'
|
||||
import { readDirectiveMark } from './directive-marks.ts'
|
||||
@@ -305,9 +306,15 @@ function closeImage(scan: Scan, at: number, inner: readonly Piece[], definition:
|
||||
}
|
||||
|
||||
function imageAlt(inner: readonly Piece[]): string {
|
||||
return resolveNodes(inner)
|
||||
.map((node) => (node.type === 'hardBreak' ? ' ' : (node.text ?? '')))
|
||||
.join('')
|
||||
return resolveNodes(inner).map(altText).join('')
|
||||
}
|
||||
|
||||
// spec/flavour.md, The CommonMark image: the description's plain text, the content slot included.
|
||||
function altText(node: AdfNode): string {
|
||||
if (node.type === 'hardBreak') return ' '
|
||||
const slot = inlineDirective(node.type)?.textAttribute
|
||||
const spelled = slot === undefined ? undefined : node.attrs?.[slot]
|
||||
return typeof spelled === 'string' ? spelled : (node.text ?? '')
|
||||
}
|
||||
|
||||
function resolveNodes(pieces: readonly Piece[]): AdfNode[] {
|
||||
|
||||
@@ -647,6 +647,8 @@ test('flattens the description of a lone image to the plain text alt holds', ()
|
||||
assert.deepEqual(content(markdownToAdf('\n')), [image('/u', 'a b')])
|
||||
assert.deepEqual(content(markdownToAdf('\n')), [image('/u', 'a b')])
|
||||
assert.deepEqual(content(markdownToAdf('\n')), [image('/u', 'a b')])
|
||||
assert.deepEqual(content(markdownToAdf('![a :mention[@A]{id=b1c2} b](/u)\n')), [image('/u', 'a @A b')])
|
||||
assert.deepEqual(content(markdownToAdf('![:mention[@A]{id=b1c2}](/u)\n')), [image('/u', '@A')])
|
||||
})
|
||||
|
||||
test('leaves the brackets of an empty link text the text they are', () => {
|
||||
@@ -697,9 +699,12 @@ test('names the content slot no one unmarked text node reads back from', () => {
|
||||
assert.equal(code(markdownToAdf(':status[:date{timestamp=1}]{color=yellow}\n')), 'unsupported-node-shape')
|
||||
assert.equal(content(markdownToAdf(':status[]{color=yellow}\n')), 'unmappable-image: an image fits only as a paragraph of its own')
|
||||
assert.equal(code(markdownToAdf(':status[<div>]{color=yellow}\n')), 'unmappable-html')
|
||||
// The slot parses before the name's table is consulted, so a doubly-broken span reports its inner error.
|
||||
assert.equal(code(markdownToAdf(':date[<div>]{timestamp=1}\n')), 'unmappable-html')
|
||||
assert.equal(code(markdownToAdf(':widget[<div>]\n')), 'unmappable-html')
|
||||
const spans = 'unspellable-whitespace: the status content slot holds a newline no inline directive spans'
|
||||
assert.equal(content(markdownToAdf(':status[:text{text="\\n"}]{color=yellow}\n')), spans)
|
||||
assert.equal(content(markdownToAdf(':status[a b]{color=yellow}\n')), spans)
|
||||
assert.equal(content(markdownToAdf(':status[a b]{color=yellow}\n')), spans)
|
||||
assert.equal(content(markdownToAdf('Part :mention{id=b1c2 text=A}.\n')), 'unsupported-node-shape: mention spells its text attribute in the content slot')
|
||||
})
|
||||
|
||||
@@ -733,6 +738,9 @@ test('reads the directive marks, the nesting outermost first', () => {
|
||||
assert.deepEqual(content(markdownToAdf(':underline[a:date{timestamp=1}]\n')), [
|
||||
{ content: [marked('a', underline), { attrs: { timestamp: '1' }, marks: [underline], type: 'date' }], type: 'paragraph' },
|
||||
])
|
||||
assert.deepEqual(content(markdownToAdf('_:underline[a:date{timestamp=1}]_\n')), [
|
||||
{ content: [marked('a', em, underline), { attrs: { timestamp: '1' }, marks: [em, underline], type: 'date' }], type: 'paragraph' },
|
||||
])
|
||||
assert.equal(content(markdownToAdf(':border[a]{color="#091e42" size=x}\n')), 'unsupported-node-shape: the size attribute of border is no number')
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user