securemark 0.280.0 → 0.280.2
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 +37 -95
- package/markdown.d.ts +6 -6
- package/package.json +1 -1
- package/src/combinator/data/parser/context/delimiter.ts +4 -4
- package/src/combinator/data/parser/context/memo.ts +9 -5
- package/src/combinator/data/parser/context.ts +21 -27
- package/src/combinator/data/parser/some.ts +1 -1
- package/src/parser/api/bind.ts +5 -4
- package/src/parser/api/parse.test.ts +10 -2
- package/src/parser/api/parse.ts +6 -7
- package/src/parser/block/heading.ts +1 -1
- package/src/parser/block/reply/quote.ts +9 -46
- package/src/parser/block.ts +5 -3
- package/src/parser/inline/bracket.ts +18 -0
- package/src/parser/source/text.ts +1 -1
- package/src/util/toc.ts +4 -1
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.280.
|
|
1
|
+
/*! securemark v0.280.2 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"));
|
|
@@ -3325,9 +3325,6 @@ const alias_1 = __webpack_require__(5406);
|
|
|
3325
3325
|
const parser_1 = __webpack_require__(6728);
|
|
3326
3326
|
const memo_1 = __webpack_require__(1090);
|
|
3327
3327
|
function reset(base, parser) {
|
|
3328
|
-
if (!('memo' in base)) {
|
|
3329
|
-
base.memo = undefined;
|
|
3330
|
-
}
|
|
3331
3328
|
const changes = Object.entries(base);
|
|
3332
3329
|
const values = Array(changes.length);
|
|
3333
3330
|
return ({
|
|
@@ -3346,44 +3343,33 @@ function context(base, parser) {
|
|
|
3346
3343
|
}
|
|
3347
3344
|
exports.context = context;
|
|
3348
3345
|
function apply(parser, source, context, changes, values, reset = false) {
|
|
3349
|
-
|
|
3346
|
+
for (let i = 0; i < changes.length; ++i) {
|
|
3350
3347
|
const change = changes[i];
|
|
3351
3348
|
const prop = change[0];
|
|
3352
3349
|
switch (prop) {
|
|
3353
3350
|
case 'resources':
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
context[prop] = (0, alias_1.ObjectCreate)(change[1]);
|
|
3357
|
-
break;
|
|
3358
|
-
// @ts-expect-error
|
|
3359
|
-
case 'memo':
|
|
3360
|
-
if (!reset) break;
|
|
3361
|
-
context.memo = new memo_1.Memo({
|
|
3362
|
-
targets: context.memo?.targets
|
|
3363
|
-
});
|
|
3364
|
-
// fallthrough
|
|
3365
|
-
default:
|
|
3366
|
-
values[i] = context[prop];
|
|
3367
|
-
context[prop] = change[1];
|
|
3351
|
+
context[prop] ??= (0, alias_1.ObjectCreate)(change[1]);
|
|
3352
|
+
continue;
|
|
3368
3353
|
}
|
|
3354
|
+
values[i] = context[prop];
|
|
3355
|
+
context[prop] = change[1];
|
|
3369
3356
|
}
|
|
3370
3357
|
const result = parser({
|
|
3371
3358
|
source,
|
|
3372
3359
|
context
|
|
3373
3360
|
});
|
|
3374
|
-
|
|
3361
|
+
for (let i = 0; i < changes.length; ++i) {
|
|
3375
3362
|
const change = changes[i];
|
|
3376
3363
|
const prop = change[0];
|
|
3377
3364
|
switch (prop) {
|
|
3378
3365
|
case 'resources':
|
|
3379
|
-
|
|
3366
|
+
break;
|
|
3380
3367
|
case 'memo':
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
default:
|
|
3384
|
-
context[prop] = values[i];
|
|
3385
|
-
values[i] = undefined;
|
|
3368
|
+
context.memo.clear();
|
|
3369
|
+
break;
|
|
3386
3370
|
}
|
|
3371
|
+
context[prop] = values[i];
|
|
3372
|
+
values[i] = undefined;
|
|
3387
3373
|
}
|
|
3388
3374
|
return result;
|
|
3389
3375
|
}
|
|
@@ -3407,7 +3393,7 @@ function syntax(syntax, prec, state, parser) {
|
|
|
3407
3393
|
cache ?? memo.set(position, syntax, stateInner, (0, parser_1.eval)(result), source.length - (0, parser_1.exec)(result, '').length);
|
|
3408
3394
|
}
|
|
3409
3395
|
if (result && !stateOuter && memo.length >= position + 2) {
|
|
3410
|
-
memo.
|
|
3396
|
+
memo.resize(position + 2);
|
|
3411
3397
|
}
|
|
3412
3398
|
context.state = stateOuter;
|
|
3413
3399
|
return result;
|
|
@@ -3547,7 +3533,7 @@ class Delimiters {
|
|
|
3547
3533
|
return `r/${pattern.source}/${pattern.flags}`;
|
|
3548
3534
|
}
|
|
3549
3535
|
}
|
|
3550
|
-
push(
|
|
3536
|
+
push(delims) {
|
|
3551
3537
|
const {
|
|
3552
3538
|
registry,
|
|
3553
3539
|
delimiters,
|
|
@@ -3557,7 +3543,7 @@ class Delimiters {
|
|
|
3557
3543
|
const {
|
|
3558
3544
|
signature,
|
|
3559
3545
|
matcher,
|
|
3560
|
-
precedence
|
|
3546
|
+
precedence
|
|
3561
3547
|
} = delims[i];
|
|
3562
3548
|
const stack = registry(signature);
|
|
3563
3549
|
const index = stack[0]?.index ?? delimiters.length;
|
|
@@ -3576,7 +3562,7 @@ class Delimiters {
|
|
|
3576
3562
|
}
|
|
3577
3563
|
}
|
|
3578
3564
|
}
|
|
3579
|
-
pop(count
|
|
3565
|
+
pop(count) {
|
|
3580
3566
|
const {
|
|
3581
3567
|
registry,
|
|
3582
3568
|
delimiters,
|
|
@@ -3640,9 +3626,8 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
3640
3626
|
}));
|
|
3641
3627
|
exports.Memo = void 0;
|
|
3642
3628
|
class Memo {
|
|
3643
|
-
constructor({
|
|
3644
|
-
targets =
|
|
3645
|
-
} = {}) {
|
|
3629
|
+
constructor(targets = ~0) {
|
|
3630
|
+
this.targets = targets;
|
|
3646
3631
|
this.memory = [];
|
|
3647
3632
|
this.targets = targets;
|
|
3648
3633
|
}
|
|
@@ -3660,15 +3645,18 @@ class Memo {
|
|
|
3660
3645
|
//console.log('set', position, syntax, state, record[syntax]?.[state]);
|
|
3661
3646
|
}
|
|
3662
3647
|
|
|
3663
|
-
|
|
3648
|
+
resize(position) {
|
|
3664
3649
|
const memory = this.memory;
|
|
3665
3650
|
for (let len = memory.length, i = position; i < len; ++i) {
|
|
3666
3651
|
memory.pop();
|
|
3667
3652
|
}
|
|
3668
|
-
//console.log('
|
|
3653
|
+
//console.log('resize', position + 1);
|
|
3669
3654
|
}
|
|
3670
|
-
}
|
|
3671
3655
|
|
|
3656
|
+
clear() {
|
|
3657
|
+
this.memory = [];
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3672
3660
|
exports.Memo = Memo;
|
|
3673
3661
|
|
|
3674
3662
|
/***/ }),
|
|
@@ -3781,7 +3769,7 @@ function some(parser, end, delimiters = [], limit = -1) {
|
|
|
3781
3769
|
let nodes;
|
|
3782
3770
|
if (delims.length > 0) {
|
|
3783
3771
|
context.delimiters ??= new delimiter_1.Delimiters();
|
|
3784
|
-
context.delimiters.push(
|
|
3772
|
+
context.delimiters.push(delims);
|
|
3785
3773
|
}
|
|
3786
3774
|
while (true) {
|
|
3787
3775
|
if (rest === '') break;
|
|
@@ -3972,7 +3960,6 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
3972
3960
|
}));
|
|
3973
3961
|
exports.bind = void 0;
|
|
3974
3962
|
const parser_1 = __webpack_require__(6728);
|
|
3975
|
-
const memo_1 = __webpack_require__(1090);
|
|
3976
3963
|
const segment_1 = __webpack_require__(9002);
|
|
3977
3964
|
const header_1 = __webpack_require__(5702);
|
|
3978
3965
|
const block_1 = __webpack_require__(4032);
|
|
@@ -3985,12 +3972,8 @@ const array_1 = __webpack_require__(8112);
|
|
|
3985
3972
|
function bind(target, settings) {
|
|
3986
3973
|
let context = {
|
|
3987
3974
|
...settings,
|
|
3988
|
-
host: settings.host ?? new url_1.ReadonlyURL(location.pathname, location.origin)
|
|
3989
|
-
memo: new memo_1.Memo({
|
|
3990
|
-
targets: 472 /* State.backtrackers */
|
|
3991
|
-
})
|
|
3975
|
+
host: settings.host ?? new url_1.ReadonlyURL(location.pathname, location.origin)
|
|
3992
3976
|
};
|
|
3993
|
-
|
|
3994
3977
|
if (context.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
|
|
3995
3978
|
if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
|
|
3996
3979
|
const blocks = [];
|
|
@@ -4297,7 +4280,6 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
4297
4280
|
}));
|
|
4298
4281
|
exports.parse = void 0;
|
|
4299
4282
|
const parser_1 = __webpack_require__(6728);
|
|
4300
|
-
const memo_1 = __webpack_require__(1090);
|
|
4301
4283
|
const segment_1 = __webpack_require__(9002);
|
|
4302
4284
|
const header_1 = __webpack_require__(5702);
|
|
4303
4285
|
const block_1 = __webpack_require__(4032);
|
|
@@ -4316,14 +4298,8 @@ function parse(source, opts = {}, context) {
|
|
|
4316
4298
|
url: url ? new url_1.ReadonlyURL(url) : context?.url,
|
|
4317
4299
|
id: opts.id ?? context?.id,
|
|
4318
4300
|
caches: context?.caches,
|
|
4319
|
-
|
|
4320
|
-
resources: context.resources
|
|
4321
|
-
}),
|
|
4322
|
-
memo: new memo_1.Memo({
|
|
4323
|
-
targets: 472 /* State.backtrackers */
|
|
4324
|
-
})
|
|
4301
|
+
resources: context?.resources
|
|
4325
4302
|
};
|
|
4326
|
-
|
|
4327
4303
|
if (context.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
|
|
4328
4304
|
if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
|
|
4329
4305
|
const node = (0, dom_1.frag)();
|
|
@@ -4376,6 +4352,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
4376
4352
|
}));
|
|
4377
4353
|
exports.block = void 0;
|
|
4378
4354
|
const combinator_1 = __webpack_require__(2087);
|
|
4355
|
+
const memo_1 = __webpack_require__(1090);
|
|
4379
4356
|
const source_1 = __webpack_require__(6743);
|
|
4380
4357
|
const pagebreak_1 = __webpack_require__(4107);
|
|
4381
4358
|
const heading_1 = __webpack_require__(4623);
|
|
@@ -4394,12 +4371,13 @@ const reply_1 = __webpack_require__(9978);
|
|
|
4394
4371
|
const paragraph_1 = __webpack_require__(6457);
|
|
4395
4372
|
const random_1 = __webpack_require__(7325);
|
|
4396
4373
|
const dom_1 = __webpack_require__(3252);
|
|
4397
|
-
exports.block = (0, combinator_1.creation)(0, false,
|
|
4374
|
+
exports.block = (0, combinator_1.creation)(0, false, (0, combinator_1.reset)({
|
|
4398
4375
|
resources: {
|
|
4399
4376
|
clock: 20000,
|
|
4400
4377
|
recursion: 20 + 1
|
|
4401
|
-
}
|
|
4402
|
-
|
|
4378
|
+
},
|
|
4379
|
+
memo: new memo_1.Memo(472 /* State.backtrackers */)
|
|
4380
|
+
}, error((0, combinator_1.union)([source_1.emptyline, pagebreak_1.pagebreak, heading_1.heading, ulist_1.ulist, olist_1.olist, ilist_1.ilist, dlist_1.dlist, table_1.table, codeblock_1.codeblock, mathblock_1.mathblock, extension_1.extension, sidefence_1.sidefence, blockquote_1.blockquote, mediablock_1.mediablock, reply_1.reply, paragraph_1.paragraph]))));
|
|
4403
4381
|
function error(parser) {
|
|
4404
4382
|
return (0, combinator_1.recover)((0, combinator_1.fallback)((0, combinator_1.open)('\x07', ({
|
|
4405
4383
|
source
|
|
@@ -5254,7 +5232,7 @@ const dom_1 = __webpack_require__(3252);
|
|
|
5254
5232
|
exports.segment = (0, combinator_1.block)((0, combinator_1.validate)('#', (0, combinator_1.focus)(/^#+[^\S\n]+\S[^\n]*(?:\n#+(?!\S)[^\n]*)*(?:$|\n)/, (0, combinator_1.some)((0, combinator_1.line)(({
|
|
5255
5233
|
source
|
|
5256
5234
|
}) => [[source], ''])))));
|
|
5257
|
-
exports.heading = (0, combinator_1.block)((0, combinator_1.rewrite)(exports.segment, (0, combinator_1.state)(256 /* State.annotation */ | 128 /* State.reference */ | 64 /* State.index */ | 32 /* State.label */ | 16 /* State.link */ | 8 /* State.media */, (0, combinator_1.line)((0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.union)([(0, combinator_1.open)((0, source_1.str)(/^##+/), (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline])))), true), (0, combinator_1.open)((0, source_1.str)('#'), (0, combinator_1.state)(
|
|
5235
|
+
exports.heading = (0, combinator_1.block)((0, combinator_1.rewrite)(exports.segment, (0, combinator_1.state)(256 /* State.annotation */ | 128 /* State.reference */ | 64 /* State.index */ | 32 /* State.label */ | 16 /* State.link */ | 8 /* State.media */, (0, combinator_1.line)((0, inline_1.indexee)((0, combinator_1.fmap)((0, combinator_1.union)([(0, combinator_1.open)((0, source_1.str)(/^##+/), (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline])))), true), (0, combinator_1.open)((0, source_1.str)('#'), (0, combinator_1.state)(502 /* State.linkers */, (0, visibility_1.visualize)((0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.indexer, inline_1.inline]))))), true)]), ([h, ...ns]) => [h.length <= 6 ? (0, dom_1.html)(`h${h.length}`, (0, visibility_1.trimNodeEnd)((0, dom_1.defrag)(ns))) : (0, dom_1.html)(`h6`, {
|
|
5258
5236
|
class: 'invalid',
|
|
5259
5237
|
'data-invalid-syntax': 'heading',
|
|
5260
5238
|
'data-invalid-type': 'syntax',
|
|
@@ -5586,7 +5564,6 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
5586
5564
|
value: true
|
|
5587
5565
|
}));
|
|
5588
5566
|
exports.quote = exports.syntax = void 0;
|
|
5589
|
-
const parser_1 = __webpack_require__(6728);
|
|
5590
5567
|
const combinator_1 = __webpack_require__(2087);
|
|
5591
5568
|
const math_1 = __webpack_require__(8946);
|
|
5592
5569
|
const autolink_1 = __webpack_require__(6051);
|
|
@@ -5601,42 +5578,7 @@ exports.quote = (0, combinator_1.lazy)(() => (0, combinator_1.creation)(1, false
|
|
|
5601
5578
|
'data-invalid-type': 'syntax',
|
|
5602
5579
|
'data-invalid-message': `Missing the whitespace after "${ns[0].split(/[^>]/, 1)[0]}"`
|
|
5603
5580
|
}, (0, dom_1.defrag)(ns)), (0, dom_1.html)('br')]), false)));
|
|
5604
|
-
const qblock = (
|
|
5605
|
-
source,
|
|
5606
|
-
context
|
|
5607
|
-
}) => {
|
|
5608
|
-
source = source.replace(/\n$/, '');
|
|
5609
|
-
const lines = source.match(/^.*\n?/mg);
|
|
5610
|
-
const quotes = source.match(/^>+[^\S\n]/mg);
|
|
5611
|
-
const content = lines.reduce((acc, line, i) => acc + line.slice(quotes[i].length), '');
|
|
5612
|
-
const nodes = (0, parser_1.eval)(text({
|
|
5613
|
-
source: `\r${content}`,
|
|
5614
|
-
context
|
|
5615
|
-
}), []);
|
|
5616
|
-
nodes.unshift(quotes.shift());
|
|
5617
|
-
for (let i = 0; i < nodes.length; ++i) {
|
|
5618
|
-
const child = nodes[i];
|
|
5619
|
-
if (typeof child === 'string') continue;
|
|
5620
|
-
if ('wholeText' in child) {
|
|
5621
|
-
nodes[i] = child.data;
|
|
5622
|
-
continue;
|
|
5623
|
-
}
|
|
5624
|
-
if (child.tagName === 'BR') {
|
|
5625
|
-
nodes.splice(i + 1, 0, quotes.shift());
|
|
5626
|
-
++i;
|
|
5627
|
-
continue;
|
|
5628
|
-
}
|
|
5629
|
-
if (child.className === 'cite' || child.classList.contains('quote')) {
|
|
5630
|
-
context.resources && (context.resources.clock -= child.childNodes.length);
|
|
5631
|
-
nodes.splice(i, 1, ...child.childNodes);
|
|
5632
|
-
--i;
|
|
5633
|
-
continue;
|
|
5634
|
-
}
|
|
5635
|
-
}
|
|
5636
|
-
nodes.unshift('');
|
|
5637
|
-
return [nodes, ''];
|
|
5638
|
-
};
|
|
5639
|
-
const text = (0, combinator_1.some)((0, combinator_1.union)([math_1.math, autolink_1.autolink, source_1.linebreak, source_1.unescsource]));
|
|
5581
|
+
const qblock = (0, combinator_1.convert)(source => source.replace(/\n$/, '').replace(/(?<=^>+[^\S\n])/mg, '\r'), (0, combinator_1.some)((0, combinator_1.union)([math_1.math, autolink_1.autolink, source_1.linebreak, source_1.unescsource])));
|
|
5640
5582
|
|
|
5641
5583
|
/***/ }),
|
|
5642
5584
|
|
|
@@ -6120,7 +6062,7 @@ exports.bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, comb
|
|
|
6120
6062
|
class: 'paren'
|
|
6121
6063
|
}, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 2, 0 /* State.none */, (0, source_1.str)(new RegExp(index.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)/g, c => c.trimStart() && String.fromCharCode(c.charCodeAt(0) + 0xFEE0)))))), (0, source_1.str)(')')), (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, ')', [[/^\\?\n/, 3], [')', 2]]))), (0, source_1.str)(')'), true, ([as, bs = [], cs], rest) => [[(0, dom_1.html)('span', {
|
|
6122
6064
|
class: 'paren'
|
|
6123
|
-
}, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, ']', [[/^\\?\n/, 3], [']', 2]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '}', [[/^\\?\n/, 3], ['}', 2]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '"', [[/^\\?\n/, 4], ['"', 3]]))), (0, source_1.str)('"'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest])]));
|
|
6065
|
+
}, (0, dom_1.defrag)((0, array_1.push)((0, array_1.unshift)(as, bs), cs)))], rest], ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, ']', [[/^\\?\n/, 3], [']', 2]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, ']', [[/^\\?\n/, 3], [']', 2]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '}', [[/^\\?\n/, 3], ['}', 2]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.creation)((0, combinator_1.syntax)(8 /* Syntax.bracket */, 2, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '}', [[/^\\?\n/, 3], ['}', 2]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '"', [[/^\\?\n/, 4], ['"', 3]]))), (0, source_1.str)('"'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('“'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '”', [[/^\\?\n/, 4], ['”', 3]]))), (0, source_1.str)('”'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('‘'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '’', [[/^\\?\n/, 4], ['’', 3]]))), (0, source_1.str)('’'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('「'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '」', [[/^\\?\n/, 4], ['」', 3]]))), (0, source_1.str)('」'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]), (0, combinator_1.surround)((0, source_1.str)('『'), (0, combinator_1.creation)((0, combinator_1.syntax)(0 /* Syntax.none */, 3, 0 /* State.none */, (0, combinator_1.some)(inline_1.inline, '』', [[/^\\?\n/, 4], ['』', 3]]))), (0, source_1.str)('』'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest])]));
|
|
6124
6066
|
|
|
6125
6067
|
/***/ }),
|
|
6126
6068
|
|
|
@@ -7618,7 +7560,7 @@ exports.isAlphanumeric = exports.linebreak = exports.txt = exports.text = export
|
|
|
7618
7560
|
const combinator_1 = __webpack_require__(2087);
|
|
7619
7561
|
const str_1 = __webpack_require__(2790);
|
|
7620
7562
|
const dom_1 = __webpack_require__(3252);
|
|
7621
|
-
exports.delimiter = /[\s\x00-\x7F
|
|
7563
|
+
exports.delimiter = /[\s\x00-\x7F()[]{}“”‘’「」『』]|\S[#>]/u;
|
|
7622
7564
|
exports.nonWhitespace = /[\S\n]|$/u;
|
|
7623
7565
|
exports.nonAlphanumeric = /[^0-9A-Za-z]|\S[#>]|$/u;
|
|
7624
7566
|
const repeat = (0, str_1.str)(/^(.)\1*/);
|
|
@@ -8564,7 +8506,7 @@ function level(h) {
|
|
|
8564
8506
|
function unlink(h) {
|
|
8565
8507
|
for (let es = h.getElementsByTagName('a'), len = es.length, i = 0; i < len; ++i) {
|
|
8566
8508
|
const el = es[i];
|
|
8567
|
-
el.replaceWith(
|
|
8509
|
+
el.firstChild ? el.replaceWith(el.firstChild) : el.remove();
|
|
8568
8510
|
}
|
|
8569
8511
|
return h.childNodes;
|
|
8570
8512
|
}
|
package/markdown.d.ts
CHANGED
|
@@ -631,12 +631,6 @@ export namespace MarkdownParser {
|
|
|
631
631
|
export namespace QuoteParser {
|
|
632
632
|
export interface BlockParser extends
|
|
633
633
|
Block<'reply/quote/block'>,
|
|
634
|
-
Parser<string | HTMLElement, Context, [
|
|
635
|
-
TextParser,
|
|
636
|
-
]> {
|
|
637
|
-
}
|
|
638
|
-
export interface TextParser extends
|
|
639
|
-
Block<'reply/quote/text'>,
|
|
640
634
|
Parser<string | HTMLElement, Context, [
|
|
641
635
|
InlineParser.MathParser,
|
|
642
636
|
InlineParser.AutolinkParser,
|
|
@@ -1252,6 +1246,12 @@ export namespace MarkdownParser {
|
|
|
1252
1246
|
InlineParser,
|
|
1253
1247
|
InlineParser,
|
|
1254
1248
|
InlineParser,
|
|
1249
|
+
InlineParser,
|
|
1250
|
+
InlineParser,
|
|
1251
|
+
InlineParser,
|
|
1252
|
+
InlineParser,
|
|
1253
|
+
InlineParser,
|
|
1254
|
+
InlineParser,
|
|
1255
1255
|
]> {
|
|
1256
1256
|
}
|
|
1257
1257
|
}
|
package/package.json
CHANGED
|
@@ -34,15 +34,15 @@ export class Delimiters {
|
|
|
34
34
|
private readonly delimiters: Delimiter[] = [];
|
|
35
35
|
private readonly order: number[] = [];
|
|
36
36
|
public push(
|
|
37
|
-
|
|
37
|
+
delims: readonly {
|
|
38
38
|
readonly signature: string;
|
|
39
39
|
readonly matcher: (source: string) => boolean | undefined;
|
|
40
|
-
readonly precedence
|
|
40
|
+
readonly precedence: number;
|
|
41
41
|
}[]
|
|
42
42
|
): void {
|
|
43
43
|
const { registry, delimiters, order } = this;
|
|
44
44
|
for (let i = 0; i < delims.length; ++i) {
|
|
45
|
-
const { signature, matcher, precedence
|
|
45
|
+
const { signature, matcher, precedence } = delims[i];
|
|
46
46
|
const stack = registry(signature);
|
|
47
47
|
const index = stack[0]?.index ?? delimiters.length;
|
|
48
48
|
if (stack.length === 0 || precedence > delimiters[index].precedence) {
|
|
@@ -61,7 +61,7 @@ export class Delimiters {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
public pop(count
|
|
64
|
+
public pop(count: number): void {
|
|
65
65
|
assert(count > 0);
|
|
66
66
|
const { registry, delimiters, order } = this;
|
|
67
67
|
for (let i = 0; i < count; ++i) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export class Memo {
|
|
2
|
-
constructor(
|
|
2
|
+
constructor(
|
|
3
|
+
public readonly targets = ~0,
|
|
4
|
+
) {
|
|
3
5
|
this.targets = targets;
|
|
4
6
|
}
|
|
5
|
-
|
|
6
|
-
private readonly memory: Record<number, Record<number, readonly [any[], number] | readonly []>>[/* pos */] = [];
|
|
7
|
+
private memory: Record<number, Record<number, readonly [any[], number] | readonly []>>[/* pos */] = [];
|
|
7
8
|
public get length(): number {
|
|
8
9
|
return this.memory.length;
|
|
9
10
|
}
|
|
@@ -32,11 +33,14 @@ export class Memo {
|
|
|
32
33
|
: [];
|
|
33
34
|
//console.log('set', position, syntax, state, record[syntax]?.[state]);
|
|
34
35
|
}
|
|
35
|
-
public
|
|
36
|
+
public resize(position: number): void {
|
|
36
37
|
const memory = this.memory;
|
|
37
38
|
for (let len = memory.length, i = position; i < len; ++i) {
|
|
38
39
|
memory.pop();
|
|
39
40
|
}
|
|
40
|
-
//console.log('
|
|
41
|
+
//console.log('resize', position + 1);
|
|
42
|
+
}
|
|
43
|
+
public clear(): void {
|
|
44
|
+
this.memory = [];
|
|
41
45
|
}
|
|
42
46
|
}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ObjectCreate } from 'spica/alias';
|
|
2
2
|
import { Parser, Result, Ctx, Tree, Context, eval, exec } from '../../data/parser';
|
|
3
3
|
import { Memo } from './context/memo';
|
|
4
4
|
|
|
5
5
|
export function reset<P extends Parser<unknown>>(base: Context<P>, parser: P): P;
|
|
6
6
|
export function reset<T>(base: Ctx, parser: Parser<T>): Parser<T> {
|
|
7
|
-
if (!('memo' in base)) {
|
|
8
|
-
base.memo = undefined;
|
|
9
|
-
}
|
|
10
7
|
assert(Object.getPrototypeOf(base) === Object.prototype);
|
|
11
8
|
assert(Object.freeze(base));
|
|
12
9
|
const changes = Object.entries(base);
|
|
@@ -27,41 +24,38 @@ export function context<T>(base: Ctx, parser: Parser<T>): Parser<T> {
|
|
|
27
24
|
|
|
28
25
|
function apply<P extends Parser<unknown>>(parser: P, source: string, context: Context<P>, changes: readonly [string, unknown][], values: unknown[], reset?: boolean): Result<Tree<P>>;
|
|
29
26
|
function apply<T>(parser: Parser<T>, source: string, context: Ctx, changes: readonly [string, unknown][], values: unknown[], reset = false): Result<T> {
|
|
30
|
-
|
|
27
|
+
for (let i = 0; i < changes.length; ++i) {
|
|
31
28
|
const change = changes[i];
|
|
32
29
|
const prop = change[0];
|
|
33
30
|
switch (prop) {
|
|
34
31
|
case 'resources':
|
|
35
|
-
|
|
36
|
-
assert(
|
|
37
|
-
assert(
|
|
38
|
-
|
|
39
|
-
context
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (!reset) break;
|
|
44
|
-
context.memo = new Memo({ targets: context.memo?.targets });
|
|
45
|
-
// fallthrough
|
|
46
|
-
default:
|
|
47
|
-
values[i] = context[prop];
|
|
48
|
-
context[prop] = change[1];
|
|
32
|
+
assert(reset);
|
|
33
|
+
assert(!context.offset);
|
|
34
|
+
assert(!context.precedence);
|
|
35
|
+
assert(!context.delimiters);
|
|
36
|
+
assert(!context.state);
|
|
37
|
+
assert(!context.memo);
|
|
38
|
+
context[prop as string] ??= ObjectCreate(change[1] as object);
|
|
39
|
+
continue;
|
|
49
40
|
}
|
|
41
|
+
values[i] = context[prop];
|
|
42
|
+
context[prop] = change[1];
|
|
50
43
|
}
|
|
51
44
|
const result = parser({ source, context });
|
|
52
|
-
|
|
45
|
+
for (let i = 0; i < changes.length; ++i) {
|
|
53
46
|
const change = changes[i];
|
|
54
47
|
const prop = change[0];
|
|
55
48
|
switch (prop) {
|
|
56
49
|
case 'resources':
|
|
57
|
-
|
|
50
|
+
assert(reset);
|
|
51
|
+
break;
|
|
58
52
|
case 'memo':
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
context[prop] = values[i];
|
|
63
|
-
values[i] = undefined;
|
|
53
|
+
assert(reset);
|
|
54
|
+
context.memo!.clear();
|
|
55
|
+
break;
|
|
64
56
|
}
|
|
57
|
+
context[prop] = values[i];
|
|
58
|
+
values[i] = undefined;
|
|
65
59
|
}
|
|
66
60
|
return result;
|
|
67
61
|
}
|
|
@@ -87,7 +81,7 @@ export function syntax<T>(syntax: number, prec: number, state: number, parser?:
|
|
|
87
81
|
}
|
|
88
82
|
if (result && !stateOuter && memo.length! >= position + 2) {
|
|
89
83
|
assert(!(stateOuter & memo.targets));
|
|
90
|
-
memo.
|
|
84
|
+
memo.resize(position + 2);
|
|
91
85
|
}
|
|
92
86
|
context.state = stateOuter;
|
|
93
87
|
return result;
|
|
@@ -22,7 +22,7 @@ export function some<T>(parser: Parser<T>, end?: string | RegExp | number, delim
|
|
|
22
22
|
let nodes: T[] | undefined;
|
|
23
23
|
if (delims.length > 0) {
|
|
24
24
|
context.delimiters ??= new Delimiters();
|
|
25
|
-
context.delimiters.push(
|
|
25
|
+
context.delimiters.push(delims);
|
|
26
26
|
}
|
|
27
27
|
while (true) {
|
|
28
28
|
if (rest === '') break;
|
package/src/parser/api/bind.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { ParserSettings, Progress } from '../../..';
|
|
2
2
|
import { MarkdownParser } from '../../../markdown';
|
|
3
3
|
import { eval } from '../../combinator/data/parser';
|
|
4
|
-
import { Memo } from '../../combinator/data/parser/context/memo';
|
|
5
4
|
import { segment, validate, MAX_INPUT_SIZE } from '../segment';
|
|
6
5
|
import { header } from '../header';
|
|
7
6
|
import { block } from '../block';
|
|
8
|
-
import { State } from '../context';
|
|
9
7
|
import { normalize } from './normalize';
|
|
10
8
|
import { headers } from './header';
|
|
11
9
|
import { figure } from '../processor/figure';
|
|
@@ -24,11 +22,14 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
|
|
|
24
22
|
let context: MarkdownParser.Context = {
|
|
25
23
|
...settings,
|
|
26
24
|
host: settings.host ?? new ReadonlyURL(location.pathname, location.origin),
|
|
27
|
-
memo: new Memo({ targets: State.backtrackers }),
|
|
28
25
|
};
|
|
26
|
+
assert(!context.offset);
|
|
27
|
+
assert(!context.precedence);
|
|
28
|
+
assert(!context.delimiters);
|
|
29
|
+
assert(!context.state);
|
|
30
|
+
assert(!context.memo);
|
|
29
31
|
if (context.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
|
|
30
32
|
if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
|
|
31
|
-
assert(!settings.id);
|
|
32
33
|
type Block = readonly [segment: string, blocks: readonly HTMLElement[], url: string];
|
|
33
34
|
const blocks: Block[] = [];
|
|
34
35
|
const adds: [HTMLElement, Node | null][] = [];
|
|
@@ -333,7 +333,6 @@ describe('Unit: parser/api/parse', () => {
|
|
|
333
333
|
|
|
334
334
|
it('creation', function () {
|
|
335
335
|
this.timeout(5000);
|
|
336
|
-
// 実測500ms程度
|
|
337
336
|
assert.deepStrictEqual(
|
|
338
337
|
[...parse('.'.repeat(20000)).children].map(el => el.outerHTML),
|
|
339
338
|
[`<p>${'.'.repeat(20000)}</p>`]);
|
|
@@ -341,7 +340,6 @@ describe('Unit: parser/api/parse', () => {
|
|
|
341
340
|
|
|
342
341
|
it('creation error', function () {
|
|
343
342
|
this.timeout(5000);
|
|
344
|
-
// 実測500ms程度
|
|
345
343
|
assert.deepStrictEqual(
|
|
346
344
|
[...parse('.'.repeat(20001)).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
347
345
|
[
|
|
@@ -350,6 +348,16 @@ describe('Unit: parser/api/parse', () => {
|
|
|
350
348
|
]);
|
|
351
349
|
});
|
|
352
350
|
|
|
351
|
+
it('recovery', function () {
|
|
352
|
+
this.timeout(5000);
|
|
353
|
+
assert.deepStrictEqual(
|
|
354
|
+
[...parse(`!>> ${'['.repeat(20)}${'{a}'.repeat(518)}\n> ${'{a}'.repeat(4)}\n\na`).children].map(el => el.outerHTML),
|
|
355
|
+
[
|
|
356
|
+
`<blockquote><blockquote><section><p>${'['.repeat(20)}${'<a class="url" href="a">a</a>'.repeat(518)}</p><h2>References</h2><ol class="references"></ol></section></blockquote><section><h1 class="error">Error: Too many creations</h1><pre class="error" translate="no">{a}{a}{a}{a}</pre><h2>References</h2><ol class="references"></ol></section></blockquote>`,
|
|
357
|
+
'<p>a</p>',
|
|
358
|
+
]);
|
|
359
|
+
});
|
|
360
|
+
|
|
353
361
|
});
|
|
354
362
|
|
|
355
363
|
});
|
package/src/parser/api/parse.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { ParserOptions } from '../../..';
|
|
2
2
|
import { MarkdownParser } from '../../../markdown';
|
|
3
3
|
import { eval } from '../../combinator/data/parser';
|
|
4
|
-
import { Memo } from '../../combinator/data/parser/context/memo';
|
|
5
4
|
import { segment, validate, MAX_SEGMENT_SIZE } from '../segment';
|
|
6
5
|
import { header } from '../header';
|
|
7
6
|
import { block } from '../block';
|
|
8
|
-
import { State } from '../context';
|
|
9
7
|
import { normalize } from './normalize';
|
|
10
8
|
import { headers } from './header';
|
|
11
9
|
import { figure } from '../processor/figure';
|
|
@@ -21,17 +19,18 @@ export function parse(source: string, opts: Options = {}, context?: MarkdownPars
|
|
|
21
19
|
if (!validate(source, MAX_SEGMENT_SIZE)) throw new Error(`Too large input over ${MAX_SEGMENT_SIZE.toLocaleString('en')} bytes`);
|
|
22
20
|
const url = headers(source).find(field => field.toLowerCase().startsWith('url:'))?.slice(4).trim() ?? '';
|
|
23
21
|
source = !context ? normalize(source) : source;
|
|
24
|
-
assert(!context?.delimiters);
|
|
25
22
|
context = {
|
|
26
23
|
host: opts.host ?? context?.host ?? new ReadonlyURL(location.pathname, location.origin),
|
|
27
24
|
url: url ? new ReadonlyURL(url as ':') : context?.url,
|
|
28
25
|
id: opts.id ?? context?.id,
|
|
29
26
|
caches: context?.caches,
|
|
30
|
-
|
|
31
|
-
resources: context.resources,
|
|
32
|
-
},
|
|
33
|
-
memo: new Memo({ targets: State.backtrackers }),
|
|
27
|
+
resources: context?.resources,
|
|
34
28
|
};
|
|
29
|
+
assert(!context.offset);
|
|
30
|
+
assert(!context.precedence);
|
|
31
|
+
assert(!context.delimiters);
|
|
32
|
+
assert(!context.state);
|
|
33
|
+
assert(!context.memo);
|
|
35
34
|
if (context.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
|
|
36
35
|
if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
|
|
37
36
|
const node = frag();
|
|
@@ -18,7 +18,7 @@ export const heading: HeadingParser = block(rewrite(segment,
|
|
|
18
18
|
visualize(trimBlankStart(some(union([indexer, inline])))), true),
|
|
19
19
|
open(
|
|
20
20
|
str('#'),
|
|
21
|
-
state(State.
|
|
21
|
+
state(State.linkers,
|
|
22
22
|
visualize(trimBlankStart(some(union([indexer, inline]))))), true),
|
|
23
23
|
]),
|
|
24
24
|
([h, ...ns]: [string, ...(HTMLElement | string)[]]) => [
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ReplyParser } from '../../block';
|
|
2
|
-
import {
|
|
3
|
-
import { union, some, creation, block, line, validate, rewrite, lazy, fmap } from '../../../combinator';
|
|
2
|
+
import { union, some, creation, block, line, validate, rewrite, convert, lazy, fmap } from '../../../combinator';
|
|
4
3
|
import { math } from '../../inline/math';
|
|
5
4
|
import { autolink } from '../../inline/autolink';
|
|
6
5
|
import { linebreak, unescsource, str, anyline } from '../../source';
|
|
@@ -33,47 +32,11 @@ export const quote: ReplyParser.QuoteParser = lazy(() => creation(1, false, bloc
|
|
|
33
32
|
]),
|
|
34
33
|
false)));
|
|
35
34
|
|
|
36
|
-
const qblock: ReplyParser.QuoteParser.BlockParser = (
|
|
37
|
-
source
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const nodes = eval(text({ source: `\r${content}`, context }), []);
|
|
45
|
-
nodes.unshift(quotes.shift()!);
|
|
46
|
-
for (let i = 0; i < nodes.length; ++i) {
|
|
47
|
-
const child = nodes[i] as string | Text | Element;
|
|
48
|
-
if (typeof child === 'string') continue;
|
|
49
|
-
if ('wholeText' in child) {
|
|
50
|
-
nodes[i] = child.data;
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
assert(child instanceof HTMLElement);
|
|
54
|
-
if (child.tagName === 'BR') {
|
|
55
|
-
assert(quotes.length > 0);
|
|
56
|
-
nodes.splice(i + 1, 0, quotes.shift()!);
|
|
57
|
-
++i;
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
if (child.className === 'cite' || child.classList.contains('quote')) {
|
|
61
|
-
context.resources && (context.resources.clock -= child.childNodes.length);
|
|
62
|
-
nodes.splice(i, 1, ...child.childNodes as NodeListOf<HTMLElement>);
|
|
63
|
-
--i;
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
nodes.unshift('');
|
|
68
|
-
assert(nodes.length > 1);
|
|
69
|
-
assert(nodes.every(n => typeof n === 'string' || n instanceof HTMLElement));
|
|
70
|
-
assert(quotes.length === 0);
|
|
71
|
-
return [nodes, ''];
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const text: ReplyParser.QuoteParser.TextParser = some(union([
|
|
75
|
-
math, // quote補助関数が残した数式をパースする。他の構文で数式を残す場合はソーステキストを直接使用する。
|
|
76
|
-
autolink,
|
|
77
|
-
linebreak,
|
|
78
|
-
unescsource,
|
|
79
|
-
]));
|
|
35
|
+
const qblock: ReplyParser.QuoteParser.BlockParser = convert(
|
|
36
|
+
source => source.replace(/\n$/, '').replace(/(?<=^>+[^\S\n])/mg, '\r'),
|
|
37
|
+
some(union([
|
|
38
|
+
math, // quote補助関数が残した数式をパースする。他の構文で数式を残す場合はソーステキストを直接使用する。
|
|
39
|
+
autolink,
|
|
40
|
+
linebreak,
|
|
41
|
+
unescsource,
|
|
42
|
+
])));
|
package/src/parser/block.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../markdown';
|
|
2
2
|
import { union, reset, creation, open, fallback, recover } from '../combinator';
|
|
3
|
+
import { Memo } from '../combinator/data/parser/context/memo';
|
|
3
4
|
import { emptyline } from './source';
|
|
4
5
|
import { pagebreak } from './block/pagebreak';
|
|
5
6
|
import { heading } from './block/heading';
|
|
@@ -16,6 +17,7 @@ import { blockquote } from './block/blockquote';
|
|
|
16
17
|
import { mediablock } from './block/mediablock';
|
|
17
18
|
import { reply } from './block/reply';
|
|
18
19
|
import { paragraph } from './block/paragraph';
|
|
20
|
+
import { State } from './context';
|
|
19
21
|
import { rnd0Z } from 'spica/random';
|
|
20
22
|
import { html } from 'typed-dom/dom';
|
|
21
23
|
|
|
@@ -36,9 +38,9 @@ export import MediaBlockParser = BlockParser.MediaBlockParser;
|
|
|
36
38
|
export import ReplyParser = BlockParser.ReplyParser;
|
|
37
39
|
export import ParagraphParser = BlockParser.ParagraphParser;
|
|
38
40
|
|
|
39
|
-
export const block: BlockParser = creation(0, false,
|
|
40
|
-
reset({ resources: { clock: 20000, recursion: 20 + 1 } },
|
|
41
|
-
union([
|
|
41
|
+
export const block: BlockParser = creation(0, false,
|
|
42
|
+
reset({ resources: { clock: 20000, recursion: 20 + 1 }, memo: new Memo(State.backtrackers) },
|
|
43
|
+
error(union([
|
|
42
44
|
emptyline,
|
|
43
45
|
pagebreak,
|
|
44
46
|
heading,
|
|
@@ -20,10 +20,28 @@ export const bracket: BracketParser = lazy(() => union([
|
|
|
20
20
|
surround(str('['), creation(syntax(Syntax.bracket, 2, State.none, some(inline, ']', [[/^\\?\n/, 3], [']', 2]]))), str(']'), true,
|
|
21
21
|
undefined,
|
|
22
22
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
23
|
+
surround(str('['), creation(syntax(Syntax.bracket, 2, State.none, some(inline, ']', [[/^\\?\n/, 3], [']', 2]]))), str(']'), true,
|
|
24
|
+
undefined,
|
|
25
|
+
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
23
26
|
surround(str('{'), creation(syntax(Syntax.bracket, 2, State.none, some(inline, '}', [[/^\\?\n/, 3], ['}', 2]]))), str('}'), true,
|
|
24
27
|
undefined,
|
|
25
28
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
29
|
+
surround(str('{'), creation(syntax(Syntax.bracket, 2, State.none, some(inline, '}', [[/^\\?\n/, 3], ['}', 2]]))), str('}'), true,
|
|
30
|
+
undefined,
|
|
31
|
+
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
26
32
|
surround(str('"'), creation(syntax(Syntax.none, 3, State.none, some(inline, '"', [[/^\\?\n/, 4], ['"', 3]]))), str('"'), true,
|
|
27
33
|
undefined,
|
|
28
34
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
35
|
+
surround(str('“'), creation(syntax(Syntax.none, 3, State.none, some(inline, '”', [[/^\\?\n/, 4], ['”', 3]]))), str('”'), true,
|
|
36
|
+
undefined,
|
|
37
|
+
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
38
|
+
surround(str('‘'), creation(syntax(Syntax.none, 3, State.none, some(inline, '’', [[/^\\?\n/, 4], ['’', 3]]))), str('’'), true,
|
|
39
|
+
undefined,
|
|
40
|
+
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
41
|
+
surround(str('「'), creation(syntax(Syntax.none, 3, State.none, some(inline, '」', [[/^\\?\n/, 4], ['」', 3]]))), str('」'), true,
|
|
42
|
+
undefined,
|
|
43
|
+
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
44
|
+
surround(str('『'), creation(syntax(Syntax.none, 3, State.none, some(inline, '』', [[/^\\?\n/, 4], ['』', 3]]))), str('』'), true,
|
|
45
|
+
undefined,
|
|
46
|
+
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
29
47
|
]));
|
|
@@ -3,7 +3,7 @@ import { union, creation, focus } from '../../combinator';
|
|
|
3
3
|
import { str } from './str';
|
|
4
4
|
import { html } from 'typed-dom/dom';
|
|
5
5
|
|
|
6
|
-
export const delimiter = /[\s\x00-\x7F
|
|
6
|
+
export const delimiter = /[\s\x00-\x7F()[]{}“”‘’「」『』]|\S[#>]/u;
|
|
7
7
|
export const nonWhitespace = /[\S\n]|$/u;
|
|
8
8
|
export const nonAlphanumeric = /[^0-9A-Za-z]|\S[#>]|$/u;
|
|
9
9
|
const repeat = str(/^(.)\1*/);
|
package/src/util/toc.ts
CHANGED
|
@@ -61,7 +61,10 @@ function level(h: HTMLHeadingElement): number {
|
|
|
61
61
|
function unlink(h: HTMLHeadingElement): Iterable<Node> {
|
|
62
62
|
for (let es = h.getElementsByTagName('a'), len = es.length, i = 0; i < len; ++i) {
|
|
63
63
|
const el = es[i];
|
|
64
|
-
|
|
64
|
+
assert(el.childNodes.length <= 1);
|
|
65
|
+
el.firstChild
|
|
66
|
+
? el.replaceWith(el.firstChild)
|
|
67
|
+
: el.remove();
|
|
65
68
|
}
|
|
66
69
|
return h.childNodes;
|
|
67
70
|
}
|