Fix line endings in nested labels
Closes GH-13.
This commit is contained in:
parent
ed6c0bbfcd
commit
68d01105ec
2 changed files with 79 additions and 45 deletions
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* @typedef {import('micromark-util-types').Effects} Effects
|
||||
* @typedef {import('micromark-util-types').State} State
|
||||
* @typedef {import('micromark-util-types').Token} Token
|
||||
*/
|
||||
|
||||
import {ok as assert} from 'uvu/assert'
|
||||
|
@ -35,6 +36,8 @@ export function factoryLabel(
|
|||
) {
|
||||
let size = 0
|
||||
let balance = 0
|
||||
/** @type {Token|undefined} */
|
||||
let previous
|
||||
|
||||
return start
|
||||
|
||||
|
@ -59,43 +62,28 @@ export function factoryLabel(
|
|||
}
|
||||
|
||||
effects.enter(stringType)
|
||||
return atBreak(code)
|
||||
return lineStart(code)
|
||||
}
|
||||
|
||||
/** @type {State} */
|
||||
function atBreak(code) {
|
||||
if (code === codes.eof || size > constants.linkReferenceSizeMax) {
|
||||
return nok(code)
|
||||
}
|
||||
|
||||
if (code === codes.rightSquareBracket && !balance--) {
|
||||
function lineStart(code) {
|
||||
if (code === codes.rightSquareBracket && !balance) {
|
||||
return atClosingBrace(code)
|
||||
}
|
||||
|
||||
if (markdownLineEnding(code)) {
|
||||
if (disallowEol) {
|
||||
return nok(code)
|
||||
}
|
||||
|
||||
effects.enter(types.lineEnding)
|
||||
effects.consume(code)
|
||||
effects.exit(types.lineEnding)
|
||||
return atBreak
|
||||
}
|
||||
|
||||
effects.enter(types.chunkText, {contentType: constants.contentTypeText})
|
||||
return label(code)
|
||||
const token = effects.enter(types.chunkText, {
|
||||
contentType: constants.contentTypeText,
|
||||
previous
|
||||
})
|
||||
if (previous) previous.next = token
|
||||
previous = token
|
||||
return data(code)
|
||||
}
|
||||
|
||||
/** @type {State} */
|
||||
function label(code) {
|
||||
if (
|
||||
code === codes.eof ||
|
||||
markdownLineEnding(code) ||
|
||||
size > constants.linkReferenceSizeMax
|
||||
) {
|
||||
effects.exit(types.chunkText)
|
||||
return atBreak(code)
|
||||
function data(code) {
|
||||
if (code === codes.eof || size > constants.linkReferenceSizeMax) {
|
||||
return nok(code)
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -110,8 +98,33 @@ export function factoryLabel(
|
|||
return atClosingBrace(code)
|
||||
}
|
||||
|
||||
if (markdownLineEnding(code)) {
|
||||
if (disallowEol) {
|
||||
return nok(code)
|
||||
}
|
||||
|
||||
effects.consume(code)
|
||||
effects.exit(types.chunkText)
|
||||
return lineStart
|
||||
}
|
||||
|
||||
effects.consume(code)
|
||||
return code === codes.backslash ? labelEscape : label
|
||||
return code === codes.backslash ? dataEscape : data
|
||||
}
|
||||
|
||||
/** @type {State} */
|
||||
function dataEscape(code) {
|
||||
if (
|
||||
code === codes.leftSquareBracket ||
|
||||
code === codes.backslash ||
|
||||
code === codes.rightSquareBracket
|
||||
) {
|
||||
effects.consume(code)
|
||||
size++
|
||||
return data
|
||||
}
|
||||
|
||||
return data(code)
|
||||
}
|
||||
|
||||
/** @type {State} */
|
||||
|
@ -123,19 +136,4 @@ export function factoryLabel(
|
|||
effects.exit(type)
|
||||
return ok
|
||||
}
|
||||
|
||||
/** @type {State} */
|
||||
function labelEscape(code) {
|
||||
if (
|
||||
code === codes.leftSquareBracket ||
|
||||
code === codes.backslash ||
|
||||
code === codes.rightSquareBracket
|
||||
) {
|
||||
effects.consume(code)
|
||||
size++
|
||||
return label
|
||||
}
|
||||
|
||||
return label(code)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1278,7 +1278,43 @@ test('content', (t) => {
|
|||
t.equal(
|
||||
micromark(':abbr[\na\r]', options({abbr})),
|
||||
'<p><abbr>\na\r</abbr></p>',
|
||||
'should support EOLs at the edges of a label'
|
||||
'should support EOLs at the edges of a label (1)'
|
||||
)
|
||||
|
||||
t.equal(
|
||||
micromark(':abbr[\n]', options({abbr})),
|
||||
'<p><abbr>\n</abbr></p>',
|
||||
'should support EOLs at the edges of a label (2)'
|
||||
)
|
||||
|
||||
t.equal(
|
||||
micromark(':abbr[a\n:abbr[b]\nc]', options({abbr})),
|
||||
'<p><abbr>a\n<abbr>b</abbr>\nc</abbr></p>',
|
||||
'should support EOLs around nested directives'
|
||||
)
|
||||
|
||||
t.equal(
|
||||
micromark(':abbr[:abbr[\n]]', options({abbr})),
|
||||
'<p><abbr><abbr>\n</abbr></abbr></p>',
|
||||
'should support EOLs inside nested directives (1)'
|
||||
)
|
||||
|
||||
t.equal(
|
||||
micromark(':abbr[:abbr[a\nb]]', options({abbr})),
|
||||
'<p><abbr><abbr>a\nb</abbr></abbr></p>',
|
||||
'should support EOLs inside nested directives (2)'
|
||||
)
|
||||
|
||||
t.equal(
|
||||
micromark(':abbr[:abbr[\nb\n]]', options({abbr})),
|
||||
'<p><abbr><abbr>\nb\n</abbr></abbr></p>',
|
||||
'should support EOLs inside nested directives (3)'
|
||||
)
|
||||
|
||||
t.equal(
|
||||
micromark(':abbr[:abbr[\\\n]]', options({abbr})),
|
||||
'<p><abbr><abbr><br />\n</abbr></abbr></p>',
|
||||
'should support EOLs inside nested directives (4)'
|
||||
)
|
||||
|
||||
t.equal(
|
||||
|
|
Loading…
Add table
Reference in a new issue