mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-15 21:10:25 +01:00
Answer stability round 1: 0 🔴, 2 🟡; a mark's malformed attrs name their cause, the docs name a value of the wrong type as a fallback
This commit is contained in:
@@ -4,7 +4,7 @@ import type { ConvertFault } from '../../result.ts'
|
||||
import type { DirectiveAttributes, DirectiveValue } from '../directive-syntax.ts'
|
||||
import type { Elsewhere } from './directive-attributes.ts'
|
||||
import { attributeNestingMessage, isUnmarkedSpellableText } from '../../adf/document.ts'
|
||||
import { attributeValue, directivePrefix, readAttributes, readDirectiveName, unknownDirectiveFault } from '../directive-syntax.ts'
|
||||
import { attributeValue, directiveEscape, directivePrefix, readAttributes, readDirectiveName, unknownDirectiveFault } from '../directive-syntax.ts'
|
||||
import { blockArgument, blockDirectiveForm, marksAttribute, readMarkValues, spellBlockMarks } from '../block-directive.ts'
|
||||
import { blockNodeModel } from '../../adf/block-nodes.ts'
|
||||
import { carryFencePrefix, carryName } from '../opaque-carry.ts'
|
||||
@@ -132,10 +132,14 @@ function readNamedMark(type: string, text: string, index: number, path: ConvertE
|
||||
const name = readDirectiveName(text, index)
|
||||
if (name === undefined) return failure('unsupported-node-shape', unnamedMarks(type), path)
|
||||
const vocabulary = markVocabularies.get(name)
|
||||
if (vocabulary === undefined) return failure('unsupported-node-shape', `the ${marksAttribute} attribute of ${type} names ${name}, a mark it spells only in its JSON array`, path)
|
||||
if (vocabulary === undefined) return failure('unsupported-node-shape', `the ${marksAttribute} attribute of ${type} names ${name}, no mark the flavour lists: spell an unlisted mark in the JSON array`, path)
|
||||
const start = index + name.length
|
||||
const attributes = text.charAt(start) === '{' ? readAttributes(text, start) : { value: { attributes: new Map<string, DirectiveValue>(), end: start } }
|
||||
if (attributes.fault !== undefined) return failure('unsupported-node-shape', unnamedMarks(type), path)
|
||||
if (attributes.fault !== undefined) {
|
||||
// A quoted value holds no directive, so the fault's escape hint does not apply.
|
||||
const cause = attributes.fault.message.replace(`; ${directiveEscape}`, '')
|
||||
return failure('unsupported-node-shape', `the ${name} mark in the ${marksAttribute} attribute of ${type}: ${cause}`, path)
|
||||
}
|
||||
const mark = readMarkAttributes(name, attributes.value.attributes, vocabulary, path)
|
||||
return mark.ok ? success({ end: attributes.value.end, mark: mark.value }) : mark
|
||||
}
|
||||
|
||||
@@ -556,12 +556,13 @@ test('names the marks key no marks read back from', () => {
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="{}"}\n')), named)
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="em strong"}\n')), named)
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="em "}\n')), named)
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="breakout{width=1 mode=wide}"}\n')), named)
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="breakout{mode}"}\n')), named)
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="breakout{mode=wide"}\n')), named)
|
||||
const inBreakout = (cause: string): string => `unsupported-node-shape: the breakout mark in the marks attribute of rule: ${cause}`
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="breakout{width=1 mode=wide}"}\n')), inBreakout('the {attrs} keys read in alphabetical order: mode before width'))
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="breakout{mode}"}\n')), inBreakout('an attribute reads key=value, the value bare or double-quoted: this one does not'))
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="breakout{mode=wide"}\n')), inBreakout('the {attrs} closing brace is missing'))
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="em{attrs=empty}strong"}\n')), named)
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="em{attrs=x}"}\n')), 'unsupported-node-shape: the reserved key attrs takes only the value empty: this one spells attrs=x')
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks=x}\n')), 'unsupported-node-shape: the marks attribute of rule names x, a mark it spells only in its JSON array')
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks=x}\n')), 'unsupported-node-shape: the marks attribute of rule names x, no mark the flavour lists: spell an unlisted mark in the JSON array')
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="breakout{width=wide}"}\n')), 'unsupported-node-shape: the width attribute of breakout is no number')
|
||||
assert.equal(content(losslessMarkdownToAdf('!adf:rule {marks="breakout{bogus=1}"}\n')), 'unsupported-node-shape: breakout holds no bogus attribute: this one spells it')
|
||||
})
|
||||
@@ -596,7 +597,6 @@ test('names the depth an attribute value nests past, never the kind the JSON rea
|
||||
assert.equal(content(losslessMarkdownToAdf(`!adf:extension {parameters="${nested(largestNesting + 1)}"}\n`)), deeper('parameters', 'extension'))
|
||||
assert.equal(content(losslessMarkdownToAdf(`!adf:rule {marks="${nested(largestNesting + 1)}"}\n`)), deeper('marks', 'rule'))
|
||||
assert.equal(content(losslessMarkdownToAdf(`!adf:rule {marks="[{\\"attrs\\":{\\"deep\\":${nested(largestNesting - 2)}},\\"type\\":\\"em\\"}]"}\n`)), deeper('marks', 'rule'))
|
||||
assert.equal(content(losslessMarkdownToAdf(`!adf:rule {marks="dataConsumer{sources=\\"${nested(largestNesting + 1)}\\"}"}\n`)), deeper('sources', 'dataConsumer'))
|
||||
assert.equal(content(losslessMarkdownToAdf(`!adf:media {width="${nested(largestNesting + 1)}"}\n`)), 'unsupported-node-shape: the width attribute of media is no number')
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user