securemark 0.299.4 → 0.300.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/design.md +0 -6
- package/dist/index.js +2847 -1993
- package/index.d.ts +2 -1
- package/markdown.d.ts +209 -183
- package/package.json +1 -1
- package/src/api/bind.test.ts +0 -22
- package/src/api/bind.ts +15 -10
- package/src/api/header.ts +8 -5
- package/src/api/parse.test.ts +118 -122
- package/src/api/parse.ts +13 -31
- package/src/api/run.ts +6 -0
- package/src/api.ts +1 -0
- package/src/combinator/control/inits.ts +35 -0
- package/src/combinator/control/sequence.test.ts +38 -0
- package/src/combinator/control/sequence.ts +19 -0
- package/src/combinator/control/some.test.ts +41 -0
- package/src/combinator/{data/parser → control}/some.ts +39 -26
- package/src/combinator/control/state.ts +33 -0
- package/src/combinator/control/subsequence.test.ts +47 -0
- package/src/combinator/control/subsequence.ts +16 -0
- package/src/combinator/control/tails.ts +8 -0
- package/src/combinator/control/union.test.ts +37 -0
- package/src/combinator/control/union.ts +31 -0
- package/src/combinator/{data/delimiter.ts → delimiter.ts} +40 -60
- package/src/combinator/effect/backtrack.ts +64 -0
- package/src/combinator/effect/clock.ts +10 -0
- package/src/combinator/effect/precedence.ts +50 -0
- package/src/combinator/effect/recursion.ts +30 -0
- package/src/combinator/effect/scope.ts +100 -0
- package/src/combinator/effect/state.ts +72 -0
- package/src/combinator/{data/list → parser}/list.ts +35 -10
- package/src/combinator/parser.ts +303 -0
- package/src/combinator/process/bind.ts +34 -0
- package/src/combinator/process/block.test.ts +20 -0
- package/src/combinator/process/block.ts +33 -0
- package/src/combinator/process/clear.ts +16 -0
- package/src/combinator/process/contract.ts +35 -0
- package/src/combinator/process/duplicate.ts +7 -0
- package/src/combinator/process/error.ts +13 -0
- package/src/combinator/{control/manipulation → process}/fallback.ts +3 -3
- package/src/combinator/process/fence.ts +59 -0
- package/src/combinator/process/fmap.ts +10 -0
- package/src/combinator/process/indent.test.ts +31 -0
- package/src/combinator/process/indent.ts +51 -0
- package/src/combinator/process/lazy.ts +8 -0
- package/src/combinator/process/line.test.ts +21 -0
- package/src/combinator/process/line.ts +55 -0
- package/src/combinator/process/match.ts +37 -0
- package/src/combinator/process/reverse.ts +7 -0
- package/src/combinator/process/scope.ts +102 -0
- package/src/combinator/process/surround.ts +273 -0
- package/src/combinator.ts +28 -24
- package/src/debug.test.ts +11 -8
- package/src/parser/autolink.test.ts +17 -18
- package/src/parser/block/blockquote.test.ts +78 -79
- package/src/parser/block/blockquote.ts +32 -25
- package/src/parser/block/codeblock.test.ts +54 -57
- package/src/parser/block/codeblock.ts +44 -26
- package/src/parser/block/dlist.test.ts +56 -57
- package/src/parser/block/dlist.ts +5 -5
- package/src/parser/block/extension/aside.test.ts +7 -9
- package/src/parser/block/extension/aside.ts +76 -47
- package/src/parser/block/extension/example.test.ts +16 -19
- package/src/parser/block/extension/example.ts +88 -48
- package/src/parser/block/extension/fig.test.ts +37 -36
- package/src/parser/block/extension/fig.ts +20 -25
- package/src/parser/block/extension/figbase.test.ts +18 -19
- package/src/parser/block/extension/figbase.ts +3 -3
- package/src/parser/block/extension/figure.test.ts +58 -63
- package/src/parser/block/extension/figure.ts +23 -21
- package/src/parser/block/extension/message.test.ts +12 -14
- package/src/parser/block/extension/message.ts +52 -39
- package/src/parser/block/extension/placeholder.test.ts +13 -13
- package/src/parser/block/extension/placeholder.ts +23 -21
- package/src/parser/block/extension/table.test.ts +69 -71
- package/src/parser/block/extension/table.ts +43 -31
- package/src/parser/block/extension.test.ts +24 -24
- package/src/parser/block/extension.ts +3 -3
- package/src/parser/block/heading.test.ts +58 -59
- package/src/parser/block/heading.ts +19 -18
- package/src/parser/block/ilist.test.ts +8 -8
- package/src/parser/block/ilist.ts +9 -7
- package/src/parser/block/mathblock.test.ts +29 -32
- package/src/parser/block/mathblock.ts +24 -23
- package/src/parser/block/mediablock.ts +7 -7
- package/src/parser/block/olist.test.ts +102 -103
- package/src/parser/block/olist.ts +11 -12
- package/src/parser/block/pagebreak.test.ts +15 -16
- package/src/parser/block/pagebreak.ts +5 -5
- package/src/parser/block/paragraph.test.ts +57 -58
- package/src/parser/block/paragraph.ts +1 -1
- package/src/parser/block/reply/cite.test.ts +39 -40
- package/src/parser/block/reply/cite.ts +5 -5
- package/src/parser/block/reply/quote.test.ts +50 -51
- package/src/parser/block/reply/quote.ts +8 -7
- package/src/parser/block/reply.test.ts +19 -20
- package/src/parser/block/reply.ts +2 -2
- package/src/parser/block/sidefence.test.ts +41 -48
- package/src/parser/block/sidefence.ts +17 -11
- package/src/parser/block/table.test.ts +48 -49
- package/src/parser/block/table.ts +10 -9
- package/src/parser/block/ulist.test.ts +52 -53
- package/src/parser/block/ulist.ts +9 -8
- package/src/parser/block.ts +63 -51
- package/src/parser/context.ts +40 -40
- package/src/parser/document.ts +48 -0
- package/src/parser/header.test.ts +19 -20
- package/src/parser/header.ts +31 -25
- package/src/parser/inline/annotation.test.ts +49 -50
- package/src/parser/inline/annotation.ts +14 -16
- package/src/parser/inline/autolink/account.test.ts +32 -33
- package/src/parser/inline/autolink/account.ts +18 -19
- package/src/parser/inline/autolink/anchor.test.ts +21 -22
- package/src/parser/inline/autolink/anchor.ts +7 -8
- package/src/parser/inline/autolink/channel.test.ts +14 -15
- package/src/parser/inline/autolink/email.test.ts +36 -37
- package/src/parser/inline/autolink/email.ts +6 -6
- package/src/parser/inline/autolink/hashnum.test.ts +32 -33
- package/src/parser/inline/autolink/hashnum.ts +7 -8
- package/src/parser/inline/autolink/hashtag.test.ts +59 -60
- package/src/parser/inline/autolink/hashtag.ts +8 -9
- package/src/parser/inline/autolink/url.test.ts +75 -76
- package/src/parser/inline/autolink/url.ts +17 -18
- package/src/parser/inline/autolink.ts +24 -11
- package/src/parser/inline/bracket.test.ts +73 -74
- package/src/parser/inline/bracket.ts +88 -63
- package/src/parser/inline/code.test.ts +30 -31
- package/src/parser/inline/code.ts +6 -6
- package/src/parser/inline/deletion.test.ts +27 -28
- package/src/parser/inline/deletion.ts +5 -5
- package/src/parser/inline/emphasis.test.ts +39 -40
- package/src/parser/inline/emphasis.ts +5 -5
- package/src/parser/inline/emstrong.test.ts +101 -102
- package/src/parser/inline/emstrong.ts +103 -85
- package/src/parser/inline/extension/index.test.ts +91 -92
- package/src/parser/inline/extension/index.ts +17 -13
- package/src/parser/inline/extension/indexee.ts +4 -4
- package/src/parser/inline/extension/indexer.test.ts +23 -24
- package/src/parser/inline/extension/indexer.ts +6 -5
- package/src/parser/inline/extension/label.test.ts +32 -33
- package/src/parser/inline/extension/label.ts +14 -5
- package/src/parser/inline/extension/placeholder.test.ts +42 -43
- package/src/parser/inline/extension/placeholder.ts +8 -9
- package/src/parser/inline/html.test.ts +109 -109
- package/src/parser/inline/html.ts +27 -27
- package/src/parser/inline/htmlentity.test.ts +37 -38
- package/src/parser/inline/htmlentity.ts +6 -7
- package/src/parser/inline/insertion.test.ts +27 -28
- package/src/parser/inline/insertion.ts +5 -5
- package/src/parser/inline/italic.test.ts +55 -56
- package/src/parser/inline/italic.ts +5 -5
- package/src/parser/inline/link.test.ts +186 -187
- package/src/parser/inline/link.ts +29 -30
- package/src/parser/inline/mark.test.ts +31 -32
- package/src/parser/inline/mark.ts +6 -6
- package/src/parser/inline/math.test.ts +140 -141
- package/src/parser/inline/math.ts +7 -8
- package/src/parser/inline/media.test.ts +92 -93
- package/src/parser/inline/media.ts +35 -41
- package/src/parser/inline/reference.test.ts +111 -112
- package/src/parser/inline/reference.ts +61 -32
- package/src/parser/inline/remark.test.ts +49 -50
- package/src/parser/inline/remark.ts +13 -13
- package/src/parser/inline/ruby.test.ts +49 -50
- package/src/parser/inline/ruby.ts +100 -52
- package/src/parser/inline/shortmedia.test.ts +9 -10
- package/src/parser/inline/shortmedia.ts +11 -9
- package/src/parser/inline/strong.test.ts +36 -37
- package/src/parser/inline/strong.ts +5 -5
- package/src/parser/inline/template.test.ts +22 -23
- package/src/parser/inline/template.ts +17 -20
- package/src/parser/inline.test.ts +225 -226
- package/src/parser/inline.ts +68 -34
- package/src/parser/parser.ts +51 -0
- package/src/parser/repeat.ts +118 -91
- package/src/parser/segment.test.ts +0 -11
- package/src/parser/segment.ts +25 -28
- package/src/parser/source/escapable.test.ts +23 -24
- package/src/parser/source/escapable.ts +19 -20
- package/src/parser/source/line.test.ts +17 -18
- package/src/parser/source/line.ts +19 -24
- package/src/parser/source/str.ts +17 -10
- package/src/parser/source/text.test.ts +88 -89
- package/src/parser/source/text.ts +32 -62
- package/src/parser/source/unescapable.test.ts +23 -24
- package/src/parser/source/unescapable.ts +15 -16
- package/src/parser/source/whitespace.ts +36 -0
- package/src/parser/source.ts +1 -0
- package/src/parser/util.ts +1 -1
- package/src/parser/visibility.ts +37 -15
- package/src/processor/figure.test.ts +20 -20
- package/src/processor/figure.ts +18 -10
- package/src/processor/note.test.ts +13 -13
- package/src/processor/note.ts +4 -2
- package/src/renderer/render/media/pdf.ts +2 -2
- package/src/renderer/render/media/twitter.ts +2 -2
- package/src/renderer/render/media.test.ts +12 -12
- package/src/renderer/render.test.ts +11 -11
- package/src/util/info.test.ts +2 -2
- package/src/util/quote.test.ts +3 -3
- package/src/util/quote.ts +6 -5
- package/src/util/toc.test.ts +12 -12
- package/src/combinator/control/constraint/block.test.ts +0 -20
- package/src/combinator/control/constraint/block.ts +0 -28
- package/src/combinator/control/constraint/contract.ts +0 -27
- package/src/combinator/control/constraint/line.test.ts +0 -21
- package/src/combinator/control/constraint/line.ts +0 -42
- package/src/combinator/control/manipulation/clear.ts +0 -5
- package/src/combinator/control/manipulation/convert.ts +0 -22
- package/src/combinator/control/manipulation/duplicate.ts +0 -7
- package/src/combinator/control/manipulation/fence.ts +0 -54
- package/src/combinator/control/manipulation/indent.test.ts +0 -31
- package/src/combinator/control/manipulation/indent.ts +0 -39
- package/src/combinator/control/manipulation/lazy.ts +0 -8
- package/src/combinator/control/manipulation/match.ts +0 -27
- package/src/combinator/control/manipulation/recovery.ts +0 -18
- package/src/combinator/control/manipulation/reverse.ts +0 -8
- package/src/combinator/control/manipulation/scope.ts +0 -61
- package/src/combinator/control/manipulation/surround.ts +0 -223
- package/src/combinator/control/monad/bind.ts +0 -26
- package/src/combinator/control/monad/fmap.ts +0 -10
- package/src/combinator/data/parser/context.ts +0 -96
- package/src/combinator/data/parser/inits.ts +0 -20
- package/src/combinator/data/parser/sequence.test.ts +0 -33
- package/src/combinator/data/parser/sequence.ts +0 -20
- package/src/combinator/data/parser/some.test.ts +0 -37
- package/src/combinator/data/parser/subsequence.test.ts +0 -41
- package/src/combinator/data/parser/subsequence.ts +0 -13
- package/src/combinator/data/parser/tails.ts +0 -8
- package/src/combinator/data/parser/union.test.ts +0 -33
- package/src/combinator/data/parser/union.ts +0 -18
- package/src/combinator/data/parser.ts +0 -144
package/package.json
CHANGED
package/src/api/bind.test.ts
CHANGED
|
@@ -29,28 +29,6 @@ describe('Unit: api/bind', () => {
|
|
|
29
29
|
|
|
30
30
|
const cfgs = { notes: { references: html('ol') } };
|
|
31
31
|
|
|
32
|
-
it('huge input', () => {
|
|
33
|
-
const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(1e6 + 1)}`);
|
|
34
|
-
assert.deepStrictEqual(
|
|
35
|
-
inspect(iter),
|
|
36
|
-
[
|
|
37
|
-
'<h1 class="error">Error: Too large input over 1,000,000 bytes.</h1>',
|
|
38
|
-
`<pre class="error" translate="no">${'\n'.repeat(997)}...</pre>`,
|
|
39
|
-
]);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('huge segment', function () {
|
|
43
|
-
this.timeout(10 * 1000);
|
|
44
|
-
|
|
45
|
-
const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(1e5 + 1)}`);
|
|
46
|
-
assert.deepStrictEqual(
|
|
47
|
-
inspect(iter, 3),
|
|
48
|
-
[
|
|
49
|
-
'<h1 class="error">Error: Too large segment over 100,000 bytes.</h1>',
|
|
50
|
-
`<pre class="error" translate="no">${'\n'.repeat(997)}...</pre>`,
|
|
51
|
-
]);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
32
|
it('empty', () => {
|
|
55
33
|
const el = html('div');
|
|
56
34
|
const update = bind(el, cfgs).parse;
|
package/src/api/bind.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ParserSettings, Progress } from '../..';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { Input, Options, Segment } from '../parser/context';
|
|
3
|
+
import { Output, run } from '../combinator/parser';
|
|
4
4
|
import { segment } from '../parser/segment';
|
|
5
5
|
import { block } from '../parser/block';
|
|
6
6
|
import { headers } from './header';
|
|
@@ -20,12 +20,13 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
|
|
|
20
20
|
const options: Options = {
|
|
21
21
|
...settings,
|
|
22
22
|
host: settings.host ?? new ReadonlyURL(location.pathname, location.origin),
|
|
23
|
+
header: true,
|
|
23
24
|
};
|
|
24
25
|
if (options.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
|
|
25
26
|
if (options.host?.origin === 'null') throw new Error(`Invalid host: ${options.host.href}`);
|
|
26
27
|
type Block = readonly [segment: string, blocks: readonly HTMLElement[], url: string];
|
|
27
28
|
const blocks: Block[] = [];
|
|
28
|
-
const adds: (readonly [HTMLElement, Node | null])[] = [];
|
|
29
|
+
const adds: (readonly [HTMLElement, global.Node | null])[] = [];
|
|
29
30
|
const dels: (readonly [HTMLElement])[] = [];
|
|
30
31
|
const bottom = target.firstChild;
|
|
31
32
|
let revision: symbol | undefined;
|
|
@@ -43,7 +44,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
|
|
|
43
44
|
const rev = revision = Symbol();
|
|
44
45
|
const sourceSegments: string[] = [];
|
|
45
46
|
const sourceSegmentAttrs: Segment[] = [];
|
|
46
|
-
for (const [seg, attr] of segment(source
|
|
47
|
+
for (const [seg, attr] of segment(source)) {
|
|
47
48
|
sourceSegments.push(seg);
|
|
48
49
|
sourceSegmentAttrs.push(attr);
|
|
49
50
|
yield { type: 'segment', value: seg };
|
|
@@ -65,18 +66,22 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
|
|
|
65
66
|
}
|
|
66
67
|
assert(last <= targetSegments.length);
|
|
67
68
|
assert(head + last <= targetSegments.length);
|
|
69
|
+
const output = new Output<HTMLElement>();
|
|
68
70
|
const base = next(head);
|
|
69
71
|
let index = head;
|
|
70
|
-
// @ts-expect-error
|
|
71
72
|
options.header = true;
|
|
72
73
|
for (; index < sourceSegments.length - last; ++index) {
|
|
73
74
|
assert(rev === revision);
|
|
74
75
|
const seg = sourceSegments[index];
|
|
75
76
|
options.segment = sourceSegmentAttrs[index] | Segment.write;
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
for (const _ of run(block, new Input(options, seg), output)) {
|
|
78
|
+
yield { type: 'break' };
|
|
79
|
+
}
|
|
80
|
+
assert(output.data.length === 1);
|
|
81
|
+
const es = output.pop()
|
|
82
|
+
.foldl<HTMLElement[]>((acc, { value }) => (acc.push(value), acc), []);
|
|
83
|
+
output.push();
|
|
84
|
+
options.header &&= false;
|
|
80
85
|
blocks.length === index
|
|
81
86
|
? blocks.push([seg, es, url])
|
|
82
87
|
: blocks.splice(index, 0, [seg, es, url]);
|
|
@@ -137,7 +142,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
|
|
|
137
142
|
}
|
|
138
143
|
}
|
|
139
144
|
|
|
140
|
-
function next(index: number): Node | null {
|
|
145
|
+
function next(index: number): global.Node | null {
|
|
141
146
|
assert(index >= 0);
|
|
142
147
|
assert(index <= blocks.length);
|
|
143
148
|
for (let i = index; i < blocks.length; ++i) {
|
package/src/api/header.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Input } from '../parser/context';
|
|
2
|
+
import { Output, run } from '../combinator/parser';
|
|
2
3
|
import { header as h } from '../parser/header';
|
|
3
4
|
|
|
4
5
|
export function header(source: string): string {
|
|
@@ -16,10 +17,12 @@ export function headers(source: string): string[] {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
function parse(source: string): [HTMLElement, number] | [] {
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
20
|
+
const input = new Input({ source });
|
|
21
|
+
const output = new Output<HTMLElement>();
|
|
22
|
+
for (const _ of run(h,input, output));
|
|
23
|
+
assert(output.data.length === 1);
|
|
24
|
+
const el = output.peek().head?.value;
|
|
22
25
|
return el?.tagName === 'ASIDE'
|
|
23
|
-
? [el,
|
|
26
|
+
? [el, input.position]
|
|
24
27
|
: [];
|
|
25
28
|
}
|
package/src/api/parse.test.ts
CHANGED
|
@@ -1,104 +1,87 @@
|
|
|
1
|
+
import { run } from './run';
|
|
1
2
|
import { parse } from './parse';
|
|
2
|
-
import {
|
|
3
|
+
import { Input } from '../parser/context';
|
|
3
4
|
import { html } from 'typed-dom/dom';
|
|
4
5
|
import { normalize } from '../debug.test';
|
|
5
6
|
|
|
6
7
|
describe('Unit: api/parse', () => {
|
|
7
8
|
describe('parse', () => {
|
|
8
|
-
it('huge input', () => {
|
|
9
|
-
assert.deepStrictEqual(
|
|
10
|
-
[...parse(`${'\n'.repeat(1e6 + 1)}`, { id: '' }).children].map(el => el.outerHTML),
|
|
11
|
-
[
|
|
12
|
-
'<h1 class="error">Error: Too large input over 1,000,000 bytes.</h1>',
|
|
13
|
-
`<pre class="error" translate="no">${'\n'.repeat(997)}...</pre>`,
|
|
14
|
-
]);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('huge segment', () => {
|
|
18
|
-
assert.deepStrictEqual(
|
|
19
|
-
[...parse(`${'\n'.repeat(1e5 + 1)}`, { id: '' }).children].map(el => el.outerHTML),
|
|
20
|
-
[
|
|
21
|
-
'<h1 class="error">Error: Too large segment over 100,000 bytes.</h1>',
|
|
22
|
-
`<pre class="error" translate="no">${'\n'.repeat(997)}...</pre>`,
|
|
23
|
-
]);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
9
|
it('result', () => {
|
|
27
|
-
assert(parse('') instanceof DocumentFragment);
|
|
10
|
+
assert(run(parse('')) instanceof DocumentFragment);
|
|
28
11
|
});
|
|
29
12
|
|
|
30
13
|
it('empty', () => {
|
|
31
14
|
assert.deepStrictEqual(
|
|
32
|
-
[...parse('').children].map(el => el.outerHTML),
|
|
33
|
-
[]);
|
|
15
|
+
[...run(parse('')).children].map(el => el.outerHTML),
|
|
16
|
+
['<ol class="references"></ol>']);
|
|
34
17
|
});
|
|
35
18
|
|
|
36
19
|
it('invisible', () => {
|
|
37
20
|
assert.deepStrictEqual(
|
|
38
|
-
[...parse(' ').children].map(el => el.outerHTML),
|
|
39
|
-
[]);
|
|
21
|
+
[...run(parse(' ')).children].map(el => el.outerHTML),
|
|
22
|
+
['<ol class="references"></ol>']);
|
|
40
23
|
assert.deepStrictEqual(
|
|
41
|
-
[...parse('\n').children].map(el => el.outerHTML),
|
|
42
|
-
[]);
|
|
24
|
+
[...run(parse('\n')).children].map(el => el.outerHTML),
|
|
25
|
+
['<ol class="references"></ol>']);
|
|
43
26
|
assert.deepStrictEqual(
|
|
44
|
-
[...parse('\n\n').children].map(el => el.outerHTML),
|
|
45
|
-
[]);
|
|
27
|
+
[...run(parse('\n\n')).children].map(el => el.outerHTML),
|
|
28
|
+
['<ol class="references"></ol>']);
|
|
46
29
|
assert.deepStrictEqual(
|
|
47
|
-
[...parse('\\').children].map(el => el.outerHTML),
|
|
48
|
-
['<p>\\</p>']);
|
|
30
|
+
[...run(parse('\\')).children].map(el => el.outerHTML),
|
|
31
|
+
['<p>\\</p>', '<ol class="references"></ol>']);
|
|
49
32
|
assert.deepStrictEqual(
|
|
50
|
-
[...parse('\\\na').children].map(el => el.outerHTML),
|
|
51
|
-
['<p>\\<br>a</p>']);
|
|
33
|
+
[...run(parse('\\\na')).children].map(el => el.outerHTML),
|
|
34
|
+
['<p>\\<br>a</p>', '<ol class="references"></ol>']);
|
|
52
35
|
assert.deepStrictEqual(
|
|
53
|
-
[...parse('	').children].map(el => el.outerHTML),
|
|
54
|
-
['<p>&Tab;</p>']);
|
|
36
|
+
[...run(parse('	')).children].map(el => el.outerHTML),
|
|
37
|
+
['<p>&Tab;</p>', '<ol class="references"></ol>']);
|
|
55
38
|
assert.deepStrictEqual(
|
|
56
|
-
[...parse('	\na').children].map(el => el.outerHTML),
|
|
57
|
-
['<p>&Tab;<br>a</p>']);
|
|
39
|
+
[...run(parse('	\na')).children].map(el => el.outerHTML),
|
|
40
|
+
['<p>&Tab;<br>a</p>', '<ol class="references"></ol>']);
|
|
58
41
|
assert.deepStrictEqual(
|
|
59
|
-
[...parse('<wbr>').children].map(el => el.outerHTML),
|
|
60
|
-
['<p><wbr></p>']);
|
|
42
|
+
[...run(parse('<wbr>')).children].map(el => el.outerHTML),
|
|
43
|
+
['<p><wbr></p>', '<ol class="references"></ol>']);
|
|
61
44
|
assert.deepStrictEqual(
|
|
62
|
-
[...parse('<wbr>\na').children].map(el => el.outerHTML),
|
|
63
|
-
['<p><wbr><br>a</p>']);
|
|
45
|
+
[...run(parse('<wbr>\na')).children].map(el => el.outerHTML),
|
|
46
|
+
['<p><wbr><br>a</p>', '<ol class="references"></ol>']);
|
|
64
47
|
assert.deepStrictEqual(
|
|
65
|
-
[...parse('[%\n<wbr>\n%]').children].map(el => el.outerHTML),
|
|
66
|
-
['<p><span class="remark"><input type="checkbox"><span>[%<br><wbr><br>%]</span></span></p>']);
|
|
48
|
+
[...run(parse('[%\n<wbr>\n%]')).children].map(el => el.outerHTML),
|
|
49
|
+
['<p><span class="remark"><input type="checkbox"><span>[%<br><wbr><br>%]</span></span></p>', '<ol class="references"></ol>']);
|
|
67
50
|
assert.deepStrictEqual(
|
|
68
|
-
[...parse('[%\n<wbr>\n%]\na').children].map(el => el.outerHTML),
|
|
69
|
-
['<p><span class="remark"><input type="checkbox"><span>[%<br><wbr><br>%]</span></span><br>a</p>']);
|
|
51
|
+
[...run(parse('[%\n<wbr>\n%]\na')).children].map(el => el.outerHTML),
|
|
52
|
+
['<p><span class="remark"><input type="checkbox"><span>[%<br><wbr><br>%]</span></span><br>a</p>', '<ol class="references"></ol>']);
|
|
70
53
|
});
|
|
71
54
|
|
|
72
55
|
it('linebreak', () => {
|
|
73
56
|
assert.deepStrictEqual(
|
|
74
|
-
[...parse('\\ ').children].map(el => el.outerHTML),
|
|
75
|
-
['<p>\\</p>']);
|
|
57
|
+
[...run(parse('\\ ')).children].map(el => el.outerHTML),
|
|
58
|
+
['<p>\\</p>', '<ol class="references"></ol>']);
|
|
76
59
|
assert.deepStrictEqual(
|
|
77
|
-
[...parse('\\\n').children].map(el => el.outerHTML),
|
|
78
|
-
['<p>\\</p>']);
|
|
60
|
+
[...run(parse('\\\n')).children].map(el => el.outerHTML),
|
|
61
|
+
['<p>\\</p>', '<ol class="references"></ol>']);
|
|
79
62
|
assert.deepStrictEqual(
|
|
80
|
-
[...parse('a\\ \nb').children].map(el => el.outerHTML),
|
|
81
|
-
['<p>a <br>b</p>']);
|
|
63
|
+
[...run(parse('a\\ \nb')).children].map(el => el.outerHTML),
|
|
64
|
+
['<p>a <br>b</p>', '<ol class="references"></ol>']);
|
|
82
65
|
assert.deepStrictEqual(
|
|
83
|
-
[...parse('a\\\nb').children].map(el => el.outerHTML),
|
|
84
|
-
['<p>a<br>b</p>']);
|
|
66
|
+
[...run(parse('a\\\nb')).children].map(el => el.outerHTML),
|
|
67
|
+
['<p>a<br>b</p>', '<ol class="references"></ol>']);
|
|
85
68
|
assert.deepStrictEqual(
|
|
86
|
-
[...parse('a\n\\ \nb').children].map(el => el.outerHTML),
|
|
87
|
-
['<p>a<br>\\<br>b</p>']);
|
|
69
|
+
[...run(parse('a\n\\ \nb')).children].map(el => el.outerHTML),
|
|
70
|
+
['<p>a<br>\\<br>b</p>', '<ol class="references"></ol>']);
|
|
88
71
|
assert.deepStrictEqual(
|
|
89
|
-
[...parse('a\n\\\nb').children].map(el => el.outerHTML),
|
|
90
|
-
['<p>a<br>\\<br>b</p>']);
|
|
72
|
+
[...run(parse('a\n\\\nb')).children].map(el => el.outerHTML),
|
|
73
|
+
['<p>a<br>\\<br>b</p>', '<ol class="references"></ol>']);
|
|
91
74
|
});
|
|
92
75
|
|
|
93
76
|
it('indent', () => {
|
|
94
77
|
assert.deepStrictEqual(
|
|
95
|
-
[...parse('\ta').children].map(el => el.outerHTML),
|
|
96
|
-
['<p>\ta</p>']);
|
|
78
|
+
[...run(parse('\ta')).children].map(el => el.outerHTML),
|
|
79
|
+
['<p>\ta</p>', '<ol class="references"></ol>']);
|
|
97
80
|
});
|
|
98
81
|
|
|
99
82
|
it('url', () => {
|
|
100
83
|
assert.deepStrictEqual(
|
|
101
|
-
[...parse([
|
|
84
|
+
[...run(parse([
|
|
102
85
|
[
|
|
103
86
|
'---',
|
|
104
87
|
'URL: https://source/x/y',
|
|
@@ -123,7 +106,7 @@ describe('Unit: api/parse', () => {
|
|
|
123
106
|
'!{a}',
|
|
124
107
|
'!{^/a}',
|
|
125
108
|
'!{../../a}',
|
|
126
|
-
].join('\n\n'), { host: new URL(`${location.origin}/z`) }).children].map(el => el.outerHTML),
|
|
109
|
+
].join('\n\n'), { host: new URL(`${location.origin}/z`) })).children].map(el => el.outerHTML),
|
|
127
110
|
[
|
|
128
111
|
'<aside class="header"><details open=""><summary>Header</summary><div class="field" data-name="url" data-value="https://source/x/y"><span class="field-name">URL</span>: <span class="field-value">https://source/x/y</span></div></details></aside>',
|
|
129
112
|
'<p><a class="account" href="https://source/@a" target="_blank">@a</a></p>',
|
|
@@ -146,9 +129,10 @@ describe('Unit: api/parse', () => {
|
|
|
146
129
|
'<div><a href="/z/a" target="_blank"><img class="media" data-src="/z/a" alt="^/a"></a></div>',
|
|
147
130
|
'<div><a href="https://source/a" target="_blank"><img class="media" data-src="https://source/a" alt="../../a"></a></div>',
|
|
148
131
|
'<ol class="annotations"><li id="annotation::def:a:1" data-marker="*1"><span>a</span><sup><a href="#annotation::ref:a:1">^1</a></sup></li></ol>',
|
|
132
|
+
'<ol class="references"></ol>',
|
|
149
133
|
]);
|
|
150
134
|
assert.deepStrictEqual(
|
|
151
|
-
[...parse([
|
|
135
|
+
[...run(parse([
|
|
152
136
|
[
|
|
153
137
|
'---',
|
|
154
138
|
'URL: https://source/x/y',
|
|
@@ -156,14 +140,15 @@ describe('Unit: api/parse', () => {
|
|
|
156
140
|
].join('\n'),
|
|
157
141
|
'{^/a}',
|
|
158
142
|
'{./a}',
|
|
159
|
-
].join('\n\n'), { host: new URL(`${location.origin}/index.md`) }).children].map(el => el.outerHTML),
|
|
143
|
+
].join('\n\n'), { host: new URL(`${location.origin}/index.md`) })).children].map(el => el.outerHTML),
|
|
160
144
|
[
|
|
161
145
|
'<aside class="header"><details open=""><summary>Header</summary><div class="field" data-name="url" data-value="https://source/x/y"><span class="field-name">URL</span>: <span class="field-value">https://source/x/y</span></div></details></aside>',
|
|
162
146
|
'<p><a class="url" href="/a">^/a</a></p>',
|
|
163
147
|
'<p><a class="url" href="https://source/x/a" target="_blank">./a</a></p>',
|
|
148
|
+
'<ol class="references"></ol>',
|
|
164
149
|
]);
|
|
165
150
|
assert.deepStrictEqual(
|
|
166
|
-
[...parse([
|
|
151
|
+
[...run(parse([
|
|
167
152
|
[
|
|
168
153
|
'---',
|
|
169
154
|
`URL: ${location.origin}/x/y`,
|
|
@@ -171,17 +156,18 @@ describe('Unit: api/parse', () => {
|
|
|
171
156
|
].join('\n'),
|
|
172
157
|
'{^/a}',
|
|
173
158
|
'{./a}',
|
|
174
|
-
].join('\n\n'), { host: new URL(`${location.origin}/z`) }).children].map(el => el.outerHTML),
|
|
159
|
+
].join('\n\n'), { host: new URL(`${location.origin}/z`) })).children].map(el => el.outerHTML),
|
|
175
160
|
[
|
|
176
161
|
`<aside class="header"><details open=""><summary>Header</summary><div class="field" data-name="url" data-value="${location.origin}/x/y"><span class="field-name">URL</span>: <span class="field-value">${location.origin}/x/y</span></div></details></aside>`,
|
|
177
162
|
'<p><a class="url" href="/z/a">^/a</a></p>',
|
|
178
163
|
'<p><a class="url" href="/x/a">./a</a></p>',
|
|
164
|
+
'<ol class="references"></ol>',
|
|
179
165
|
]);
|
|
180
166
|
});
|
|
181
167
|
|
|
182
168
|
it('separation', () => {
|
|
183
169
|
assert.deepStrictEqual(
|
|
184
|
-
[...parse([
|
|
170
|
+
[...run(parse([
|
|
185
171
|
[
|
|
186
172
|
'---',
|
|
187
173
|
'URL: https://example/x',
|
|
@@ -202,19 +188,20 @@ describe('Unit: api/parse', () => {
|
|
|
202
188
|
'~~~',
|
|
203
189
|
].join('\n'),
|
|
204
190
|
'{#}',
|
|
205
|
-
].join('\n\n'), { host: new URL(`${location.origin}/z`) }).children].map(el => normalize(el.outerHTML)),
|
|
191
|
+
].join('\n\n'), { host: new URL(`${location.origin}/z`) })).children].map(el => normalize(el.outerHTML)),
|
|
206
192
|
[
|
|
207
193
|
`<aside class="header"><details open=""><summary>Header</summary><div class="field" data-name="url" data-value="https://example/x"><span class="field-name">URL</span>: <span class="field-value">https://example/x</span></div></details></aside>`,
|
|
208
194
|
'<pre class="invalid" translate="no">---\nURL: https://example/y\n---\n</pre>',
|
|
209
195
|
'<aside class="example" data-type="markdown"><pre translate="no">---\nURL: https://example/y\n---\n\n{#}</pre><hr><section><aside class="header"><details open=""><summary>Header</summary><div class="field" data-name="url" data-value="https://example/y"><span class="field-name">URL</span>: <span class="field-value">https://example/y</span></div></details></aside><p><a class="url" href="https://example/y#" target="_blank">#</a></p><h2>References</h2><ol class="references"></ol></section></aside>',
|
|
210
196
|
'<p><a class="url" href="https://example/x#" target="_blank">#</a></p>',
|
|
197
|
+
'<ol class="references"></ol>',
|
|
211
198
|
]);
|
|
212
199
|
});
|
|
213
200
|
|
|
214
201
|
it('note', () => {
|
|
215
202
|
const notes = { references: html('ol') };
|
|
216
203
|
assert.deepStrictEqual(
|
|
217
|
-
[...parse('$-a\n$$\n$$\n\n(($-a[[^B]]))[[^B|$-a]]', { notes }).children].map(el => el.outerHTML),
|
|
204
|
+
[...run(parse('$-a\n$$\n$$\n\n(($-a[[^B]]))[[^B|$-a]]', { notes })).children].map(el => el.outerHTML),
|
|
218
205
|
[
|
|
219
206
|
'<figure data-type="math" data-label="$-a" data-group="$" data-number="1" id="label:$-a"><figcaption><span class="figindex">(1)</span><span class="figtext"></span></figcaption><div><div class="math" translate="no">$$\n$$</div></div></figure>',
|
|
220
207
|
'<p><sup class="annotation" id="annotation::ref:[$-a][[^B]]:1" title="(1)[[^B]]"><a href="#annotation::def:[$-a][[^B]]:1">*1</a></sup><sup class="reference" data-abbr="B" id="reference::ref:B:2" title="(1)"><a href="#reference::def:B">[B]</a></sup></p>',
|
|
@@ -224,7 +211,7 @@ describe('Unit: api/parse', () => {
|
|
|
224
211
|
notes.references.outerHTML,
|
|
225
212
|
'<ol><li id="reference::def:B"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a></span><sup><a href="#reference::ref:B:1">^1</a><a href="#reference::ref:B:2" title="(1)">^2</a></sup></li></ol>');
|
|
226
213
|
assert.deepStrictEqual(
|
|
227
|
-
[...parse([
|
|
214
|
+
[...run(parse([
|
|
228
215
|
'[[^A 1|b]]',
|
|
229
216
|
'[[^A 1,|b]]',
|
|
230
217
|
'[[^A 1, |b]]',
|
|
@@ -255,7 +242,7 @@ describe('Unit: api/parse', () => {
|
|
|
255
242
|
'[[^A title 2020, 1|b]]',
|
|
256
243
|
'[[^Constitution, art. 2|b]]',
|
|
257
244
|
'[[^Constitution, art. 2, sec. 1|b]]',
|
|
258
|
-
].join('\n\n'), { notes }).children].map(el => el.outerHTML),
|
|
245
|
+
].join('\n\n'), { notes })).children].map(el => el.outerHTML),
|
|
259
246
|
[
|
|
260
247
|
'<p><sup class="reference" data-abbr="A 1" id="reference::ref:A_1:1" title="b"><a href="#reference::def:A_1">[A 1]</a></sup></p>',
|
|
261
248
|
'<p><sup class="reference" data-abbr="A 1," id="reference::ref:A_1:2" title="b"><a href="#reference::def:A_1">[A 1,]</a></sup></p>',
|
|
@@ -292,87 +279,96 @@ describe('Unit: api/parse', () => {
|
|
|
292
279
|
|
|
293
280
|
it('normalize', () => {
|
|
294
281
|
assert.deepStrictEqual(
|
|
295
|
-
[...parse('a\\\r\nb').children].map(el => el.outerHTML),
|
|
296
|
-
['<p>a<br>b</p>']);
|
|
282
|
+
[...run(parse('a\\\r\nb')).children].map(el => el.outerHTML),
|
|
283
|
+
['<p>a<br>b</p>', '<ol class="references"></ol>']);
|
|
297
284
|
});
|
|
298
285
|
|
|
299
286
|
it('recursion', () => {
|
|
300
287
|
assert.deepStrictEqual(
|
|
301
|
-
[...parse(`${'
|
|
302
|
-
[
|
|
288
|
+
[...run(parse(`${'('.repeat(100)}0`)).children].map(el => el.tagName),
|
|
289
|
+
['P', 'OL']);
|
|
303
290
|
assert.deepStrictEqual(
|
|
304
|
-
[...parse(`${'
|
|
305
|
-
[
|
|
306
|
-
'<h1 id="error:rnd" class="error">Error: Too much recursion</h1>',
|
|
307
|
-
`<pre class="error" translate="no">${'['.repeat(21)}0</pre>`,
|
|
308
|
-
]);
|
|
291
|
+
[...run(parse(`${'('.repeat(101)}0`)).children].map(el => el.tagName),
|
|
292
|
+
['H1', 'PRE', 'OL']);
|
|
309
293
|
assert.deepStrictEqual(
|
|
310
|
-
[...parse(`${'
|
|
311
|
-
['P']);
|
|
294
|
+
[...run(parse(`${'['.repeat(100)}0`)).children].map(el => el.tagName),
|
|
295
|
+
['P', 'OL']);
|
|
312
296
|
assert.deepStrictEqual(
|
|
313
|
-
[...parse(`${'
|
|
314
|
-
['H1', 'PRE']);
|
|
297
|
+
[...run(parse(`${'['.repeat(101)}0`)).children].map(el => el.tagName),
|
|
298
|
+
['H1', 'PRE', 'OL']);
|
|
315
299
|
assert.deepStrictEqual(
|
|
316
|
-
[...parse(`${'
|
|
300
|
+
[...run(parse(`${'{'.repeat(102)}0`)).children].map(el => el.tagName),
|
|
317
301
|
['P', 'OL']);
|
|
318
302
|
assert.deepStrictEqual(
|
|
319
|
-
[...parse(`${'
|
|
320
|
-
['H1', 'PRE']);
|
|
303
|
+
[...run(parse(`${'{'.repeat(103)}0`)).children].map(el => el.tagName),
|
|
304
|
+
['H1', 'PRE', 'OL']);
|
|
321
305
|
assert.deepStrictEqual(
|
|
322
|
-
[...parse(
|
|
306
|
+
[...run(parse(`${'{ '.repeat(100)}0`)).children].map(el => el.tagName),
|
|
323
307
|
['P', 'OL']);
|
|
324
308
|
assert.deepStrictEqual(
|
|
325
|
-
[...parse(
|
|
326
|
-
['
|
|
309
|
+
[...run(parse(`${'{ '.repeat(1000)}0`)).children].map(el => el.tagName),
|
|
310
|
+
['P', 'OL']);
|
|
327
311
|
assert.deepStrictEqual(
|
|
328
|
-
[...parse(`${'
|
|
312
|
+
[...run(parse(`${'{ '.repeat(100)}0`)).children].map(el => el.tagName),
|
|
329
313
|
['P', 'OL']);
|
|
330
314
|
assert.deepStrictEqual(
|
|
331
|
-
[...parse(`${'
|
|
332
|
-
['H1', 'PRE']);
|
|
315
|
+
[...run(parse(`${'{ '.repeat(101)}0`)).children].map(el => el.tagName),
|
|
316
|
+
['H1', 'PRE', 'OL']);
|
|
333
317
|
assert.deepStrictEqual(
|
|
334
|
-
[...parse(`${'(('.repeat(2)}0${'))'.repeat(2)}
|
|
335
|
-
['P', 'OL']);
|
|
318
|
+
[...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}`)).children].map(el => el.tagName),
|
|
319
|
+
['P', 'OL', 'OL']);
|
|
320
|
+
assert.deepStrictEqual(
|
|
321
|
+
[...run(parse(`${'(('.repeat(3)}0${'))'.repeat(3)}`)).children].map(el => el.tagName),
|
|
322
|
+
['H1', 'PRE', 'OL']);
|
|
323
|
+
assert.deepStrictEqual(
|
|
324
|
+
[...run(parse(`(${'(('.repeat(2)}0${'))'.repeat(2)}`)).children].map(el => el.tagName),
|
|
325
|
+
['P', 'OL', 'OL']);
|
|
326
|
+
assert.deepStrictEqual(
|
|
327
|
+
[...run(parse(`(${'(('.repeat(3)}0${'))'.repeat(3)}`)).children].map(el => el.tagName),
|
|
328
|
+
['H1', 'PRE', 'OL']);
|
|
329
|
+
assert.deepStrictEqual(
|
|
330
|
+
[...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(2)}0${'))'.repeat(2)}`)).children].map(el => el.tagName),
|
|
331
|
+
['P', 'OL', 'OL']);
|
|
336
332
|
assert.deepStrictEqual(
|
|
337
|
-
[...parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(
|
|
338
|
-
['H1', 'PRE']);
|
|
333
|
+
[...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(3)}0${'))'.repeat(3)}`)).children].map(el => el.tagName),
|
|
334
|
+
['H1', 'PRE', 'OL']);
|
|
339
335
|
assert.deepStrictEqual(
|
|
340
|
-
[...parse(`${'(('.repeat(
|
|
341
|
-
['
|
|
336
|
+
[...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(9)}0${'))'.repeat(2)}`)).children].map(el => el.tagName),
|
|
337
|
+
['P', 'OL', 'OL']);
|
|
338
|
+
assert.deepStrictEqual(
|
|
339
|
+
[...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(9)}0${'))'.repeat(3)}`)).children].map(el => el.tagName),
|
|
340
|
+
['H1', 'PRE', 'OL']);
|
|
341
|
+
assert.deepStrictEqual(
|
|
342
|
+
[...run(parse(`${'(('.repeat(3)}0))((1))))))`)).children].map(el => el.tagName),
|
|
343
|
+
['H1', 'PRE', 'OL']);
|
|
342
344
|
});
|
|
343
345
|
|
|
344
346
|
it('recovery', () => {
|
|
345
347
|
assert.deepStrictEqual(
|
|
346
|
-
[...parse(`${'
|
|
347
|
-
[
|
|
348
|
-
`<p>${'['.repeat(20)}0</p>`,
|
|
349
|
-
'<p>[a]</p>',
|
|
350
|
-
]);
|
|
351
|
-
assert.deepStrictEqual(
|
|
352
|
-
[...parse(`${'['.repeat(21)}0\n\n[a]`).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
348
|
+
[...run(parse(`${'('.repeat(101)}0\n\n*a*`)).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
353
349
|
[
|
|
354
350
|
'<h1 id="error:rnd" class="error">Error: Too much recursion</h1>',
|
|
355
|
-
`<pre class="error" translate="no">${'
|
|
356
|
-
'<p>
|
|
351
|
+
`<pre class="error" translate="no">${'('.repeat(101)}0\n</pre>`,
|
|
352
|
+
'<p><em>a</em></p>',
|
|
353
|
+
'<ol class="references"></ol>',
|
|
357
354
|
]);
|
|
358
355
|
});
|
|
359
356
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
it('creation', function () {
|
|
363
|
-
this.timeout(10000);
|
|
357
|
+
it('creation', () => {
|
|
364
358
|
assert.deepStrictEqual(
|
|
365
|
-
[...parse('.'.repeat(100000)).children]
|
|
366
|
-
|
|
359
|
+
[...run(parse('.'.repeat(100000), {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
|
|
360
|
+
.map(el => el.outerHTML),
|
|
361
|
+
[`<p>${'.'.repeat(100000)}</p>`, '<ol class="references"></ol>']);
|
|
367
362
|
});
|
|
368
363
|
|
|
369
|
-
it
|
|
370
|
-
this.timeout(10000);
|
|
364
|
+
it('creation error', () => {
|
|
371
365
|
assert.deepStrictEqual(
|
|
372
|
-
[...parse('.'.repeat(100001)
|
|
366
|
+
[...run(parse('.'.repeat(100001), {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
|
|
367
|
+
.map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
373
368
|
[
|
|
374
369
|
'<h1 id="error:rnd" class="error">Error: Too many creations</h1>',
|
|
375
370
|
`<pre class="error" translate="no">${'.'.repeat(1000 - 3)}...</pre>`,
|
|
371
|
+
'<ol class="references"></ol>',
|
|
376
372
|
]);
|
|
377
373
|
});
|
|
378
374
|
|
|
@@ -380,30 +376,30 @@ describe('Unit: api/parse', () => {
|
|
|
380
376
|
// 最悪計算量での実行速度はCommonMarkの公式JS実装の32nに対して1-4倍程度。
|
|
381
377
|
// 5n = reference + link + url/math + ruby + text
|
|
382
378
|
assert.deepStrictEqual(
|
|
383
|
-
[...parse(`((([[[[#$http://[${'.'.repeat(
|
|
379
|
+
[...run(parse(`((([[[[#$http://[${'.'.repeat(19983)}`, {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
|
|
384
380
|
.map(el => el.tagName),
|
|
385
|
-
['P']);
|
|
381
|
+
['P', 'OL']);
|
|
386
382
|
});
|
|
387
383
|
|
|
388
384
|
it('backtrack 1 error', () => {
|
|
389
385
|
assert.deepStrictEqual(
|
|
390
|
-
[...parse(`((([[[[#$http://[${'.'.repeat(
|
|
386
|
+
[...run(parse(`((([[[[#$http://[${'.'.repeat(19983 + 1)}`, {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
|
|
391
387
|
.map(el => el.tagName),
|
|
392
|
-
['H1', 'PRE']);
|
|
388
|
+
['H1', 'PRE', 'OL']);
|
|
393
389
|
});
|
|
394
390
|
|
|
395
391
|
it('backtrack 2', () => {
|
|
396
392
|
assert.deepStrictEqual(
|
|
397
|
-
[...parse(`((([[[[#$http://[${'.'.repeat(
|
|
393
|
+
[...run(parse(`((([[[[#$http://[${'.'.repeat(33313)}]]]`, {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
|
|
398
394
|
.map(el => el.tagName),
|
|
399
395
|
['P', 'OL']);
|
|
400
396
|
});
|
|
401
397
|
|
|
402
398
|
it('backtrack 2 error', () => {
|
|
403
399
|
assert.deepStrictEqual(
|
|
404
|
-
[...parse(`((([[[[#$http://[${'.'.repeat(
|
|
400
|
+
[...run(parse(`((([[[[#$http://[${'.'.repeat(33313 + 1)}]]]`, {}, new Input({ resources: { clock: 100000, recursions: [100] } }))).children]
|
|
405
401
|
.map(el => el.tagName),
|
|
406
|
-
['H1', 'PRE']);
|
|
402
|
+
['H1', 'PRE', 'OL']);
|
|
407
403
|
});
|
|
408
404
|
|
|
409
405
|
});
|
package/src/api/parse.ts
CHANGED
|
@@ -1,48 +1,30 @@
|
|
|
1
1
|
import { ParserOptions } from '../..';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { block } from '../parser/block';
|
|
6
|
-
import { headers } from './header';
|
|
7
|
-
import { figure } from '../processor/figure';
|
|
8
|
-
import { note } from '../processor/note';
|
|
2
|
+
import { Input, Options } from '../parser/context';
|
|
3
|
+
import { Output, run } from '../combinator/parser';
|
|
4
|
+
import { document } from '../parser/document';
|
|
9
5
|
import { ReadonlyURL } from 'spica/url';
|
|
10
|
-
import { frag } from 'typed-dom/dom';
|
|
11
6
|
|
|
12
7
|
interface Opts extends ParserOptions {
|
|
13
8
|
readonly local?: boolean;
|
|
14
9
|
readonly test?: boolean;
|
|
15
10
|
}
|
|
16
11
|
|
|
17
|
-
export function parse(source: string, opts: Opts = {}, options?: Options): DocumentFragment {
|
|
18
|
-
const url = headers(source).find(field => field.toLowerCase().startsWith('url:'))?.slice(4).trim() ?? '';
|
|
12
|
+
export function* parse(source: string, opts: Opts = {}, options?: Options): Generator<void, DocumentFragment, void> {
|
|
19
13
|
options = {
|
|
20
14
|
host: opts.host ?? options?.host ?? new ReadonlyURL(location.pathname, location.origin),
|
|
21
|
-
url:
|
|
15
|
+
url: options?.url,
|
|
22
16
|
id: opts.id ?? options?.id,
|
|
23
|
-
|
|
17
|
+
notes: opts.notes ?? options?.notes,
|
|
24
18
|
caches: options?.caches,
|
|
25
19
|
resources: options?.resources,
|
|
20
|
+
header: true,
|
|
21
|
+
test: opts.test,
|
|
26
22
|
};
|
|
27
23
|
if (options.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
|
|
28
24
|
if (options.host?.origin === 'null') throw new Error(`Invalid host: ${options.host.href}`);
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const es = block(input(seg, new Context(options)))!
|
|
35
|
-
.foldl<HTMLElement[]>((acc, { value }) => void acc.push(value) || acc, [])
|
|
36
|
-
// @ts-expect-error
|
|
37
|
-
options.header = false;
|
|
38
|
-
if (es.length === 0) continue;
|
|
39
|
-
node.append(...es);
|
|
40
|
-
}
|
|
41
|
-
assert(opts.id !== '' || !node.querySelector('[id], .index[href], .label[href], .annotation > a[href], .reference > a[href]'));
|
|
42
|
-
if (opts.test) return node;
|
|
43
|
-
for (const _ of figure(node, opts.notes, options));
|
|
44
|
-
for (const _ of note(node, opts.notes, options));
|
|
45
|
-
assert(opts.id !== '' || !node.querySelector('[id], .index[href], .label[href], .annotation > a[href], .reference > a[href]'));
|
|
46
|
-
assert(opts.id !== '' || !opts.notes?.references.querySelector('[id], .index[href], .label[href]'));
|
|
47
|
-
return node;
|
|
25
|
+
const output = new Output<DocumentFragment>();
|
|
26
|
+
for (const _ of run(document, new Input(options, source), output)) yield;
|
|
27
|
+
assert(output.data.length === 1);
|
|
28
|
+
assert(output.peek().length === 1);
|
|
29
|
+
return output.peek().head!.value;
|
|
48
30
|
}
|