securemark 0.295.3 → 0.295.5
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 +45 -55
- package/markdown.d.ts +3 -3
- package/package.json +1 -1
- package/src/combinator/data/parser/inits.ts +2 -3
- package/src/combinator/data/parser/sequence.ts +2 -3
- package/src/combinator/data/parser/subsequence.ts +4 -4
- package/src/combinator/data/parser/tails.ts +4 -4
- package/src/parser/api/bind.test.ts +2 -2
- package/src/parser/api/parse.test.ts +20 -10
- package/src/parser/block/table.test.ts +0 -1
- package/src/parser/inline/bracket.ts +9 -21
- package/src/parser/inline/extension/index.ts +11 -17
- package/src/parser/inline/html.ts +6 -4
- package/src/parser/inline/link.ts +13 -9
- package/src/parser/inline/media.ts +1 -1
- package/src/parser/inline/reference.ts +7 -3
- package/src/parser/inline/ruby.ts +2 -2
- package/src/parser/inline.test.ts +3 -1
- package/src/parser/segment.test.ts +2 -2
- package/src/parser/segment.ts +2 -2
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.295.
|
|
1
|
+
/*! securemark v0.295.5 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"));
|
|
@@ -3862,7 +3862,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
3862
3862
|
value: true
|
|
3863
3863
|
}));
|
|
3864
3864
|
exports.inits = void 0;
|
|
3865
|
-
function inits(parsers
|
|
3865
|
+
function inits(parsers) {
|
|
3866
3866
|
if (parsers.length === 1) return parsers[0];
|
|
3867
3867
|
return input => {
|
|
3868
3868
|
const {
|
|
@@ -3878,7 +3878,6 @@ function inits(parsers, resume) {
|
|
|
3878
3878
|
const result = parsers[i](input);
|
|
3879
3879
|
if (result === undefined) break;
|
|
3880
3880
|
nodes = nodes?.import(result) ?? result;
|
|
3881
|
-
if (resume?.(result) === false) break;
|
|
3882
3881
|
}
|
|
3883
3882
|
return nodes;
|
|
3884
3883
|
};
|
|
@@ -3897,7 +3896,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
3897
3896
|
value: true
|
|
3898
3897
|
}));
|
|
3899
3898
|
exports.sequence = void 0;
|
|
3900
|
-
function sequence(parsers
|
|
3899
|
+
function sequence(parsers) {
|
|
3901
3900
|
if (parsers.length === 1) return parsers[0];
|
|
3902
3901
|
return input => {
|
|
3903
3902
|
const {
|
|
@@ -3913,7 +3912,6 @@ function sequence(parsers, resume) {
|
|
|
3913
3912
|
const result = parsers[i](input);
|
|
3914
3913
|
if (result === undefined) return;
|
|
3915
3914
|
nodes = nodes?.import(result) ?? result;
|
|
3916
|
-
if (resume?.(result) === false) return;
|
|
3917
3915
|
}
|
|
3918
3916
|
return nodes;
|
|
3919
3917
|
};
|
|
@@ -3985,8 +3983,8 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
3985
3983
|
exports.subsequence = void 0;
|
|
3986
3984
|
const union_1 = __webpack_require__(2369);
|
|
3987
3985
|
const inits_1 = __webpack_require__(2861);
|
|
3988
|
-
function subsequence(parsers
|
|
3989
|
-
return (0, union_1.union)(parsers.map((_, i) => i + 1 < parsers.length ? (0, inits_1.inits)([parsers[i], subsequence(parsers.slice(i + 1)
|
|
3986
|
+
function subsequence(parsers) {
|
|
3987
|
+
return (0, union_1.union)(parsers.map((_, i) => i + 1 < parsers.length ? (0, inits_1.inits)([parsers[i], subsequence(parsers.slice(i + 1))]) : parsers[i]));
|
|
3990
3988
|
}
|
|
3991
3989
|
exports.subsequence = subsequence;
|
|
3992
3990
|
|
|
@@ -4004,8 +4002,8 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
4004
4002
|
exports.tails = void 0;
|
|
4005
4003
|
const union_1 = __webpack_require__(2369);
|
|
4006
4004
|
const sequence_1 = __webpack_require__(3989);
|
|
4007
|
-
function tails(parsers
|
|
4008
|
-
return (0, union_1.union)(parsers.map((_, i) => (0, sequence_1.sequence)(parsers.slice(i)
|
|
4005
|
+
function tails(parsers) {
|
|
4006
|
+
return (0, union_1.union)(parsers.map((_, i) => (0, sequence_1.sequence)(parsers.slice(i))));
|
|
4009
4007
|
}
|
|
4010
4008
|
exports.tails = tails;
|
|
4011
4009
|
|
|
@@ -6567,19 +6565,19 @@ exports.bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([input =>
|
|
|
6567
6565
|
return d1(input);
|
|
6568
6566
|
}
|
|
6569
6567
|
}]));
|
|
6570
|
-
const p1 = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.precedence)(1, (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.some)(inline_1.inline, ')', [[')', 1]]))), (0, source_1.str)(')'),
|
|
6568
|
+
const p1 = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.precedence)(1, (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.some)(inline_1.inline, ')', [[')', 1]]))), (0, source_1.str)(')'),
|
|
6569
|
+
// 唯一の参照者であるAnnotation構文に対してのみバックトラックを記録しその他は記録しない。
|
|
6570
|
+
// 二重括弧構文の内括弧のバックトラックは二重括弧構文自身が記録するため記録不要。
|
|
6571
|
+
// Ruby構文の丸括弧は常にRuby構文が先に到達し記録するため記録不要。
|
|
6572
|
+
true, [], ([as, bs = new parser_1.List(), cs], context) => {
|
|
6571
6573
|
const {
|
|
6572
6574
|
source,
|
|
6573
6575
|
position,
|
|
6574
6576
|
range
|
|
6575
6577
|
} = context;
|
|
6576
6578
|
const head = position - range;
|
|
6577
|
-
if (context.linebreak !== 0) {
|
|
6578
|
-
|
|
6579
|
-
(0, combinator_1.setBacktrack)(context, 2 | 128 /* Backtrack.doublebracket */, head - 1);
|
|
6580
|
-
}
|
|
6581
|
-
} else if (source[position] !== ')' && source[head - 1] === '(') {
|
|
6582
|
-
(0, combinator_1.setBacktrack)(context, 2 | 128 /* Backtrack.doublebracket */, head - 1);
|
|
6579
|
+
if (source[head + 1] === '(' && (context.linebreak !== 0 || source[position - 2] !== ')')) {
|
|
6580
|
+
(0, combinator_1.setBacktrack)(context, 2 | 128 /* Backtrack.doublebracket */, head);
|
|
6583
6581
|
}
|
|
6584
6582
|
const str = source.slice(position - range + 1, position - 1);
|
|
6585
6583
|
return indexA.test(str) ? new parser_1.List([new parser_1.Node(as.head.value), new parser_1.Node(str), new parser_1.Node(cs.head.value)]) : new parser_1.List([new parser_1.Node((0, dom_1.html)('span', {
|
|
@@ -6623,12 +6621,8 @@ const s1 = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, source_1.
|
|
|
6623
6621
|
range
|
|
6624
6622
|
} = context;
|
|
6625
6623
|
const head = position - range;
|
|
6626
|
-
if (context.linebreak !== 0) {
|
|
6627
|
-
|
|
6628
|
-
(0, combinator_1.setBacktrack)(context, 2 | 128 /* Backtrack.doublebracket */, head - 1);
|
|
6629
|
-
}
|
|
6630
|
-
} else if (source[position] !== ']' && source[head - 1] === '[') {
|
|
6631
|
-
(0, combinator_1.setBacktrack)(context, 2 | 128 /* Backtrack.doublebracket */, head - 1);
|
|
6624
|
+
if (source[head + 1] === '[' && (context.linebreak !== 0 || source[position - 2] !== ']')) {
|
|
6625
|
+
(0, combinator_1.setBacktrack)(context, 2 | 128 /* Backtrack.doublebracket */, head);
|
|
6632
6626
|
}
|
|
6633
6627
|
if (context.state & 8 /* State.link */) {
|
|
6634
6628
|
if (context.linebreak !== 0) {
|
|
@@ -6636,15 +6630,12 @@ const s1 = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, source_1.
|
|
|
6636
6630
|
} else if (source[position] !== '{') {
|
|
6637
6631
|
(0, combinator_1.setBacktrack)(context, 2 | 64 /* Backtrack.link */, head);
|
|
6638
6632
|
} else {
|
|
6639
|
-
context
|
|
6640
|
-
const result = !(0, combinator_1.isBacktrack)(context, 1 | 64 /* Backtrack.link */) ? (0, link_1.textlink)({
|
|
6633
|
+
if (!(0, combinator_1.isBacktrack)(context, 1 | 64 /* Backtrack.link */) && !(0, link_1.textlink)({
|
|
6641
6634
|
context
|
|
6642
|
-
})
|
|
6643
|
-
context.position = position;
|
|
6644
|
-
if (!result) {
|
|
6635
|
+
})) {
|
|
6645
6636
|
(0, combinator_1.setBacktrack)(context, 2 | 64 /* Backtrack.link */, head);
|
|
6646
6637
|
}
|
|
6647
|
-
context.
|
|
6638
|
+
context.position = position;
|
|
6648
6639
|
context.range = range;
|
|
6649
6640
|
}
|
|
6650
6641
|
}
|
|
@@ -6914,19 +6905,14 @@ const dom_1 = __webpack_require__(394);
|
|
|
6914
6905
|
exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(32 /* State.index */, (0, combinator_1.fmap)((0, indexee_1.indexee)((0, combinator_1.surround)((0, source_1.str)('[#'), (0, combinator_1.precedence)(1, (0, combinator_1.state)(251 /* State.linkers */, (0, visibility_1.tightStart)((0, combinator_1.some)((0, combinator_1.inits)([inline_1.inline, exports.signature]), ']', [[']', 1]])))), (0, source_1.str)(']'), false, [3 | 4 /* Backtrack.common */], ([, bs], context) => context.linebreak === 0 && (0, visibility_1.trimBlankNodeEnd)(bs).length > 0 ? new parser_1.List([new parser_1.Node((0, dom_1.html)('a', {
|
|
6915
6906
|
'data-index': dataindex(bs)
|
|
6916
6907
|
}, (0, dom_1.defrag)((0, util_1.unwrap)(bs))))]) : undefined, undefined)), ns => {
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
}))]);
|
|
6924
|
-
} else {
|
|
6925
|
-
ns.pop();
|
|
6926
|
-
return ns;
|
|
6927
|
-
}
|
|
6908
|
+
const el = ns.head.value;
|
|
6909
|
+
return new parser_1.List([new parser_1.Node((0, dom_1.define)(el, {
|
|
6910
|
+
id: el.id ? null : undefined,
|
|
6911
|
+
class: 'index',
|
|
6912
|
+
href: el.id ? `#${el.id}` : undefined
|
|
6913
|
+
}))]);
|
|
6928
6914
|
})));
|
|
6929
|
-
exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.surround)((0, source_1.str)(/\|(?!\\?\s)/y), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, (0, combinator_1.some)(source_1.txt, /(?:[$"`\[\](){}<>()[]{}|])/y)]), ']'), /(?=])/y, false, [3 | 16 /* Backtrack.escapable */], ([, ns], context) => {
|
|
6915
|
+
exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.surround)((0, source_1.str)(/\|(?!\\?\s)/y), (0, combinator_1.precedence)(9, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, (0, combinator_1.some)(source_1.txt, /(?:[$"`\[\](){}<>()[]{}|])/y)]), ']')), /(?=])/y, false, [3 | 16 /* Backtrack.escapable */], ([, ns], context) => {
|
|
6930
6916
|
const index = (0, indexee_1.identity)('index', undefined, ns.foldl((acc, {
|
|
6931
6917
|
value
|
|
6932
6918
|
}) => acc + value, ''))?.slice(7);
|
|
@@ -7214,14 +7200,14 @@ Object.setPrototypeOf(attrspecs, null);
|
|
|
7214
7200
|
Object.values(attrspecs).forEach(o => Object.setPrototypeOf(o, null));
|
|
7215
7201
|
exports.html = (0, combinator_1.lazy)(() => (0, combinator_1.validate)(/<[a-z]+(?=[ >])/yi, (0, combinator_1.union)([(0, combinator_1.surround)(
|
|
7216
7202
|
// https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
7217
|
-
(0, source_1.str)(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[ >])/y), (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), (0, combinator_1.open)((0, source_1.str)(/ ?/y), (0, source_1.str)('>'), true), true, [], ([as, bs = new parser_1.List(), cs], context) => new parser_1.List([new parser_1.Node(elem(as.head.value.slice(1), false, [...(0, util_1.unwrap)(as.import(bs).import(cs))], new parser_1.List(), new parser_1.List(), context))]), ([as, bs = new parser_1.List()], context) => new parser_1.List([new parser_1.Node(elem(as.head.value.slice(1), false, [...(0, util_1.unwrap)(as.import(bs))], new parser_1.List(), new parser_1.List(), context))])), (0, combinator_1.match)(new RegExp(String.raw`<(${TAGS.join('|')})(?=[ >])`, 'y'), (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.some)(exports.attribute), (0, combinator_1.open)((0, source_1.str)(/ ?/y), (0, source_1.str)('>'), true), true, [], ([as, bs = new parser_1.List(), cs]) => as.import(bs).import(cs), ([as, bs = new parser_1.List()]) => as.import(bs)),
|
|
7203
|
+
(0, source_1.str)(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[ >])/y), (0, combinator_1.precedence)(9, (0, combinator_1.some)((0, combinator_1.union)([exports.attribute]))), (0, combinator_1.open)((0, source_1.str)(/ ?/y), (0, source_1.str)('>'), true), true, [], ([as, bs = new parser_1.List(), cs], context) => new parser_1.List([new parser_1.Node(elem(as.head.value.slice(1), false, [...(0, util_1.unwrap)(as.import(bs).import(cs))], new parser_1.List(), new parser_1.List(), context))]), ([as, bs = new parser_1.List()], context) => new parser_1.List([new parser_1.Node(elem(as.head.value.slice(1), false, [...(0, util_1.unwrap)(as.import(bs))], new parser_1.List(), new parser_1.List(), context))])), (0, combinator_1.match)(new RegExp(String.raw`<(${TAGS.join('|')})(?=[ >])`, 'y'), (0, memoize_1.memoize)(([, tag]) => (0, combinator_1.surround)((0, combinator_1.surround)((0, source_1.str)(`<${tag}`), (0, combinator_1.precedence)(9, (0, combinator_1.some)(exports.attribute)), (0, combinator_1.open)((0, source_1.str)(/ ?/y), (0, source_1.str)('>'), true), true, [], ([as, bs = new parser_1.List(), cs]) => as.import(bs).import(cs), ([as, bs = new parser_1.List()]) => as.import(bs)),
|
|
7218
7204
|
// 不可視のHTML構造が可視構造を変化させるべきでない。
|
|
7219
7205
|
// 可視のHTMLは優先度変更を検討する。
|
|
7220
|
-
//
|
|
7206
|
+
// このため`<>`記号は将来的に共通構造を変化させる可能性があり
|
|
7221
7207
|
// 共通構造を変化させない非構造文字列としては依然としてエスケープを要する。
|
|
7222
7208
|
(0, combinator_1.precedence)(0, (0, combinator_1.recursion)(4 /* Recursion.inline */, (0, combinator_1.some)((0, combinator_1.union)([(0, combinator_1.some)(inline_1.inline, (0, visibility_1.blankWith)('\n', `</${tag}>`)), (0, combinator_1.open)('\n', (0, combinator_1.some)(inline_1.inline, `</${tag}>`), true)])))), (0, source_1.str)(`</${tag}>`), true, [], ([as, bs = new parser_1.List(), cs], context) => new parser_1.List([new parser_1.Node(elem(tag, true, [...(0, util_1.unwrap)(as)], bs, cs, context))]), ([as, bs = new parser_1.List()], context) => new parser_1.List([new parser_1.Node(elem(tag, true, [...(0, util_1.unwrap)(as)], bs, new parser_1.List(), context))])), ([, tag]) => tag, new Map())), (0, combinator_1.surround)(
|
|
7223
7209
|
// https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
7224
|
-
(0, source_1.str)(/<[a-z]+(?=[ >])/yi), (0, combinator_1.some)((0, combinator_1.union)([exports.attribute])), (0, combinator_1.open)((0, source_1.str)(/ ?/y), (0, source_1.str)('>'), true), true, [], ([as, bs = new parser_1.List(), cs], context) => new parser_1.List([new parser_1.Node(elem(as.head.value.slice(1), false, [...(0, util_1.unwrap)(as.import(bs).import(cs))], new parser_1.List(), new parser_1.List(), context))]), ([as, bs = new parser_1.List()], context) => new parser_1.List([new parser_1.Node(elem(as.head.value.slice(1), false, [...(0, util_1.unwrap)(as.import(bs))], new parser_1.List(), new parser_1.List(), context))]))])));
|
|
7210
|
+
(0, source_1.str)(/<[a-z]+(?=[ >])/yi), (0, combinator_1.precedence)(9, (0, combinator_1.some)((0, combinator_1.union)([exports.attribute]))), (0, combinator_1.open)((0, source_1.str)(/ ?/y), (0, source_1.str)('>'), true), true, [], ([as, bs = new parser_1.List(), cs], context) => new parser_1.List([new parser_1.Node(elem(as.head.value.slice(1), false, [...(0, util_1.unwrap)(as.import(bs).import(cs))], new parser_1.List(), new parser_1.List(), context))]), ([as, bs = new parser_1.List()], context) => new parser_1.List([new parser_1.Node(elem(as.head.value.slice(1), false, [...(0, util_1.unwrap)(as.import(bs))], new parser_1.List(), new parser_1.List(), context))]))])));
|
|
7225
7211
|
exports.attribute = (0, combinator_1.union)([(0, source_1.str)(/ [a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[ >])/yi), (0, source_1.str)(/ [^\s<>]+/y)]);
|
|
7226
7212
|
function elem(tag, content, as, bs, cs, context) {
|
|
7227
7213
|
if (!tags.includes(tag)) return ielem('tag', `Invalid HTML tag name "${tag}"`, context);
|
|
@@ -7381,20 +7367,21 @@ const optspec = {
|
|
|
7381
7367
|
rel: ['nofollow']
|
|
7382
7368
|
};
|
|
7383
7369
|
Object.setPrototypeOf(optspec, null);
|
|
7384
|
-
exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /* State.link */, (0, combinator_1.
|
|
7370
|
+
exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.bind)((0, combinator_1.subsequence)([(0, combinator_1.constraint)(8 /* State.link */, (0, combinator_1.state)(251 /* State.linkers */, (0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.precedence)(1, (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [[']', 1]]))), ']', true, [3 | 4 /* Backtrack.common */ | 64 /* Backtrack.link */, 2 | 32 /* Backtrack.ruby */], ([, ns = new parser_1.List()], context) => {
|
|
7385
7371
|
if (context.linebreak !== 0) {
|
|
7386
7372
|
const head = context.position - context.range;
|
|
7387
7373
|
return void (0, combinator_1.setBacktrack)(context, 2 | 64 /* Backtrack.link */ | 32 /* Backtrack.ruby */, head);
|
|
7388
7374
|
}
|
|
7389
7375
|
return ns.push(new parser_1.Node("\u001F" /* Command.Separator */)) && ns;
|
|
7390
|
-
})),
|
|
7376
|
+
})))),
|
|
7391
7377
|
// `{ `と`{`で個別にバックトラックが発生し+1nされる。
|
|
7392
7378
|
// 自己再帰的にパースしてもオプションの不要なパースによる計算量の増加により相殺される。
|
|
7393
|
-
(0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), / ?}/y, false, [], undefined, ([as, bs]) => bs && as.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && as))]), ([{
|
|
7379
|
+
(0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.precedence)(9, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)])), / ?}/y, false, [], undefined, ([as, bs]) => bs && as.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && as))]), ([{
|
|
7394
7380
|
value: content
|
|
7395
7381
|
}, {
|
|
7396
7382
|
value: params = undefined
|
|
7397
7383
|
} = {}], context) => {
|
|
7384
|
+
if (context.state & 8 /* State.link */) return new parser_1.List([new parser_1.Node(context.source.slice(context.position - context.range, context.position))]);
|
|
7398
7385
|
if (content.last.value === "\u001F" /* Command.Separator */) {
|
|
7399
7386
|
content.pop();
|
|
7400
7387
|
if (params === undefined) {
|
|
@@ -7414,8 +7401,8 @@ exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /
|
|
|
7414
7401
|
}
|
|
7415
7402
|
if (content.length !== 0 && (0, visibility_1.trimBlankNodeEnd)(content).length === 0) return;
|
|
7416
7403
|
return new parser_1.List([new parser_1.Node(parse(content, params, context))]);
|
|
7417
|
-
}))
|
|
7418
|
-
exports.medialink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /* State.link */ | 4 /* State.media */, (0, combinator_1.state)(251 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.sequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.union)([inline_1.media, inline_1.shortmedia]), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)]), / ?}/y))]), ([{
|
|
7404
|
+
}));
|
|
7405
|
+
exports.medialink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /* State.link */ | 4 /* State.media */, (0, combinator_1.state)(251 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.sequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.union)([inline_1.media, inline_1.shortmedia]), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.precedence)(9, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)])), / ?}/y))]), ([{
|
|
7419
7406
|
value: content
|
|
7420
7407
|
}, {
|
|
7421
7408
|
value: params
|
|
@@ -7616,7 +7603,7 @@ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(4 /* S
|
|
|
7616
7603
|
return void (0, combinator_1.setBacktrack)(context, 2 | 64 /* Backtrack.link */ | 32 /* Backtrack.ruby */, head);
|
|
7617
7604
|
}
|
|
7618
7605
|
return ns;
|
|
7619
|
-
})), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.inits)([link_1.uri, (0, combinator_1.some)(option)]), / ?}/y, false, [], undefined, ([as, bs]) => bs && as.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && as))]), nodes => nodes.length === 1 ? new parser_1.List([new parser_1.Node(new parser_1.List([new parser_1.Node('')])), nodes.delete(nodes.head)]) : new parser_1.List([new parser_1.Node(new parser_1.List([new parser_1.Node(nodes.head.value.foldl((acc, {
|
|
7606
|
+
})), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.precedence)(9, (0, combinator_1.inits)([link_1.uri, (0, combinator_1.some)(option)])), / ?}/y, false, [], undefined, ([as, bs]) => bs && as.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && as))]), nodes => nodes.length === 1 ? new parser_1.List([new parser_1.Node(new parser_1.List([new parser_1.Node('')])), nodes.delete(nodes.head)]) : new parser_1.List([new parser_1.Node(new parser_1.List([new parser_1.Node(nodes.head.value.foldl((acc, {
|
|
7620
7607
|
value
|
|
7621
7608
|
}) => acc + value, ''))])), nodes.delete(nodes.last)])), ([{
|
|
7622
7609
|
value: [{
|
|
@@ -7740,14 +7727,17 @@ exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(64
|
|
|
7740
7727
|
(0, combinator_1.setBacktrack)(context, 2 | 4 /* Backtrack.common */, head, 2);
|
|
7741
7728
|
} else if (linebreak !== 0) {
|
|
7742
7729
|
(0, combinator_1.setBacktrack)(context, 2 | 128 /* Backtrack.doublebracket */ | 64 /* Backtrack.link */ | 32 /* Backtrack.ruby */, head, 2);
|
|
7730
|
+
} else if (source[position + 1] !== '{') {
|
|
7731
|
+
(0, combinator_1.setBacktrack)(context, 2 | 64 /* Backtrack.link */, head + 1);
|
|
7743
7732
|
} else {
|
|
7744
7733
|
context.position += 1;
|
|
7745
|
-
if (
|
|
7734
|
+
if (!(0, link_1.textlink)({
|
|
7746
7735
|
context
|
|
7747
7736
|
})) {
|
|
7748
7737
|
(0, combinator_1.setBacktrack)(context, 2 | 64 /* Backtrack.link */, head + 1);
|
|
7749
7738
|
}
|
|
7750
7739
|
context.position = position;
|
|
7740
|
+
context.range = range;
|
|
7751
7741
|
}
|
|
7752
7742
|
})));
|
|
7753
7743
|
// Chicago-Style
|
|
@@ -7861,11 +7851,11 @@ exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.bind)((0, combinato
|
|
|
7861
7851
|
value: ruby = ''
|
|
7862
7852
|
} = {}]) => acc.import(ruby ? new parser_1.List([new parser_1.Node(text), new parser_1.Node((0, dom_1.html)('rp', '(')), new parser_1.Node((0, dom_1.html)('rt', ruby)), new parser_1.Node((0, dom_1.html)('rp', ')'))]) : new parser_1.List([new parser_1.Node(text), new parser_1.Node((0, dom_1.html)('rt'))])), new parser_1.List())))))]);
|
|
7863
7853
|
default:
|
|
7864
|
-
return new parser_1.List([new parser_1.Node((0, dom_1.html)('ruby', (0, dom_1.defrag)((0, util_1.unwrap)(new parser_1.List([new parser_1.Node(texts.
|
|
7854
|
+
return new parser_1.List([new parser_1.Node((0, dom_1.html)('ruby', (0, dom_1.defrag)((0, util_1.unwrap)(new parser_1.List([new parser_1.Node(texts.foldl((acc, {
|
|
7865
7855
|
value
|
|
7866
|
-
}
|
|
7856
|
+
}) => acc ? acc + ' ' + value : value, '')), new parser_1.Node((0, dom_1.html)('rp', '(')), new parser_1.Node((0, dom_1.html)('rt', rubies.foldl((acc, {
|
|
7867
7857
|
value
|
|
7868
|
-
}
|
|
7858
|
+
}) => acc ? acc + ' ' + value : value, '').trim())), new parser_1.Node((0, dom_1.html)('rp', ')'))])))))]);
|
|
7869
7859
|
}
|
|
7870
7860
|
}));
|
|
7871
7861
|
const delimiter = /[$"`\[\](){}<>()[]{}|]|\\?\n/y;
|
|
@@ -8313,7 +8303,7 @@ const extension_1 = __webpack_require__(6193);
|
|
|
8313
8303
|
const source_1 = __webpack_require__(8745);
|
|
8314
8304
|
exports.MAX_SEGMENT_SIZE = 100_000; // 100,000 bytes (Max value size of FDB)
|
|
8315
8305
|
exports.MAX_INPUT_SIZE = exports.MAX_SEGMENT_SIZE * 10;
|
|
8316
|
-
const parser = (0, combinator_1.union)([(0, combinator_1.some)(source_1.emptyline), input => {
|
|
8306
|
+
const parser = (0, combinator_1.union)([(0, combinator_1.some)(source_1.emptyline, exports.MAX_SEGMENT_SIZE + 1), input => {
|
|
8317
8307
|
const {
|
|
8318
8308
|
context: {
|
|
8319
8309
|
source,
|
|
@@ -8339,7 +8329,7 @@ const parser = (0, combinator_1.union)([(0, combinator_1.some)(source_1.emptylin
|
|
|
8339
8329
|
case '$':
|
|
8340
8330
|
return (0, extension_1.segment)(input);
|
|
8341
8331
|
}
|
|
8342
|
-
}, (0, combinator_1.some)(source_1.contentline)]);
|
|
8332
|
+
}, (0, combinator_1.some)(source_1.contentline, exports.MAX_SEGMENT_SIZE + 1)]);
|
|
8343
8333
|
function* segment(source) {
|
|
8344
8334
|
if (!validate(source, exports.MAX_INPUT_SIZE)) return yield `${"\u0007" /* Command.Error */}Too large input over ${exports.MAX_INPUT_SIZE.toLocaleString('en')} bytes.\n${source.slice(0, 1001)}`;
|
|
8345
8335
|
for (let position = 0; position < source.length;) {
|
package/markdown.d.ts
CHANGED
|
@@ -714,7 +714,7 @@ export namespace MarkdownParser {
|
|
|
714
714
|
// [#index]
|
|
715
715
|
// [#index|signature]
|
|
716
716
|
Inline<'extension/index'>,
|
|
717
|
-
Parser<
|
|
717
|
+
Parser<HTMLAnchorElement, Context, [
|
|
718
718
|
InlineParser,
|
|
719
719
|
IndexParser.SignatureParser,
|
|
720
720
|
]> {
|
|
@@ -767,7 +767,7 @@ export namespace MarkdownParser {
|
|
|
767
767
|
// { uri }
|
|
768
768
|
// [abc]{uri nofollow}
|
|
769
769
|
Inline<'link'>,
|
|
770
|
-
Parser<HTMLAnchorElement | HTMLSpanElement, Context, [
|
|
770
|
+
Parser<HTMLAnchorElement | HTMLSpanElement | string, Context, [
|
|
771
771
|
LinkParser.MediaLinkParser,
|
|
772
772
|
LinkParser.TextLinkParser,
|
|
773
773
|
]> {
|
|
@@ -775,7 +775,7 @@ export namespace MarkdownParser {
|
|
|
775
775
|
export namespace LinkParser {
|
|
776
776
|
export interface TextLinkParser extends
|
|
777
777
|
Inline<'link/textlink'>,
|
|
778
|
-
Parser<HTMLAnchorElement | HTMLSpanElement, Context, [
|
|
778
|
+
Parser<HTMLAnchorElement | HTMLSpanElement | string, Context, [
|
|
779
779
|
Parser<List<Node<string | HTMLElement>>, Context, [
|
|
780
780
|
InlineParser,
|
|
781
781
|
]>,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Parser, List, Node, Context } from '../parser';
|
|
2
2
|
|
|
3
|
-
export function inits<P extends Parser>(parsers: Parser.SubParsers<P
|
|
4
|
-
export function inits<N, D extends Parser<N>[]>(parsers: D
|
|
3
|
+
export function inits<P extends Parser>(parsers: Parser.SubParsers<P>): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
|
|
4
|
+
export function inits<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context, D> {
|
|
5
5
|
assert(parsers.every(f => f));
|
|
6
6
|
if (parsers.length === 1) return parsers[0];
|
|
7
7
|
return input => {
|
|
@@ -14,7 +14,6 @@ export function inits<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: Lis
|
|
|
14
14
|
const result = parsers[i](input);
|
|
15
15
|
if (result === undefined) break;
|
|
16
16
|
nodes = nodes?.import(result) ?? result;
|
|
17
|
-
if (resume?.(result) === false) break;
|
|
18
17
|
}
|
|
19
18
|
return nodes;
|
|
20
19
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Parser, List, Node, Context } from '../parser';
|
|
2
2
|
|
|
3
|
-
export function sequence<P extends Parser>(parsers: Parser.SubParsers<P
|
|
4
|
-
export function sequence<N, D extends Parser<N>[]>(parsers: D
|
|
3
|
+
export function sequence<P extends Parser>(parsers: Parser.SubParsers<P>): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
|
|
4
|
+
export function sequence<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context, D> {
|
|
5
5
|
assert(parsers.every(f => f));
|
|
6
6
|
if (parsers.length === 1) return parsers[0];
|
|
7
7
|
return input => {
|
|
@@ -14,7 +14,6 @@ export function sequence<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes:
|
|
|
14
14
|
const result = parsers[i](input);
|
|
15
15
|
if (result === undefined) return;
|
|
16
16
|
nodes = nodes?.import(result) ?? result;
|
|
17
|
-
if (resume?.(result) === false) return;
|
|
18
17
|
}
|
|
19
18
|
return nodes;
|
|
20
19
|
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Parser,
|
|
1
|
+
import { Parser, Context } from '../parser';
|
|
2
2
|
import { union } from './union';
|
|
3
3
|
import { inits } from './inits';
|
|
4
4
|
|
|
5
|
-
export function subsequence<P extends Parser>(parsers: Parser.SubParsers<P
|
|
6
|
-
export function subsequence<N, D extends Parser<N>[]>(parsers: D
|
|
5
|
+
export function subsequence<P extends Parser>(parsers: Parser.SubParsers<P>): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
|
|
6
|
+
export function subsequence<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context, D> {
|
|
7
7
|
assert(parsers.every(f => f));
|
|
8
8
|
return union(
|
|
9
9
|
parsers.map((_, i) =>
|
|
10
10
|
i + 1 < parsers.length
|
|
11
|
-
? inits([parsers[i], subsequence(parsers.slice(i + 1)
|
|
11
|
+
? inits([parsers[i], subsequence(parsers.slice(i + 1))])
|
|
12
12
|
: parsers[i]) as D);
|
|
13
13
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Parser,
|
|
1
|
+
import { Parser, Context } from '../parser';
|
|
2
2
|
import { union } from './union';
|
|
3
3
|
import { sequence } from './sequence';
|
|
4
4
|
|
|
5
|
-
export function tails<P extends Parser>(parsers: Parser.SubParsers<P
|
|
6
|
-
export function tails<N, D extends Parser<N>[]>(parsers: D
|
|
7
|
-
return union(parsers.map((_, i) => sequence(parsers.slice(i)
|
|
5
|
+
export function tails<P extends Parser>(parsers: Parser.SubParsers<P>): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
|
|
6
|
+
export function tails<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context, D> {
|
|
7
|
+
return union(parsers.map((_, i) => sequence(parsers.slice(i))) as D);
|
|
8
8
|
}
|
|
@@ -30,7 +30,7 @@ describe('Unit: parser/api/bind', () => {
|
|
|
30
30
|
const cfgs = { notes: { references: html('ol') } };
|
|
31
31
|
|
|
32
32
|
it('huge input', () => {
|
|
33
|
-
const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(
|
|
33
|
+
const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(1e6 + 1)}`);
|
|
34
34
|
assert.deepStrictEqual(
|
|
35
35
|
inspect(iter),
|
|
36
36
|
[
|
|
@@ -42,7 +42,7 @@ describe('Unit: parser/api/bind', () => {
|
|
|
42
42
|
it('huge segment', function () {
|
|
43
43
|
this.timeout(10 * 1000);
|
|
44
44
|
|
|
45
|
-
const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(
|
|
45
|
+
const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(1e5 + 1)}`);
|
|
46
46
|
assert.deepStrictEqual(
|
|
47
47
|
inspect(iter, 3),
|
|
48
48
|
[
|
|
@@ -6,7 +6,7 @@ describe('Unit: parser/api/parse', () => {
|
|
|
6
6
|
describe('parse', () => {
|
|
7
7
|
it('huge input', () => {
|
|
8
8
|
assert.deepStrictEqual(
|
|
9
|
-
[...parse(`${'\n'.repeat(
|
|
9
|
+
[...parse(`${'\n'.repeat(1e6 + 1)}`, { id: '' }).children].map(el => el.outerHTML),
|
|
10
10
|
[
|
|
11
11
|
'<h1 class="error">Error: Too large input over 1,000,000 bytes.</h1>',
|
|
12
12
|
`<pre class="error" translate="no">${'\n'.repeat(997)}...</pre>`,
|
|
@@ -15,7 +15,7 @@ describe('Unit: parser/api/parse', () => {
|
|
|
15
15
|
|
|
16
16
|
it('huge segment', () => {
|
|
17
17
|
assert.deepStrictEqual(
|
|
18
|
-
[...parse(`${'\n'.repeat(
|
|
18
|
+
[...parse(`${'\n'.repeat(1e5 + 1)}`, { id: '' }).children].map(el => el.outerHTML),
|
|
19
19
|
[
|
|
20
20
|
'<h1 class="error">Error: Too large segment over 100,000 bytes.</h1>',
|
|
21
21
|
`<pre class="error" translate="no">${'\n'.repeat(997)}...</pre>`,
|
|
@@ -360,22 +360,32 @@ describe('Unit: parser/api/parse', () => {
|
|
|
360
360
|
]);
|
|
361
361
|
});
|
|
362
362
|
|
|
363
|
-
it('backtrack',
|
|
364
|
-
this.timeout(5000);
|
|
363
|
+
it('backtrack 1', () => {
|
|
365
364
|
// 最悪計算量での実行速度はCommonMarkの公式JS実装の32nに対して50-400%程度。
|
|
366
365
|
// 6n = annotation + reference + link + url/math + ruby + text
|
|
367
|
-
const source = `((([[[[#$[${'.'.repeat(16665)}`;
|
|
368
366
|
assert.deepStrictEqual(
|
|
369
|
-
[...parse(
|
|
367
|
+
[...parse(`((([[[[#$[${'.'.repeat(16665)}`, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
|
|
370
368
|
.map(el => el.tagName),
|
|
371
369
|
['P']);
|
|
372
370
|
});
|
|
373
371
|
|
|
374
|
-
it('backtrack error',
|
|
375
|
-
this.timeout(5000);
|
|
376
|
-
const source = `((([[[[#$[${'.'.repeat(16665 + 1)}`;
|
|
372
|
+
it('backtrack 1 error', () => {
|
|
377
373
|
assert.deepStrictEqual(
|
|
378
|
-
[...parse(
|
|
374
|
+
[...parse(`((([[[[#$[${'.'.repeat(16665 + 1)}`, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
|
|
375
|
+
.map(el => el.tagName),
|
|
376
|
+
['H1', 'PRE']);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
it('backtrack 2', () => {
|
|
380
|
+
assert.deepStrictEqual(
|
|
381
|
+
[...parse(`((([[[[#$[${'.'.repeat(16664)}]]]`, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
|
|
382
|
+
.map(el => el.tagName),
|
|
383
|
+
['P', 'OL']);
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
it('backtrack 2 error', () => {
|
|
387
|
+
assert.deepStrictEqual(
|
|
388
|
+
[...parse(`((([[[[#$[${'.'.repeat(16664 + 1)}]]]`, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
|
|
379
389
|
.map(el => el.tagName),
|
|
380
390
|
['H1', 'PRE']);
|
|
381
391
|
});
|
|
@@ -34,7 +34,6 @@ describe('Unit: parser/block/table', () => {
|
|
|
34
34
|
assert.deepStrictEqual(inspect(parser, input('|"|\n|-\n|', new Context())), [['<table><thead><tr><th>"</th></tr></thead><tbody><tr></tr></tbody></table>'], '']);
|
|
35
35
|
assert.deepStrictEqual(inspect(parser, input('|`|`|\n|-\n|', new Context())), [['<table><thead><tr><th><code data-src="`|`">|</code></th></tr></thead><tbody><tr></tr></tbody></table>'], '']);
|
|
36
36
|
assert.deepStrictEqual(inspect(parser, input('|((|\n|-\n|', new Context())), [['<table><thead><tr><th><span class="paren">(<span class="paren">(</span></span></th></tr></thead><tbody><tr></tr></tbody></table>'], '']);
|
|
37
|
-
assert.deepStrictEqual(inspect(parser, input('|${|\n|-\n|', new Context())), [['<table><thead><tr><th>${</th></tr></thead><tbody><tr></tr></tbody></table>'], '']);
|
|
38
37
|
assert.deepStrictEqual(inspect(parser, input('|a|b|\n|-|-|\n|1|2|', new Context())), [['<table><thead><tr><th>a</th><th>b</th></tr></thead><tbody><tr><td>1</td><td>2</td></tr></tbody></table>'], '']);
|
|
39
38
|
assert.deepStrictEqual(inspect(parser, input('|a|b\n|-|-\n|1|2', new Context())), [['<table><thead><tr><th>a</th><th>b</th></tr></thead><tbody><tr><td>1</td><td>2</td></tr></tbody></table>'], '']);
|
|
40
39
|
assert.deepStrictEqual(inspect(parser, input('|a|\n|-|\n|1|', new Context())), [['<table><thead><tr><th>a</th></tr></thead><tbody><tr><td>1</td></tr></tbody></table>'], '']);
|
|
@@ -38,17 +38,15 @@ const p1 = lazy(() => surround(
|
|
|
38
38
|
str('('),
|
|
39
39
|
precedence(1, recursion(Recursion.bracket, some(inline, ')', [[')', 1]]))),
|
|
40
40
|
str(')'),
|
|
41
|
+
// 唯一の参照者であるAnnotation構文に対してのみバックトラックを記録しその他は記録しない。
|
|
42
|
+
// 二重括弧構文の内括弧のバックトラックは二重括弧構文自身が記録するため記録不要。
|
|
43
|
+
// Ruby構文の丸括弧は常にRuby構文が先に到達し記録するため記録不要。
|
|
41
44
|
true, [],
|
|
42
45
|
([as, bs = new List(), cs], context) => {
|
|
43
46
|
const { source, position, range } = context;
|
|
44
47
|
const head = position - range;
|
|
45
|
-
if (context.linebreak !== 0) {
|
|
46
|
-
|
|
47
|
-
setBacktrack(context, 2 | Backtrack.doublebracket, head - 1);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
else if (source[position] !== ')' && source[head - 1] === '(') {
|
|
51
|
-
setBacktrack(context, 2 | Backtrack.doublebracket, head - 1);
|
|
48
|
+
if (source[head + 1] === '(' && (context.linebreak !== 0 || source[position - 2] !== ')')) {
|
|
49
|
+
setBacktrack(context, 2 | Backtrack.doublebracket, head);
|
|
52
50
|
}
|
|
53
51
|
const str = source.slice(position - range + 1, position - 1);
|
|
54
52
|
return indexA.test(str)
|
|
@@ -91,13 +89,8 @@ const s1 = lazy(() => surround(
|
|
|
91
89
|
([as, bs = new List(), cs], context) => {
|
|
92
90
|
const { source, position, range } = context;
|
|
93
91
|
const head = position - range;
|
|
94
|
-
if (context.linebreak !== 0) {
|
|
95
|
-
|
|
96
|
-
setBacktrack(context, 2 | Backtrack.doublebracket, head - 1);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
else if (source[position] !== ']' && source[head - 1] === '[') {
|
|
100
|
-
setBacktrack(context, 2 | Backtrack.doublebracket, head - 1);
|
|
92
|
+
if (source[head + 1] === '[' && (context.linebreak !== 0 || source[position - 2] !== ']')) {
|
|
93
|
+
setBacktrack(context, 2 | Backtrack.doublebracket, head);
|
|
101
94
|
}
|
|
102
95
|
if (context.state & State.link) {
|
|
103
96
|
if (context.linebreak !== 0) {
|
|
@@ -107,15 +100,10 @@ const s1 = lazy(() => surround(
|
|
|
107
100
|
setBacktrack(context, 2 | Backtrack.link, head);
|
|
108
101
|
}
|
|
109
102
|
else {
|
|
110
|
-
context
|
|
111
|
-
const result = !isBacktrack(context, 1 | Backtrack.link)
|
|
112
|
-
? textlink({ context })
|
|
113
|
-
: undefined;
|
|
114
|
-
context.position = position;
|
|
115
|
-
if (!result) {
|
|
103
|
+
if (!isBacktrack(context, 1 | Backtrack.link) && !textlink({ context })) {
|
|
116
104
|
setBacktrack(context, 2 | Backtrack.link, head);
|
|
117
105
|
}
|
|
118
|
-
context.
|
|
106
|
+
context.position = position;
|
|
119
107
|
context.range = range;
|
|
120
108
|
}
|
|
121
109
|
}
|
|
@@ -29,29 +29,23 @@ export const index: IndexParser = lazy(() => constraint(State.index, fmap(indexe
|
|
|
29
29
|
: undefined,
|
|
30
30
|
undefined)),
|
|
31
31
|
ns => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
assert(ns.last?.value === '');
|
|
44
|
-
ns.pop();
|
|
45
|
-
return ns;
|
|
46
|
-
}
|
|
32
|
+
assert(ns.length === 1);
|
|
33
|
+
const el = ns.head!.value as HTMLAnchorElement;
|
|
34
|
+
return new List([
|
|
35
|
+
new Node(define(el, {
|
|
36
|
+
id: el.id ? null : undefined,
|
|
37
|
+
class: 'index',
|
|
38
|
+
href: el.id ? `#${el.id}` : undefined,
|
|
39
|
+
}))
|
|
40
|
+
]);
|
|
47
41
|
})));
|
|
48
42
|
|
|
49
43
|
export const signature: IndexParser.SignatureParser = lazy(() => validate('|', surround(
|
|
50
44
|
str(/\|(?!\\?\s)/y),
|
|
51
|
-
some(union([
|
|
45
|
+
precedence(9, some(union([
|
|
52
46
|
unsafehtmlentity,
|
|
53
47
|
some(txt, /(?:[$"`\[\](){}<>()[]{}|])/y),
|
|
54
|
-
]), ']'),
|
|
48
|
+
]), ']')),
|
|
55
49
|
/(?=])/y,
|
|
56
50
|
false,
|
|
57
51
|
[3 | Backtrack.escapable],
|
|
@@ -24,7 +24,7 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
24
24
|
surround(
|
|
25
25
|
// https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
26
26
|
str(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[ >])/y),
|
|
27
|
-
some(union([attribute])),
|
|
27
|
+
precedence(9, some(union([attribute]))),
|
|
28
28
|
open(str(/ ?/y), str('>'), true),
|
|
29
29
|
true, [],
|
|
30
30
|
([as, bs = new List(), cs], context) =>
|
|
@@ -37,13 +37,15 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
37
37
|
([, tag]) =>
|
|
38
38
|
surround<HTMLParser.TagParser, string>(
|
|
39
39
|
surround(
|
|
40
|
-
str(`<${tag}`),
|
|
40
|
+
str(`<${tag}`),
|
|
41
|
+
precedence(9, some(attribute)),
|
|
42
|
+
open(str(/ ?/y), str('>'), true),
|
|
41
43
|
true, [],
|
|
42
44
|
([as, bs = new List(), cs]) => as.import(bs).import(cs),
|
|
43
45
|
([as, bs = new List()]) => as.import(bs)),
|
|
44
46
|
// 不可視のHTML構造が可視構造を変化させるべきでない。
|
|
45
47
|
// 可視のHTMLは優先度変更を検討する。
|
|
46
|
-
//
|
|
48
|
+
// このため`<>`記号は将来的に共通構造を変化させる可能性があり
|
|
47
49
|
// 共通構造を変化させない非構造文字列としては依然としてエスケープを要する。
|
|
48
50
|
precedence(0, recursion(Recursion.inline,
|
|
49
51
|
some(union([
|
|
@@ -61,7 +63,7 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
61
63
|
surround(
|
|
62
64
|
// https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
63
65
|
str(/<[a-z]+(?=[ >])/yi),
|
|
64
|
-
some(union([attribute])),
|
|
66
|
+
precedence(9, some(union([attribute]))),
|
|
65
67
|
open(str(/ ?/y), str('>'), true),
|
|
66
68
|
true, [],
|
|
67
69
|
([as, bs = new List(), cs], context) =>
|
|
@@ -15,12 +15,12 @@ const optspec = {
|
|
|
15
15
|
} as const;
|
|
16
16
|
Object.setPrototypeOf(optspec, null);
|
|
17
17
|
|
|
18
|
-
export const textlink: LinkParser.TextLinkParser = lazy(() =>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
dup(surround(
|
|
18
|
+
export const textlink: LinkParser.TextLinkParser = lazy(() => bind(
|
|
19
|
+
subsequence([
|
|
20
|
+
constraint(State.link, state(State.linkers, dup(surround(
|
|
22
21
|
'[',
|
|
23
|
-
|
|
22
|
+
precedence(1,
|
|
23
|
+
trimBlankStart(some(union([inline]), ']', [[']', 1]]))),
|
|
24
24
|
']',
|
|
25
25
|
true,
|
|
26
26
|
[3 | Backtrack.common | Backtrack.link, 2 | Backtrack.ruby],
|
|
@@ -30,12 +30,12 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
30
30
|
return void setBacktrack(context, 2 | Backtrack.link | Backtrack.ruby, head);
|
|
31
31
|
}
|
|
32
32
|
return ns.push(new Node(Command.Separator)) && ns;
|
|
33
|
-
})),
|
|
33
|
+
})))),
|
|
34
34
|
// `{ `と`{`で個別にバックトラックが発生し+1nされる。
|
|
35
35
|
// 自己再帰的にパースしてもオプションの不要なパースによる計算量の増加により相殺される。
|
|
36
36
|
dup(surround(
|
|
37
37
|
/{(?![{}])/y,
|
|
38
|
-
inits([uri, some(option)]),
|
|
38
|
+
precedence(9, inits([uri, some(option)])),
|
|
39
39
|
/ ?}/y,
|
|
40
40
|
false, [],
|
|
41
41
|
undefined,
|
|
@@ -43,6 +43,7 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
43
43
|
bs && as.import(bs).push(new Node(Command.Cancel)) && as)),
|
|
44
44
|
]),
|
|
45
45
|
([{ value: content }, { value: params = undefined } = {}], context) => {
|
|
46
|
+
if (context.state & State.link) return new List([new Node(context.source.slice(context.position - context.range, context.position))]);
|
|
46
47
|
if (content.last!.value === Command.Separator) {
|
|
47
48
|
content.pop();
|
|
48
49
|
if (params === undefined) {
|
|
@@ -69,7 +70,7 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
69
70
|
assert(content.head?.value !== '');
|
|
70
71
|
if (content.length !== 0 && trimBlankNodeEnd(content).length === 0) return;
|
|
71
72
|
return new List([new Node(parse(content, params as List<Node<string>>, context))]);
|
|
72
|
-
}))
|
|
73
|
+
}));
|
|
73
74
|
|
|
74
75
|
export const medialink: LinkParser.MediaLinkParser = lazy(() => constraint(State.link | State.media,
|
|
75
76
|
state(State.linkers,
|
|
@@ -78,7 +79,10 @@ export const medialink: LinkParser.MediaLinkParser = lazy(() => constraint(State
|
|
|
78
79
|
'[',
|
|
79
80
|
union([media, shortmedia]),
|
|
80
81
|
']')),
|
|
81
|
-
dup(surround(
|
|
82
|
+
dup(surround(
|
|
83
|
+
/{(?![{}])/y,
|
|
84
|
+
precedence(9, inits([uri, some(option)])),
|
|
85
|
+
/ ?}/y)),
|
|
82
86
|
]),
|
|
83
87
|
([{ value: content }, { value: params }], context) =>
|
|
84
88
|
new List([new Node(parse(content, params as List<Node<string>>, context))])))));
|
|
@@ -38,15 +38,19 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
38
38
|
else if (linebreak !== 0) {
|
|
39
39
|
setBacktrack(context, 2 | Backtrack.doublebracket | Backtrack.link | Backtrack.ruby, head, 2);
|
|
40
40
|
}
|
|
41
|
+
else if (source[position + 1] !== '{') {
|
|
42
|
+
setBacktrack(context, 2 | Backtrack.link, head + 1);
|
|
43
|
+
}
|
|
41
44
|
else {
|
|
42
45
|
assert(source[position] === ']');
|
|
46
|
+
assert(~context.state & State.link);
|
|
43
47
|
context.position += 1;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
!textlink({ context })) {
|
|
48
|
+
assert(!isBacktrack(context, 1 | Backtrack.link));
|
|
49
|
+
if (!textlink({ context })) {
|
|
47
50
|
setBacktrack(context, 2 | Backtrack.link, head + 1);
|
|
48
51
|
}
|
|
49
52
|
context.position = position;
|
|
53
|
+
context.range = range;
|
|
50
54
|
}
|
|
51
55
|
})));
|
|
52
56
|
|
|
@@ -53,9 +53,9 @@ export const ruby: RubyParser = lazy(() => bind(
|
|
|
53
53
|
assert(rubies.length > 0);
|
|
54
54
|
return new List([
|
|
55
55
|
new Node(html('ruby', defrag(unwrap(new List<Node<string | HTMLElement>>([
|
|
56
|
-
new Node(texts.
|
|
56
|
+
new Node(texts.foldl((acc, { value }) => acc ? acc + ' ' + value : value, '')),
|
|
57
57
|
new Node(html('rp', '(')),
|
|
58
|
-
new Node(html('rt', rubies.
|
|
58
|
+
new Node(html('rt', rubies.foldl((acc, { value }) => acc ? acc + ' ' + value : value, '').trim())),
|
|
59
59
|
new Node(html('rp', ')')),
|
|
60
60
|
]))))),
|
|
61
61
|
]);
|
|
@@ -165,11 +165,13 @@ describe('Unit: parser/inline', () => {
|
|
|
165
165
|
assert.deepStrictEqual(inspect(parser, input('[^a@b', new Context())), [['[^', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
|
|
166
166
|
assert.deepStrictEqual(inspect(parser, input('"[% *"*"*', new Context())), [['"', '[%', ' ', '*', '"', '*', '"', '*'], '']);
|
|
167
167
|
assert.deepStrictEqual(inspect(parser, input('"[% "*"* %]', new Context())), [['"', '<span class="remark"><input type="checkbox"><span>[% "*"* %]</span></span>'], '']);
|
|
168
|
-
assert.deepStrictEqual(inspect(parser, input('"{{""}}', new Context())), [['"', '{', '
|
|
168
|
+
assert.deepStrictEqual(inspect(parser, input('"{{""}}', new Context())), [['"', '{', '<a class="url" href="""">""</a>', '}'], '']);
|
|
169
169
|
assert.deepStrictEqual(inspect(parser, input('[#http://host/(<bdi>)]</bdi>', new Context())), [['<a class="index" href="#index::http://host/(<bdi>)">http://host/<span class="paren">(<span class="invalid"><bdi></span>)</span></a>', '</bdi', '>'], '']);
|
|
170
170
|
assert.deepStrictEqual(inspect(parser, input('[#@a/http://host/(<bdi>)]</bdi>', new Context())), [['<a class="index" href="#index::@a/http://host/(<bdi>)">@a/http://host/<span class="paren">(<span class="invalid"><bdi></span>)</span></a>', '</bdi', '>'], '']);
|
|
171
171
|
assert.deepStrictEqual(inspect(parser, input('[#a|<bdi>]</bdi>', new Context())), [['<a class="index" href="#index::a|<bdi>">a|<span class="invalid"><bdi></span></a>', '</bdi', '>'], '']);
|
|
172
172
|
assert.deepStrictEqual(inspect(parser, input('[[#a|<bdi>]</bdi>', new Context())), [['[', '<a class="index" href="#index::a|<bdi>">a|<span class="invalid"><bdi></span></a>', '</bdi', '>'], '']);
|
|
173
|
+
assert.deepStrictEqual(inspect(parser, input('[]{"}[[""]]}]', new Context())), [['<a class="url" href=""">"</a>', '<sup class="reference"><span>""</span></sup>', '}', ']'], '']);
|
|
174
|
+
assert.deepStrictEqual(inspect(parser, input('[ []{"}[[""]]}]', new Context())), [['[', ' ', '<a class="url" href=""">"</a>', '<sup class="reference"><span>""</span></sup>', '}', ']'], '']);
|
|
173
175
|
});
|
|
174
176
|
|
|
175
177
|
it('uri', () => {
|
|
@@ -4,12 +4,12 @@ import { Command } from './context';
|
|
|
4
4
|
describe('Unit: parser/segment', () => {
|
|
5
5
|
describe('segment', () => {
|
|
6
6
|
it('huge input', () => {
|
|
7
|
-
const result = segment(`${'\n'.repeat(
|
|
7
|
+
const result = segment(`${'\n'.repeat(1e6 + 1)}`).next().value?.split('\n', 1)[0];
|
|
8
8
|
assert(result?.startsWith(`${Command.Error}Too large input`));
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
it('huge segment', () => {
|
|
12
|
-
const result = segment(`${'\n'.repeat(
|
|
12
|
+
const result = segment(`${'\n'.repeat(1e5 + 1)}`).next().value?.split('\n', 1)[0];
|
|
13
13
|
assert(result?.startsWith(`${Command.Error}Too large segment`));
|
|
14
14
|
});
|
|
15
15
|
|
package/src/parser/segment.ts
CHANGED
|
@@ -13,7 +13,7 @@ export const MAX_SEGMENT_SIZE = 100_000; // 100,000 bytes (Max value size of FDB
|
|
|
13
13
|
export const MAX_INPUT_SIZE = MAX_SEGMENT_SIZE * 10;
|
|
14
14
|
|
|
15
15
|
const parser: SegmentParser = union([
|
|
16
|
-
some(emptyline),
|
|
16
|
+
some(emptyline, MAX_SEGMENT_SIZE + 1),
|
|
17
17
|
input => {
|
|
18
18
|
const { context: { source, position } } = input;
|
|
19
19
|
if (position === source.length) return;
|
|
@@ -36,7 +36,7 @@ const parser: SegmentParser = union([
|
|
|
36
36
|
return extension(input);
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
|
-
some(contentline),
|
|
39
|
+
some(contentline, MAX_SEGMENT_SIZE + 1),
|
|
40
40
|
]) as any;
|
|
41
41
|
|
|
42
42
|
export function* segment(source: string): Generator<string, undefined, undefined> {
|