securemark 0.300.5 → 0.300.7
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/dist/index.js +12 -25
- package/package.json +1 -1
- package/src/api/parse.test.ts +0 -27
- package/src/combinator/parser/list.ts +2 -1
- package/src/parser/context.ts +0 -18
- package/src/parser/inline/annotation.test.ts +27 -0
- package/src/parser/inline/annotation.ts +16 -7
- package/src/parser/repeat.ts +1 -0
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.300.
|
|
1
|
+
/*! securemark v0.300.7 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
|
|
2
2
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
3
3
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
4
4
|
module.exports = factory(require("Prism"), require("DOMPurify"));
|
|
@@ -6414,7 +6414,6 @@ exports.input = input;
|
|
|
6414
6414
|
class Input extends parser_1.Input {
|
|
6415
6415
|
constructor(options = {}, source) {
|
|
6416
6416
|
super(options);
|
|
6417
|
-
this.recursion = new RecursionCounter(2);
|
|
6418
6417
|
const {
|
|
6419
6418
|
segment,
|
|
6420
6419
|
header,
|
|
@@ -6449,23 +6448,6 @@ class Input extends parser_1.Input {
|
|
|
6449
6448
|
}
|
|
6450
6449
|
}
|
|
6451
6450
|
exports.Input = Input;
|
|
6452
|
-
class RecursionCounter {
|
|
6453
|
-
constructor(limit) {
|
|
6454
|
-
this.limit = limit;
|
|
6455
|
-
this.stack = [];
|
|
6456
|
-
this.index = 0;
|
|
6457
|
-
}
|
|
6458
|
-
add(depth) {
|
|
6459
|
-
const {
|
|
6460
|
-
stack
|
|
6461
|
-
} = this;
|
|
6462
|
-
for (; this.index > 0 && stack[this.index - 1] >= depth; --this.index);
|
|
6463
|
-
// 内側から数えるので無効化処理できずエラーを投げるしかない。
|
|
6464
|
-
if (this.index === this.limit) return new Error(`Too much recursion`);
|
|
6465
|
-
stack[this.index] = depth;
|
|
6466
|
-
++this.index;
|
|
6467
|
-
}
|
|
6468
|
-
}
|
|
6469
6451
|
|
|
6470
6452
|
/***/ },
|
|
6471
6453
|
|
|
@@ -6729,9 +6711,7 @@ exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(1
|
|
|
6729
6711
|
const {
|
|
6730
6712
|
position,
|
|
6731
6713
|
linebreak,
|
|
6732
|
-
range
|
|
6733
|
-
recursion,
|
|
6734
|
-
resources
|
|
6714
|
+
range
|
|
6735
6715
|
} = input;
|
|
6736
6716
|
if (linebreak !== 0 || nodes.length === 0 || lead === 0 || follow % 2 === 0) {
|
|
6737
6717
|
nodes.unshift(new parser_1.Node('('));
|
|
@@ -6740,14 +6720,20 @@ exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(1
|
|
|
6740
6720
|
class: (0, bracket_1.bracketname)(input, 1, 1)
|
|
6741
6721
|
}, (0, dom_1.defrag)((0, util_1.unwrap)(nodes))))]);
|
|
6742
6722
|
}
|
|
6743
|
-
output.error ??= recursion.add(resources?.recursions[2 /* Recursion.inline */] ?? resources?.recursions.at(-1));
|
|
6744
6723
|
input.position += 1;
|
|
6745
6724
|
const el = (0, dom_1.html)('sup', {
|
|
6746
6725
|
class: 'annotation'
|
|
6747
6726
|
}, [(0, dom_1.html)('span', (0, dom_1.defrag)((0, util_1.unwrap)((0, visibility_1.trimBlankNodeEnd)(nodes))))]);
|
|
6748
6727
|
for (let list = output.annotations.at(-1), node = list.last, pos = position - range, i = 0;; node = node.prev, ++i) {
|
|
6749
|
-
if (node && node.position > pos)
|
|
6750
|
-
|
|
6728
|
+
if (node && node.position > pos) {
|
|
6729
|
+
if (~node.flags & 2 /* Node.Flag.nested */) continue;
|
|
6730
|
+
return new parser_1.List([new parser_1.Node((0, dom_1.define)(el.firstElementChild, {
|
|
6731
|
+
class: 'invalid',
|
|
6732
|
+
...(0, util_1.invalid)('annotation', 'syntax', 'Recursions must be two or fewer')
|
|
6733
|
+
}))]);
|
|
6734
|
+
}
|
|
6735
|
+
const flag = i === 0 ? 0 /* Node.Flag.none */ : 2 /* Node.Flag.nested */;
|
|
6736
|
+
i === list.length ? list.unshift(new parser_1.Node(el, pos, flag)) : list.insert(new parser_1.Node(el, pos, flag), node?.next);
|
|
6751
6737
|
break;
|
|
6752
6738
|
}
|
|
6753
6739
|
return new parser_1.List([new parser_1.Node(el)]);
|
|
@@ -8685,6 +8671,7 @@ function repeat(opener, after, closer, recursion, parser, cons, termination = (n
|
|
|
8685
8671
|
input.position += closer.length;
|
|
8686
8672
|
const pos = input.position;
|
|
8687
8673
|
m.follow = m.follow > 0 ? m.follow : countFollows(source, pos, closer, lead / opener.length | 0);
|
|
8674
|
+
input.range = input.position - m.position - m.i + opener.length;
|
|
8688
8675
|
output.push(cons(output.pop(), input, output, lead, m.follow));
|
|
8689
8676
|
if (input.position > pos) {
|
|
8690
8677
|
const advance = input.position - pos;
|
package/package.json
CHANGED
package/src/api/parse.test.ts
CHANGED
|
@@ -314,33 +314,6 @@ describe('Unit: api/parse', () => {
|
|
|
314
314
|
assert.deepStrictEqual(
|
|
315
315
|
[...run(parse(`${'{ '.repeat(101)}0`)).children].map(el => el.tagName),
|
|
316
316
|
['H1', 'PRE', 'OL']);
|
|
317
|
-
assert.deepStrictEqual(
|
|
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']);
|
|
332
|
-
assert.deepStrictEqual(
|
|
333
|
-
[...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(3)}0${'))'.repeat(3)}`)).children].map(el => el.tagName),
|
|
334
|
-
['H1', 'PRE', 'OL']);
|
|
335
|
-
assert.deepStrictEqual(
|
|
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']);
|
|
344
317
|
});
|
|
345
318
|
|
|
346
319
|
it('recovery', () => {
|
package/src/parser/context.ts
CHANGED
|
@@ -56,7 +56,6 @@ export class Input<M extends object = object> extends Ipt<M> {
|
|
|
56
56
|
public header: boolean;
|
|
57
57
|
public local: boolean;
|
|
58
58
|
public whitespace: boolean;
|
|
59
|
-
public recursion = new RecursionCounter(2);
|
|
60
59
|
public readonly host?: URL;
|
|
61
60
|
public readonly url?: URL;
|
|
62
61
|
public id?: string;
|
|
@@ -72,23 +71,6 @@ export class Input<M extends object = object> extends Ipt<M> {
|
|
|
72
71
|
}
|
|
73
72
|
export type Options = Partial<Input>;
|
|
74
73
|
|
|
75
|
-
class RecursionCounter {
|
|
76
|
-
constructor(
|
|
77
|
-
private readonly limit: number,
|
|
78
|
-
) {
|
|
79
|
-
}
|
|
80
|
-
private readonly stack: number[] = [];
|
|
81
|
-
private index = 0;
|
|
82
|
-
public add(depth: number): Error | undefined {
|
|
83
|
-
const { stack } = this
|
|
84
|
-
for (; this.index > 0 && stack[this.index - 1] >= depth; --this.index);
|
|
85
|
-
// 内側から数えるので無効化処理できずエラーを投げるしかない。
|
|
86
|
-
if (this.index === this.limit) return new Error(`Too much recursion`);
|
|
87
|
-
stack[this.index] = depth;
|
|
88
|
-
++this.index;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
74
|
export const enum Segment {
|
|
93
75
|
unknown = 0,
|
|
94
76
|
read = 0,
|
|
@@ -62,6 +62,33 @@ describe('Unit: parser/inline/annotation', () => {
|
|
|
62
62
|
assert.deepStrictEqual(inspect(parser, input('(((a)))')), [['<sup class="annotation"><span><span class="paren">(a)</span></span></sup>'], '']);
|
|
63
63
|
assert.deepStrictEqual(inspect(parser, input('((((a))))')), [['<sup class="annotation"><span><sup class="annotation"><span>a</span></sup></span></sup>'], '']);
|
|
64
64
|
assert.deepStrictEqual(inspect(parser, input('(([[a]]))')), [['<sup class="annotation"><span><sup class="reference"><span>a</span></sup></span></sup>'], '']);
|
|
65
|
+
assert.deepStrictEqual(
|
|
66
|
+
inspect(parser, input(`${'(('.repeat(2)}0${'))'.repeat(2)}`)),
|
|
67
|
+
[['<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>'], '']);
|
|
68
|
+
assert.deepStrictEqual(
|
|
69
|
+
inspect(parser, input(`${'(('.repeat(3)}0${'))'.repeat(3)}`)),
|
|
70
|
+
[['<span class="invalid"><sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup></span>'], '']);
|
|
71
|
+
assert.deepStrictEqual(
|
|
72
|
+
inspect(parser, input(`(${'(('.repeat(2)}0${'))'.repeat(2)}`)),
|
|
73
|
+
[['<span class="paren">(<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup></span>'], '']);
|
|
74
|
+
assert.deepStrictEqual(
|
|
75
|
+
inspect(parser, input(`(${'(('.repeat(3)}0${'))'.repeat(3)}`)),
|
|
76
|
+
[['<span class="paren">(<span class="invalid"><sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup></span></span>'], '']);
|
|
77
|
+
assert.deepStrictEqual(
|
|
78
|
+
inspect(parser, input(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(2)}0${'))'.repeat(2)}`)),
|
|
79
|
+
[['<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>', '<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>'], '']);
|
|
80
|
+
assert.deepStrictEqual(
|
|
81
|
+
inspect(parser, input(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(3)}0${'))'.repeat(2)}`)),
|
|
82
|
+
[['<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>', '<span class="paren">(<span class="paren">(<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup></span></span>'], '']);
|
|
83
|
+
assert.deepStrictEqual(
|
|
84
|
+
inspect(parser, input(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(3)}0${'))'.repeat(3)}`)),
|
|
85
|
+
[['<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>', '<span class="invalid"><sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup></span>'], '']);
|
|
86
|
+
assert.deepStrictEqual(
|
|
87
|
+
inspect(parser, input(`${'(('.repeat(3)}0))((1))))))`)),
|
|
88
|
+
[['<span class="invalid"><sup class="annotation"><span><sup class="annotation"><span>0</span></sup><sup class="annotation"><span>1</span></sup></span></sup></span>'], '']);
|
|
89
|
+
assert.deepStrictEqual(
|
|
90
|
+
inspect(parser, input(`${'(0'.repeat(4)}((0${'))'.repeat(3)}${'(('.repeat(2)}0${'))'.repeat(2)}`)),
|
|
91
|
+
[['<span class="paren">(0<span class="paren">(0<span class="paren">(0<span class="paren">(0<sup class="annotation"><span>0</span></sup>)</span>)</span>)</span>)</span>', '<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>'], '']);
|
|
65
92
|
});
|
|
66
93
|
|
|
67
94
|
});
|
|
@@ -6,8 +6,8 @@ import { inline } from '../inline';
|
|
|
6
6
|
import { bracketname } from './bracket';
|
|
7
7
|
import { repeat } from '../repeat';
|
|
8
8
|
import { beforeNonblank, trimBlankNodeEnd } from '../visibility';
|
|
9
|
-
import { unwrap } from '../util';
|
|
10
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
9
|
+
import { unwrap, invalid } from '../util';
|
|
10
|
+
import { html, define, defrag } from 'typed-dom/dom';
|
|
11
11
|
|
|
12
12
|
// シグネチャ等生成のために構文木のツリーウォークを再帰的に行い指数計算量にならないよう
|
|
13
13
|
// 動的計画法を適用するか再帰数を制限する必要がある。
|
|
@@ -32,7 +32,7 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
|
|
|
32
32
|
([, bs], _, output) => output.import(bs),
|
|
33
33
|
([, bs], _, output) => bs && output.import(bs.push(new Node(Command.Cancel)))))),
|
|
34
34
|
(nodes, input, output, lead, follow) => {
|
|
35
|
-
const { position, linebreak, range
|
|
35
|
+
const { position, linebreak, range } = input;
|
|
36
36
|
if (linebreak !== 0 || nodes.length === 0 || lead === 0 || follow % 2 === 0) {
|
|
37
37
|
nodes.unshift(new Node('('));
|
|
38
38
|
nodes.push(new Node(')'));
|
|
@@ -40,16 +40,25 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
|
|
|
40
40
|
new Node(html('span', { class: bracketname(input, 1, 1) }, defrag(unwrap(nodes))))
|
|
41
41
|
]);
|
|
42
42
|
}
|
|
43
|
-
output.error ??= recursion.add(resources?.recursions[Recursion.inline] ?? resources?.recursions.at(-1));
|
|
44
43
|
input.position += 1;
|
|
45
44
|
const el = html('sup', { class: 'annotation' }, [
|
|
46
45
|
html('span', defrag(unwrap(trimBlankNodeEnd(nodes))))
|
|
47
46
|
]);
|
|
48
47
|
for (let list = output.annotations.at(-1)!, node = list.last, pos = position - range, i = 0; ; node = node!.prev, ++i) {
|
|
49
|
-
if (node && node.position > pos)
|
|
48
|
+
if (node && node.position > pos) {
|
|
49
|
+
if (~node.flags & Node.Flag.nested) continue;
|
|
50
|
+
return new List([
|
|
51
|
+
new Node(define(el.firstElementChild as HTMLElement,
|
|
52
|
+
{
|
|
53
|
+
class: 'invalid',
|
|
54
|
+
...invalid('annotation', 'syntax', 'Recursions must be two or fewer')
|
|
55
|
+
}))
|
|
56
|
+
]);
|
|
57
|
+
}
|
|
58
|
+
const flag = i === 0 ? Node.Flag.none : Node.Flag.nested;
|
|
50
59
|
i === list.length
|
|
51
|
-
? list.unshift(new Node(el, pos))
|
|
52
|
-
: list.insert(new Node(el, pos), node?.next);
|
|
60
|
+
? list.unshift(new Node(el, pos, flag))
|
|
61
|
+
: list.insert(new Node(el, pos, flag), node?.next);
|
|
53
62
|
break;
|
|
54
63
|
}
|
|
55
64
|
return new List([new Node(el)]);
|
package/src/parser/repeat.ts
CHANGED
|
@@ -93,6 +93,7 @@ export function repeat<T extends HTMLElement | string>(
|
|
|
93
93
|
input.position += closer.length;
|
|
94
94
|
const pos = input.position;
|
|
95
95
|
m.follow = m.follow > 0 ? m.follow : countFollows(source, pos, closer, lead / opener.length | 0);
|
|
96
|
+
input.range = input.position - m.position - m.i + opener.length;
|
|
96
97
|
output.push(cons(output.pop(), input, output, lead, m.follow));
|
|
97
98
|
if (input.position > pos) {
|
|
98
99
|
const advance = input.position - pos;
|