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 CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.288.2
4
+
5
+ - Fix signature syntax.
6
+
3
7
  ## 0.288.1
4
8
 
5
9
  - Refactoring.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.288.1 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
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 (0, memoize_1.reduce)(source => pattern.test(source) || undefined);
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
- Escape: /\x1B/g
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)|\)(?=\)$)/g, c => String.fromCodePoint(c.codePointAt(0) + 0xFEE0)));
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, source_1.str)(indexA))), (0, source_1.str)(')'), false, undefined, undefined, [3 | 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) => [[(0, dom_1.html)('span', {
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], [3 | 8 /* Backtrack.bracket */]), (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.recursion)(5 /* Recursion.bracket */, (0, combinator_1.precedence)(1, (0, source_1.str)(indexF))), (0, source_1.str)(')'), false, undefined, undefined, [3 | 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) => [[(0, dom_1.html)('span', {
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], [3 | 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], [3 | 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]),
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]), (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]), (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]), (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]), (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
- const index = (0, indexee_1.identity)('index', undefined, (0, indexee_1.text)((0, dom_1.frag)(bs)))?.slice(7);
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
- exports.text = (0, memoize_1.reduce)(source => {
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
- }) => [[parse(source) ?? `${"\u001B" /* Command.Escape */}${source}`], '']));
6624
- exports.htmlentity = (0, combinator_1.fmap)((0, combinator_1.union)([exports.unsafehtmlentity]), ([text]) => [text[0] === "\u001B" /* Command.Escape */ ? (0, dom_1.html)('span', {
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 parse = (0, memoize_1.reduce)((el => entity => {
6641
+ const parser = (el => entity => {
6629
6642
  if (entity === '&NewLine;') 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("\u001B" /* Command.Escape */)) {
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.Escape, ''),
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("\u001B" /* Command.Escape */)) continue;
7102
- ss[i] = ss[i].replace(context_1.CmdRegExp.Escape, '');
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] !== '\n' && source[0].trimStart() === '';
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
- count && m && (0, combinator_1.consume)(m[0].length, context);
7696
- if (m && not && source.slice(m[0].length, m[0].length + not.length) === not) return;
7697
- //assert(!m || m[0]);
7698
- return m ? [[m[0]], source.slice(m[0].length)] : undefined;
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
- const isTightStart = (0, memoize_1.reduce)((input, except) => {
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 | HTMLSpanElement, Context, []> {
1248
+ Parser<string | HTMLBRElement, Context, []> {
1255
1249
  }
1256
1250
  export interface TxtParser extends
1257
1251
  // abc
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.288.1",
3
+ "version": "0.288.2",
4
4
  "description": "Secure markdown renderer working on browsers for user input data.",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/falsandtru/securemark",
@@ -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, reduce } from 'spica/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 reduce(source => pattern.test(source) || undefined);
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(0 + 0)}((${'['.repeat(13)}{{http://[[[${'.'.repeat(8326)}`;
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(0 + 1)}((${'['.repeat(13)}{{http://[[[${'.'.repeat(8326)}`;
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::b`c`${d}$">a<span class="indexer" data-index="b`c`${d}$"></span></h1>'], '']);
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>'], '']);
@@ -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
- Escape: /\x1B/g,
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)|\)(?=\)$)/g, c => String.fromCodePoint(c.codePointAt(0)! + 0xFEE0)));
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) => [[html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))], rest],
18
- ([as, bs = []], rest) => [unshift(as, bs), rest], [3 | Backtrack.bracket]),
19
- surround(str('('), recursion(Recursion.bracket, precedence(1, str(indexF))), str(')'), false,
20
- undefined, undefined, [3 | Backtrack.bracket]),
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) => [[html('span', { class: 'paren' }, defrag(push(unshift(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], [3 | Backtrack.bracket]),
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], [3 | Backtrack.bracket]),
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::b">a<span class="indexer" data-index="b"></span></a>'], '']);
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, text } from './indexee';
6
- import { str } from '../../source';
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 { frag, html, define, defrag } from 'typed-dom/dom';
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 index = identity('index', undefined, text(frag(bs)))?.slice(7);
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 const text = reduce((source: Element | DocumentFragment): string => {
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(' [|*A*]')), [['<span class="indexer" data-index="A"></span>'], '']);
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 }) => [[parse(source) ?? `${Command.Escape}${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.Escape
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 parse = reduce((el => (entity: string): string | undefined => {
22
+ const parser = (el => (entity: string): string | undefined => {
24
23
  if (entity === '&NewLine;') 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.Escape)) {
113
+ if (alt.includes(Command.Error)) {
114
114
  define(target, {
115
115
  class: 'invalid',
116
- alt: target.getAttribute('alt')?.replace(CmdRegExp.Escape, ''),
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.Escape)) continue;
105
- ss[i] = ss[i].replace(CmdRegExp.Escape, '');
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>&lt;</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>&lt;</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
- const b = source[0] !== '\n' && source[0].trimStart() === '';
40
+ assert(source[0] !== '\n');
41
+ const b = source[0].trimStart() === '';
36
42
  const i = b
37
43
  ? source.search(nonWhitespace)
38
44
  : 1;
@@ -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
- count && m && consume(m[0].length, context);
23
- if (m && not && source.slice(m[0].length, m[0].length + not.length) === not) return;
24
- //assert(!m || m[0]);
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
  }
@@ -27,6 +27,7 @@ export const text: TextParser = ({ source, context }) => {
27
27
  case '\\':
28
28
  switch (source[1]) {
29
29
  case undefined:
30
+ return [[], ''];
30
31
  case '\n':
31
32
  assert(source[0] !== Command.Escape);
32
33
  return [[], source.slice(1)];
@@ -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(source[0] !== Command.Escape);
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);
@@ -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
- const isTightStart = reduce((input: Input<MarkdownParser.Context>, except?: string): boolean => {
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
- }, ({ source }, except = '') => `${source}${Command.Separator}${except}`);
111
+ }
113
112
 
114
113
  export function isLooseNodeStart(nodes: readonly (HTMLElement | string)[]): boolean {
115
114
  if (nodes.length === 0) return true;