securemark 0.234.3 → 0.235.0

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.235.0
4
+
5
+ - Change signature syntax to require leading whitespace.
6
+
3
7
  ## 0.234.3
4
8
 
5
9
  - Refactoring.
@@ -1,4 +1,4 @@
1
- /*! securemark v0.234.3 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
1
+ /*! securemark v0.235.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
2
2
  require = function () {
3
3
  function r(e, n, t) {
4
4
  function o(i, f) {
@@ -3318,10 +3318,14 @@ require = function () {
3318
3318
  }
3319
3319
  exports.guard = guard;
3320
3320
  function reset(base, parser) {
3321
+ if (isEmpty(base))
3322
+ return parser;
3321
3323
  return (source, context) => parser(source, inherit((0, alias_1.ObjectCreate)(context), base));
3322
3324
  }
3323
3325
  exports.reset = reset;
3324
3326
  function context(base, parser) {
3327
+ if (isEmpty(base))
3328
+ return parser;
3325
3329
  const override = (0, memoize_1.memoize)(context => inherit((0, alias_1.ObjectCreate)(context), base), new global_1.WeakMap());
3326
3330
  return (source, context) => parser(source, override(context));
3327
3331
  }
@@ -3347,6 +3351,11 @@ require = function () {
3347
3351
  return target[prop] = source[prop];
3348
3352
  }
3349
3353
  });
3354
+ function isEmpty(context) {
3355
+ for (const _ in context)
3356
+ return false;
3357
+ return true;
3358
+ }
3350
3359
  },
3351
3360
  {
3352
3361
  'spica/alias': 5,
@@ -3906,28 +3915,56 @@ require = function () {
3906
3915
  exports.some = void 0;
3907
3916
  const global_1 = _dereq_('spica/global');
3908
3917
  const parser_1 = _dereq_('../parser');
3918
+ const memoize_1 = _dereq_('spica/memoize');
3909
3919
  const array_1 = _dereq_('spica/array');
3920
+ const signature = pattern => {
3921
+ switch (typeof pattern) {
3922
+ case 'undefined':
3923
+ return signature('');
3924
+ case 'string':
3925
+ return `s:${ pattern }`;
3926
+ case 'object':
3927
+ return `r/${ pattern.source }/${ pattern.flags }`;
3928
+ }
3929
+ };
3930
+ const [matcher, delimiter] = [...Array(2)].map(() => (0, memoize_1.memoize)(pattern => {
3931
+ switch (typeof pattern) {
3932
+ case 'undefined':
3933
+ return () => false;
3934
+ case 'string':
3935
+ return source => source.slice(0, pattern.length) === pattern;
3936
+ case 'object':
3937
+ return (0, memoize_1.reduce)(source => pattern.test(source));
3938
+ }
3939
+ }, signature));
3910
3940
  function some(parser, until, deep, limit = -1) {
3911
3941
  if (typeof until === 'number')
3912
3942
  return some(parser, global_1.undefined, deep, until);
3913
- const match = typeof until === 'string' && until !== global_1.undefined ? source => source.slice(0, until.length) === until : source => !!until && until.test(source);
3914
- const delim = typeof deep === 'string' && deep !== global_1.undefined ? source => source.slice(0, deep.length) === deep : source => !!deep && deep.test(source);
3915
- let memory = '';
3943
+ const match = matcher(until);
3944
+ const delim = delimiter(deep);
3945
+ const sig = signature(deep);
3916
3946
  return (source, context) => {
3917
3947
  var _a, _b, _c;
3918
- if (source === memory)
3948
+ var _d;
3949
+ if (source === '')
3919
3950
  return;
3920
3951
  let rest = source;
3921
3952
  let nodes;
3922
3953
  if (context && deep) {
3923
- context.delimiters ? context.delimiters.push(delim) : context.delimiters = [delim];
3954
+ (_a = context.delimiters) !== null && _a !== void 0 ? _a : context.delimiters = {
3955
+ stack: [],
3956
+ matchers: {}
3957
+ };
3958
+ context.delimiters.stack.push(sig);
3959
+ (_b = (_d = context.delimiters.matchers)[sig]) !== null && _b !== void 0 ? _b : _d[sig] = delim;
3924
3960
  }
3961
+ const {stack, matchers} = (_c = context.delimiters) !== null && _c !== void 0 ? _c : {};
3925
3962
  while (true) {
3926
3963
  if (rest === '')
3927
3964
  break;
3928
3965
  if (match(rest))
3929
3966
  break;
3930
- if ((_a = context === null || context === void 0 ? void 0 : context.delimiters) === null || _a === void 0 ? void 0 : _a.some(match => match(rest)))
3967
+ if (stack === null || stack === void 0 ? void 0 : stack.some(sig => matchers[sig](rest)))
3931
3968
  break;
3932
3969
  const result = parser(rest, context);
3933
3970
  if (!result)
@@ -3938,9 +3975,8 @@ require = function () {
3938
3975
  break;
3939
3976
  }
3940
3977
  if (context && deep) {
3941
- ((_b = context.delimiters) === null || _b === void 0 ? void 0 : _b.length) > 1 ? (_c = context.delimiters) === null || _c === void 0 ? void 0 : _c.pop() : context.delimiters = global_1.undefined;
3978
+ stack === null || stack === void 0 ? void 0 : stack.pop();
3942
3979
  }
3943
- memory = limit < 0 && rest || memory;
3944
3980
  return nodes && rest.length < source.length ? [
3945
3981
  nodes,
3946
3982
  rest
@@ -3952,7 +3988,8 @@ require = function () {
3952
3988
  {
3953
3989
  '../parser': 47,
3954
3990
  'spica/array': 6,
3955
- 'spica/global': 15
3991
+ 'spica/global': 15,
3992
+ 'spica/memoize': 18
3956
3993
  }
3957
3994
  ],
3958
3995
  51: [
@@ -6675,7 +6712,7 @@ require = function () {
6675
6712
  const array_1 = _dereq_('spica/array');
6676
6713
  exports.emphasis = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('*'), (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
6677
6714
  strong_1.strong,
6678
- (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(String.raw`\*`)),
6715
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(/\*/)),
6679
6716
  (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '*'), inline_1.inline)
6680
6717
  ])), '*'), (0, source_1.str)('*'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
6681
6718
  [(0, typed_dom_1.html)('em', (0, typed_dom_1.defrag)(bs))],
@@ -6711,16 +6748,16 @@ require = function () {
6711
6748
  const typed_dom_1 = _dereq_('typed-dom');
6712
6749
  const array_1 = _dereq_('spica/array');
6713
6750
  const substrong = (0, combinator_1.lazy)(() => (0, combinator_1.some)((0, combinator_1.union)([
6714
- (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(String.raw`\*\*`)),
6751
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(/\*\*/)),
6715
6752
  (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '*'), inline_1.inline)
6716
6753
  ])));
6717
6754
  const subemphasis = (0, combinator_1.lazy)(() => (0, combinator_1.some)((0, combinator_1.union)([
6718
6755
  strong_1.strong,
6719
- (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(String.raw`\*`)),
6756
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(/\*/)),
6720
6757
  (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '*'), inline_1.inline)
6721
6758
  ])));
6722
6759
  exports.emstrong = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('***'), (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
6723
- (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(String.raw`\*`)),
6760
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(/\*/)),
6724
6761
  (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '*'), inline_1.inline)
6725
6762
  ]))), (0, source_1.str)(/^\*{1,3}/), false, ([as, bs, cs], rest, context) => {
6726
6763
  var _a, _b;
@@ -6870,18 +6907,18 @@ require = function () {
6870
6907
  autolink: false
6871
6908
  }
6872
6909
  }
6873
- }, (0, combinator_1.open)((0, source_1.str)(/^\|?/, false), (0, combinator_1.some)((0, combinator_1.union)([
6910
+ }, (0, combinator_1.some)((0, combinator_1.union)([
6874
6911
  signature,
6875
6912
  inline_1.inline
6876
- ]), ']', /^\\?\n/), true)))), ']'), ns => [(0, typed_dom_1.html)('a', (0, util_1.trimNodeEnd)((0, typed_dom_1.defrag)(ns)))])), ([el]) => [(0, typed_dom_1.define)(el, {
6913
+ ]), ']', /^\\?\n/)))), ']'), ns => [(0, typed_dom_1.html)('a', (0, util_1.trimNodeEnd)((0, typed_dom_1.defrag)(ns)))])), ([el]) => [(0, typed_dom_1.define)(el, {
6877
6914
  id: el.id ? null : global_1.undefined,
6878
6915
  class: 'index',
6879
6916
  href: el.id ? `#${ el.id }` : global_1.undefined
6880
6917
  }, el.childNodes)]))));
6881
- const signature = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.fmap)((0, combinator_1.open)('|#', (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
6918
+ const signature = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.fmap)((0, combinator_1.open)(/^\s+\|#/, (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
6882
6919
  bracket,
6883
6920
  source_1.txt
6884
- ]), ']', /^\\?\n/))), ns => [(0, typed_dom_1.html)('span', {
6921
+ ]), ']'))), ns => [(0, typed_dom_1.html)('span', {
6885
6922
  class: 'indexer',
6886
6923
  'data-index': (0, indexee_1.identity)((0, array_1.join)(ns)).slice(6)
6887
6924
  })])));
@@ -7300,10 +7337,10 @@ require = function () {
7300
7337
  const url_1 = _dereq_('spica/url');
7301
7338
  const optspec = { rel: ['nofollow'] };
7302
7339
  (0, alias_1.ObjectSetPrototypeOf)(optspec, null);
7303
- exports.link = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, combinator_1.bind)((0, combinator_1.validate)([
7340
+ exports.link = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, combinator_1.validate)([
7304
7341
  '[',
7305
7342
  '{'
7306
- ], '}', '\n', (0, combinator_1.guard)(context => {
7343
+ ], '}', '\n', (0, combinator_1.bind)((0, combinator_1.guard)(context => {
7307
7344
  var _a, _b, _c;
7308
7345
  return (_c = (_b = (_a = context.syntax) === null || _a === void 0 ? void 0 : _a.inline) === null || _b === void 0 ? void 0 : _b.link) !== null && _c !== void 0 ? _c : true;
7309
7346
  }, (0, combinator_1.reverse)((0, combinator_1.tails)([
@@ -7327,7 +7364,7 @@ require = function () {
7327
7364
  exports.uri,
7328
7365
  (0, combinator_1.some)(exports.option)
7329
7366
  ]), /^[^\S\n]?}/))
7330
- ])))), ([params, content = []], rest, context) => {
7367
+ ]))), ([params, content = []], rest, context) => {
7331
7368
  var _a, _b, _c, _d, _e, _f;
7332
7369
  if ((_a = (0, parser_1.eval)((0, combinator_1.some)(autolink_1.autolink)((0, util_1.stringify)(content), context))) === null || _a === void 0 ? void 0 : _a.some(node => typeof node === 'object'))
7333
7370
  return;
@@ -7342,7 +7379,7 @@ require = function () {
7342
7379
  [(0, typed_dom_1.define)(el, (0, html_1.attributes)('link', [], optspec, params))],
7343
7380
  rest
7344
7381
  ];
7345
- })));
7382
+ }))));
7346
7383
  exports.uri = (0, combinator_1.union)([
7347
7384
  (0, combinator_1.open)(/^[^\S\n]/, (0, source_1.str)(/^\S+/)),
7348
7385
  (0, source_1.str)(/^[^\s{}]+/)
@@ -7438,7 +7475,7 @@ require = function () {
7438
7475
  const typed_dom_1 = _dereq_('typed-dom');
7439
7476
  const array_1 = _dereq_('spica/array');
7440
7477
  exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('=='), (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
7441
- (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)('==')),
7478
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(/==/)),
7442
7479
  (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '='), inline_1.inline)
7443
7480
  ]))), (0, source_1.str)('=='), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
7444
7481
  [(0, typed_dom_1.html)('mark', (0, typed_dom_1.defrag)(bs))],
@@ -7524,10 +7561,10 @@ require = function () {
7524
7561
  rel: global_1.undefined
7525
7562
  };
7526
7563
  (0, alias_1.ObjectSetPrototypeOf)(optspec, null);
7527
- exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.fmap)((0, combinator_1.open)('!', (0, combinator_1.validate)([
7528
- '[',
7529
- '{'
7530
- ], '}', '\n', (0, combinator_1.guard)(context => {
7564
+ exports.media = (0, combinator_1.lazy)(() => (0, combinator_1.creator)(10, (0, combinator_1.validate)([
7565
+ '![',
7566
+ '!{'
7567
+ ], '}', '\n', (0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.fmap)((0, combinator_1.open)('!', (0, combinator_1.guard)(context => {
7531
7568
  var _a, _b, _c;
7532
7569
  return (_c = (_b = (_a = context.syntax) === null || _a === void 0 ? void 0 : _a.inline) === null || _b === void 0 ? void 0 : _b.media) !== null && _c !== void 0 ? _c : true;
7533
7570
  }, (0, combinator_1.tails)([
@@ -7540,7 +7577,7 @@ require = function () {
7540
7577
  link_1.uri,
7541
7578
  (0, combinator_1.some)(option)
7542
7579
  ]), /^[^\S\n]?}/))
7543
- ])))), ([as, bs]) => bs ? [
7580
+ ]))), ([as, bs]) => bs ? [
7544
7581
  [(0, array_1.join)(as).trim() || (0, array_1.join)(as)],
7545
7582
  bs
7546
7583
  ] : [
@@ -7569,7 +7606,7 @@ require = function () {
7569
7606
  rest
7570
7607
  ];
7571
7608
  return (0, combinator_1.fmap)(link_1.link, ([link]) => [(0, typed_dom_1.define)(link, { target: '_blank' }, [el])])(`{ ${ INSECURE_URI }${ (0, array_1.join)(params) } }${ rest }`, context);
7572
- })));
7609
+ }))));
7573
7610
  const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.union)([
7574
7611
  (0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([
7575
7612
  htmlentity_1.unsafehtmlentity,
@@ -7727,10 +7764,10 @@ require = function () {
7727
7764
  const util_1 = _dereq_('../util');
7728
7765
  const typed_dom_1 = _dereq_('typed-dom');
7729
7766
  const array_1 = _dereq_('spica/array');
7730
- exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.validate)('[', ')', '\n', (0, combinator_1.sequence)([
7767
+ exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.validate)('[', ')', '\n', (0, combinator_1.bind)((0, combinator_1.verify)((0, combinator_1.sequence)([
7731
7768
  (0, combinator_1.surround)('[', (0, combinator_1.focus)(/^(?:\\[^\n]|[^\\\[\]\n])+(?=]\()/, text), ']'),
7732
7769
  (0, combinator_1.surround)('(', (0, combinator_1.focus)(/^(?:\\[^\n]|[^\\\(\)\n])+(?=\))/, text), ')')
7733
- ])), ([texts]) => (0, util_1.isStartTightNodes)(texts)), ([texts, rubies], rest) => {
7770
+ ]), ([texts]) => (0, util_1.isStartTightNodes)(texts)), ([texts, rubies], rest) => {
7734
7771
  const tail = typeof texts[texts.length - 1] === 'object' ? [texts.pop()] : [];
7735
7772
  tail.length === 0 && texts[texts.length - 1] === '' && texts.pop();
7736
7773
  switch (true) {
@@ -7762,7 +7799,7 @@ require = function () {
7762
7799
  rest
7763
7800
  ];
7764
7801
  }
7765
- })));
7802
+ }))));
7766
7803
  const text = (0, combinator_1.creator)((source, context) => {
7767
7804
  var _a;
7768
7805
  const acc = [''];
@@ -7857,7 +7894,7 @@ require = function () {
7857
7894
  const typed_dom_1 = _dereq_('typed-dom');
7858
7895
  const array_1 = _dereq_('spica/array');
7859
7896
  exports.strong = (0, combinator_1.lazy)(() => (0, combinator_1.creator)((0, combinator_1.surround)((0, source_1.str)('**'), (0, util_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([
7860
- (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(String.raw`\*\*`)),
7897
+ (0, combinator_1.some)(inline_1.inline, (0, util_1.delimiter)(/\*\*/)),
7861
7898
  (0, combinator_1.open)((0, combinator_1.some)(inline_1.inline, '*'), inline_1.inline)
7862
7899
  ])), '*'), (0, source_1.str)('**'), false, ([as, bs, cs], rest) => (0, util_1.isEndTightNodes)(bs) ? [
7863
7900
  [(0, typed_dom_1.html)('strong', (0, typed_dom_1.defrag)(bs))],
@@ -8659,7 +8696,7 @@ require = function () {
8659
8696
  const normalize_1 = _dereq_('./api/normalize');
8660
8697
  const array_1 = _dereq_('spica/array');
8661
8698
  function delimiter(opener) {
8662
- return new RegExp(String.raw`^(?:\s+|\\\s|&(?:${ normalize_1.invisibleHTMLEntityNames.join('|') });|<wbr>)?${ opener }`);
8699
+ return new RegExp(String.raw`^(?:\s+|\\\s|&(?:${ normalize_1.invisibleHTMLEntityNames.join('|') });|<wbr>)?${ opener.source }`);
8663
8700
  }
8664
8701
  exports.delimiter = delimiter;
8665
8702
  function visualize(parser) {
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.234.3",
3
+ "version": "0.235.0",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -449,9 +449,9 @@
449
449
  },
450
450
  "dependencies": {
451
451
  "lru-cache": {
452
- "version": "7.7.1",
453
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz",
454
- "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==",
452
+ "version": "7.7.2",
453
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.2.tgz",
454
+ "integrity": "sha512-WkdIOIF7HkfVHXxKLjhH6lyAxSFoSO5NZpZS9cH8Oe5rAI2ZDrVmIweDAZUHqIhl0zasQUprVVR8uv2yggYYvw==",
455
455
  "dev": true
456
456
  },
457
457
  "mkdirp": {
@@ -1760,10 +1760,13 @@
1760
1760
  "dev": true
1761
1761
  },
1762
1762
  "builtins": {
1763
- "version": "1.0.3",
1764
- "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
1765
- "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=",
1766
- "dev": true
1763
+ "version": "5.0.0",
1764
+ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.0.tgz",
1765
+ "integrity": "sha512-aizhtbxgT1Udg0Fj6GssXshAVK+nxbtCV+1OtTrMNy67jffDFBY6CUBAkhO4owbleAx6fdbnWdpsmmcXydbzNw==",
1766
+ "dev": true,
1767
+ "requires": {
1768
+ "semver": "^7.0.0"
1769
+ }
1767
1770
  },
1768
1771
  "bytes": {
1769
1772
  "version": "3.1.2",
@@ -1798,9 +1801,9 @@
1798
1801
  },
1799
1802
  "dependencies": {
1800
1803
  "lru-cache": {
1801
- "version": "7.7.1",
1802
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz",
1803
- "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==",
1804
+ "version": "7.7.2",
1805
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.2.tgz",
1806
+ "integrity": "sha512-WkdIOIF7HkfVHXxKLjhH6lyAxSFoSO5NZpZS9cH8Oe5rAI2ZDrVmIweDAZUHqIhl0zasQUprVVR8uv2yggYYvw==",
1804
1807
  "dev": true
1805
1808
  },
1806
1809
  "mkdirp": {
@@ -3030,9 +3033,9 @@
3030
3033
  "dev": true
3031
3034
  },
3032
3035
  "electron-to-chromium": {
3033
- "version": "1.4.98",
3034
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.98.tgz",
3035
- "integrity": "sha512-1IdsuSAnIGVxoYT1LkcUFb9MfjRxdHhCU9qiaDzhl1XvYgK9c8E2O9aJOPgGMQ68CSI8NxmLwrYhjvGauT8yuw==",
3036
+ "version": "1.4.100",
3037
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.100.tgz",
3038
+ "integrity": "sha512-pNrSE2naf8fizl6/Uxq8UbKb8hU9EiYW4OzCYswosXoLV5NTMOUVKECNzDaHiUubsPq/kAckOzZd7zd8S8CHVw==",
3036
3039
  "dev": true
3037
3040
  },
3038
3041
  "elliptic": {
@@ -7092,9 +7095,9 @@
7092
7095
  }
7093
7096
  },
7094
7097
  "make-fetch-happen": {
7095
- "version": "10.1.0",
7096
- "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.0.tgz",
7097
- "integrity": "sha512-HeP4QlkadP/Op+hE+Une1070kcyN85FshQObku3/rmzRh4zDcKXA19d2L3AQR6UoaX3uZmhSOpTLH15b1vOFvQ==",
7098
+ "version": "10.1.1",
7099
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.1.tgz",
7100
+ "integrity": "sha512-3/mCljDQNjmrP7kl0vhS5WVlV+TvSKoZaFhdiYV7MOijEnrhrjaVnqbp/EY/7S+fhUB2KpH7j8c1iRsIOs+kjw==",
7098
7101
  "dev": true,
7099
7102
  "requires": {
7100
7103
  "agentkeepalive": "^4.2.1",
@@ -7116,9 +7119,9 @@
7116
7119
  },
7117
7120
  "dependencies": {
7118
7121
  "lru-cache": {
7119
- "version": "7.7.1",
7120
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz",
7121
- "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==",
7122
+ "version": "7.7.2",
7123
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.2.tgz",
7124
+ "integrity": "sha512-WkdIOIF7HkfVHXxKLjhH6lyAxSFoSO5NZpZS9cH8Oe5rAI2ZDrVmIweDAZUHqIhl0zasQUprVVR8uv2yggYYvw==",
7122
7125
  "dev": true
7123
7126
  }
7124
7127
  }
@@ -8128,14 +8131,14 @@
8128
8131
  "dev": true
8129
8132
  },
8130
8133
  "npm-package-arg": {
8131
- "version": "9.0.1",
8132
- "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.0.1.tgz",
8133
- "integrity": "sha512-Xs9wznfEAmZAR61qsYH3iN24V/qMYYkvAR5CRQNMvC6PjN2fHtO8y9XP/xdp5K+Icx+u1wMBMgWRPCmAEChSog==",
8134
+ "version": "9.0.2",
8135
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.0.2.tgz",
8136
+ "integrity": "sha512-v/miORuX8cndiOheW8p2moNuPJ7QhcFh9WGlTorruG8hXSA23vMTEp5hTCmDxic0nD8KHhj/NQgFuySD3GYY3g==",
8134
8137
  "dev": true,
8135
8138
  "requires": {
8136
8139
  "hosted-git-info": "^5.0.0",
8137
8140
  "semver": "^7.3.5",
8138
- "validate-npm-package-name": "^3.0.0"
8141
+ "validate-npm-package-name": "^4.0.0"
8139
8142
  },
8140
8143
  "dependencies": {
8141
8144
  "hosted-git-info": {
@@ -8148,9 +8151,9 @@
8148
8151
  }
8149
8152
  },
8150
8153
  "lru-cache": {
8151
- "version": "7.7.1",
8152
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz",
8153
- "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==",
8154
+ "version": "7.7.2",
8155
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.2.tgz",
8156
+ "integrity": "sha512-WkdIOIF7HkfVHXxKLjhH6lyAxSFoSO5NZpZS9cH8Oe5rAI2ZDrVmIweDAZUHqIhl0zasQUprVVR8uv2yggYYvw==",
8154
8157
  "dev": true
8155
8158
  }
8156
8159
  }
@@ -9187,9 +9190,9 @@
9187
9190
  }
9188
9191
  },
9189
9192
  "lru-cache": {
9190
- "version": "7.7.1",
9191
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz",
9192
- "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==",
9193
+ "version": "7.7.2",
9194
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.2.tgz",
9195
+ "integrity": "sha512-WkdIOIF7HkfVHXxKLjhH6lyAxSFoSO5NZpZS9cH8Oe5rAI2ZDrVmIweDAZUHqIhl0zasQUprVVR8uv2yggYYvw==",
9193
9196
  "dev": true
9194
9197
  },
9195
9198
  "normalize-package-data": {
@@ -11307,12 +11310,12 @@
11307
11310
  }
11308
11311
  },
11309
11312
  "validate-npm-package-name": {
11310
- "version": "3.0.0",
11311
- "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz",
11312
- "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=",
11313
+ "version": "4.0.0",
11314
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz",
11315
+ "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==",
11313
11316
  "dev": true,
11314
11317
  "requires": {
11315
- "builtins": "^1.0.3"
11318
+ "builtins": "^5.0.0"
11316
11319
  }
11317
11320
  },
11318
11321
  "value-or-function": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.234.3",
3
+ "version": "0.235.0",
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",
@@ -6,10 +6,8 @@ export function block<P extends Parser<unknown>>(parser: P, separation?: boolean
6
6
  export function block<T>(parser: Parser<T>, separation = true): Parser<T> {
7
7
  assert(parser);
8
8
  return (source, context) => {
9
- assert(!context?.delimiters);
10
9
  if (source === '') return;
11
10
  const result = parser(source, context);
12
- assert(!context?.delimiters);
13
11
  if (!result) return;
14
12
  const rest = exec(result);
15
13
  if (separation && !isEmpty(firstline(rest))) return;
@@ -15,7 +15,7 @@ export function validate<T>(patterns: string | RegExp | (string | RegExp)[], has
15
15
  if (typeof end === 'function') return validate(patterns, has, '', end);
16
16
  if (!isArray(patterns)) return validate([patterns], has, end!, parser!);
17
17
  assert(patterns.length > 0);
18
- assert(patterns.every(pattern => pattern instanceof RegExp ? !pattern.global && pattern.source.startsWith('^') : true));
18
+ assert(patterns.every(pattern => pattern instanceof RegExp ? !pattern.flags.match(/[gmy]/) && pattern.source.startsWith('^') : true));
19
19
  assert(parser);
20
20
  const match: (source: string) => boolean = Function([
21
21
  '"use strict";',
@@ -17,6 +17,7 @@ export function reset<P extends Parser<unknown>>(context: Context<P>, parser: P)
17
17
  export function reset<T>(base: Ctx, parser: Parser<T>): Parser<T> {
18
18
  assert(Object.getPrototypeOf(base) === Object.prototype);
19
19
  assert(Object.freeze(base));
20
+ if (isEmpty(base)) return parser;
20
21
  return (source, context) =>
21
22
  parser(source, inherit(ObjectCreate(context), base));
22
23
  }
@@ -25,6 +26,7 @@ export function context<P extends Parser<unknown>>(context: Context<P>, parser:
25
26
  export function context<T>(base: Ctx, parser: Parser<T>): Parser<T> {
26
27
  assert(Object.getPrototypeOf(base) === Object.prototype);
27
28
  assert(Object.freeze(base));
29
+ if (isEmpty(base)) return parser;
28
30
  const override = memoize<Ctx, Ctx>(context => inherit(ObjectCreate(context), base), new WeakMap());
29
31
  return (source, context) =>
30
32
  parser(source, override(context));
@@ -56,3 +58,8 @@ const inherit = template((prop, target, source) => {
56
58
  return target[prop] = source[prop];
57
59
  }
58
60
  });
61
+
62
+ function isEmpty(context: Ctx): boolean {
63
+ for (const _ in context) return false;
64
+ return true;
65
+ }
@@ -3,7 +3,7 @@ import { Parser, exec, check } from '../../data/parser';
3
3
 
4
4
  export function match<P extends Parser<unknown>>(pattern: RegExp, f: (matched: RegExpMatchArray) => P): P;
5
5
  export function match<T>(pattern: RegExp, f: (matched: RegExpMatchArray) => Parser<T>): Parser<T> {
6
- assert(!pattern.global && pattern.source.startsWith('^'));
6
+ assert(!pattern.flags.match(/[gmy]/) && pattern.source.startsWith('^'));
7
7
  return (source, context) => {
8
8
  if (source === '') return;
9
9
  const param = source.match(pattern);
@@ -3,7 +3,7 @@ import { Parser, Context, eval, exec, check } from '../../data/parser';
3
3
 
4
4
  export function focus<P extends Parser<unknown>>(scope: string | RegExp, parser: P): P;
5
5
  export function focus<T>(scope: string | RegExp, parser: Parser<T>): Parser<T> {
6
- assert(scope instanceof RegExp ? !scope.global && scope.source.startsWith('^') : scope);
6
+ assert(scope instanceof RegExp ? !scope.flags.match(/[gmy]/) && scope.source.startsWith('^') : scope);
7
7
  assert(parser);
8
8
  const match: (source: string) => string = typeof scope === 'string'
9
9
  ? source => source.slice(0, scope.length) === scope ? scope : ''
@@ -14,7 +14,7 @@ export function inits<T, D extends Parser<T>[]>(parsers: D): Parser<T, Ctx, D> {
14
14
  const result = parsers[i](rest, context);
15
15
  assert(check(rest, result));
16
16
  if (!result) break;
17
- assert(!context?.delimiters?.some(match => match(rest)));
17
+ assert(!context?.delimiters?.stack.some(sig => context.delimiters!.matchers[sig](rest)));
18
18
  nodes = nodes
19
19
  ? push(nodes, eval(result))
20
20
  : eval(result);
@@ -14,7 +14,7 @@ export function sequence<T, D extends Parser<T>[]>(parsers: D): Parser<T, Ctx, D
14
14
  const result = parsers[i](rest, context);
15
15
  assert(check(rest, result));
16
16
  if (!result) return;
17
- assert(!context?.delimiters?.some(match => match(rest)));
17
+ assert(!context?.delimiters?.stack.some(sig => context.delimiters!.matchers[sig](rest)));
18
18
  nodes = nodes
19
19
  ? push(nodes, eval(result))
20
20
  : eval(result);
@@ -1,33 +1,58 @@
1
1
  import { undefined } from 'spica/global';
2
2
  import { Parser, eval, exec, check } from '../parser';
3
+ import { memoize, reduce } from 'spica/memoize';
3
4
  import { push } from 'spica/array';
4
5
 
6
+ const signature = (pattern: string | RegExp | undefined): string => {
7
+ switch (typeof pattern) {
8
+ case 'undefined':
9
+ return signature('');
10
+ case 'string':
11
+ return `s:${pattern}`;
12
+ case 'object':
13
+ return `r/${pattern.source}/${pattern.flags}`;
14
+ }
15
+ };
16
+ const [matcher, delimiter] = [...Array(2)].map(() =>
17
+ memoize(
18
+ (pattern: string | RegExp | undefined): (source: string) => boolean => {
19
+ switch (typeof pattern) {
20
+ case 'undefined':
21
+ return () => false;
22
+ case 'string':
23
+ return source => source.slice(0, pattern.length) === pattern;
24
+ case 'object':
25
+ return reduce(source => pattern.test(source));
26
+ }
27
+ },
28
+ signature));
29
+
5
30
  export function some<P extends Parser<unknown>>(parser: P, until?: string | RegExp | number, deep?: string | RegExp, limit?: number): P;
6
31
  export function some<T>(parser: Parser<T>, until?: string | RegExp | number, deep?: string | RegExp, limit = -1): Parser<T> {
7
32
  assert(parser);
8
- assert(until instanceof RegExp ? !until.global && until.source.startsWith('^') : true);
33
+ assert(until instanceof RegExp ? !until.flags.match(/[gmy]/) && until.source.startsWith('^') : true);
34
+ assert(deep instanceof RegExp ? !deep.flags.match(/[gmy]/) && deep.source.startsWith('^') : true);
9
35
  if (typeof until === 'number') return some(parser, undefined, deep, until);
10
- const match: (source: string) => boolean = typeof until === 'string' && until !== undefined
11
- ? source => source.slice(0, until.length) === until
12
- : source => !!until && until.test(source);
13
- const delim: (source: string) => boolean = typeof deep === 'string' && deep !== undefined
14
- ? source => source.slice(0, deep.length) === deep
15
- : source => !!deep && deep.test(source);
16
- let memory = '';
36
+ const match = matcher(until);
37
+ const delim = delimiter(deep);
38
+ const sig = signature(deep);
17
39
  return (source, context) => {
18
- if (source === memory) return;
40
+ if (source === '') return;
19
41
  let rest = source;
20
42
  let nodes: T[] | undefined;
21
43
  if (context && deep) {
22
- context.delimiters
23
- ? context.delimiters.push(delim)
24
- : context.delimiters = [delim];
25
- assert(context.delimiters.length <= 3);
44
+ // bracket > annotation > bracket > reference > bracket > link > media | bracket
45
+ // bracket > annotation > bracket > reference > bracket > index > bracket
46
+ context.delimiters ??= { stack: [], matchers: {} };
47
+ context.delimiters.stack.push(sig);
48
+ context.delimiters.matchers[sig] ??= delim;
49
+ assert(context.delimiters.matchers[sig] === delim);
26
50
  }
51
+ const { stack, matchers } = context.delimiters ?? {};
27
52
  while (true) {
28
53
  if (rest === '') break;
29
54
  if (match(rest)) break;
30
- if (context?.delimiters?.some(match => match(rest))) break;
55
+ if (stack?.some(sig => matchers![sig](rest))) break;
31
56
  const result = parser(rest, context);
32
57
  assert.doesNotThrow(() => limit < 0 && check(rest, result));
33
58
  if (!result) break;
@@ -38,11 +63,8 @@ export function some<T>(parser: Parser<T>, until?: string | RegExp | number, dee
38
63
  if (limit >= 0 && source.length - rest.length > limit) break;
39
64
  }
40
65
  if (context && deep) {
41
- context.delimiters?.length! > 1
42
- ? context.delimiters?.pop()
43
- : context.delimiters = undefined;
66
+ stack?.pop();
44
67
  }
45
- memory = limit < 0 && rest || memory;
46
68
  assert(rest.length <= source.length);
47
69
  return nodes && rest.length < source.length
48
70
  ? [nodes, rest]
@@ -2,7 +2,10 @@ export interface Ctx {
2
2
  readonly resources?: {
3
3
  budget: number;
4
4
  };
5
- delimiters?: ((source: string) => boolean)[];
5
+ delimiters?: {
6
+ readonly stack: string[];
7
+ readonly matchers: Record<string, (source: string) => boolean>;
8
+ };
6
9
  }
7
10
 
8
11
  export type Parser<T, C extends Ctx = Ctx, D extends Parser<unknown, C>[] = any>
@@ -74,7 +74,7 @@ describe('Unit: parser/block/heading', () => {
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 [#a((b))]')), [['<h1 id="index:a((b))">a<span class="indexer" data-index="a((b))"></span></h1>'], '']);
76
76
  assert.deepStrictEqual(inspect(parser('# a [#a[[b]]]')), [['<h1 id="index:a[[b]]">a<span class="indexer" data-index="a[[b]]"></span></h1>'], '']);
77
- assert.deepStrictEqual(inspect(parser('# a [#b|#c]')), [['<h1 id="index:c">a<span class="indexer" data-index="c"></span></h1>'], '']);
77
+ assert.deepStrictEqual(inspect(parser('# a [#b |#c]')), [['<h1 id="index:c">a<span class="indexer" data-index="c"></span></h1>'], '']);
78
78
  assert.deepStrictEqual(inspect(parser('# a [#b] [#c]')), [['<h1 id="index:c">a [#b]<span class="indexer" data-index="c"></span></h1>'], '']);
79
79
  assert.deepStrictEqual(inspect(parser('# a [#b] \n')), [['<h1 id="index:b">a<span class="indexer" data-index="b"></span></h1>'], '']);
80
80
  assert.deepStrictEqual(inspect(parser('# a \\[#b]')), [['<h1 id="index:a_[#b]">a [#b]</h1>'], '']);
@@ -11,7 +11,7 @@ export const emphasis: EmphasisParser = lazy(() => creator(surround(
11
11
  str('*'),
12
12
  startTight(some(union([
13
13
  strong,
14
- some(inline, delimiter(String.raw`\*`)),
14
+ some(inline, delimiter(/\*/)),
15
15
  open(some(inline, '*'), inline),
16
16
  ])), '*'),
17
17
  str('*'), false,
@@ -10,19 +10,19 @@ import { html, defrag } from 'typed-dom';
10
10
  import { unshift } from 'spica/array';
11
11
 
12
12
  const substrong: IntermediateParser<StrongParser> = lazy(() => some(union([
13
- some(inline, delimiter(String.raw`\*\*`)),
13
+ some(inline, delimiter(/\*\*/)),
14
14
  open(some(inline, '*'), inline),
15
15
  ])));
16
16
  const subemphasis: IntermediateParser<EmphasisParser> = lazy(() => some(union([
17
17
  strong,
18
- some(inline, delimiter(String.raw`\*`)),
18
+ some(inline, delimiter(/\*/)),
19
19
  open(some(inline, '*'), inline),
20
20
  ])));
21
21
 
22
22
  export const emstrong: EmStrongParser = lazy(() => creator(surround(
23
23
  str('***'),
24
24
  startTight(some(union([
25
- some(inline, delimiter(String.raw`\*`)),
25
+ some(inline, delimiter(/\*/)),
26
26
  open(some(inline, '*'), inline),
27
27
  ]))),
28
28
  str(/^\*{1,3}/), false,
@@ -20,13 +20,19 @@ describe('Unit: parser/inline/extension/index', () => {
20
20
  assert.deepStrictEqual(inspect(parser('[#\\]')), undefined);
21
21
  assert.deepStrictEqual(inspect(parser('[#a')), undefined);
22
22
  assert.deepStrictEqual(inspect(parser('[#*a\nb*]')), undefined);
23
+ assert.deepStrictEqual(inspect(parser('[#a\n|#b]')), undefined);
23
24
  assert.deepStrictEqual(inspect(parser('[#a|#\n]')), undefined);
24
25
  assert.deepStrictEqual(inspect(parser('[#a|#\\\n]')), undefined);
26
+ assert.deepStrictEqual(inspect(parser('[#a|#(\n)]')), undefined);
27
+ assert.deepStrictEqual(inspect(parser('[#a|#(\\\n)]')), undefined);
25
28
  assert.deepStrictEqual(inspect(parser('[# |]')), undefined);
26
29
  assert.deepStrictEqual(inspect(parser('[# |#]')), undefined);
27
30
  assert.deepStrictEqual(inspect(parser('[# |#b]')), undefined);
28
- assert.deepStrictEqual(inspect(parser('[# |# ]')), undefined);
29
- assert.deepStrictEqual(inspect(parser('[# |# b]')), undefined);
31
+ assert.deepStrictEqual(inspect(parser('[# a|]')), undefined);
32
+ assert.deepStrictEqual(inspect(parser('[# a|#]')), undefined);
33
+ assert.deepStrictEqual(inspect(parser('[# a|#b]')), undefined);
34
+ assert.deepStrictEqual(inspect(parser('[# a|# ]')), undefined);
35
+ assert.deepStrictEqual(inspect(parser('[# a|# b]')), undefined);
30
36
  assert.deepStrictEqual(inspect(parser(' [#a]')), undefined);
31
37
  });
32
38
 
@@ -64,26 +70,21 @@ describe('Unit: parser/inline/extension/index', () => {
64
70
  assert.deepStrictEqual(inspect(parser('[#|]')), [['<a class="index" href="#index:|">|</a>'], '']);
65
71
  assert.deepStrictEqual(inspect(parser('[#|#]')), [['<a class="index" href="#index:|#">|#</a>'], '']);
66
72
  assert.deepStrictEqual(inspect(parser('[#|#b]')), [['<a class="index" href="#index:|#b">|#b</a>'], '']);
67
- assert.deepStrictEqual(inspect(parser('[#a|]')), [['<a class="index" href="#index:a|">a|</a>'], '']);
68
- assert.deepStrictEqual(inspect(parser('[#a|#]')), [['<a class="index" href="#index:a|#">a|#</a>'], '']);
69
- assert.deepStrictEqual(inspect(parser('[#a|# ]')), [['<a class="index" href="#index:a|#">a|#</a>'], '']);
70
- assert.deepStrictEqual(inspect(parser('[#a|#\\ ]')), [['<a class="index" href="#index:a|#">a|#</a>'], '']);
71
- assert.deepStrictEqual(inspect(parser('[#a|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
72
- assert.deepStrictEqual(inspect(parser('[#a|#b ]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
73
- assert.deepStrictEqual(inspect(parser('[#a|#b ]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
74
- assert.deepStrictEqual(inspect(parser('[#a|#\\b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
75
- assert.deepStrictEqual(inspect(parser('[#a|#*b*]')), [['<a class="index" href="#index:*b*">a<span class="indexer" data-index="*b*"></span></a>'], '']);
76
- assert.deepStrictEqual(inspect(parser('[#a|#b c]')), [['<a class="index" href="#index:b_c">a<span class="indexer" data-index="b_c"></span></a>'], '']);
77
- assert.deepStrictEqual(inspect(parser('[#a|#b c]')), [['<a class="index" href="#index:b_c">a<span class="indexer" data-index="b_c"></span></a>'], '']);
78
- assert.deepStrictEqual(inspect(parser('[#a|#[]]')), [['<a class="index" href="#index:[]">a<span class="indexer" data-index="[]"></span></a>'], '']);
79
- assert.deepStrictEqual(inspect(parser('[#a|#&copy;]')), [['<a class="index" href="#index:&amp;copy;">a<span class="indexer" data-index="&amp;copy;"></span></a>'], '']);
73
+ assert.deepStrictEqual(inspect(parser('[#a|#b]')), [['<a class="index" href="#index:a|#b">a|#b</a>'], '']);
80
74
  assert.deepStrictEqual(inspect(parser('[#a |]')), [['<a class="index" href="#index:a_|">a |</a>'], '']);
81
75
  assert.deepStrictEqual(inspect(parser('[#a |#]')), [['<a class="index" href="#index:a_|#">a |#</a>'], '']);
76
+ assert.deepStrictEqual(inspect(parser('[#a |# ]')), [['<a class="index" href="#index:a_|#">a |#</a>'], '']);
77
+ assert.deepStrictEqual(inspect(parser('[#a |#\\ ]')), [['<a class="index" href="#index:a_|#">a |#</a>'], '']);
82
78
  assert.deepStrictEqual(inspect(parser('[#a |#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
79
+ assert.deepStrictEqual(inspect(parser('[#a |#b ]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
80
+ assert.deepStrictEqual(inspect(parser('[#a |#b ]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
81
+ assert.deepStrictEqual(inspect(parser('[#a |#\\b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
82
+ assert.deepStrictEqual(inspect(parser('[#a |#*b*]')), [['<a class="index" href="#index:*b*">a<span class="indexer" data-index="*b*"></span></a>'], '']);
83
+ assert.deepStrictEqual(inspect(parser('[#a |#b c]')), [['<a class="index" href="#index:b_c">a<span class="indexer" data-index="b_c"></span></a>'], '']);
84
+ assert.deepStrictEqual(inspect(parser('[#a |#b c]')), [['<a class="index" href="#index:b_c">a<span class="indexer" data-index="b_c"></span></a>'], '']);
85
+ assert.deepStrictEqual(inspect(parser('[#a |#[]]')), [['<a class="index" href="#index:[]">a<span class="indexer" data-index="[]"></span></a>'], '']);
86
+ assert.deepStrictEqual(inspect(parser('[#a |#&copy;]')), [['<a class="index" href="#index:&amp;copy;">a<span class="indexer" data-index="&amp;copy;"></span></a>'], '']);
83
87
  assert.deepStrictEqual(inspect(parser('[#a |#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
84
- assert.deepStrictEqual(inspect(parser('[#a &nbsp;|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
85
- assert.deepStrictEqual(inspect(parser('[#a <wbr>|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
86
- assert.deepStrictEqual(inspect(parser('[#a [# b #]|#b]')), [['<a class="index" href="#index:b">a <span class="comment"><input type="checkbox"><span>[# b #]</span></span><span class="indexer" data-index="b"></span></a>'], '']);
87
88
  });
88
89
 
89
90
  });
@@ -23,11 +23,10 @@ export const index: IndexParser = lazy(() => creator(validate('[#', ']', '\n', f
23
23
  media: false,
24
24
  autolink: false,
25
25
  }}},
26
- open(str(/^\|?/, false),
27
26
  some(union([
28
27
  signature,
29
28
  inline,
30
- ]), ']', /^\\?\n/), true)))),
29
+ ]), ']', /^\\?\n/)))),
31
30
  ']'),
32
31
  ns => [html('a', trimNodeEnd(defrag(ns)))])),
33
32
  ([el]: [HTMLAnchorElement]) => [
@@ -41,8 +40,8 @@ export const index: IndexParser = lazy(() => creator(validate('[#', ']', '\n', f
41
40
  ]))));
42
41
 
43
42
  const signature: IndexParser.SignatureParser = lazy(() => creator(fmap(open(
44
- '|#',
45
- startTight(some(union([bracket, txt]), ']', /^\\?\n/))),
43
+ /^\s+\|#/,
44
+ startTight(some(union([bracket, txt]), ']'))),
46
45
  ns => [
47
46
  html('span', { class: 'indexer', 'data-index': identity(join(ns)).slice(6) }),
48
47
  ])));
@@ -15,6 +15,7 @@ describe('Unit: parser/inline/extension/indexer', () => {
15
15
  assert.deepStrictEqual(inspect(parser(' [#]')), undefined);
16
16
  assert.deepStrictEqual(inspect(parser(' [#]]')), undefined);
17
17
  assert.deepStrictEqual(inspect(parser(' [#a]]')), undefined);
18
+ assert.deepStrictEqual(inspect(parser(' [#&a;]')), undefined);
18
19
  });
19
20
 
20
21
  it('valid', () => {
@@ -10,6 +10,7 @@ export const indexer: ExtensionParser.IndexerParser = creator(fmap(verify(surrou
10
10
  }}},
11
11
  union([index])),
12
12
  /^\s*$/),
13
+ // Indexer is invisible but invalids must be visible.
13
14
  ([el]) => el.getElementsByClassName('invalid').length === 0),
14
15
  ([el]) => [
15
16
  html('span', { class: 'indexer', 'data-index': el.getAttribute('href')!.slice(7) }),
@@ -16,8 +16,7 @@ const optspec = {
16
16
  } as const;
17
17
  ObjectSetPrototypeOf(optspec, null);
18
18
 
19
- export const link: LinkParser = lazy(() => creator(10, bind(
20
- validate(['[', '{'], '}', '\n',
19
+ export const link: LinkParser = lazy(() => creator(10, validate(['[', '{'], '}', '\n', bind(
21
20
  guard(context => context.syntax?.inline?.link ?? true,
22
21
  reverse(tails([
23
22
  context({ syntax: { inline: {
@@ -44,7 +43,7 @@ export const link: LinkParser = lazy(() => creator(10, bind(
44
43
  true),
45
44
  ]))),
46
45
  dup(surround(/^{(?![{}])/, inits([uri, some(option)]), /^[^\S\n]?}/)),
47
- ])))),
46
+ ]))),
48
47
  ([params, content = []]: [string[], (HTMLElement | string)[]], rest, context) => {
49
48
  assert(params.every(p => typeof p === 'string'));
50
49
  if (eval(some(autolink)(stringify(content), context))?.some(node => typeof node === 'object')) return;
@@ -62,7 +61,7 @@ export const link: LinkParser = lazy(() => creator(10, bind(
62
61
  if (el.classList.contains('invalid')) return [[el], rest];
63
62
  assert(el.classList.length === 0);
64
63
  return [[define(el, attributes('link', [], optspec, params))], rest];
65
- })));
64
+ }))));
66
65
 
67
66
  export const uri: LinkParser.ParameterParser.UriParser = union([
68
67
  open(/^[^\S\n]/, str(/^\S+/)),
@@ -9,7 +9,7 @@ import { unshift } from 'spica/array';
9
9
  export const mark: MarkParser = lazy(() => creator(surround(
10
10
  str('=='),
11
11
  startTight(some(union([
12
- some(inline, delimiter('==')),
12
+ some(inline, delimiter(/==/)),
13
13
  open(some(inline, '='), inline),
14
14
  ]))),
15
15
  str('=='), false,
@@ -18,14 +18,17 @@ const optspec = {
18
18
  } as const;
19
19
  ObjectSetPrototypeOf(optspec, null);
20
20
 
21
- export const media: MediaParser = lazy(() => creator(10, bind(verify(fmap(open(
21
+ export const media: MediaParser = lazy(() => creator(10, validate(['![', '!{'], '}', '\n', bind(verify(fmap(open(
22
22
  '!',
23
- validate(['[', '{'], '}', '\n',
24
23
  guard(context => context.syntax?.inline?.media ?? true,
25
24
  tails([
26
- dup(surround(/^\[(?!\s*\\\s)/, some(union([unsafehtmlentity, bracket, txt]), ']', /^\\?\n/), ']', true)),
25
+ dup(surround(
26
+ /^\[(?!\s*\\\s)/,
27
+ some(union([unsafehtmlentity, bracket, txt]), ']', /^\\?\n/),
28
+ ']',
29
+ true)),
27
30
  dup(surround(/^{(?![{}])/, inits([uri, some(option)]), /^[^\S\n]?}/)),
28
- ])))),
31
+ ]))),
29
32
  ([as, bs]) => bs ? [[join(as).trim() || join(as)], bs] : [[''], as]),
30
33
  ([[text]]) => text === '' || text.trim() !== ''),
31
34
  ([[text], params], rest, context) => {
@@ -51,7 +54,7 @@ export const media: MediaParser = lazy(() => creator(10, bind(verify(fmap(open(
51
54
  link as MediaParser,
52
55
  ([link]) => [define(link, { target: '_blank' }, [el])])
53
56
  (`{ ${INSECURE_URI}${join(params)} }${rest}`, context);
54
- })));
57
+ }))));
55
58
 
56
59
  const bracket: MediaParser.TextParser.BracketParser = lazy(() => union([
57
60
  surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
@@ -8,12 +8,11 @@ import { isStartTightNodes } from '../util';
8
8
  import { html, defrag } from 'typed-dom';
9
9
  import { unshift, push, join } from 'spica/array';
10
10
 
11
- export const ruby: RubyParser = lazy(() => creator(bind(verify(
12
- validate('[', ')', '\n',
11
+ export const ruby: RubyParser = lazy(() => creator(validate('[', ')', '\n', bind(verify(
13
12
  sequence([
14
13
  surround('[', focus(/^(?:\\[^\n]|[^\\\[\]\n])+(?=]\()/, text), ']'),
15
14
  surround('(', focus(/^(?:\\[^\n]|[^\\\(\)\n])+(?=\))/, text), ')'),
16
- ])),
15
+ ]),
17
16
  ([texts]) => isStartTightNodes(texts)),
18
17
  ([texts, rubies], rest) => {
19
18
  const tail = typeof texts[texts.length - 1] === 'object'
@@ -44,7 +43,7 @@ export const ruby: RubyParser = lazy(() => creator(bind(verify(
44
43
  [html('rp', '('), html('rt', join(rubies, ' ').trim()), html('rp', ')')]), tail)))
45
44
  ], rest];
46
45
  }
47
- })));
46
+ }))));
48
47
 
49
48
  const text: RubyParser.TextParser = creator((source, context) => {
50
49
  const acc = [''];
@@ -9,7 +9,7 @@ import { unshift } from 'spica/array';
9
9
  export const strong: StrongParser = lazy(() => creator(surround(
10
10
  str('**'),
11
11
  startTight(some(union([
12
- some(inline, delimiter(String.raw`\*\*`)),
12
+ some(inline, delimiter(/\*\*/)),
13
13
  open(some(inline, '*'), inline),
14
14
  ])), '*'),
15
15
  str('**'), false,
@@ -7,8 +7,8 @@ import { linebreak, unescsource } from './source';
7
7
  import { invisibleHTMLEntityNames } from './api/normalize';
8
8
  import { push, pop } from 'spica/array';
9
9
 
10
- export function delimiter(opener: string): RegExp {
11
- return new RegExp(String.raw`^(?:\s+|\\\s|&(?:${invisibleHTMLEntityNames.join('|')});|<wbr>)?${opener}`);
10
+ export function delimiter(opener: RegExp): RegExp {
11
+ return new RegExp(String.raw`^(?:\s+|\\\s|&(?:${invisibleHTMLEntityNames.join('|')});|<wbr>)?${opener.source}`);
12
12
  }
13
13
 
14
14
  export function visualize<P extends Parser<HTMLElement | string>>(parser: P): P;