securemark 0.295.4 → 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 +4 -0
- package/dist/index.js +17 -23
- package/markdown.d.ts +3 -3
- package/package.json +1 -1
- package/src/parser/api/bind.test.ts +2 -2
- package/src/parser/api/parse.test.ts +20 -10
- package/src/parser/inline/bracket.ts +0 -2
- package/src/parser/inline/extension/index.ts +11 -17
- package/src/parser/inline/link.ts +8 -7
- package/src/parser/inline/ruby.ts +2 -2
- package/src/parser/inline.test.ts +2 -0
- 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"));
|
|
@@ -6630,7 +6630,6 @@ const s1 = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, source_1.
|
|
|
6630
6630
|
} else if (source[position] !== '{') {
|
|
6631
6631
|
(0, combinator_1.setBacktrack)(context, 2 | 64 /* Backtrack.link */, head);
|
|
6632
6632
|
} else {
|
|
6633
|
-
context.state ^= 8 /* State.link */;
|
|
6634
6633
|
if (!(0, combinator_1.isBacktrack)(context, 1 | 64 /* Backtrack.link */) && !(0, link_1.textlink)({
|
|
6635
6634
|
context
|
|
6636
6635
|
})) {
|
|
@@ -6638,7 +6637,6 @@ const s1 = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, source_1.
|
|
|
6638
6637
|
}
|
|
6639
6638
|
context.position = position;
|
|
6640
6639
|
context.range = range;
|
|
6641
|
-
context.state ^= 8 /* State.link */;
|
|
6642
6640
|
}
|
|
6643
6641
|
}
|
|
6644
6642
|
return as.import(bs).import(cs);
|
|
@@ -6907,19 +6905,14 @@ const dom_1 = __webpack_require__(394);
|
|
|
6907
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', {
|
|
6908
6906
|
'data-index': dataindex(bs)
|
|
6909
6907
|
}, (0, dom_1.defrag)((0, util_1.unwrap)(bs))))]) : undefined, undefined)), ns => {
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
}))]);
|
|
6917
|
-
} else {
|
|
6918
|
-
ns.pop();
|
|
6919
|
-
return ns;
|
|
6920
|
-
}
|
|
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
|
+
}))]);
|
|
6921
6914
|
})));
|
|
6922
|
-
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) => {
|
|
6923
6916
|
const index = (0, indexee_1.identity)('index', undefined, ns.foldl((acc, {
|
|
6924
6917
|
value
|
|
6925
6918
|
}) => acc + value, ''))?.slice(7);
|
|
@@ -7374,13 +7367,13 @@ const optspec = {
|
|
|
7374
7367
|
rel: ['nofollow']
|
|
7375
7368
|
};
|
|
7376
7369
|
Object.setPrototypeOf(optspec, null);
|
|
7377
|
-
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) => {
|
|
7378
7371
|
if (context.linebreak !== 0) {
|
|
7379
7372
|
const head = context.position - context.range;
|
|
7380
7373
|
return void (0, combinator_1.setBacktrack)(context, 2 | 64 /* Backtrack.link */ | 32 /* Backtrack.ruby */, head);
|
|
7381
7374
|
}
|
|
7382
7375
|
return ns.push(new parser_1.Node("\u001F" /* Command.Separator */)) && ns;
|
|
7383
|
-
})),
|
|
7376
|
+
})))),
|
|
7384
7377
|
// `{ `と`{`で個別にバックトラックが発生し+1nされる。
|
|
7385
7378
|
// 自己再帰的にパースしてもオプションの不要なパースによる計算量の増加により相殺される。
|
|
7386
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))]), ([{
|
|
@@ -7388,6 +7381,7 @@ exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /
|
|
|
7388
7381
|
}, {
|
|
7389
7382
|
value: params = undefined
|
|
7390
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))]);
|
|
7391
7385
|
if (content.last.value === "\u001F" /* Command.Separator */) {
|
|
7392
7386
|
content.pop();
|
|
7393
7387
|
if (params === undefined) {
|
|
@@ -7407,7 +7401,7 @@ exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /
|
|
|
7407
7401
|
}
|
|
7408
7402
|
if (content.length !== 0 && (0, visibility_1.trimBlankNodeEnd)(content).length === 0) return;
|
|
7409
7403
|
return new parser_1.List([new parser_1.Node(parse(content, params, context))]);
|
|
7410
|
-
}))
|
|
7404
|
+
}));
|
|
7411
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))]), ([{
|
|
7412
7406
|
value: content
|
|
7413
7407
|
}, {
|
|
@@ -7857,11 +7851,11 @@ exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.bind)((0, combinato
|
|
|
7857
7851
|
value: ruby = ''
|
|
7858
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())))))]);
|
|
7859
7853
|
default:
|
|
7860
|
-
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, {
|
|
7861
7855
|
value
|
|
7862
|
-
}
|
|
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, {
|
|
7863
7857
|
value
|
|
7864
|
-
}
|
|
7858
|
+
}) => acc ? acc + ' ' + value : value, '').trim())), new parser_1.Node((0, dom_1.html)('rp', ')'))])))))]);
|
|
7865
7859
|
}
|
|
7866
7860
|
}));
|
|
7867
7861
|
const delimiter = /[$"`\[\](){}<>()[]{}|]|\\?\n/y;
|
|
@@ -8309,7 +8303,7 @@ const extension_1 = __webpack_require__(6193);
|
|
|
8309
8303
|
const source_1 = __webpack_require__(8745);
|
|
8310
8304
|
exports.MAX_SEGMENT_SIZE = 100_000; // 100,000 bytes (Max value size of FDB)
|
|
8311
8305
|
exports.MAX_INPUT_SIZE = exports.MAX_SEGMENT_SIZE * 10;
|
|
8312
|
-
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 => {
|
|
8313
8307
|
const {
|
|
8314
8308
|
context: {
|
|
8315
8309
|
source,
|
|
@@ -8335,7 +8329,7 @@ const parser = (0, combinator_1.union)([(0, combinator_1.some)(source_1.emptylin
|
|
|
8335
8329
|
case '$':
|
|
8336
8330
|
return (0, extension_1.segment)(input);
|
|
8337
8331
|
}
|
|
8338
|
-
}, (0, combinator_1.some)(source_1.contentline)]);
|
|
8332
|
+
}, (0, combinator_1.some)(source_1.contentline, exports.MAX_SEGMENT_SIZE + 1)]);
|
|
8339
8333
|
function* segment(source) {
|
|
8340
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)}`;
|
|
8341
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
|
@@ -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(16664)}]]]`;
|
|
368
366
|
assert.deepStrictEqual(
|
|
369
|
-
[...parse(
|
|
367
|
+
[...parse(`((([[[[#$[${'.'.repeat(16665)}`, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
|
|
368
|
+
.map(el => el.tagName),
|
|
369
|
+
['P']);
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
it('backtrack 1 error', () => {
|
|
373
|
+
assert.deepStrictEqual(
|
|
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]
|
|
370
382
|
.map(el => el.tagName),
|
|
371
383
|
['P', 'OL']);
|
|
372
384
|
});
|
|
373
385
|
|
|
374
|
-
it('backtrack error',
|
|
375
|
-
this.timeout(5000);
|
|
376
|
-
const source = `((([[[[#$[${'.'.repeat(16664 + 1)}]]]`;
|
|
386
|
+
it('backtrack 2 error', () => {
|
|
377
387
|
assert.deepStrictEqual(
|
|
378
|
-
[...parse(
|
|
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
|
});
|
|
@@ -100,13 +100,11 @@ const s1 = lazy(() => surround(
|
|
|
100
100
|
setBacktrack(context, 2 | Backtrack.link, head);
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
|
-
context.state ^= State.link;
|
|
104
103
|
if (!isBacktrack(context, 1 | Backtrack.link) && !textlink({ context })) {
|
|
105
104
|
setBacktrack(context, 2 | Backtrack.link, head);
|
|
106
105
|
}
|
|
107
106
|
context.position = position;
|
|
108
107
|
context.range = range;
|
|
109
|
-
context.state ^= State.link;
|
|
110
108
|
}
|
|
111
109
|
}
|
|
112
110
|
return as.import(bs as List<Node<string>>).import(cs);
|
|
@@ -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],
|
|
@@ -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,7 +30,7 @@ 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(
|
|
@@ -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,
|
|
@@ -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
|
]);
|
|
@@ -170,6 +170,8 @@ describe('Unit: parser/inline', () => {
|
|
|
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> {
|