securemark 0.298.5 → 0.298.6
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 +4 -0
- package/dist/index.js +64 -27
- package/package.json +1 -1
- package/src/combinator/data/delimiter.ts +40 -14
- package/src/combinator/data/parser/context.ts +5 -3
- package/src/combinator/data/parser/some.ts +2 -0
- package/src/combinator/data/parser/union.ts +1 -4
- package/src/combinator/data/parser.ts +7 -0
- package/src/parser/inline/autolink/url.test.ts +1 -0
- package/src/parser/inline/deletion.ts +3 -3
- package/src/parser/inline/emstrong.ts +3 -3
- package/src/parser/inline/insertion.ts +3 -3
- package/src/parser/inline/italic.ts +3 -3
- package/src/parser/inline/mark.ts +3 -3
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.298.
|
|
1
|
+
/*! securemark v0.298.6 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"));
|
|
@@ -3376,16 +3376,24 @@ class Delimiters {
|
|
|
3376
3376
|
exports.Delimiters = Delimiters;
|
|
3377
3377
|
function matcher(pattern, advance, after) {
|
|
3378
3378
|
const count = typeof pattern === 'object' ? /[^^\\*+][*+]|{\d+,}/.test(pattern.source) : false;
|
|
3379
|
+
let sid = 0,
|
|
3380
|
+
pos = 0,
|
|
3381
|
+
index = -1;
|
|
3379
3382
|
switch (typeof pattern) {
|
|
3380
3383
|
case 'string':
|
|
3381
3384
|
if (pattern === '') return () => new parser_1.List([new parser_1.Node(pattern)]);
|
|
3382
3385
|
return input => {
|
|
3383
3386
|
const context = input;
|
|
3384
3387
|
const {
|
|
3388
|
+
SID,
|
|
3385
3389
|
source,
|
|
3386
3390
|
position
|
|
3387
3391
|
} = context;
|
|
3388
|
-
|
|
3392
|
+
const hit = SID === sid && position === pos;
|
|
3393
|
+
index = hit ? index : source.startsWith(pattern, position) ? position : -1;
|
|
3394
|
+
sid = SID;
|
|
3395
|
+
pos = position;
|
|
3396
|
+
if (index === -1) return;
|
|
3389
3397
|
if (advance) {
|
|
3390
3398
|
context.position += pattern.length;
|
|
3391
3399
|
}
|
|
@@ -3396,15 +3404,20 @@ function matcher(pattern, advance, after) {
|
|
|
3396
3404
|
return input => {
|
|
3397
3405
|
const context = input;
|
|
3398
3406
|
const {
|
|
3407
|
+
SID,
|
|
3399
3408
|
source,
|
|
3400
3409
|
position
|
|
3401
3410
|
} = context;
|
|
3411
|
+
const hit = SID === sid && position === pos;
|
|
3402
3412
|
pattern.lastIndex = position;
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3413
|
+
index = hit ? index : pattern.test(source) ? pattern.lastIndex : -1;
|
|
3414
|
+
sid = SID;
|
|
3415
|
+
pos = position;
|
|
3416
|
+
if (index === -1) return;
|
|
3417
|
+
const src = source.slice(position, index);
|
|
3418
|
+
count && !hit && (0, context_1.consume)(src.length, context);
|
|
3406
3419
|
if (advance) {
|
|
3407
|
-
context.position
|
|
3420
|
+
context.position = index;
|
|
3408
3421
|
}
|
|
3409
3422
|
const next = after?.(input);
|
|
3410
3423
|
return after ? next && new parser_1.List([new parser_1.Node(src)]).import(next) : new parser_1.List([new parser_1.Node(src)]);
|
|
@@ -3414,16 +3427,24 @@ function matcher(pattern, advance, after) {
|
|
|
3414
3427
|
exports.matcher = matcher;
|
|
3415
3428
|
function tester(pattern, advance, after) {
|
|
3416
3429
|
const count = typeof pattern === 'object' ? /[^^\\*+][*+]|{\d+,}/.test(pattern.source) : false;
|
|
3430
|
+
let sid = 0,
|
|
3431
|
+
pos = 0,
|
|
3432
|
+
index = -1;
|
|
3417
3433
|
switch (typeof pattern) {
|
|
3418
3434
|
case 'string':
|
|
3419
3435
|
if (pattern === '') return () => new parser_1.List();
|
|
3420
3436
|
return input => {
|
|
3421
3437
|
const context = input;
|
|
3422
3438
|
const {
|
|
3439
|
+
SID,
|
|
3423
3440
|
source,
|
|
3424
3441
|
position
|
|
3425
3442
|
} = context;
|
|
3426
|
-
|
|
3443
|
+
const hit = SID === sid && position === pos;
|
|
3444
|
+
index = hit ? index : source.startsWith(pattern, position) ? position : -1;
|
|
3445
|
+
sid = SID;
|
|
3446
|
+
pos = position;
|
|
3447
|
+
if (index === -1) return;
|
|
3427
3448
|
if (advance) {
|
|
3428
3449
|
context.position += pattern.length;
|
|
3429
3450
|
}
|
|
@@ -3434,15 +3455,20 @@ function tester(pattern, advance, after) {
|
|
|
3434
3455
|
return input => {
|
|
3435
3456
|
const context = input;
|
|
3436
3457
|
const {
|
|
3458
|
+
SID,
|
|
3437
3459
|
source,
|
|
3438
3460
|
position
|
|
3439
3461
|
} = context;
|
|
3462
|
+
const hit = SID === sid && position === pos;
|
|
3440
3463
|
pattern.lastIndex = position;
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3464
|
+
index = hit ? index : pattern.test(source) ? pattern.lastIndex : -1;
|
|
3465
|
+
sid = SID;
|
|
3466
|
+
pos = position;
|
|
3467
|
+
if (index === -1) return;
|
|
3468
|
+
const len = index - position;
|
|
3469
|
+
count && !hit && (0, context_1.consume)(len, context);
|
|
3444
3470
|
if (advance) {
|
|
3445
|
-
context.position
|
|
3471
|
+
context.position = index;
|
|
3446
3472
|
}
|
|
3447
3473
|
if (after && after(input) === undefined) return;
|
|
3448
3474
|
return new parser_1.List();
|
|
@@ -3625,6 +3651,10 @@ class Node {
|
|
|
3625
3651
|
}
|
|
3626
3652
|
}
|
|
3627
3653
|
exports.Node = Node;
|
|
3654
|
+
let SID = 0;
|
|
3655
|
+
function sid() {
|
|
3656
|
+
return SID = ++SID >>> 0 || 1;
|
|
3657
|
+
}
|
|
3628
3658
|
class Context {
|
|
3629
3659
|
constructor({
|
|
3630
3660
|
source,
|
|
@@ -3639,6 +3669,7 @@ class Context {
|
|
|
3639
3669
|
offset,
|
|
3640
3670
|
backtracks
|
|
3641
3671
|
} = {}) {
|
|
3672
|
+
this.SID = sid();
|
|
3642
3673
|
this.source = source ?? '';
|
|
3643
3674
|
this.position = position ?? 0;
|
|
3644
3675
|
this.segment = segment ?? 0;
|
|
@@ -3654,6 +3685,7 @@ class Context {
|
|
|
3654
3685
|
}
|
|
3655
3686
|
exports.Context = Context;
|
|
3656
3687
|
function input(source, context) {
|
|
3688
|
+
context.SID = sid();
|
|
3657
3689
|
context.source = source;
|
|
3658
3690
|
context.position = 0;
|
|
3659
3691
|
return context;
|
|
@@ -3662,6 +3694,7 @@ exports.input = input;
|
|
|
3662
3694
|
function subinput(source, context) {
|
|
3663
3695
|
return {
|
|
3664
3696
|
...context,
|
|
3697
|
+
SID: sid(),
|
|
3665
3698
|
source,
|
|
3666
3699
|
position: 0,
|
|
3667
3700
|
offset: 0,
|
|
@@ -3808,13 +3841,15 @@ function recursions(rs, parser) {
|
|
|
3808
3841
|
} = resources;
|
|
3809
3842
|
for (const recursion of rs) {
|
|
3810
3843
|
const rec = (0, alias_1.min)(recursion, recursions.length - 1);
|
|
3811
|
-
if (rec
|
|
3812
|
-
rec
|
|
3844
|
+
if (rec === -1) continue;
|
|
3845
|
+
if (recursions[rec] < 1) throw new Error('Too much recursion');
|
|
3846
|
+
--recursions[rec];
|
|
3813
3847
|
}
|
|
3814
3848
|
const result = parser(input);
|
|
3815
3849
|
for (const recursion of rs) {
|
|
3816
3850
|
const rec = (0, alias_1.min)(recursion, recursions.length - 1);
|
|
3817
|
-
rec
|
|
3851
|
+
if (rec === -1) continue;
|
|
3852
|
+
++recursions[rec];
|
|
3818
3853
|
}
|
|
3819
3854
|
return result;
|
|
3820
3855
|
};
|
|
@@ -3975,8 +4010,10 @@ function some(parser, delimiter, after, delimiters, limit = -1) {
|
|
|
3975
4010
|
for (const len = source.length; context.position < len;) {
|
|
3976
4011
|
if (match(input)) break;
|
|
3977
4012
|
if (context.delimiters.test(input)) break;
|
|
4013
|
+
const pos = context.position;
|
|
3978
4014
|
const result = parser(input);
|
|
3979
4015
|
if (result === undefined) break;
|
|
4016
|
+
if (context.position === pos) break;
|
|
3980
4017
|
nodes = nodes?.import(result) ?? result;
|
|
3981
4018
|
if (limit >= 0 && context.position - position > limit) break;
|
|
3982
4019
|
}
|
|
@@ -4043,7 +4080,7 @@ function union(parsers) {
|
|
|
4043
4080
|
case 1:
|
|
4044
4081
|
return parsers[0];
|
|
4045
4082
|
default:
|
|
4046
|
-
return eval(['(
|
|
4083
|
+
return eval(['(', parsers.map((_, i) => `parser${i},`).join(''), ') =>', 'input =>', parsers.map((_, i) => `|| parser${i}(input)`).join('').slice(2)].join(''))(...parsers);
|
|
4047
4084
|
}
|
|
4048
4085
|
}
|
|
4049
4086
|
exports.union = union;
|
|
@@ -6790,11 +6827,11 @@ const inline_1 = __webpack_require__(7973);
|
|
|
6790
6827
|
const visibility_1 = __webpack_require__(6364);
|
|
6791
6828
|
const util_1 = __webpack_require__(4992);
|
|
6792
6829
|
const dom_1 = __webpack_require__(394);
|
|
6793
|
-
exports.deletion = (0, combinator_1.lazy)(() => (0,
|
|
6830
|
+
exports.deletion = (0, combinator_1.lazy)(() => (0, util_1.repeat)('~~', '', (0, combinator_1.precedence)(0, (0, combinator_1.recursion)(3 /* Recursion.inline */, (0, combinator_1.surround)('', (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, visibility_1.blankWith)('\n', '~~')), (0, combinator_1.open)('\n', (0, combinator_1.some)(inline_1.inline, '~'), true)])), '~~', false, [], ([, bs], {
|
|
6794
6831
|
buffer
|
|
6795
6832
|
}) => buffer.import(bs), ([, bs], {
|
|
6796
6833
|
buffer
|
|
6797
|
-
}) => bs && buffer.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && buffer)), nodes => new parser_1.List([new parser_1.Node((0, dom_1.html)('del', (0, dom_1.defrag)((0, util_1.unwrap)(nodes))))])))
|
|
6834
|
+
}) => bs && buffer.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && buffer))), nodes => new parser_1.List([new parser_1.Node((0, dom_1.html)('del', (0, dom_1.defrag)((0, util_1.unwrap)(nodes))))])));
|
|
6798
6835
|
|
|
6799
6836
|
/***/ },
|
|
6800
6837
|
|
|
@@ -6844,7 +6881,7 @@ const subemphasis = (0, combinator_1.lazy)(() => (0, combinator_1.some)((0, comb
|
|
|
6844
6881
|
// 開閉が明示的でない構文は開閉の不明確な記号による再帰的適用を行わず
|
|
6845
6882
|
// 可能な限り早く閉じるよう解析しなければならない。
|
|
6846
6883
|
// このため終端記号の後ろを見て終端を中止し同じ構文を再帰的に適用してはならない。
|
|
6847
|
-
exports.emstrong = (0, combinator_1.lazy)(() => (0,
|
|
6884
|
+
exports.emstrong = (0, combinator_1.lazy)(() => (0, util_1.repeat)('***', visibility_1.beforeNonblank, (0, combinator_1.precedence)(0, (0, combinator_1.recursion)(3 /* Recursion.inline */, (0, combinator_1.surround)('', (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, '*', visibility_1.afterNonblank)])), (0, source_1.strs)('*', 1, 3), false, [], ([, bs, cs], context) => {
|
|
6848
6885
|
const {
|
|
6849
6886
|
buffer
|
|
6850
6887
|
} = context;
|
|
@@ -6888,7 +6925,7 @@ exports.emstrong = (0, combinator_1.lazy)(() => (0, combinator_1.precedence)(0,
|
|
|
6888
6925
|
}
|
|
6889
6926
|
}, ([, bs], {
|
|
6890
6927
|
buffer
|
|
6891
|
-
}) => bs && buffer.import(bs) && buffer.push(new parser_1.Node("\u0018" /* Command.Cancel */)) && buffer)),
|
|
6928
|
+
}) => bs && buffer.import(bs) && buffer.push(new parser_1.Node("\u0018" /* Command.Cancel */)) && buffer))),
|
|
6892
6929
|
// 3以上の`*`に対してemの適用を保証する
|
|
6893
6930
|
nodes => new parser_1.List([new parser_1.Node((0, dom_1.html)('em', [(0, dom_1.html)('strong', (0, dom_1.defrag)((0, util_1.unwrap)(nodes)))]))]), (nodes, context, prefix, postfix, state) => {
|
|
6894
6931
|
context.position += postfix;
|
|
@@ -6943,7 +6980,7 @@ nodes => new parser_1.List([new parser_1.Node((0, dom_1.html)('em', [(0, dom_1.h
|
|
|
6943
6980
|
nodes = prepend('*'.repeat(prefix - postfix), nodes);
|
|
6944
6981
|
}
|
|
6945
6982
|
return nodes;
|
|
6946
|
-
}))
|
|
6983
|
+
}));
|
|
6947
6984
|
function prepend(prefix, nodes) {
|
|
6948
6985
|
if (typeof nodes.head?.value === 'string') {
|
|
6949
6986
|
nodes.head.value = prefix + nodes.head.value;
|
|
@@ -7416,11 +7453,11 @@ const inline_1 = __webpack_require__(7973);
|
|
|
7416
7453
|
const visibility_1 = __webpack_require__(6364);
|
|
7417
7454
|
const util_1 = __webpack_require__(4992);
|
|
7418
7455
|
const dom_1 = __webpack_require__(394);
|
|
7419
|
-
exports.insertion = (0, combinator_1.lazy)(() => (0,
|
|
7456
|
+
exports.insertion = (0, combinator_1.lazy)(() => (0, util_1.repeat)('++', '', (0, combinator_1.precedence)(0, (0, combinator_1.recursion)(3 /* Recursion.inline */, (0, combinator_1.surround)('', (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, visibility_1.blankWith)('\n', '++')), (0, combinator_1.open)('\n', (0, combinator_1.some)(inline_1.inline, '+'), true)])), '++', false, [], ([, bs], {
|
|
7420
7457
|
buffer
|
|
7421
7458
|
}) => buffer.import(bs), ([, bs], {
|
|
7422
7459
|
buffer
|
|
7423
|
-
}) => bs && buffer.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && buffer)), nodes => new parser_1.List([new parser_1.Node((0, dom_1.html)('ins', (0, dom_1.defrag)((0, util_1.unwrap)(nodes))))])))
|
|
7460
|
+
}) => bs && buffer.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && buffer))), nodes => new parser_1.List([new parser_1.Node((0, dom_1.html)('ins', (0, dom_1.defrag)((0, util_1.unwrap)(nodes))))])));
|
|
7424
7461
|
|
|
7425
7462
|
/***/ },
|
|
7426
7463
|
|
|
@@ -7443,11 +7480,11 @@ const dom_1 = __webpack_require__(394);
|
|
|
7443
7480
|
// 可読性のため実際にはオブリーク体を指定する。
|
|
7444
7481
|
// 斜体は単語に使うとかえって見づらく読み飛ばしやすくなるため使わないべきであり
|
|
7445
7482
|
// ある程度の長さのある文に使うのが望ましい。
|
|
7446
|
-
exports.italic = (0, combinator_1.lazy)(() => (0,
|
|
7483
|
+
exports.italic = (0, combinator_1.lazy)(() => (0, util_1.repeat)('///', visibility_1.beforeNonblank, (0, combinator_1.precedence)(0, (0, combinator_1.recursion)(3 /* Recursion.inline */, (0, combinator_1.surround)('', (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), '///', visibility_1.afterNonblank), '///', false, [], ([, bs], {
|
|
7447
7484
|
buffer
|
|
7448
7485
|
}) => buffer.import(bs), ([, bs], {
|
|
7449
7486
|
buffer
|
|
7450
|
-
}) => bs && buffer.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && buffer)), nodes => new parser_1.List([new parser_1.Node((0, dom_1.html)('i', (0, dom_1.defrag)((0, util_1.unwrap)(nodes))))])))
|
|
7487
|
+
}) => bs && buffer.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && buffer))), nodes => new parser_1.List([new parser_1.Node((0, dom_1.html)('i', (0, dom_1.defrag)((0, util_1.unwrap)(nodes))))])));
|
|
7451
7488
|
|
|
7452
7489
|
/***/ },
|
|
7453
7490
|
|
|
@@ -7624,11 +7661,11 @@ const indexee_1 = __webpack_require__(7610);
|
|
|
7624
7661
|
const visibility_1 = __webpack_require__(6364);
|
|
7625
7662
|
const util_1 = __webpack_require__(4992);
|
|
7626
7663
|
const dom_1 = __webpack_require__(394);
|
|
7627
|
-
exports.mark = (0, combinator_1.lazy)(() => (0,
|
|
7664
|
+
exports.mark = (0, combinator_1.lazy)(() => (0, util_1.repeat)('==', visibility_1.beforeNonblank, (0, combinator_1.precedence)(0, (0, combinator_1.recursion)(3 /* Recursion.inline */, (0, combinator_1.surround)('', (0, combinator_1.state)(2 /* State.mark */, (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), '==', visibility_1.afterNonblank)), '==', false, [], ([, bs], {
|
|
7628
7665
|
buffer
|
|
7629
7666
|
}) => buffer.import(bs), ([, bs], {
|
|
7630
7667
|
buffer
|
|
7631
|
-
}) => bs && buffer.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && buffer)), (nodes, {
|
|
7668
|
+
}) => bs && buffer.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && buffer))), (nodes, {
|
|
7632
7669
|
id,
|
|
7633
7670
|
state
|
|
7634
7671
|
}, nest) => {
|
|
@@ -7640,7 +7677,7 @@ exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.precedence)(0, (0,
|
|
|
7640
7677
|
return el.id ? new parser_1.List([new parser_1.Node(el), new parser_1.Node((0, dom_1.html)('a', {
|
|
7641
7678
|
href: `#${el.id}`
|
|
7642
7679
|
}))]) : new parser_1.List([new parser_1.Node(el)]);
|
|
7643
|
-
}))
|
|
7680
|
+
}));
|
|
7644
7681
|
|
|
7645
7682
|
/***/ },
|
|
7646
7683
|
|
package/package.json
CHANGED
|
@@ -161,13 +161,20 @@ export function matcher(pattern: string | RegExp, advance: boolean, after?: Pars
|
|
|
161
161
|
const count = typeof pattern === 'object'
|
|
162
162
|
? /[^^\\*+][*+]|{\d+,}/.test(pattern.source)
|
|
163
163
|
: false;
|
|
164
|
+
let sid = 0, pos = 0, index = -1;
|
|
164
165
|
switch (typeof pattern) {
|
|
165
166
|
case 'string':
|
|
166
167
|
if (pattern === '') return () => new List([new Node(pattern)]);
|
|
167
168
|
return input => {
|
|
168
169
|
const context = input;
|
|
169
|
-
const { source, position } = context;
|
|
170
|
-
|
|
170
|
+
const { SID, source, position } = context;
|
|
171
|
+
const hit = SID === sid && position === pos;
|
|
172
|
+
index = hit
|
|
173
|
+
? index
|
|
174
|
+
: source.startsWith(pattern, position) ? position : -1;
|
|
175
|
+
sid = SID;
|
|
176
|
+
pos = position;
|
|
177
|
+
if (index === -1) return;
|
|
171
178
|
if (advance) {
|
|
172
179
|
context.position += pattern.length;
|
|
173
180
|
}
|
|
@@ -180,13 +187,19 @@ export function matcher(pattern: string | RegExp, advance: boolean, after?: Pars
|
|
|
180
187
|
assert(pattern.sticky);
|
|
181
188
|
return input => {
|
|
182
189
|
const context = input;
|
|
183
|
-
const { source, position } = context;
|
|
190
|
+
const { SID, source, position } = context;
|
|
191
|
+
const hit = SID === sid && position === pos;
|
|
184
192
|
pattern.lastIndex = position;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
193
|
+
index = hit
|
|
194
|
+
? index
|
|
195
|
+
: pattern.test(source) ? pattern.lastIndex : -1;
|
|
196
|
+
sid = SID;
|
|
197
|
+
pos = position;
|
|
198
|
+
if (index === -1) return;
|
|
199
|
+
const src = source.slice(position, index);
|
|
200
|
+
count && !hit && consume(src.length, context);
|
|
188
201
|
if (advance) {
|
|
189
|
-
context.position
|
|
202
|
+
context.position = index;
|
|
190
203
|
}
|
|
191
204
|
const next = after?.(input);
|
|
192
205
|
return after
|
|
@@ -201,13 +214,20 @@ export function tester(pattern: string | RegExp, advance: boolean, after?: Parse
|
|
|
201
214
|
const count = typeof pattern === 'object'
|
|
202
215
|
? /[^^\\*+][*+]|{\d+,}/.test(pattern.source)
|
|
203
216
|
: false;
|
|
217
|
+
let sid = 0, pos = 0, index = -1;
|
|
204
218
|
switch (typeof pattern) {
|
|
205
219
|
case 'string':
|
|
206
220
|
if (pattern === '') return () => new List();
|
|
207
221
|
return input => {
|
|
208
222
|
const context = input;
|
|
209
|
-
const { source, position } = context;
|
|
210
|
-
|
|
223
|
+
const { SID, source, position } = context;
|
|
224
|
+
const hit = SID === sid && position === pos;
|
|
225
|
+
index = hit
|
|
226
|
+
? index
|
|
227
|
+
: source.startsWith(pattern, position) ? position : -1;
|
|
228
|
+
sid = SID;
|
|
229
|
+
pos = position;
|
|
230
|
+
if (index === -1) return;
|
|
211
231
|
if (advance) {
|
|
212
232
|
context.position += pattern.length;
|
|
213
233
|
}
|
|
@@ -218,13 +238,19 @@ export function tester(pattern: string | RegExp, advance: boolean, after?: Parse
|
|
|
218
238
|
assert(pattern.sticky);
|
|
219
239
|
return input => {
|
|
220
240
|
const context = input;
|
|
221
|
-
const { source, position } = context;
|
|
241
|
+
const { SID, source, position } = context;
|
|
242
|
+
const hit = SID === sid && position === pos;
|
|
222
243
|
pattern.lastIndex = position;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
244
|
+
index = hit
|
|
245
|
+
? index
|
|
246
|
+
: pattern.test(source) ? pattern.lastIndex : -1;
|
|
247
|
+
sid = SID;
|
|
248
|
+
pos = position;
|
|
249
|
+
if (index === -1) return;
|
|
250
|
+
const len = index - position;
|
|
251
|
+
count && !hit && consume(len, context);
|
|
226
252
|
if (advance) {
|
|
227
|
-
context.position
|
|
253
|
+
context.position = index;
|
|
228
254
|
}
|
|
229
255
|
if (after && after(input) === undefined) return;
|
|
230
256
|
return new List();
|
|
@@ -122,13 +122,15 @@ export function recursions(rs: readonly number[], parser: Parser): Parser {
|
|
|
122
122
|
assert(recursions.length > 0);
|
|
123
123
|
for (const recursion of rs) {
|
|
124
124
|
const rec = min(recursion, recursions.length - 1);
|
|
125
|
-
if (rec
|
|
126
|
-
rec
|
|
125
|
+
if (rec === -1) continue;
|
|
126
|
+
if (recursions[rec] < 1) throw new Error('Too much recursion');
|
|
127
|
+
--recursions[rec];
|
|
127
128
|
}
|
|
128
129
|
const result = parser(input);
|
|
129
130
|
for (const recursion of rs) {
|
|
130
131
|
const rec = min(recursion, recursions.length - 1);
|
|
131
|
-
rec
|
|
132
|
+
if (rec === -1) continue;
|
|
133
|
+
++recursions[rec];
|
|
132
134
|
}
|
|
133
135
|
return result;
|
|
134
136
|
};
|
|
@@ -38,8 +38,10 @@ export function some<N>(parser: Parser<N>, delimiter?: number | string | RegExp
|
|
|
38
38
|
for (const len = source.length; context.position < len;) {
|
|
39
39
|
if (match(input)) break;
|
|
40
40
|
if (context.delimiters.test(input)) break;
|
|
41
|
+
const pos = context.position;
|
|
41
42
|
const result = parser(input);
|
|
42
43
|
if (result === undefined) break;
|
|
44
|
+
if (context.position === pos) break;
|
|
43
45
|
nodes = nodes?.import(result) ?? result;
|
|
44
46
|
if (limit >= 0 && context.position - position > limit) break;
|
|
45
47
|
}
|
|
@@ -10,12 +10,9 @@ export function union<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context,
|
|
|
10
10
|
return parsers[0];
|
|
11
11
|
default:
|
|
12
12
|
return eval([
|
|
13
|
-
'((',
|
|
14
|
-
parsers.map((_, i) => `parser${i},`).join(''),
|
|
15
|
-
') =>',
|
|
13
|
+
'(', parsers.map((_, i) => `parser${i},`).join(''), ') =>',
|
|
16
14
|
'input =>',
|
|
17
15
|
parsers.map((_, i) => `|| parser${i}(input)`).join('').slice(2),
|
|
18
|
-
')',
|
|
19
16
|
].join(''))(...parsers);
|
|
20
17
|
}
|
|
21
18
|
}
|
|
@@ -26,6 +26,10 @@ export class Node<N> implements List.Node {
|
|
|
26
26
|
public next?: this = undefined;
|
|
27
27
|
public prev?: this = undefined;
|
|
28
28
|
}
|
|
29
|
+
let SID = 0;
|
|
30
|
+
function sid(): number {
|
|
31
|
+
return SID = ++SID >>> 0 || 1;
|
|
32
|
+
}
|
|
29
33
|
export class Context {
|
|
30
34
|
constructor(
|
|
31
35
|
{
|
|
@@ -54,6 +58,7 @@ export class Context {
|
|
|
54
58
|
this.offset = offset ?? 0;
|
|
55
59
|
this.backtracks = backtracks ?? {};
|
|
56
60
|
}
|
|
61
|
+
public SID: number = sid();
|
|
57
62
|
public source: string;
|
|
58
63
|
public position: number;
|
|
59
64
|
public segment: number;
|
|
@@ -110,6 +115,7 @@ export const enum Segment {
|
|
|
110
115
|
}
|
|
111
116
|
|
|
112
117
|
export function input<C extends Context>(source: string, context: C): Input<C> {
|
|
118
|
+
context.SID = sid();
|
|
113
119
|
context.source = source;
|
|
114
120
|
context.position = 0;
|
|
115
121
|
return context;
|
|
@@ -118,6 +124,7 @@ export function input<C extends Context>(source: string, context: C): Input<C> {
|
|
|
118
124
|
export function subinput<C extends Context>(source: string, context: C): Input<C> {
|
|
119
125
|
return {
|
|
120
126
|
...context,
|
|
127
|
+
SID: sid(),
|
|
121
128
|
source,
|
|
122
129
|
position: 0,
|
|
123
130
|
offset: 0,
|
|
@@ -83,6 +83,7 @@ describe('Unit: parser/inline/autolink/url', () => {
|
|
|
83
83
|
assert.deepStrictEqual(inspect(parser, input(' http://host>', new Context())), [['<a class="url" href="http://host" target="_blank">http://host</a>'], '>']);
|
|
84
84
|
assert.deepStrictEqual(inspect(parser, input(' http://host(', new Context())), [['<a class="url" href="http://host" target="_blank">http://host</a>'], '(']);
|
|
85
85
|
assert.deepStrictEqual(inspect(parser, input(' http://host)', new Context())), [['<a class="url" href="http://host" target="_blank">http://host</a>'], ')']);
|
|
86
|
+
assert.deepStrictEqual(inspect(parser, input(` http://host${'+'.repeat(5e5)}`, new Context())), [['<a class="url" href="http://host" target="_blank">http://host</a>'], '+'.repeat(5e5)]);
|
|
86
87
|
});
|
|
87
88
|
|
|
88
89
|
it('trailing entities', () => {
|
|
@@ -8,7 +8,7 @@ import { unwrap, repeat } from '../util';
|
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const deletion: DeletionParser = lazy(() =>
|
|
11
|
-
|
|
11
|
+
repeat('~~', '', precedence(0, recursion(Recursion.inline, surround(
|
|
12
12
|
'',
|
|
13
13
|
some(union([
|
|
14
14
|
some(inline, blankWith('\n', '~~')),
|
|
@@ -17,5 +17,5 @@ export const deletion: DeletionParser = lazy(() =>
|
|
|
17
17
|
'~~',
|
|
18
18
|
false, [],
|
|
19
19
|
([, bs], { buffer }) => buffer.import(bs),
|
|
20
|
-
([, bs], { buffer }) => bs && buffer.import(bs).push(new Node(Command.Cancel)) && buffer)),
|
|
21
|
-
nodes => new List([new Node(html('del', defrag(unwrap(nodes))))])))
|
|
20
|
+
([, bs], { buffer }) => bs && buffer.import(bs).push(new Node(Command.Cancel)) && buffer))),
|
|
21
|
+
nodes => new List([new Node(html('del', defrag(unwrap(nodes))))])));
|
|
@@ -23,7 +23,7 @@ const subemphasis: Parser.IntermediateParser<EmphasisParser> = lazy(() => some(u
|
|
|
23
23
|
// 可能な限り早く閉じるよう解析しなければならない。
|
|
24
24
|
// このため終端記号の後ろを見て終端を中止し同じ構文を再帰的に適用してはならない。
|
|
25
25
|
export const emstrong: EmStrongParser = lazy(() =>
|
|
26
|
-
|
|
26
|
+
repeat('***', beforeNonblank, precedence(0, recursion(Recursion.inline, surround(
|
|
27
27
|
'',
|
|
28
28
|
some(union([some(inline, '*', afterNonblank)])),
|
|
29
29
|
strs('*', 1, 3),
|
|
@@ -75,7 +75,7 @@ export const emstrong: EmStrongParser = lazy(() =>
|
|
|
75
75
|
}
|
|
76
76
|
assert(false);
|
|
77
77
|
},
|
|
78
|
-
([, bs], { buffer }) => bs && buffer.import(bs) && buffer.push(new Node(Command.Cancel)) && buffer)),
|
|
78
|
+
([, bs], { buffer }) => bs && buffer.import(bs) && buffer.push(new Node(Command.Cancel)) && buffer))),
|
|
79
79
|
// 3以上の`*`に対してemの適用を保証する
|
|
80
80
|
nodes => new List([new Node(html('em', [html('strong', defrag(unwrap(nodes)))]))]),
|
|
81
81
|
(nodes, context, prefix, postfix, state) => {
|
|
@@ -137,7 +137,7 @@ export const emstrong: EmStrongParser = lazy(() =>
|
|
|
137
137
|
nodes = prepend('*'.repeat(prefix - postfix), nodes);
|
|
138
138
|
}
|
|
139
139
|
return nodes;
|
|
140
|
-
}))
|
|
140
|
+
}));
|
|
141
141
|
|
|
142
142
|
function prepend<N>(prefix: string, nodes: List<Node<N>>): List<Node<N>> {
|
|
143
143
|
if (typeof nodes.head?.value === 'string') {
|
|
@@ -8,7 +8,7 @@ import { unwrap, repeat } from '../util';
|
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const insertion: InsertionParser = lazy(() =>
|
|
11
|
-
|
|
11
|
+
repeat('++', '', precedence(0, recursion(Recursion.inline, surround(
|
|
12
12
|
'',
|
|
13
13
|
some(union([
|
|
14
14
|
some(inline, blankWith('\n', '++')),
|
|
@@ -17,5 +17,5 @@ export const insertion: InsertionParser = lazy(() =>
|
|
|
17
17
|
'++',
|
|
18
18
|
false, [],
|
|
19
19
|
([, bs], { buffer }) => buffer.import(bs),
|
|
20
|
-
([, bs], { buffer }) => bs && buffer.import(bs).push(new Node(Command.Cancel)) && buffer)),
|
|
21
|
-
nodes => new List([new Node(html('ins', defrag(unwrap(nodes))))])))
|
|
20
|
+
([, bs], { buffer }) => bs && buffer.import(bs).push(new Node(Command.Cancel)) && buffer))),
|
|
21
|
+
nodes => new List([new Node(html('ins', defrag(unwrap(nodes))))])));
|
|
@@ -11,11 +11,11 @@ import { html, defrag } from 'typed-dom/dom';
|
|
|
11
11
|
// 斜体は単語に使うとかえって見づらく読み飛ばしやすくなるため使わないべきであり
|
|
12
12
|
// ある程度の長さのある文に使うのが望ましい。
|
|
13
13
|
export const italic: ItalicParser = lazy(() =>
|
|
14
|
-
|
|
14
|
+
repeat('///', beforeNonblank, precedence(0, recursion(Recursion.inline, surround(
|
|
15
15
|
'',
|
|
16
16
|
some(union([inline]), '///', afterNonblank),
|
|
17
17
|
'///',
|
|
18
18
|
false, [],
|
|
19
19
|
([, bs], { buffer }) => buffer.import(bs),
|
|
20
|
-
([, bs], { buffer }) => bs && buffer.import(bs).push(new Node(Command.Cancel)) && buffer)),
|
|
21
|
-
nodes => new List([new Node(html('i', defrag(unwrap(nodes))))])))
|
|
20
|
+
([, bs], { buffer }) => bs && buffer.import(bs).push(new Node(Command.Cancel)) && buffer))),
|
|
21
|
+
nodes => new List([new Node(html('i', defrag(unwrap(nodes))))])));
|
|
@@ -9,13 +9,13 @@ import { unwrap, repeat } from '../util';
|
|
|
9
9
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
10
10
|
|
|
11
11
|
export const mark: MarkParser = lazy(() =>
|
|
12
|
-
|
|
12
|
+
repeat('==', beforeNonblank, precedence(0, recursion(Recursion.inline, surround(
|
|
13
13
|
'',
|
|
14
14
|
state(State.mark, some(union([inline]), '==', afterNonblank)),
|
|
15
15
|
'==',
|
|
16
16
|
false, [],
|
|
17
17
|
([, bs], { buffer }) => buffer.import(bs),
|
|
18
|
-
([, bs], { buffer }) => bs && buffer.import(bs).push(new Node(Command.Cancel)) && buffer)),
|
|
18
|
+
([, bs], { buffer }) => bs && buffer.import(bs).push(new Node(Command.Cancel)) && buffer))),
|
|
19
19
|
(nodes, { id, state }, nest) => {
|
|
20
20
|
const el = html('mark', defrag(unwrap(nodes)));
|
|
21
21
|
if (state & State.linkers || nest) return new List([new Node(el)]);
|
|
@@ -23,4 +23,4 @@ export const mark: MarkParser = lazy(() =>
|
|
|
23
23
|
return el.id
|
|
24
24
|
? new List([new Node(el), new Node(html('a', { href: `#${el.id}` }))])
|
|
25
25
|
: new List([new Node(el)]);
|
|
26
|
-
}))
|
|
26
|
+
}));
|