Read the three directive forms, their attributes and the fences that nest them #35
@@ -1 +1 @@
|
|||||||
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > :a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - :a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[:a[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
|
||||||
|
|||||||
+2
-2
@@ -83,8 +83,8 @@ block content
|
|||||||
|
|
||||||
The fence is three or more colons. `arg` is one optional bare token whose meaning each node
|
The fence is three or more colons. `arg` is one optional bare token whose meaning each node
|
||||||
defines (e.g. the panel type). The body is block markdown. The closing fence is a line of at
|
defines (e.g. the panel type). The body is block markdown. The closing fence is a line of at
|
||||||
least the opening's length, and a container's fence is longer than every directive fence line
|
least the opening's length and closes the innermost open container however long its run, and a
|
||||||
anywhere in its body, however deeply a list item or blockquote nests it; a colon run inside a code
|
container's fence is longer than every directive fence line anywhere in its body, however deeply a list item or blockquote nests it; a colon run inside a code
|
||||||
fence or opaque carry is content. Canonical form uses minimal lengths.
|
fence or opaque carry is content. Canonical form uses minimal lengths.
|
||||||
Directive fence lines follow code-fence indentation (up to three spaces relative to their
|
Directive fence lines follow code-fence indentation (up to three spaces relative to their
|
||||||
container).
|
container).
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ test('names the inline directive left unclosed at the end of its line', () => {
|
|||||||
assert.equal(inline(':underline[:status[x'), 'an inline directive [content] is unclosed')
|
assert.equal(inline(':underline[:status[x'), 'an inline directive [content] is unclosed')
|
||||||
assert.equal(inline(':mention[@A]{id=1'), 'the {attrs} closing brace is missing')
|
assert.equal(inline(':mention[@A]{id=1'), 'the {attrs} closing brace is missing')
|
||||||
assert.equal(inline(':mention{id=1'), 'the {attrs} closing brace is missing')
|
assert.equal(inline(':mention{id=1'), 'the {attrs} closing brace is missing')
|
||||||
|
assert.equal(inline(':text{text="a\nb"}'), 'the {attrs} quoted value is not a JSON string')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('refuses inline directives nested deeper than the parser carries', () => {
|
test('refuses inline directives nested deeper than the parser carries', () => {
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ function readNestedDirective(text: string, index: number, depth: number): Read<D
|
|||||||
return { value: { attributes, content, length: cursor - index, name } }
|
return { value: { attributes, content, length: cursor - index, name } }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Where the content's own closing bracket sits: a code span, an escape and a nested directive each bind before it.
|
// A code span, an escape and a nested directive each bind before the content's own closing bracket.
|
||||||
function readDirectiveContent(text: string, start: number, depth: number): Read<number> {
|
function readDirectiveContent(text: string, start: number, depth: number): Read<number> {
|
||||||
let brackets = 0
|
let brackets = 0
|
||||||
let cursor = start
|
let cursor = start
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ test('holds a directive container open until the fence that closes it', () => {
|
|||||||
test('names the directive fence a container does not sit longer than', () => {
|
test('names the directive fence a container does not sit longer than', () => {
|
||||||
assert.deepEqual(faults(':::panel info\n:::expand\nPart.\n:::\n'), ["a directive fence line is at least as long as the container's 3 colons"])
|
assert.deepEqual(faults(':::panel info\n:::expand\nPart.\n:::\n'), ["a directive fence line is at least as long as the container's 3 colons"])
|
||||||
assert.deepEqual(faults('::::panel info\n:::\n::::\n'), ['a closing fence is shorter than the 4 colons it would close'])
|
assert.deepEqual(faults('::::panel info\n:::\n::::\n'), ['a closing fence is shorter than the 4 colons it would close'])
|
||||||
|
assert.deepEqual(faults('::::panel info\n:::expand\nPart.\n:::::\n::::\n'), [])
|
||||||
assert.deepEqual(faults(':::panel info\nPart.\n'), ['a container fenced with 3 colons is unclosed'])
|
assert.deepEqual(faults(':::panel info\nPart.\n'), ['a container fenced with 3 colons is unclosed'])
|
||||||
assert.deepEqual(faults('- :::panel info\n\nPart.\n'), ['a container fenced with 3 colons is unclosed'])
|
assert.deepEqual(faults('- :::panel info\n\nPart.\n'), ['a container fenced with 3 colons is unclosed'])
|
||||||
assert.deepEqual(faults('Part.\n\n:::\n'), ['a closing fence closes no open container'])
|
assert.deepEqual(faults('Part.\n\n:::\n'), ['a closing fence closes no open container'])
|
||||||
|
|||||||
@@ -130,7 +130,6 @@ test('claims a block-level colon run with no directive to parse it', () => {
|
|||||||
assert.equal(code(markdownToAdf(':::\n')), 'malformed-directive')
|
assert.equal(code(markdownToAdf(':::\n')), 'malformed-directive')
|
||||||
assert.equal(code(markdownToAdf('::Panel\n')), 'malformed-directive')
|
assert.equal(code(markdownToAdf('::Panel\n')), 'malformed-directive')
|
||||||
assert.equal(code(markdownToAdf('::panel {a=1 a=2}\n')), 'malformed-directive')
|
assert.equal(code(markdownToAdf('::panel {a=1 a=2}\n')), 'malformed-directive')
|
||||||
assert.deepEqual(path(markdownToAdf('Part.\n:::x\n')), ['content', 1])
|
|
||||||
assert.deepEqual(content(markdownToAdf(':10:30\n')), [paragraph(':10:30')])
|
assert.deepEqual(content(markdownToAdf(':10:30\n')), [paragraph(':10:30')])
|
||||||
assert.deepEqual(content(markdownToAdf(':: two\n')), [paragraph(':: two')])
|
assert.deepEqual(content(markdownToAdf(':: two\n')), [paragraph(':: two')])
|
||||||
})
|
})
|
||||||
@@ -141,6 +140,8 @@ test('reads the three directive forms, and names the node none of them reads bac
|
|||||||
assert.equal(code(markdownToAdf('Part :mention[@A]{id=b1c2}.\n')), 'unknown-directive-name')
|
assert.equal(code(markdownToAdf('Part :mention[@A]{id=b1c2}.\n')), 'unknown-directive-name')
|
||||||
assert.equal(content(markdownToAdf('::rule\n')), 'unknown-directive-name: the directive name rule reads back to no node')
|
assert.equal(content(markdownToAdf('::rule\n')), 'unknown-directive-name: the directive name rule reads back to no node')
|
||||||
assert.deepEqual(path(markdownToAdf('Part.\n\n::rule\n')), ['content', 1])
|
assert.deepEqual(path(markdownToAdf('Part.\n\n::rule\n')), ['content', 1])
|
||||||
|
assert.equal(content(markdownToAdf('Part.\n:::x\n')), 'malformed-directive: a container fenced with 3 colons is unclosed')
|
||||||
|
assert.deepEqual(path(markdownToAdf('Part.\n:::x\n')), ['content', 1])
|
||||||
})
|
})
|
||||||
|
|
||||||
test('leaves the colon that opens no directive the text it is', () => {
|
test('leaves the colon that opens no directive the text it is', () => {
|
||||||
|
|||||||
@@ -289,11 +289,19 @@ detail is settled at its own milestone.
|
|||||||
directions, beside the escaping regexes and the spellings it must not drift from. And the
|
directions, beside the escaping regexes and the spellings it must not drift from. And the
|
||||||
500-level guards compose here for the first time — a recursive reader stacked on the block
|
500-level guards compose here for the first time — a recursive reader stacked on the block
|
||||||
walk — so `nesting-depth-composed` pins both axes now rather than waiting for 3i's third.
|
walk — so `nesting-depth-composed` pins both axes now rather than waiting for 3i's third.
|
||||||
|
A closing fence closes the innermost open container however long its run, which
|
||||||
|
`spec/flavour.md`'s closing-fence sentence now says: a run reaching past the innermost
|
||||||
|
leaves the fence it did not close a named error, which §2 prefers to closing more than the
|
||||||
|
author wrote.
|
||||||
- [ ] **3g — The node tables read backwards.** `commonmark-subset/` reads back, the first
|
- [ ] **3g — The node tables read backwards.** `commonmark-subset/` reads back, the first
|
||||||
directory to. A parsed directive becomes its node: the name to the type and an unknown one
|
directory to. A parsed directive becomes its node: the name to the type and an unknown one
|
||||||
to a named error, the arg to the attribute it names, each value to the type its section
|
to a named error, the arg to the attribute it names, each value to the type its section
|
||||||
assigns, the body to `content`, the reserved `marks` key to the marks array. 3a's drift
|
assigns, the body to `content`, the reserved `marks` key to the marks array. 3a's drift
|
||||||
guard is built here if the answer there was yes.
|
guard is built here if the answer there was yes.
|
||||||
|
3f leaves two here: `Read<T>` moves to `src/result.ts` once a second reader takes it, and
|
||||||
|
the reserved `adf` name in block position needs an error of its own — 3f reports it as
|
||||||
|
`unknown-directive-name`, which §8 makes the signal that a later MINOR may give the name
|
||||||
|
meaning, and `adf` never will.
|
||||||
- [ ] **3h — The block nodes.** `block-nodes/` reads back: the plain-versus-directive choice 2f
|
- [ ] **3h — The block nodes.** `block-nodes/` reads back: the plain-versus-directive choice 2f
|
||||||
settles, read from the other side; the `codeBlock` directive's fenced body and the
|
settles, read from the other side; the `codeBlock` directive's fenced body and the
|
||||||
`language` attribute a bare fence leaves it; the media family's composition; both table
|
`language` attribute a bare fence leaves it; the media family's composition; both table
|
||||||
|
|||||||
Reference in New Issue
Block a user