securemark 0.288.1 → 0.288.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 +4 -0
- package/dist/index.js +55 -38
- package/markdown.d.ts +1 -7
- package/package.json +1 -1
- package/src/combinator/control/manipulation/surround.ts +5 -0
- package/src/combinator/data/parser/context/delimiter.ts +2 -2
- package/src/combinator/data/parser.ts +1 -0
- package/src/parser/api/parse.test.ts +2 -2
- package/src/parser/block/heading.test.ts +1 -1
- package/src/parser/context.ts +1 -2
- package/src/parser/inline/annotation.test.ts +1 -0
- package/src/parser/inline/bracket.ts +18 -24
- package/src/parser/inline/extension/index.test.ts +1 -1
- package/src/parser/inline/extension/index.ts +17 -7
- package/src/parser/inline/extension/indexee.ts +2 -3
- package/src/parser/inline/extension/indexer.test.ts +2 -1
- package/src/parser/inline/htmlentity.ts +4 -5
- package/src/parser/inline/media.ts +2 -2
- package/src/parser/inline/reference.ts +1 -1
- package/src/parser/inline/ruby.ts +2 -2
- package/src/parser/inline.test.ts +5 -3
- package/src/parser/source/escapable.test.ts +5 -5
- package/src/parser/source/escapable.ts +7 -1
- package/src/parser/source/str.ts +4 -6
- package/src/parser/source/text.ts +1 -0
- package/src/parser/source/unescapable.test.ts +5 -5
- package/src/parser/source/unescapable.ts +13 -8
- package/src/parser/visibility.ts +2 -3
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.288.
|
|
1
|
+
/*! securemark v0.288.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"));
|
|
@@ -3232,6 +3232,7 @@ function surround(opener, parser, closer, optional = false, f, g, backtracks = [
|
|
|
3232
3232
|
backtracks[source.length + offset - 1] |= 1 << (backtrack >>> 2) + shift;
|
|
3233
3233
|
}
|
|
3234
3234
|
}
|
|
3235
|
+
context.recent = [lmr_.slice(0, lmr_.length - mr_.length), mr_.slice(0, mr_.length - r_.length), r_.slice(0, r_.length - rest.length)];
|
|
3235
3236
|
return rr ? f ? f([rl, rm, rr], rest, context) : [(0, array_1.push)((0, array_1.unshift)(rl, rm ?? []), rr), rest] : g ? g([rl, rm, mr_], rest, context) : undefined;
|
|
3236
3237
|
};
|
|
3237
3238
|
}
|
|
@@ -3659,7 +3660,7 @@ Delimiters.matcher = (0, memoize_1.memoize)(pattern => {
|
|
|
3659
3660
|
case 'string':
|
|
3660
3661
|
return source => source.slice(0, pattern.length) === pattern || undefined;
|
|
3661
3662
|
case 'object':
|
|
3662
|
-
return
|
|
3663
|
+
return source => pattern.test(source) || undefined;
|
|
3663
3664
|
}
|
|
3664
3665
|
}, _a.signature);
|
|
3665
3666
|
|
|
@@ -5672,7 +5673,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
5672
5673
|
}));
|
|
5673
5674
|
exports.CmdRegExp = void 0;
|
|
5674
5675
|
exports.CmdRegExp = {
|
|
5675
|
-
|
|
5676
|
+
Error: /\x07/g
|
|
5676
5677
|
};
|
|
5677
5678
|
|
|
5678
5679
|
/***/ },
|
|
@@ -6098,15 +6099,19 @@ const inline_1 = __webpack_require__(7973);
|
|
|
6098
6099
|
const source_1 = __webpack_require__(8745);
|
|
6099
6100
|
const array_1 = __webpack_require__(6876);
|
|
6100
6101
|
const dom_1 = __webpack_require__(394);
|
|
6101
|
-
const indexA = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)
|
|
6102
|
-
const indexF = new RegExp(indexA.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)
|
|
6103
|
-
exports.bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0,
|
|
6102
|
+
const indexA = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*$/;
|
|
6103
|
+
const indexF = new RegExp(indexA.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)/g, c => String.fromCodePoint(c.codePointAt(0) + 0xFEE0)));
|
|
6104
|
+
exports.bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ')', [[')', 1]]))), (0, source_1.str)(')'), true, ([as, bs = [], cs], rest, {
|
|
6105
|
+
recent = []
|
|
6106
|
+
}) => [indexA.test(recent[1]) ? recent : [(0, dom_1.html)('span', {
|
|
6104
6107
|
class: 'paren'
|
|
6105
|
-
}, (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], [
|
|
6108
|
+
}, (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], [2 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ')', [[')', 1]]))), (0, source_1.str)(')'), true, ([as, bs = [], cs], rest, {
|
|
6109
|
+
recent = []
|
|
6110
|
+
}) => [indexF.test(recent[1]) ? recent : [(0, dom_1.html)('span', {
|
|
6106
6111
|
class: 'paren'
|
|
6107
|
-
}, (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.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ']', [[']', 1]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [
|
|
6112
|
+
}, (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.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ']', [[']', 1]]))), (0, source_1.str)(']'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [2 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, ']', [[']', 1]]))), (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.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, '}', [['}', 1]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [2 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, combinator_1.some)(inline_1.inline, '}', [['}', 1]]))), (0, source_1.str)('}'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]),
|
|
6108
6113
|
// 改行禁止はバックトラックなしでは内側の構文を破壊するため安易に行えない。
|
|
6109
|
-
(0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(2, (0, combinator_1.some)(inline_1.inline, '"', [['\n', 9], ['"', 2]]))), (0, source_1.str)('"'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest]
|
|
6114
|
+
(0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(2, (0, combinator_1.some)(inline_1.inline, '"', [['\n', 9], ['"', 2]]))), (0, source_1.str)('"'), true, undefined, ([as, bs = []], rest) => [(0, array_1.unshift)(as, bs), rest], [2 | 8 /* Backtrack.bracket */])]));
|
|
6110
6115
|
|
|
6111
6116
|
/***/ },
|
|
6112
6117
|
|
|
@@ -6275,9 +6280,11 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
6275
6280
|
value: true
|
|
6276
6281
|
}));
|
|
6277
6282
|
exports.dataindex = exports.signature = exports.index = void 0;
|
|
6283
|
+
const parser_1 = __webpack_require__(605);
|
|
6278
6284
|
const combinator_1 = __webpack_require__(3484);
|
|
6279
6285
|
const inline_1 = __webpack_require__(7973);
|
|
6280
6286
|
const indexee_1 = __webpack_require__(7610);
|
|
6287
|
+
const htmlentity_1 = __webpack_require__(470);
|
|
6281
6288
|
const source_1 = __webpack_require__(8745);
|
|
6282
6289
|
const visibility_1 = __webpack_require__(6364);
|
|
6283
6290
|
const array_1 = __webpack_require__(6876);
|
|
@@ -6289,8 +6296,14 @@ exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(32 /*
|
|
|
6289
6296
|
class: 'index',
|
|
6290
6297
|
href: el.id ? `#${el.id}` : undefined
|
|
6291
6298
|
})])));
|
|
6292
|
-
exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.surround)((0, source_1.str)(/^\|(?!\\?\s)/), (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']'), /^(?=])/, false, ([as, bs], rest
|
|
6293
|
-
|
|
6299
|
+
exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.surround)((0, source_1.str)(/^\|(?!\\?\s)/), (0, visibility_1.tightStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']')), /^(?=])/, false, ([as, bs], rest, {
|
|
6300
|
+
recent = []
|
|
6301
|
+
}) => {
|
|
6302
|
+
const sig = (0, parser_1.eval)(parser({
|
|
6303
|
+
source: recent[1],
|
|
6304
|
+
context: {}
|
|
6305
|
+
}), []).join('');
|
|
6306
|
+
const index = sig.includes("\u0007" /* Command.Error */) ? undefined : (0, indexee_1.identity)('index', undefined, sig)?.slice(7);
|
|
6294
6307
|
return index ? [[(0, dom_1.html)('span', {
|
|
6295
6308
|
class: 'indexer',
|
|
6296
6309
|
'data-index': index
|
|
@@ -6307,6 +6320,7 @@ function dataindex(ns) {
|
|
|
6307
6320
|
}
|
|
6308
6321
|
}
|
|
6309
6322
|
exports.dataindex = dataindex;
|
|
6323
|
+
const parser = (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, source_1.text]));
|
|
6310
6324
|
|
|
6311
6325
|
/***/ },
|
|
6312
6326
|
|
|
@@ -6321,7 +6335,6 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
6321
6335
|
}));
|
|
6322
6336
|
exports.text = exports.signature = exports.identity = exports.indexee = void 0;
|
|
6323
6337
|
const combinator_1 = __webpack_require__(3484);
|
|
6324
|
-
const memoize_1 = __webpack_require__(6925);
|
|
6325
6338
|
const dom_1 = __webpack_require__(394);
|
|
6326
6339
|
function indexee(parser) {
|
|
6327
6340
|
return (0, combinator_1.fmap)(parser, ([el], _, {
|
|
@@ -6414,7 +6427,7 @@ function signature(source) {
|
|
|
6414
6427
|
return target.textContent.trim();
|
|
6415
6428
|
}
|
|
6416
6429
|
exports.signature = signature;
|
|
6417
|
-
|
|
6430
|
+
function text(source) {
|
|
6418
6431
|
const target = source.cloneNode(true);
|
|
6419
6432
|
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .remark, rt, rp, br, .annotation, .reference, .checkbox, ul, ol'), len = es.length, i = 0; i < len; ++i) {
|
|
6420
6433
|
const el = es[i];
|
|
@@ -6443,7 +6456,8 @@ exports.text = (0, memoize_1.reduce)(source => {
|
|
|
6443
6456
|
}
|
|
6444
6457
|
}
|
|
6445
6458
|
return target.textContent;
|
|
6446
|
-
}
|
|
6459
|
+
}
|
|
6460
|
+
exports.text = text;
|
|
6447
6461
|
|
|
6448
6462
|
/***/ },
|
|
6449
6463
|
|
|
@@ -6617,20 +6631,19 @@ exports.htmlentity = exports.unsafehtmlentity = void 0;
|
|
|
6617
6631
|
const combinator_1 = __webpack_require__(3484);
|
|
6618
6632
|
const util_1 = __webpack_require__(4992);
|
|
6619
6633
|
const dom_1 = __webpack_require__(394);
|
|
6620
|
-
const memoize_1 = __webpack_require__(6925);
|
|
6621
6634
|
exports.unsafehtmlentity = (0, combinator_1.validate)('&', (0, combinator_1.focus)(/^&[0-9A-Za-z]{1,99};/, ({
|
|
6622
6635
|
source
|
|
6623
|
-
}) => [[
|
|
6624
|
-
exports.htmlentity = (0, combinator_1.fmap)((0, combinator_1.union)([exports.unsafehtmlentity]), ([text]) => [text[0] === "\
|
|
6636
|
+
}) => [[parser(source) ?? `${"\u0007" /* Command.Error */}${source}`], '']));
|
|
6637
|
+
exports.htmlentity = (0, combinator_1.fmap)((0, combinator_1.union)([exports.unsafehtmlentity]), ([text]) => [text[0] === "\u0007" /* Command.Error */ ? (0, dom_1.html)('span', {
|
|
6625
6638
|
class: 'invalid',
|
|
6626
6639
|
...(0, util_1.invalid)('htmlentity', 'syntax', 'Invalid HTML entity')
|
|
6627
6640
|
}, text.slice(1)) : text]);
|
|
6628
|
-
const
|
|
6641
|
+
const parser = (el => entity => {
|
|
6629
6642
|
if (entity === '
') return ' ';
|
|
6630
6643
|
el.innerHTML = entity;
|
|
6631
6644
|
const text = el.textContent;
|
|
6632
6645
|
return entity === text ? undefined : text;
|
|
6633
|
-
})((0, dom_1.html)('span'))
|
|
6646
|
+
})((0, dom_1.html)('span'));
|
|
6634
6647
|
|
|
6635
6648
|
/***/ },
|
|
6636
6649
|
|
|
@@ -6930,10 +6943,10 @@ function sanitize(target, uri, alt) {
|
|
|
6930
6943
|
});
|
|
6931
6944
|
return false;
|
|
6932
6945
|
}
|
|
6933
|
-
if (alt.includes("\
|
|
6946
|
+
if (alt.includes("\u0007" /* Command.Error */)) {
|
|
6934
6947
|
(0, dom_1.define)(target, {
|
|
6935
6948
|
class: 'invalid',
|
|
6936
|
-
alt: target.getAttribute('alt')?.replace(context_1.CmdRegExp.
|
|
6949
|
+
alt: target.getAttribute('alt')?.replace(context_1.CmdRegExp.Error, ''),
|
|
6937
6950
|
...(0, util_1.invalid)('media', 'argument', `Cannot use invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)[0]}"`)
|
|
6938
6951
|
});
|
|
6939
6952
|
return false;
|
|
@@ -6960,7 +6973,7 @@ const visibility_1 = __webpack_require__(6364);
|
|
|
6960
6973
|
const dom_1 = __webpack_require__(394);
|
|
6961
6974
|
const array_1 = __webpack_require__(6876);
|
|
6962
6975
|
const util_1 = __webpack_require__(4992);
|
|
6963
|
-
exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(64 /* State.reference */, false, (0, combinator_1.surround)('[[', (0, combinator_1.precedence)(1, (0, combinator_1.state)(128 /* State.annotation */ | 64 /* State.reference */ | 4 /* State.media */, (0, combinator_1.subsequence)([abbr, (0, visibility_1.trimBlankStart)((0, combinator_1.some)(inline_1.inline, ']', [['\n', 9], [']', 1]]))]))), ']]', false, ([, ns], rest) => (0, visibility_1.trimBlankNodeEnd)(ns).length > 0 ? [[(0, dom_1.html)('sup', attributes(ns), [(0, dom_1.html)('span', (0, dom_1.defrag)(ns))])], rest] : undefined, ([as, bs], rest, {
|
|
6976
|
+
exports.reference = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(64 /* State.reference */, false, (0, combinator_1.surround)((0, source_1.str)('[['), (0, combinator_1.precedence)(1, (0, combinator_1.state)(128 /* State.annotation */ | 64 /* State.reference */ | 4 /* State.media */, (0, combinator_1.subsequence)([abbr, (0, visibility_1.trimBlankStart)((0, combinator_1.some)(inline_1.inline, ']', [['\n', 9], [']', 1]]))]))), ']]', false, ([, ns], rest) => (0, visibility_1.trimBlankNodeEnd)(ns).length > 0 ? [[(0, dom_1.html)('sup', attributes(ns), [(0, dom_1.html)('span', (0, dom_1.defrag)(ns))])], rest] : undefined, ([as, bs], rest, {
|
|
6964
6977
|
state = 0
|
|
6965
6978
|
}) => state & 128 /* State.annotation */ ? [(0, array_1.unshift)(as, bs), rest] : undefined, [3 | 16 /* Backtrack.linedoublebracket */, 1 | 12 /* Backtrack.linebracket */], 8 /* Backtrack.bracket */ | 1 /* BacktrackState.nobreak */)));
|
|
6966
6979
|
// Chicago-Style
|
|
@@ -7098,8 +7111,8 @@ function attributes(texts, rubies) {
|
|
|
7098
7111
|
let attrs;
|
|
7099
7112
|
for (const ss of [texts, rubies]) {
|
|
7100
7113
|
for (let i = 0; i < ss.length; ++i) {
|
|
7101
|
-
if (!ss[i].includes("\
|
|
7102
|
-
ss[i] = ss[i].replace(context_1.CmdRegExp.
|
|
7114
|
+
if (!ss[i].includes("\u0007" /* Command.Error */)) continue;
|
|
7115
|
+
ss[i] = ss[i].replace(context_1.CmdRegExp.Error, '');
|
|
7103
7116
|
attrs ??= {
|
|
7104
7117
|
class: 'invalid',
|
|
7105
7118
|
...(0, util_1.invalid)('ruby', ss === texts ? 'content' : 'argument', 'Invalid HTML entity')
|
|
@@ -7629,14 +7642,17 @@ const escsource = ({
|
|
|
7629
7642
|
case '\\':
|
|
7630
7643
|
switch (source[1]) {
|
|
7631
7644
|
case undefined:
|
|
7645
|
+
return [[source[0]], ''];
|
|
7632
7646
|
case '\n':
|
|
7633
7647
|
return [[source[0]], source.slice(1)];
|
|
7634
7648
|
default:
|
|
7635
7649
|
(0, combinator_1.consume)(1, context);
|
|
7636
7650
|
return [[source.slice(0, 2)], source.slice(2)];
|
|
7637
7651
|
}
|
|
7652
|
+
case '\n':
|
|
7653
|
+
return [[source[0]], source.slice(1)];
|
|
7638
7654
|
default:
|
|
7639
|
-
const b = source[0]
|
|
7655
|
+
const b = source[0].trimStart() === '';
|
|
7640
7656
|
const i = b ? source.search(text_1.nonWhitespace) : 1;
|
|
7641
7657
|
(0, combinator_1.consume)(i - 1, context);
|
|
7642
7658
|
return [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
|
|
@@ -7692,10 +7708,10 @@ function str(pattern, not) {
|
|
|
7692
7708
|
}) => {
|
|
7693
7709
|
if (source === '') return;
|
|
7694
7710
|
const m = source.match(pattern);
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
return
|
|
7711
|
+
if (m === null) return;
|
|
7712
|
+
count && (0, combinator_1.consume)(m[0].length, context);
|
|
7713
|
+
if (not && source.slice(m[0].length, m[0].length + not.length) === not) return;
|
|
7714
|
+
return [[m[0]], source.slice(m[0].length)];
|
|
7699
7715
|
};
|
|
7700
7716
|
}
|
|
7701
7717
|
exports.str = str;
|
|
@@ -7739,6 +7755,7 @@ const text = ({
|
|
|
7739
7755
|
case '\\':
|
|
7740
7756
|
switch (source[1]) {
|
|
7741
7757
|
case undefined:
|
|
7758
|
+
return [[], ''];
|
|
7742
7759
|
case '\n':
|
|
7743
7760
|
return [[], source.slice(1)];
|
|
7744
7761
|
default:
|
|
@@ -7807,11 +7824,14 @@ const unescsource = ({
|
|
|
7807
7824
|
case "\u001B" /* Command.Escape */:
|
|
7808
7825
|
(0, combinator_1.consume)(1, context);
|
|
7809
7826
|
return [[source.slice(1, 2)], source.slice(2)];
|
|
7827
|
+
case '\n':
|
|
7828
|
+
return [[source[0]], source.slice(1)];
|
|
7829
|
+
default:
|
|
7830
|
+
const b = source[0].trimStart() === '';
|
|
7831
|
+
const i = b || (0, text_1.isAlphanumeric)(source[0]) ? source.search(b ? text_1.nonWhitespace : text_1.nonAlphanumeric) || 1 : 1;
|
|
7832
|
+
(0, combinator_1.consume)(i - 1, context);
|
|
7833
|
+
return [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
|
|
7810
7834
|
}
|
|
7811
|
-
const b = source[0] !== '\n' && source[0].trimStart() === '';
|
|
7812
|
-
const i = b || (0, text_1.isAlphanumeric)(source[0]) ? source.search(b ? text_1.nonWhitespace : text_1.nonAlphanumeric) || 1 : 1;
|
|
7813
|
-
(0, combinator_1.consume)(i - 1, context);
|
|
7814
|
-
return [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
|
|
7815
7835
|
}
|
|
7816
7836
|
default:
|
|
7817
7837
|
(0, combinator_1.consume)(i, context);
|
|
@@ -7963,7 +7983,6 @@ const combinator_1 = __webpack_require__(3484);
|
|
|
7963
7983
|
const htmlentity_1 = __webpack_require__(470);
|
|
7964
7984
|
const source_1 = __webpack_require__(8745);
|
|
7965
7985
|
const normalize_1 = __webpack_require__(4490);
|
|
7966
|
-
const memoize_1 = __webpack_require__(6925);
|
|
7967
7986
|
const array_1 = __webpack_require__(6876);
|
|
7968
7987
|
var blank;
|
|
7969
7988
|
(function (blank) {
|
|
@@ -7998,7 +8017,7 @@ function tightStart(parser, except) {
|
|
|
7998
8017
|
return input => isTightStart(input, except) ? parser(input) : undefined;
|
|
7999
8018
|
}
|
|
8000
8019
|
exports.tightStart = tightStart;
|
|
8001
|
-
|
|
8020
|
+
function isTightStart(input, except) {
|
|
8002
8021
|
const {
|
|
8003
8022
|
source
|
|
8004
8023
|
} = input;
|
|
@@ -8027,9 +8046,7 @@ const isTightStart = (0, memoize_1.reduce)((input, except) => {
|
|
|
8027
8046
|
default:
|
|
8028
8047
|
return source[0].trimStart() !== '';
|
|
8029
8048
|
}
|
|
8030
|
-
}
|
|
8031
|
-
source
|
|
8032
|
-
}, except = '') => `${source}${"\u001F" /* Command.Separator */}${except}`);
|
|
8049
|
+
}
|
|
8033
8050
|
function isLooseNodeStart(nodes) {
|
|
8034
8051
|
if (nodes.length === 0) return true;
|
|
8035
8052
|
for (let i = 0; i < nodes.length; ++i) {
|
package/markdown.d.ts
CHANGED
|
@@ -1112,12 +1112,6 @@ export namespace MarkdownParser {
|
|
|
1112
1112
|
// ""
|
|
1113
1113
|
Inline<'bracket'>,
|
|
1114
1114
|
Parser<HTMLElement | string, Context, [
|
|
1115
|
-
SourceParser.StrParser,
|
|
1116
|
-
InlineParser,
|
|
1117
|
-
SourceParser.StrParser,
|
|
1118
|
-
InlineParser,
|
|
1119
|
-
InlineParser,
|
|
1120
|
-
InlineParser,
|
|
1121
1115
|
InlineParser,
|
|
1122
1116
|
InlineParser,
|
|
1123
1117
|
InlineParser,
|
|
@@ -1251,7 +1245,7 @@ export namespace MarkdownParser {
|
|
|
1251
1245
|
export interface TextParser extends
|
|
1252
1246
|
// abc
|
|
1253
1247
|
Source<'text'>,
|
|
1254
|
-
Parser<string | HTMLBRElement
|
|
1248
|
+
Parser<string | HTMLBRElement, Context, []> {
|
|
1255
1249
|
}
|
|
1256
1250
|
export interface TxtParser extends
|
|
1257
1251
|
// abc
|
package/package.json
CHANGED
|
@@ -94,6 +94,11 @@ export function surround<T>(
|
|
|
94
94
|
backtracks[source.length + offset - 1] |= 1 << (backtrack >>> 2) + shift;
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
+
context.recent = [
|
|
98
|
+
lmr_.slice(0, lmr_.length - mr_.length),
|
|
99
|
+
mr_.slice(0, mr_.length - r_.length),
|
|
100
|
+
r_.slice(0, r_.length - rest.length),
|
|
101
|
+
];
|
|
97
102
|
return rr
|
|
98
103
|
? f
|
|
99
104
|
? f([rl, rm!, rr], rest, context)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { memoize
|
|
1
|
+
import { memoize } from 'spica/memoize';
|
|
2
2
|
|
|
3
3
|
interface Delimiter {
|
|
4
4
|
readonly index: number;
|
|
@@ -27,7 +27,7 @@ export class Delimiters {
|
|
|
27
27
|
case 'string':
|
|
28
28
|
return source => source.slice(0, pattern.length) === pattern || undefined;
|
|
29
29
|
case 'object':
|
|
30
|
-
return
|
|
30
|
+
return source => pattern.test(source) || undefined;
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
this.signature);
|
|
@@ -21,6 +21,7 @@ export interface Ctx {
|
|
|
21
21
|
state?: number;
|
|
22
22
|
backtracks?: Record<number, number>;
|
|
23
23
|
backtrack?: number;
|
|
24
|
+
recent?: string[];
|
|
24
25
|
}
|
|
25
26
|
export type Tree<P extends Parser<unknown>> = P extends Parser<infer T> ? T : never;
|
|
26
27
|
export type SubParsers<P extends Parser<unknown>> = P extends Parser<unknown, Ctx, infer D> ? D : never;
|
|
@@ -350,7 +350,7 @@ describe('Unit: parser/api/parse', () => {
|
|
|
350
350
|
|
|
351
351
|
it('backtrack', function () {
|
|
352
352
|
this.timeout(5000);
|
|
353
|
-
const str = `${'.'.repeat(
|
|
353
|
+
const str = `${'.'.repeat(7 + 0)}((${'['.repeat(13)}{{http://[[[${'.'.repeat(8328)}`;
|
|
354
354
|
assert.deepStrictEqual(
|
|
355
355
|
[...parse(str).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
356
356
|
[`<p>${str}</p>`]);
|
|
@@ -358,7 +358,7 @@ describe('Unit: parser/api/parse', () => {
|
|
|
358
358
|
|
|
359
359
|
it('backtrack error', function () {
|
|
360
360
|
this.timeout(5000);
|
|
361
|
-
const str = `${'.'.repeat(
|
|
361
|
+
const str = `${'.'.repeat(7 + 1)}((${'['.repeat(13)}{{http://[[[${'.'.repeat(8328)}`;
|
|
362
362
|
assert.deepStrictEqual(
|
|
363
363
|
[...parse(str).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
364
364
|
[
|
|
@@ -69,7 +69,7 @@ describe('Unit: parser/block/heading', () => {
|
|
|
69
69
|
assert.deepStrictEqual(inspect(parser('# a [|b ]')), [['<h1 id="index::b">a<span class="indexer" data-index="b"></span></h1>'], '']);
|
|
70
70
|
assert.deepStrictEqual(inspect(parser('# a [|b ]')), [['<h1 id="index::b">a<span class="indexer" data-index="b"></span></h1>'], '']);
|
|
71
71
|
assert.deepStrictEqual(inspect(parser('# a [|b c]')), [['<h1 id="index::b_c">a<span class="indexer" data-index="b_c"></span></h1>'], '']);
|
|
72
|
-
assert.deepStrictEqual(inspect(parser('# a [|*b*`c`${d}$]')), [['<h1 id="index
|
|
72
|
+
assert.deepStrictEqual(inspect(parser('# a [|*b*`c`${d}$]')), [['<h1 id="index::*b*`c`${d}$">a<span class="indexer" data-index="*b*`c`${d}$"></span></h1>'], '']);
|
|
73
73
|
assert.deepStrictEqual(inspect(parser('# a [|@a]')), [['<h1 id="index::@a">a<span class="indexer" data-index="@a"></span></h1>'], '']);
|
|
74
74
|
assert.deepStrictEqual(inspect(parser('# a [|http://host]')), [['<h1 id="index::http://host">a<span class="indexer" data-index="http://host"></span></h1>'], '']);
|
|
75
75
|
assert.deepStrictEqual(inspect(parser('# a [|!http://host]')), [['<h1 id="index::!http://host">a<span class="indexer" data-index="!http://host"></span></h1>'], '']);
|
package/src/parser/context.ts
CHANGED
|
@@ -7,7 +7,6 @@ export const enum State {
|
|
|
7
7
|
media = 1 << 2,
|
|
8
8
|
mark = 1 << 1,
|
|
9
9
|
autolink = 1 << 0,
|
|
10
|
-
all = ~0,
|
|
11
10
|
linkers = 0
|
|
12
11
|
| State.annotation
|
|
13
12
|
| State.reference
|
|
@@ -51,5 +50,5 @@ export const enum Command {
|
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
export const CmdRegExp = {
|
|
54
|
-
|
|
53
|
+
Error: /\x07/g,
|
|
55
54
|
} as const;
|
|
@@ -50,6 +50,7 @@ describe('Unit: parser/inline/annotation', () => {
|
|
|
50
50
|
assert.deepStrictEqual(inspect(parser('((@a))')), [['<sup class="annotation"><span><a class="account" href="/@a">@a</a></span></sup>'], '']);
|
|
51
51
|
assert.deepStrictEqual(inspect(parser('((http://host))')), [['<sup class="annotation"><span><a class="url" href="http://host" target="_blank">http://host</a></span></sup>'], '']);
|
|
52
52
|
assert.deepStrictEqual(inspect(parser('((![]{a}))')), [['<sup class="annotation"><span>!<a class="url" href="a">a</a></span></sup>'], '']);
|
|
53
|
+
assert.deepStrictEqual(inspect(parser('(([[a] ]))')), [['<sup class="annotation"><span>[[a] ]</span></sup>'], '']);
|
|
53
54
|
assert.deepStrictEqual(inspect(parser('(((a)))')), [['<sup class="annotation"><span>(a)</span></sup>'], '']);
|
|
54
55
|
assert.deepStrictEqual(inspect(parser('((((a))))')), [['<sup class="annotation"><span><span class="paren">((a))</span></span></sup>'], '']);
|
|
55
56
|
assert.deepStrictEqual(inspect(parser('(([[a]]))')), [['<sup class="annotation"><span><sup class="reference"><span>a</span></sup></span></sup>'], '']);
|
|
@@ -6,47 +6,41 @@ import { str } from '../source';
|
|
|
6
6
|
import { unshift, push } from 'spica/array';
|
|
7
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
8
8
|
|
|
9
|
-
const indexA = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)
|
|
9
|
+
const indexA = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*$/;
|
|
10
10
|
const indexF = new RegExp(indexA.source.replace(', ', '[,、]')
|
|
11
|
-
.replace(/[09AZaz.]|\-(?!\w)
|
|
11
|
+
.replace(/[09AZaz.]|\-(?!\w)/g, c => String.fromCodePoint(c.codePointAt(0)! + 0xFEE0)));
|
|
12
12
|
|
|
13
13
|
export const bracket: BracketParser = lazy(() => union([
|
|
14
|
-
surround(str('('), recursion(Recursion.bracket, precedence(1, str(indexA))), str(')'), false,
|
|
15
|
-
undefined, undefined, [3 | Backtrack.bracket]),
|
|
16
14
|
surround(str('('), recursion(Recursion.bracket, precedence(1, some(inline, ')', [[')', 1]]))), str(')'), true,
|
|
17
|
-
([as, bs = [], cs], rest
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
([as, bs = [], cs], rest, { recent = [] }) => [
|
|
16
|
+
indexA.test(recent[1])
|
|
17
|
+
? recent
|
|
18
|
+
: [html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))],
|
|
19
|
+
rest
|
|
20
|
+
],
|
|
21
|
+
([as, bs = []], rest) => [unshift(as, bs), rest], [2 | Backtrack.bracket]),
|
|
21
22
|
surround(str('('), recursion(Recursion.bracket, precedence(1, some(inline, ')', [[')', 1]]))), str(')'), true,
|
|
22
|
-
([as, bs = [], cs], rest
|
|
23
|
+
([as, bs = [], cs], rest, { recent = [] }) => [
|
|
24
|
+
indexF.test(recent[1])
|
|
25
|
+
? recent
|
|
26
|
+
: [html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))],
|
|
27
|
+
rest
|
|
28
|
+
],
|
|
23
29
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
24
30
|
surround(str('['), recursion(Recursion.bracket, precedence(1, some(inline, ']', [[']', 1]]))), str(']'), true,
|
|
25
31
|
undefined,
|
|
26
|
-
([as, bs = []], rest) => [unshift(as, bs), rest], [
|
|
32
|
+
([as, bs = []], rest) => [unshift(as, bs), rest], [2 | Backtrack.bracket]),
|
|
27
33
|
surround(str('['), recursion(Recursion.bracket, precedence(1, some(inline, ']', [[']', 1]]))), str(']'), true,
|
|
28
34
|
undefined,
|
|
29
35
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
30
36
|
surround(str('{'), recursion(Recursion.bracket, precedence(1, some(inline, '}', [['}', 1]]))), str('}'), true,
|
|
31
37
|
undefined,
|
|
32
|
-
([as, bs = []], rest) => [unshift(as, bs), rest], [
|
|
38
|
+
([as, bs = []], rest) => [unshift(as, bs), rest], [2 | Backtrack.bracket]),
|
|
33
39
|
surround(str('{'), recursion(Recursion.bracket, precedence(1, some(inline, '}', [['}', 1]]))), str('}'), true,
|
|
34
40
|
undefined,
|
|
35
41
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
36
42
|
// 改行禁止はバックトラックなしでは内側の構文を破壊するため安易に行えない。
|
|
37
43
|
surround(str('"'), recursion(Recursion.bracket, precedence(2, some(inline, '"', [['\n', 9], ['"', 2]]))), str('"'), true,
|
|
38
44
|
undefined,
|
|
39
|
-
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
40
|
-
surround(str('“'), recursion(Recursion.bracket, precedence(2, some(inline, '”', [['\n', 9], ['”', 2]]))), str('”'), true,
|
|
41
|
-
undefined,
|
|
42
|
-
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
43
|
-
surround(str('‘'), recursion(Recursion.bracket, precedence(2, some(inline, '’', [['\n', 9], ['’', 2]]))), str('’'), true,
|
|
44
|
-
undefined,
|
|
45
|
-
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
46
|
-
surround(str('「'), recursion(Recursion.bracket, precedence(2, some(inline, '」', [['\n', 9], ['」', 2]]))), str('」'), true,
|
|
47
|
-
undefined,
|
|
48
|
-
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
49
|
-
surround(str('『'), recursion(Recursion.bracket, precedence(2, some(inline, '』', [['\n', 9], ['』', 2]]))), str('』'), true,
|
|
50
|
-
undefined,
|
|
51
|
-
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
45
|
+
([as, bs = []], rest) => [unshift(as, bs), rest], [2 | Backtrack.bracket]),
|
|
52
46
|
]));
|
|
@@ -84,7 +84,7 @@ describe('Unit: parser/inline/extension/index', () => {
|
|
|
84
84
|
assert.deepStrictEqual(inspect(parser('[#a|b ]')), [['<a class="index" href="#index::b">a<span class="indexer" data-index="b"></span></a>'], '']);
|
|
85
85
|
assert.deepStrictEqual(inspect(parser('[#a|b ]')), [['<a class="index" href="#index::b">a<span class="indexer" data-index="b"></span></a>'], '']);
|
|
86
86
|
assert.deepStrictEqual(inspect(parser('[#a|\\b]')), [['<a class="index" href="#index::b">a<span class="indexer" data-index="b"></span></a>'], '']);
|
|
87
|
-
assert.deepStrictEqual(inspect(parser('[#a|*b*]')), [['<a class="index" href="#index
|
|
87
|
+
assert.deepStrictEqual(inspect(parser('[#a|*b*]')), [['<a class="index" href="#index::*b*">a<span class="indexer" data-index="*b*"></span></a>'], '']);
|
|
88
88
|
assert.deepStrictEqual(inspect(parser('[#a|*]*]')), [['<a class="index" href="#index::*">a<span class="indexer" data-index="*"></span></a>'], '*]']);
|
|
89
89
|
assert.deepStrictEqual(inspect(parser('[#a|b c]')), [['<a class="index" href="#index::b_c">a<span class="indexer" data-index="b_c"></span></a>'], '']);
|
|
90
90
|
assert.deepStrictEqual(inspect(parser('[#a|b c]')), [['<a class="index" href="#index::b__c">a<span class="indexer" data-index="b__c"></span></a>'], '']);
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
|
-
import { State, Backtrack, BacktrackState } from '../../context';
|
|
2
|
+
import { State, Backtrack, BacktrackState, Command } from '../../context';
|
|
3
|
+
import { eval } from '../../../combinator/data/parser';
|
|
3
4
|
import { union, inits, some, precedence, state, constraint, validate, surround, lazy, fmap } from '../../../combinator';
|
|
4
5
|
import { inline } from '../../inline';
|
|
5
|
-
import { indexee, identity
|
|
6
|
-
import {
|
|
6
|
+
import { indexee, identity } from './indexee';
|
|
7
|
+
import { unsafehtmlentity } from '../htmlentity';
|
|
8
|
+
import { text, str } from '../../source';
|
|
7
9
|
import { tightStart, trimBlankNodeEnd } from '../../visibility';
|
|
8
10
|
import { unshift } from 'spica/array';
|
|
9
|
-
import {
|
|
11
|
+
import { html, define, defrag } from 'typed-dom/dom';
|
|
10
12
|
|
|
11
13
|
import IndexParser = ExtensionParser.IndexParser;
|
|
12
14
|
|
|
@@ -36,11 +38,14 @@ export const index: IndexParser = lazy(() => constraint(State.index, false, fmap
|
|
|
36
38
|
|
|
37
39
|
export const signature: IndexParser.SignatureParser = lazy(() => validate('|', surround(
|
|
38
40
|
str(/^\|(?!\\?\s)/),
|
|
39
|
-
some(union([inline]), ']'),
|
|
41
|
+
tightStart(some(union([inline]), ']')),
|
|
40
42
|
/^(?=])/,
|
|
41
43
|
false,
|
|
42
|
-
([as, bs], rest) => {
|
|
43
|
-
const
|
|
44
|
+
([as, bs], rest, { recent = [] }) => {
|
|
45
|
+
const sig = eval(parser({ source: recent[1], context: {} }), []).join('');
|
|
46
|
+
const index = sig.includes(Command.Error)
|
|
47
|
+
? undefined
|
|
48
|
+
: identity('index', undefined, sig)?.slice(7);
|
|
44
49
|
return index
|
|
45
50
|
? [[html('span', { class: 'indexer', 'data-index': index })], rest]
|
|
46
51
|
: [unshift(as, bs), rest];
|
|
@@ -57,3 +62,8 @@ export function dataindex(ns: readonly (string | HTMLElement)[]): string | undef
|
|
|
57
62
|
return node.getAttribute('data-index') ?? undefined;
|
|
58
63
|
}
|
|
59
64
|
}
|
|
65
|
+
|
|
66
|
+
const parser = some(union([
|
|
67
|
+
unsafehtmlentity,
|
|
68
|
+
text,
|
|
69
|
+
]));
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../../../markdown';
|
|
2
2
|
import { Parser } from '../../../combinator/data/parser';
|
|
3
3
|
import { fmap } from '../../../combinator';
|
|
4
|
-
import { reduce } from 'spica/memoize';
|
|
5
4
|
import { define } from 'typed-dom/dom';
|
|
6
5
|
|
|
7
6
|
export function indexee<P extends Parser<unknown, MarkdownParser.Context>>(parser: P): P;
|
|
@@ -142,7 +141,7 @@ export function signature(source: Element | DocumentFragment): string {
|
|
|
142
141
|
return target.textContent!.trim();
|
|
143
142
|
}
|
|
144
143
|
|
|
145
|
-
export
|
|
144
|
+
export function text(source: Element | DocumentFragment): string {
|
|
146
145
|
assert(!navigator.userAgent.includes('Chrome') || !source.querySelector('br:not(:has(+ :is(ul, ol)))'));
|
|
147
146
|
const target = source.cloneNode(true) as typeof source;
|
|
148
147
|
for (let es = target.querySelectorAll('code[data-src], .math[data-src], .remark, rt, rp, br, .annotation, .reference, .checkbox, ul, ol'),
|
|
@@ -173,4 +172,4 @@ export const text = reduce((source: Element | DocumentFragment): string => {
|
|
|
173
172
|
}
|
|
174
173
|
}
|
|
175
174
|
return target.textContent!;
|
|
176
|
-
}
|
|
175
|
+
}
|
|
@@ -28,7 +28,8 @@ describe('Unit: parser/inline/extension/indexer', () => {
|
|
|
28
28
|
assert.deepStrictEqual(inspect(parser(' [|a\tb]')), [['<span class="indexer" data-index="a_b=33Mw2l"></span>'], '']);
|
|
29
29
|
assert.deepStrictEqual(inspect(parser(' [|a_b]')), [['<span class="indexer" data-index="a_b=2H8oCG"></span>'], '']);
|
|
30
30
|
assert.deepStrictEqual(inspect(parser(' [|A]')), [['<span class="indexer" data-index="A"></span>'], '']);
|
|
31
|
-
assert.deepStrictEqual(inspect(parser(' [
|
|
31
|
+
assert.deepStrictEqual(inspect(parser(' [|\\A]')), [['<span class="indexer" data-index="A"></span>'], '']);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser(' [|*A*]')), [['<span class="indexer" data-index="*A*"></span>'], '']);
|
|
32
33
|
assert.deepStrictEqual(inspect(parser(' [|`A`]')), [['<span class="indexer" data-index="`A`"></span>'], '']);
|
|
33
34
|
assert.deepStrictEqual(inspect(parser(' [|${A}$]')), [['<span class="indexer" data-index="${A}$"></span>'], '']);
|
|
34
35
|
assert.deepStrictEqual(inspect(parser(' [|a]')), [['<span class="indexer" data-index="a"></span>'], '']);
|
|
@@ -3,16 +3,15 @@ import { Command } from '../context';
|
|
|
3
3
|
import { union, validate, focus, fmap } from '../../combinator';
|
|
4
4
|
import { invalid } from '../util';
|
|
5
5
|
import { html } from 'typed-dom/dom';
|
|
6
|
-
import { reduce } from 'spica/memoize';
|
|
7
6
|
|
|
8
7
|
export const unsafehtmlentity: UnsafeHTMLEntityParser = validate('&', focus(
|
|
9
8
|
/^&[0-9A-Za-z]{1,99};/,
|
|
10
|
-
({ source }) => [[
|
|
9
|
+
({ source }) => [[parser(source) ?? `${Command.Error}${source}`], '']));
|
|
11
10
|
|
|
12
11
|
export const htmlentity: HTMLEntityParser = fmap(
|
|
13
12
|
union([unsafehtmlentity]),
|
|
14
13
|
([text]) => [
|
|
15
|
-
text[0] === Command.
|
|
14
|
+
text[0] === Command.Error
|
|
16
15
|
? html('span', {
|
|
17
16
|
class: 'invalid',
|
|
18
17
|
...invalid('htmlentity', 'syntax', 'Invalid HTML entity'),
|
|
@@ -20,11 +19,11 @@ export const htmlentity: HTMLEntityParser = fmap(
|
|
|
20
19
|
: text,
|
|
21
20
|
]);
|
|
22
21
|
|
|
23
|
-
const
|
|
22
|
+
const parser = (el => (entity: string): string | undefined => {
|
|
24
23
|
if (entity === '
') return ' ';
|
|
25
24
|
el.innerHTML = entity;
|
|
26
25
|
const text = el.textContent!;
|
|
27
26
|
return entity === text
|
|
28
27
|
? undefined
|
|
29
28
|
: text;
|
|
30
|
-
})(html('span'))
|
|
29
|
+
})(html('span'));
|
|
@@ -110,10 +110,10 @@ function sanitize(target: HTMLElement, uri: ReadonlyURL, alt: string): boolean {
|
|
|
110
110
|
define(target, { class: 'invalid', ...invalid('media', 'argument', 'Invalid protocol') });
|
|
111
111
|
return false;
|
|
112
112
|
}
|
|
113
|
-
if (alt.includes(Command.
|
|
113
|
+
if (alt.includes(Command.Error)) {
|
|
114
114
|
define(target, {
|
|
115
115
|
class: 'invalid',
|
|
116
|
-
alt: target.getAttribute('alt')?.replace(CmdRegExp.
|
|
116
|
+
alt: target.getAttribute('alt')?.replace(CmdRegExp.Error, ''),
|
|
117
117
|
...invalid('media', 'argument',
|
|
118
118
|
`Cannot use invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)![0]}"`)
|
|
119
119
|
});
|
|
@@ -9,7 +9,7 @@ import { unshift } from 'spica/array';
|
|
|
9
9
|
import { invalid } from '../util';
|
|
10
10
|
|
|
11
11
|
export const reference: ReferenceParser = lazy(() => constraint(State.reference, false, surround(
|
|
12
|
-
'[[',
|
|
12
|
+
str('[['),
|
|
13
13
|
precedence(1, state(State.annotation | State.reference | State.media,
|
|
14
14
|
subsequence([
|
|
15
15
|
abbr,
|
|
@@ -101,8 +101,8 @@ function attributes(texts: string[], rubies: string[]): Record<string, string> {
|
|
|
101
101
|
let attrs: Record<string, string> | undefined;
|
|
102
102
|
for (const ss of [texts, rubies]) {
|
|
103
103
|
for (let i = 0; i < ss.length; ++i) {
|
|
104
|
-
if (!ss[i].includes(Command.
|
|
105
|
-
ss[i] = ss[i].replace(CmdRegExp.
|
|
104
|
+
if (!ss[i].includes(Command.Error)) continue;
|
|
105
|
+
ss[i] = ss[i].replace(CmdRegExp.Error, '');
|
|
106
106
|
attrs ??= {
|
|
107
107
|
class: 'invalid',
|
|
108
108
|
...invalid('ruby', ss === texts ? 'content' : 'argument', 'Invalid HTML entity'),
|
|
@@ -72,6 +72,9 @@ describe('Unit: parser/inline', () => {
|
|
|
72
72
|
assert.deepStrictEqual(inspect(parser('***a*b*c***')), [['<strong><em>a</em>b<em>c</em></strong>'], '']);
|
|
73
73
|
assert.deepStrictEqual(inspect(parser('*(*a*)*')), [['<em><span class="paren">(<em>a</em>)</span></em>'], '']);
|
|
74
74
|
assert.deepStrictEqual(inspect(parser('**(**a**)**')), [['<strong><span class="paren">(<strong>a</strong>)</span></strong>'], '']);
|
|
75
|
+
assert.deepStrictEqual(inspect(parser('*[*]')), [['*', '[', '*', ']'], '']);
|
|
76
|
+
assert.deepStrictEqual(inspect(parser('*<*>')), [['<em><</em>', '>'], '']);
|
|
77
|
+
assert.deepStrictEqual(inspect(parser('*a((b))*')), [['<em>a<sup class="annotation"><span>b</span></sup></em>'], '']);
|
|
75
78
|
assert.deepStrictEqual(inspect(parser('*++ ++*')), [['<em><ins> </ins></em>'], '']);
|
|
76
79
|
assert.deepStrictEqual(inspect(parser('*++ a ++*')), [['<em><ins> a </ins></em>'], '']);
|
|
77
80
|
assert.deepStrictEqual(inspect(parser('*++ a ++*')), [['<em><ins> a </ins></em>'], '']);
|
|
@@ -81,9 +84,6 @@ describe('Unit: parser/inline', () => {
|
|
|
81
84
|
assert.deepStrictEqual(inspect(parser('<bdi>[[<bdi>[[a]]</bdi>]]</bdi>')), [['<bdi><sup class="reference"><span><bdi>[[a]]</bdi></span></sup></bdi>'], '']);
|
|
82
85
|
assert.deepStrictEqual(inspect(parser('<bdi>[#</bdi>]')), [['<bdi>[#</bdi>', ']'], '']);
|
|
83
86
|
assert.deepStrictEqual(inspect(parser('"<bdi>("")</bdi>')), [['"', '<bdi><span class="paren">("")</span></bdi>'], '']);
|
|
84
|
-
assert.deepStrictEqual(inspect(parser('*[*]')), [['*', '[', '*', ']'], '']);
|
|
85
|
-
assert.deepStrictEqual(inspect(parser('*<*>')), [['<em><</em>', '>'], '']);
|
|
86
|
-
assert.deepStrictEqual(inspect(parser('*a((b))*')), [['<em>a<sup class="annotation"><span>b</span></sup></em>'], '']);
|
|
87
87
|
assert.deepStrictEqual(inspect(parser('++\na\n++\n~~\nb\n~~\nc')), [['<ins><br>a</ins>', '<br>', '<del><br>b</del>', '<br>', 'c'], '']);
|
|
88
88
|
assert.deepStrictEqual(inspect(parser('``a`')), [['``', 'a', '`'], '']);
|
|
89
89
|
assert.deepStrictEqual(inspect(parser('[@a]')), [['[', '<a class="account" href="/@a">@a</a>', ']'], '']);
|
|
@@ -127,6 +127,8 @@ describe('Unit: parser/inline', () => {
|
|
|
127
127
|
assert.deepStrictEqual(inspect(parser('((${))}$')), [['(', '(', '<span class="math" translate="no" data-src="${))}$">${))}$</span>'], '']);
|
|
128
128
|
assert.deepStrictEqual(inspect(parser('((a\nb))')), [['<span class="paren">(<span class="paren">(a<br>b)</span>)</span>'], '']);
|
|
129
129
|
assert.deepStrictEqual(inspect(parser('(((a\nb)))')), [['<span class="paren">(<span class="paren">(<span class="paren">(a<br>b)</span>)</span>)</span>'], '']);
|
|
130
|
+
assert.deepStrictEqual(inspect(parser('(([[a] ]))')), [['<sup class="annotation"><span>[[a] ]</span></sup>'], '']);
|
|
131
|
+
assert.deepStrictEqual(inspect(parser('(([["*(*"] ]))')), [['<sup class="annotation"><span>[["*(*"] ]</span></sup>'], '']);
|
|
130
132
|
assert.deepStrictEqual(inspect(parser('(([:a\n]')), [['(', '(', '<span class="invalid">a<br></span>'], '']);
|
|
131
133
|
assert.deepStrictEqual(inspect(parser('"((""))')), [['"', '(', '(', '"', '"', ')', ')'], '']);
|
|
132
134
|
assert.deepStrictEqual(inspect(parser('[[[a]]')), [['[', '<sup class="reference"><span>a</span></sup>'], '']);
|
|
@@ -20,13 +20,13 @@ describe('Unit: parser/source/escsource', () => {
|
|
|
20
20
|
assert.deepStrictEqual(inspect(parser(' ')), [[' '], '']);
|
|
21
21
|
assert.deepStrictEqual(inspect(parser(' ')), [[' ', ' '], '']);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser(' ')), [[' ', ' '], '']);
|
|
23
|
-
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', '\n'], '']);
|
|
24
|
-
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', ' ', '\n'], '']);
|
|
25
|
-
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', ' ', '\n'], '']);
|
|
23
|
+
//assert.deepStrictEqual(inspect(parser(' \n')), [[' ', '\n'], '']);
|
|
24
|
+
//assert.deepStrictEqual(inspect(parser(' \n')), [[' ', ' ', '\n'], '']);
|
|
25
|
+
//assert.deepStrictEqual(inspect(parser(' \n')), [[' ', ' ', '\n'], '']);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
it('linebreak', () => {
|
|
29
|
-
assert.deepStrictEqual(inspect(parser('\n\n')), [['\n', '\n'], '']);
|
|
29
|
+
//assert.deepStrictEqual(inspect(parser('\n\n')), [['\n', '\n'], '']);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
it('\\', () => {
|
|
@@ -39,7 +39,7 @@ describe('Unit: parser/source/escsource', () => {
|
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('\\a')), [['\\a'], '']);
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('\\$')), [['\\$'], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('\\ ')), [['\\ '], '']);
|
|
42
|
-
assert.deepStrictEqual(inspect(parser('\\\n')), [['\\', '\n'], '']);
|
|
42
|
+
//assert.deepStrictEqual(inspect(parser('\\\n')), [['\\', '\n'], '']);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
});
|
|
@@ -20,19 +20,25 @@ export const escsource: EscapableSourceParser = ({ source, context }) => {
|
|
|
20
20
|
consume(-1, context);
|
|
21
21
|
return [[], source.slice(1)];
|
|
22
22
|
case Command.Escape:
|
|
23
|
+
assert(false);
|
|
23
24
|
consume(1, context);
|
|
24
25
|
return [[source.slice(1, 2)], source.slice(2)];
|
|
25
26
|
case '\\':
|
|
26
27
|
switch (source[1]) {
|
|
27
28
|
case undefined:
|
|
29
|
+
return [[source[0]], ''];
|
|
28
30
|
case '\n':
|
|
29
31
|
return [[source[0]], source.slice(1)];
|
|
30
32
|
default:
|
|
31
33
|
consume(1, context);
|
|
32
34
|
return [[source.slice(0, 2)], source.slice(2)];
|
|
33
35
|
}
|
|
36
|
+
case '\n':
|
|
37
|
+
assert(false);
|
|
38
|
+
return [[source[0]], source.slice(1)];
|
|
34
39
|
default:
|
|
35
|
-
|
|
40
|
+
assert(source[0] !== '\n');
|
|
41
|
+
const b = source[0].trimStart() === '';
|
|
36
42
|
const i = b
|
|
37
43
|
? source.search(nonWhitespace)
|
|
38
44
|
: 1;
|
package/src/parser/source/str.ts
CHANGED
|
@@ -19,11 +19,9 @@ export function str(pattern: string | RegExp, not?: string): Parser<string, Cont
|
|
|
19
19
|
: ({ source, context }) => {
|
|
20
20
|
if (source === '') return;
|
|
21
21
|
const m = source.match(pattern);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return m
|
|
26
|
-
? [[m[0]], source.slice(m[0].length)]
|
|
27
|
-
: undefined;
|
|
22
|
+
if (m === null) return;
|
|
23
|
+
count && consume(m[0].length, context);
|
|
24
|
+
if (not && source.slice(m[0].length, m[0].length + not.length) === not) return;
|
|
25
|
+
return [[m[0]], source.slice(m[0].length)];
|
|
28
26
|
};
|
|
29
27
|
}
|
|
@@ -20,13 +20,13 @@ describe('Unit: parser/source/unescapable', () => {
|
|
|
20
20
|
assert.deepStrictEqual(inspect(parser(' ')), [[' '], '']);
|
|
21
21
|
assert.deepStrictEqual(inspect(parser(' ')), [[' ', ' '], '']);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser(' ')), [[' ', ' '], '']);
|
|
23
|
-
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', '\n'], '']);
|
|
24
|
-
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', ' ', '\n'], '']);
|
|
25
|
-
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', ' ', '\n'], '']);
|
|
23
|
+
//assert.deepStrictEqual(inspect(parser(' \n')), [[' ', '\n'], '']);
|
|
24
|
+
//assert.deepStrictEqual(inspect(parser(' \n')), [[' ', ' ', '\n'], '']);
|
|
25
|
+
//assert.deepStrictEqual(inspect(parser(' \n')), [[' ', ' ', '\n'], '']);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
it('linebreak', () => {
|
|
29
|
-
assert.deepStrictEqual(inspect(parser('\n\n')), [['\n', '\n'], '']);
|
|
29
|
+
//assert.deepStrictEqual(inspect(parser('\n\n')), [['\n', '\n'], '']);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
it('\\', () => {
|
|
@@ -39,7 +39,7 @@ describe('Unit: parser/source/unescapable', () => {
|
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('\\a')), [['\\', 'a'], '']);
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('\\`')), [['\\', '`'], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('\\ ')), [['\\', ' '], '']);
|
|
42
|
-
assert.deepStrictEqual(inspect(parser('\\\n')), [['\\', '\n'], '']);
|
|
42
|
+
//assert.deepStrictEqual(inspect(parser('\\\n')), [['\\', '\n'], '']);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
});
|
|
@@ -18,17 +18,22 @@ export const unescsource: UnescapableSourceParser = ({ source, context }) => {
|
|
|
18
18
|
consume(-1, context);
|
|
19
19
|
return [[], source.slice(1)];
|
|
20
20
|
case Command.Escape:
|
|
21
|
-
assert(
|
|
21
|
+
assert(false);
|
|
22
22
|
consume(1, context);
|
|
23
23
|
return [[source.slice(1, 2)], source.slice(2)];
|
|
24
|
+
case '\n':
|
|
25
|
+
assert(false);
|
|
26
|
+
return [[source[0]], source.slice(1)];
|
|
27
|
+
default:
|
|
28
|
+
assert(source[0] !== '\n');
|
|
29
|
+
const b = source[0].trimStart() === '';
|
|
30
|
+
const i = b || isAlphanumeric(source[0])
|
|
31
|
+
? source.search(b ? nonWhitespace : nonAlphanumeric) || 1
|
|
32
|
+
: 1;
|
|
33
|
+
assert(i > 0);
|
|
34
|
+
consume(i - 1, context);
|
|
35
|
+
return [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
|
|
24
36
|
}
|
|
25
|
-
const b = source[0] !== '\n' && source[0].trimStart() === '';
|
|
26
|
-
const i = b || isAlphanumeric(source[0])
|
|
27
|
-
? source.search(b ? nonWhitespace : nonAlphanumeric) || 1
|
|
28
|
-
: 1;
|
|
29
|
-
assert(i > 0);
|
|
30
|
-
consume(i - 1, context);
|
|
31
|
-
return [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
|
|
32
37
|
}
|
|
33
38
|
default:
|
|
34
39
|
consume(i, context);
|
package/src/parser/visibility.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { union, some, verify, convert, fmap } from '../combinator';
|
|
|
5
5
|
import { unsafehtmlentity } from './inline/htmlentity';
|
|
6
6
|
import { linebreak, unescsource } from './source';
|
|
7
7
|
import { invisibleHTMLEntityNames } from './api/normalize';
|
|
8
|
-
import { reduce } from 'spica/memoize';
|
|
9
8
|
import { push } from 'spica/array';
|
|
10
9
|
|
|
11
10
|
export namespace blank {
|
|
@@ -78,7 +77,7 @@ export function tightStart<T>(parser: Parser<T>, except?: string): Parser<T> {
|
|
|
78
77
|
? parser(input)
|
|
79
78
|
: undefined;
|
|
80
79
|
}
|
|
81
|
-
|
|
80
|
+
function isTightStart(input: Input<MarkdownParser.Context>, except?: string): boolean {
|
|
82
81
|
const { source } = input;
|
|
83
82
|
if (source === '') return true;
|
|
84
83
|
if (except && source.slice(0, except.length) === except) return false;
|
|
@@ -109,7 +108,7 @@ const isTightStart = reduce((input: Input<MarkdownParser.Context>, except?: stri
|
|
|
109
108
|
default:
|
|
110
109
|
return source[0].trimStart() !== '';
|
|
111
110
|
}
|
|
112
|
-
}
|
|
111
|
+
}
|
|
113
112
|
|
|
114
113
|
export function isLooseNodeStart(nodes: readonly (HTMLElement | string)[]): boolean {
|
|
115
114
|
if (nodes.length === 0) return true;
|