\n%]\na')).children].map(el => el.outerHTML),
['
a
', '
']);
});
it('linebreak', () => {
assert.deepStrictEqual(
[...run(parse('\\ ')).children].map(el => el.outerHTML),
['\\
', '
']);
assert.deepStrictEqual(
[...run(parse('\\\n')).children].map(el => el.outerHTML),
['\\
', '
']);
assert.deepStrictEqual(
[...run(parse('a\\ \nb')).children].map(el => el.outerHTML),
['a
b
', '
']);
assert.deepStrictEqual(
[...run(parse('a\\\nb')).children].map(el => el.outerHTML),
['a
b
', '
']);
assert.deepStrictEqual(
[...run(parse('a\n\\ \nb')).children].map(el => el.outerHTML),
['a
\\
b
', '
']);
assert.deepStrictEqual(
[...run(parse('a\n\\\nb')).children].map(el => el.outerHTML),
['a
\\
b
', '
']);
});
it('indent', () => {
assert.deepStrictEqual(
[...run(parse('\ta')).children].map(el => el.outerHTML),
['\ta
', '
']);
});
it('url', () => {
assert.deepStrictEqual(
[...run(parse([
[
'---',
'URL: https://source/x/y',
'---',
].join('\n'),
'@a',
'@domain/a',
'@a#b',
'@domain/a#b',
'#a',
'[#a]',
'$-a\n$$\n$$',
'$-a',
'((a))',
'{a}',
'{/a}',
'{^/a}',
'{./a}',
'{../a}',
'{../../a}',
'{//domain/a}',
'!{a}',
'!{^/a}',
'!{../../a}',
].join('\n\n'), { host: new URL(`${location.origin}/z`) })).children].map(el => el.outerHTML),
[
'',
'@a
',
'@domain/a
',
'@a#b
',
'@domain/a#b
',
'#a
',
'a
',
'(1)',
'(1)
',
'*1
',
'a
',
'/a
',
'^/a
',
'./a
',
'../a
',
'../../a
',
'//domain/a
',
'',
'',
'',
'- a^1
',
'
',
]);
assert.deepStrictEqual(
[...run(parse([
[
'---',
'URL: https://source/x/y',
'---',
].join('\n'),
'{^/a}',
'{./a}',
].join('\n\n'), { host: new URL(`${location.origin}/index.md`) })).children].map(el => el.outerHTML),
[
'',
'^/a
',
'./a
',
'
',
]);
assert.deepStrictEqual(
[...run(parse([
[
'---',
`URL: ${location.origin}/x/y`,
'---',
].join('\n'),
'{^/a}',
'{./a}',
].join('\n\n'), { host: new URL(`${location.origin}/z`) })).children].map(el => el.outerHTML),
[
``,
'^/a
',
'./a
',
'
',
]);
});
it('separation', () => {
assert.deepStrictEqual(
[...run(parse([
[
'---',
'URL: https://example/x',
'---',
].join('\n'),
[
'---',
'URL: https://example/y',
'---',
].join('\n'),
[
'~~~example/markdown',
'---',
'URL: https://example/y',
'---',
'',
'{#}',
'~~~',
].join('\n'),
'{#}',
].join('\n\n'), { host: new URL(`${location.origin}/z`) })).children].map(el => normalize(el.outerHTML)),
[
``,
'---\nURL: https://example/y\n---\n
',
'',
'#
',
'
',
]);
});
it('note', () => {
const notes = { references: html('ol') };
assert.deepStrictEqual(
[...run(parse('$-a\n$$\n$$\n\n(($-a[[^B]]))[[^B|$-a]]', { notes })).children].map(el => el.outerHTML),
[
'(1)',
'*1[B]
',
'- (1)[B]^1
',
]);
assert.deepStrictEqual(
notes.references.outerHTML,
'- (1)^1^2
');
assert.deepStrictEqual(
[...run(parse([
'[[^A 1|b]]',
'[[^A 1,|b]]',
'[[^A 1, |b]]',
'[[^Xyz 2020|b]]',
'[[^Xyz 2020, 1|b]]',
'[[^Xyz 2020, 1, 2|b]]',
'[[^Xyz 2020, 1, fig. 1.1|b]]',
'[[^Xyz 2020, 1, fig. 1.1-2.1b|b]]',
'[[^Xyz 2020, 1, fig. 1.1a-b|b]]',
'[[^Xyz 2020, 1-2|b]]',
'[[^Xyz 2020, 1:1-2|b]]',
'[[^Xyz 2020, 1n|b]]',
'[[^Xyz 2020, 1n1|b]]',
'[[^Xyz 2020, 1nn1-2|b]]',
'[[^Xyz 2020, i|b]]',
'[[^Xyz 2020, capter 1|b]]',
'[[^Xyz 2020, cap. 1|b]]',
'[[^Xyz 2020a|b]]',
'[[^Xyz 2020a, 1|b]]',
'[[^Xyz 2020-2021a|b]]',
'[[^Xyz 2020-2021a, 1|b]]',
'[[^Xyz, April 1, 2020|b]]',
'[[^Xyz, April 1, 2020, 1|b]]',
'[[^Xyz n.d.|b]]',
'[[^Xyz n.d., 1|b]]',
'[[^X. Y., and Z et al. 2020, 1-2|b]]',
'[[^A title 2020|b]]',
'[[^A title 2020, 1|b]]',
'[[^Constitution, art. 2|b]]',
'[[^Constitution, art. 2, sec. 1|b]]',
].join('\n\n'), { notes })).children].map(el => el.outerHTML),
[
'[A 1]
',
'[A 1,]
',
'[A 1,]
',
'[Xyz 2020]
',
'[Xyz 2020, 1]
',
'[Xyz 2020, 1, 2]
',
'[Xyz 2020, 1, fig. 1.1]
',
'[Xyz 2020, 1, fig. 1.1-2.1b]
',
'[Xyz 2020, 1, fig. 1.1a-b]
',
'[Xyz 2020, 1-2]
',
'[Xyz 2020, 1:1-2]
',
'[Xyz 2020, 1n]
',
'[Xyz 2020, 1n1]
',
'[Xyz 2020, 1nn1-2]
',
'[Xyz 2020, i]
',
'[Xyz 2020, capter 1]
',
'[Xyz 2020, cap. 1]
',
'[Xyz 2020a]
',
'[Xyz 2020a, 1]
',
'[Xyz 2020-2021a]
',
'[Xyz 2020-2021a, 1]
',
'[Xyz, April 1, 2020]
',
'[Xyz, April 1, 2020, 1]
',
'[Xyz n.d.]
',
'[Xyz n.d., 1]
',
'[X. Y., and Z et al. 2020, 1-2]
',
'[A title 2020]
',
'[A title 2020, 1]
',
'[Constitution, art. 2]
',
'[Constitution, art. 2, sec. 1]
',
]);
});
it('normalize', () => {
assert.deepStrictEqual(
[...run(parse('a\\\r\nb')).children].map(el => el.outerHTML),
['a
b
', '
']);
});
it('recursion', () => {
assert.deepStrictEqual(
[...run(parse(`${'('.repeat(100)}0`)).children].map(el => el.tagName),
['P', 'OL']);
assert.deepStrictEqual(
[...run(parse(`${'('.repeat(101)}0`)).children].map(el => el.tagName),
['H1', 'PRE', 'OL']);
assert.deepStrictEqual(
[...run(parse(`${'['.repeat(100)}0`)).children].map(el => el.tagName),
['P', 'OL']);
assert.deepStrictEqual(
[...run(parse(`${'['.repeat(101)}0`)).children].map(el => el.tagName),
['H1', 'PRE', 'OL']);
assert.deepStrictEqual(
[...run(parse(`${'{'.repeat(102)}0`)).children].map(el => el.tagName),
['P', 'OL']);
assert.deepStrictEqual(
[...run(parse(`${'{'.repeat(103)}0`)).children].map(el => el.tagName),
['H1', 'PRE', 'OL']);
assert.deepStrictEqual(
[...run(parse(`${'{ '.repeat(100)}0`)).children].map(el => el.tagName),
['P', 'OL']);
assert.deepStrictEqual(
[...run(parse(`${'{ '.repeat(1000)}0`)).children].map(el => el.tagName),
['P', 'OL']);
assert.deepStrictEqual(
[...run(parse(`${'{ '.repeat(100)}0`)).children].map(el => el.tagName),
['P', 'OL']);
assert.deepStrictEqual(
[...run(parse(`${'{ '.repeat(101)}0`)).children].map(el => el.tagName),
['H1', 'PRE', 'OL']);
});
it('recovery', () => {
assert.deepStrictEqual(
[...run(parse(`${'('.repeat(101)}0\n\n*a*`)).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
[
'Error: Too much recursion
',
`${'('.repeat(101)}0\n`,
'a
',
'
',
]);
});
it('creation', () => {
assert.deepStrictEqual(
[...run(parse('.'.repeat(100000), {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
.map(el => el.outerHTML),
[`${'.'.repeat(100000)}
`, '
']);
});
it('creation error', () => {
assert.deepStrictEqual(
[...run(parse('.'.repeat(100001), {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
.map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
[
'Error: Too many creations
',
`${'.'.repeat(1000 - 3)}...`,
'
',
]);
});
it('backtrack 1', () => {
// 最悪計算量での実行速度はCommonMarkの公式JS実装の32nに対して1-4倍程度。
// 5n = reference + link + url/math + ruby + text
assert.deepStrictEqual(
[...run(parse(`((([[[[#$http://[${'.'.repeat(19983)}`, {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
.map(el => el.tagName),
['P', 'OL']);
});
it('backtrack 1 error', () => {
assert.deepStrictEqual(
[...run(parse(`((([[[[#$http://[${'.'.repeat(19983 + 1)}`, {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
.map(el => el.tagName),
['H1', 'PRE', 'OL']);
});
it('backtrack 2', () => {
assert.deepStrictEqual(
[...run(parse(`((([[[[#$http://[${'.'.repeat(33313)}]]]`, {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
.map(el => el.tagName),
['P', 'OL']);
});
it('backtrack 2 error', () => {
assert.deepStrictEqual(
[...run(parse(`((([[[[#$http://[${'.'.repeat(33313 + 1)}]]]`, {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
.map(el => el.tagName),
['H1', 'PRE', 'OL']);
});
});
});