securemark 0.237.2 → 0.238.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.238.0
4
+
5
+ - Revert signature syntax not to require leading whitespace.
6
+
3
7
  ## 0.237.2
4
8
 
5
9
  - Refactoring.
@@ -1,4 +1,4 @@
1
- /*! securemark v0.237.2 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
1
+ /*! securemark v0.238.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) {
@@ -4648,7 +4648,7 @@ require = function () {
4648
4648
  paragraph_1.paragraph
4649
4649
  ]))));
4650
4650
  function error(parser) {
4651
- return (0, combinator_1.recover)((0, combinator_1.fallback)((0, combinator_1.open)('\0', source => {
4651
+ return (0, combinator_1.recover)((0, combinator_1.fallback)((0, combinator_1.open)('\x07', source => {
4652
4652
  throw new Error(source.split('\n', 1)[0]);
4653
4653
  }), parser), (source, {id}, reason) => [
4654
4654
  [
@@ -4659,7 +4659,7 @@ require = function () {
4659
4659
  (0, typed_dom_1.html)('pre', {
4660
4660
  class: 'error',
4661
4661
  translate: 'no'
4662
- }, source.replace(/^\0.*\n/, '').slice(0, 1001).replace(/^(.{997}).{4}$/s, '$1...') || global_1.undefined)
4662
+ }, source.replace(/^\x07.*\n/, '').slice(0, 1001).replace(/^(.{997}).{4}$/s, '$1...') || global_1.undefined)
4663
4663
  ],
4664
4664
  ''
4665
4665
  ]);
@@ -5043,7 +5043,7 @@ require = function () {
5043
5043
  '[$',
5044
5044
  '$'
5045
5045
  ], (0, combinator_1.sequence)([
5046
- (0, combinator_1.line)((0, combinator_1.close)(label_1.segment, /^.*\n/)),
5046
+ (0, combinator_1.line)((0, combinator_1.close)(label_1.segment, /^(?=\s).*\n/)),
5047
5047
  (0, combinator_1.union)([
5048
5048
  codeblock_1.segment,
5049
5049
  mathblock_1.segment,
@@ -5119,7 +5119,7 @@ require = function () {
5119
5119
  const memoize_1 = _dereq_('spica/memoize');
5120
5120
  const array_1 = _dereq_('spica/array');
5121
5121
  exports.segment = (0, combinator_1.block)((0, combinator_1.match)(/^(~{3,})(?:figure[^\S\n]+)?(?=\[?\$[A-Za-z-][^\n]*\n)/, (0, memoize_1.memoize)(([, fence], closer = new RegExp(String.raw`^${ fence }[^\S\n]*(?:$|\n)`)) => (0, combinator_1.close)((0, combinator_1.sequence)([
5122
- (0, combinator_1.line)((0, combinator_1.close)(label_1.segment, /^.*\n/)),
5122
+ source_1.contentline,
5123
5123
  (0, combinator_1.inits)([
5124
5124
  (0, combinator_1.union)([
5125
5125
  codeblock_1.segment_,
@@ -5164,10 +5164,6 @@ require = function () {
5164
5164
  ])])));
5165
5165
  function attributes(label, param, content, caption) {
5166
5166
  const group = label.split('-', 1)[0];
5167
- const invalidLabel = /^[^-]+-(?:[0-9]+\.)*0$/.test(label);
5168
- const invalidParam = param.trimStart() !== '';
5169
- const invalidContent = group === '$' && (!content.classList.contains('math') || caption.length > 0);
5170
- const invalid = invalidLabel || invalidParam || invalidContent || global_1.undefined;
5171
5167
  let type = content.className.split(/\s/)[0];
5172
5168
  switch (type || content.tagName) {
5173
5169
  case 'UL':
@@ -5191,24 +5187,25 @@ require = function () {
5191
5187
  break;
5192
5188
  default:
5193
5189
  }
5190
+ const invalid = /^[^-]+-(?:[0-9]+\.)*0$/.test(label) && {
5191
+ 'data-invalid-type': 'label',
5192
+ 'data-invalid-message': 'The last part of the fixed label numbers must not be 0'
5193
+ } || param.trimStart() !== '' && {
5194
+ 'data-invalid-type': 'argument',
5195
+ 'data-invalid-message': 'Invalid argument'
5196
+ } || group === '$' && (!content.classList.contains('math') || caption.length > 0) && {
5197
+ 'data-invalid-type': 'content',
5198
+ 'data-invalid-message': 'A figure labeled to define a formula number can contain only a math formula and no caption'
5199
+ } || global_1.undefined;
5194
5200
  return {
5195
5201
  'data-type': type,
5196
5202
  'data-label': label,
5197
5203
  'data-group': group,
5198
- class: invalid && 'invalid',
5199
- ...invalidLabel && {
5200
- 'data-invalid-syntax': 'figure',
5201
- 'data-invalid-type': 'label',
5202
- 'data-invalid-message': 'The last part of the fixed label numbers must not be 0'
5203
- } || invalidParam && {
5204
- 'data-invalid-syntax': 'figure',
5205
- 'data-invalid-type': 'argument',
5206
- 'data-invalid-message': 'Invalid argument'
5207
- } || invalidContent && {
5204
+ ...invalid && {
5205
+ class: 'invalid',
5208
5206
  'data-invalid-syntax': 'figure',
5209
- 'data-invalid-type': 'content',
5210
- 'data-invalid-message': 'A figure labeled to define a formula number can contain only a math formula and no caption'
5211
- } || global_1.undefined
5207
+ ...invalid
5208
+ }
5212
5209
  };
5213
5210
  }
5214
5211
  },
@@ -6989,15 +6986,15 @@ require = function () {
6989
6986
  autolink: false
6990
6987
  }
6991
6988
  }
6992
- }, (0, combinator_1.some)((0, combinator_1.union)([
6989
+ }, (0, combinator_1.open)((0, source_1.stropt)('|'), (0, combinator_1.some)((0, combinator_1.union)([
6993
6990
  signature,
6994
6991
  inline_1.inline
6995
- ]), ']', /^\\?\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, {
6992
+ ]), ']', /^\\?\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, {
6996
6993
  id: el.id ? null : global_1.undefined,
6997
6994
  class: 'index',
6998
6995
  href: el.id ? `#${ el.id }` : global_1.undefined
6999
6996
  }, el.childNodes)]))));
7000
- 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)([
6997
+ 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)([
7001
6998
  bracket,
7002
6999
  source_1.txt
7003
7000
  ]), ']'))), ns => [(0, typed_dom_1.html)('span', {
@@ -7378,11 +7375,11 @@ require = function () {
7378
7375
  exports.unsafehtmlentity = (0, combinator_1.creator)((0, combinator_1.validate)('&', (0, combinator_1.focus)(/^&[0-9A-Za-z]+;/, entity => {
7379
7376
  var _a;
7380
7377
  return [
7381
- [(_a = parse(entity)) !== null && _a !== void 0 ? _a : `\0${ entity }`],
7378
+ [(_a = parse(entity)) !== null && _a !== void 0 ? _a : `\x1B${ entity }`],
7382
7379
  ''
7383
7380
  ];
7384
7381
  })));
7385
- exports.htmlentity = (0, combinator_1.fmap)((0, combinator_1.union)([exports.unsafehtmlentity]), ([test]) => [test[0] === '\0' ? (0, typed_dom_1.html)('span', {
7382
+ exports.htmlentity = (0, combinator_1.fmap)((0, combinator_1.union)([exports.unsafehtmlentity]), ([test]) => [test[0] === '\x1B' ? (0, typed_dom_1.html)('span', {
7386
7383
  class: 'invalid',
7387
7384
  'data-invalid-syntax': 'htmlentity',
7388
7385
  'data-invalid-type': 'syntax',
@@ -7780,13 +7777,13 @@ require = function () {
7780
7777
  });
7781
7778
  return false;
7782
7779
  }
7783
- if (alt.includes('\0')) {
7780
+ if (alt.includes('\x1B')) {
7784
7781
  (0, typed_dom_1.define)(target, {
7785
7782
  class: void target.classList.add('invalid'),
7786
7783
  'data-invalid-syntax': 'media',
7787
7784
  'data-invalid-type': 'content',
7788
7785
  'data-invalid-message': `Cannot use invalid HTML entitiy "${ alt.match(/&[0-9A-Za-z]+;/)[0] }"`,
7789
- alt: (_a = target.getAttribute('alt')) === null || _a === void 0 ? void 0 : _a.replace(/\0/g, '')
7786
+ alt: (_a = target.getAttribute('alt')) === null || _a === void 0 ? void 0 : _a.replace(/\x1B/g, '')
7790
7787
  });
7791
7788
  return false;
7792
7789
  }
@@ -7949,9 +7946,9 @@ require = function () {
7949
7946
  rubies
7950
7947
  ]) {
7951
7948
  for (let i = 0; i < ss.length; ++i) {
7952
- if (ss[i].indexOf('\0') === -1)
7949
+ if (ss[i].indexOf('\x1B') === -1)
7953
7950
  continue;
7954
- ss[i] = ss[i].replace(/\0/g, '');
7951
+ ss[i] = ss[i].replace(/\x1B/g, '');
7955
7952
  attrs !== null && attrs !== void 0 ? attrs : attrs = {
7956
7953
  class: 'invalid',
7957
7954
  'data-invalid-syntax': 'ruby',
@@ -8190,7 +8187,7 @@ require = function () {
8190
8187
  const def = defs[i];
8191
8188
  if (def.parentNode !== target)
8192
8189
  continue;
8193
- const {tagName, classList} = def;
8190
+ const {tagName} = def;
8194
8191
  if (bases.length === 1 && tagName[0] === 'H')
8195
8192
  continue;
8196
8193
  const label = tagName === 'FIGURE' ? def.getAttribute('data-label') : `$-${ increment(index, def) }`;
@@ -8198,7 +8195,7 @@ require = function () {
8198
8195
  continue;
8199
8196
  if (label.endsWith('-0')) {
8200
8197
  (0, typed_dom_1.define)(def, {
8201
- class: void classList.add('invalid'),
8198
+ class: void def.classList.add('invalid'),
8202
8199
  'data-invalid-syntax': 'figure',
8203
8200
  'data-invalid-type': 'argument',
8204
8201
  'data-invalid-message': 'Invalid base index',
@@ -8209,7 +8206,7 @@ require = function () {
8209
8206
  if (tagName === 'FIGURE' && label.endsWith('.0')) {
8210
8207
  if (label.lastIndexOf('.', label.length - 3) !== -1) {
8211
8208
  (0, typed_dom_1.define)(def, {
8212
- class: void classList.add('invalid'),
8209
+ class: void def.classList.add('invalid'),
8213
8210
  'data-invalid-syntax': 'figure',
8214
8211
  'data-invalid-type': 'argument',
8215
8212
  'data-invalid-message': 'Base index must be $-x.0 format',
@@ -8219,16 +8216,16 @@ require = function () {
8219
8216
  }
8220
8217
  if (!/^H[1-6]$/.test((_d = (_c = def.previousElementSibling) === null || _c === void 0 ? void 0 : _c.tagName) !== null && _d !== void 0 ? _d : '')) {
8221
8218
  (0, typed_dom_1.define)(def, {
8222
- class: void classList.add('invalid'),
8219
+ class: void def.classList.add('invalid'),
8223
8220
  'data-invalid-syntax': 'figure',
8224
8221
  'data-invalid-type': 'position',
8225
8222
  'data-invalid-message': 'Base index declarations must be after level 1 to 6 headings',
8226
8223
  hidden: null
8227
8224
  });
8228
8225
  continue;
8229
- } else {
8230
- classList.contains('invalid') && (0, typed_dom_1.define)(def, {
8231
- class: void classList.remove('invalid'),
8226
+ } else if (def.getAttribute('data-invalid-message') === 'Base index declarations must be after level 1 to 6 headings') {
8227
+ (0, typed_dom_1.define)(def, {
8228
+ class: void def.classList.remove('invalid'),
8232
8229
  'data-invalid-syntax': null,
8233
8230
  'data-invalid-type': null,
8234
8231
  'data-invalid-message': null,
@@ -8253,39 +8250,47 @@ require = function () {
8253
8250
  continue;
8254
8251
  }
8255
8252
  !(0, label_1.isFixed)(label) && numbers.set(group, number);
8256
- opts.id !== '' && def.setAttribute('id', `label:${ opts.id ? `${ opts.id }:` : '' }${ label }`);
8257
8253
  const figindex = group === '$' ? `(${ number })` : `${ capitalize(group) }${ group === 'fig' ? '.' : '' } ${ number }`;
8258
8254
  (0, typed_dom_1.define)(def.querySelector(':scope > figcaption > .figindex'), group === '$' ? figindex : `${ figindex }. `);
8259
8255
  if (labels.has(label)) {
8260
- if (classList.contains('invalid') && def.getAttribute('data-invalid-message') !== 'Duplicate label')
8256
+ if (def.classList.contains('invalid'))
8261
8257
  continue;
8262
8258
  (0, typed_dom_1.define)(def, {
8263
8259
  id: null,
8264
- class: void classList.add('invalid'),
8260
+ class: void def.classList.add('invalid'),
8265
8261
  'data-invalid-syntax': 'figure',
8266
8262
  'data-invalid-type': 'argument',
8267
8263
  'data-invalid-message': 'Duplicate label'
8268
8264
  });
8269
8265
  continue;
8270
- } else {
8271
- labels.add(label);
8266
+ } else if (def.getAttribute('data-invalid-message') === 'Duplicate label') {
8272
8267
  (0, typed_dom_1.define)(def, {
8273
- class: void classList.remove('invalid'),
8268
+ class: void def.classList.remove('invalid'),
8274
8269
  'data-invalid-syntax': null,
8275
8270
  'data-invalid-type': null,
8276
8271
  'data-invalid-message': null
8277
8272
  });
8278
8273
  }
8274
+ labels.add(label);
8275
+ opts.id !== '' && def.setAttribute('id', `label:${ opts.id ? `${ opts.id }:` : '' }${ label }`);
8279
8276
  for (const ref of refs.take(label, global_1.Infinity)) {
8277
+ if (ref.getAttribute('data-invalid-message') === 'Missing the target figure') {
8278
+ (0, typed_dom_1.define)(ref, {
8279
+ class: void ref.classList.remove('invalid'),
8280
+ 'data-invalid-syntax': null,
8281
+ 'data-invalid-type': null,
8282
+ 'data-invalid-message': null
8283
+ });
8284
+ }
8280
8285
  if (ref.hash.slice(1) === def.id && ref.innerText === figindex)
8281
8286
  continue;
8282
8287
  yield (0, typed_dom_1.define)(ref, opts.id !== '' ? { href: `#${ def.id }` } : { class: `${ ref.className } disabled` }, figindex);
8283
8288
  }
8284
8289
  }
8285
8290
  for (const [, ref] of refs) {
8286
- if (opts.id !== '') {
8291
+ if (opts.id !== '' && !ref.classList.contains('invalid')) {
8287
8292
  (0, typed_dom_1.define)(ref, {
8288
- class: `${ ref.className } disabled invalid`,
8293
+ class: void ref.classList.add('invalid'),
8289
8294
  'data-invalid-syntax': 'label',
8290
8295
  'data-invalid-type': 'reference',
8291
8296
  'data-invalid-message': 'Missing the target figure'
@@ -8477,14 +8482,14 @@ require = function () {
8477
8482
  ]);
8478
8483
  function* segment(source) {
8479
8484
  if (!validate(source, exports.MAX_INPUT_SIZE))
8480
- return yield `\0Too large input over ${ exports.MAX_INPUT_SIZE.toLocaleString('en') } bytes.\n${ source.slice(0, 1001) }`;
8485
+ return yield `\x07Too large input over ${ exports.MAX_INPUT_SIZE.toLocaleString('en') } bytes.\n${ source.slice(0, 1001) }`;
8481
8486
  while (source !== '') {
8482
8487
  const result = parser(source, {});
8483
8488
  const rest = (0, parser_1.exec)(result);
8484
8489
  const segs = (0, parser_1.eval)(result).length ? (0, parser_1.eval)(result) : [source.slice(0, source.length - rest.length)];
8485
8490
  for (let i = 0; i < segs.length; ++i) {
8486
8491
  const seg = segs[i];
8487
- validate(seg, exports.MAX_SEGMENT_SIZE) ? yield seg : yield `\0Too large segment over ${ exports.MAX_SEGMENT_SIZE.toLocaleString('en') } bytes.\n${ seg }`;
8492
+ validate(seg, exports.MAX_SEGMENT_SIZE) ? yield seg : yield `\x07Too large segment over ${ exports.MAX_SEGMENT_SIZE.toLocaleString('en') } bytes.\n${ seg }`;
8488
8493
  }
8489
8494
  source = rest;
8490
8495
  }
@@ -8510,7 +8515,7 @@ require = function () {
8510
8515
  function (_dereq_, module, exports) {
8511
8516
  'use strict';
8512
8517
  Object.defineProperty(exports, '__esModule', { value: true });
8513
- exports.anyline = exports.emptyline = exports.contentline = exports.str = exports.unescsource = exports.escsource = exports.linebreak = exports.txt = exports.text = void 0;
8518
+ exports.anyline = exports.emptyline = exports.contentline = exports.stropt = exports.str = exports.unescsource = exports.escsource = exports.linebreak = exports.txt = exports.text = void 0;
8514
8519
  var text_1 = _dereq_('./source/text');
8515
8520
  Object.defineProperty(exports, 'text', {
8516
8521
  enumerable: true,
@@ -8551,6 +8556,12 @@ require = function () {
8551
8556
  return str_1.str;
8552
8557
  }
8553
8558
  });
8559
+ Object.defineProperty(exports, 'stropt', {
8560
+ enumerable: true,
8561
+ get: function () {
8562
+ return str_1.stropt;
8563
+ }
8564
+ });
8554
8565
  var line_1 = _dereq_('./source/line');
8555
8566
  Object.defineProperty(exports, 'contentline', {
8556
8567
  enumerable: true,
@@ -8659,10 +8670,10 @@ require = function () {
8659
8670
  function (_dereq_, module, exports) {
8660
8671
  'use strict';
8661
8672
  Object.defineProperty(exports, '__esModule', { value: true });
8662
- exports.str = void 0;
8673
+ exports.stropt = exports.str = void 0;
8663
8674
  const global_1 = _dereq_('spica/global');
8664
8675
  const combinator_1 = _dereq_('../../combinator');
8665
- function str(pattern, mustConsume = true) {
8676
+ function str(pattern) {
8666
8677
  return typeof pattern === 'string' ? (0, combinator_1.creator)(source => {
8667
8678
  if (source === '')
8668
8679
  return;
@@ -8674,14 +8685,38 @@ require = function () {
8674
8685
  if (source === '')
8675
8686
  return;
8676
8687
  const m = source.match(pattern);
8677
- return m && (!mustConsume || m[0].length > 0) ? [
8688
+ return m && m[0].length > 0 ? [
8678
8689
  [m[0]],
8679
8690
  source.slice(m[0].length)
8680
8691
  ] : global_1.undefined;
8681
8692
  });
8682
8693
  }
8683
8694
  exports.str = str;
8684
- ;
8695
+ function stropt(pattern) {
8696
+ return typeof pattern === 'string' ? (0, combinator_1.creator)(source => {
8697
+ if (source === '')
8698
+ return;
8699
+ return source.slice(0, pattern.length) === pattern ? [
8700
+ [pattern],
8701
+ source.slice(pattern.length)
8702
+ ] : [
8703
+ [],
8704
+ source
8705
+ ];
8706
+ }) : (0, combinator_1.creator)(source => {
8707
+ if (source === '')
8708
+ return;
8709
+ const m = source.match(pattern);
8710
+ return m ? [
8711
+ [m[0]],
8712
+ source.slice(m[0].length)
8713
+ ] : [
8714
+ [],
8715
+ source
8716
+ ];
8717
+ });
8718
+ }
8719
+ exports.stropt = stropt;
8685
8720
  },
8686
8721
  {
8687
8722
  '../../combinator': 27,
@@ -8898,7 +8933,7 @@ require = function () {
8898
8933
  exports.startLoose = startLoose;
8899
8934
  exports.isStartLoose = (0, memoize_1.reduce)((source, context, except) => {
8900
8935
  return isStartTight(source.replace(/^[^\S\n]+/, ''), context, except);
8901
- }, (source, _, except = '') => `${ source }\0${ except }`);
8936
+ }, (source, _, except = '') => `${ source }\x1E${ except }`);
8902
8937
  function startTight(parser, except) {
8903
8938
  return (source, context) => isStartTight(source, context, except) ? parser(source, context) : global_1.undefined;
8904
8939
  }
@@ -8932,7 +8967,7 @@ require = function () {
8932
8967
  default:
8933
8968
  return source[0].trimStart() !== '';
8934
8969
  }
8935
- }, (source, _, except = '') => `${ source }\0${ except }`);
8970
+ }, (source, _, except = '') => `${ source }\x1E${ except }`);
8936
8971
  function isStartTightNodes(nodes) {
8937
8972
  if (nodes.length === 0)
8938
8973
  return true;
package/markdown.d.ts CHANGED
@@ -388,7 +388,7 @@ export namespace MarkdownParser {
388
388
  export interface SegmentParser extends
389
389
  Block<'extension/figure/segment'>,
390
390
  Parser<never, Context, [
391
- InlineParser.ExtensionParser.LabelParser.SegmentParser,
391
+ SourceParser.ContentLineParser,
392
392
  Parser<never, Context, [
393
393
  Parser<never, Context, [
394
394
  CodeBlockParser.SegmentParser,
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.237.2",
3
+ "version": "0.238.0",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -1923,9 +1923,9 @@
1923
1923
  "dev": true
1924
1924
  },
1925
1925
  "caniuse-lite": {
1926
- "version": "1.0.30001324",
1927
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001324.tgz",
1928
- "integrity": "sha512-/eYp1J6zYh1alySQB4uzYFkLmxxI8tk0kxldbNHXp8+v+rdMKdUBNjRLz7T7fz6Iox+1lIdYpc7rq6ZcXfTukg==",
1926
+ "version": "1.0.30001325",
1927
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001325.tgz",
1928
+ "integrity": "sha512-sB1bZHjseSjDtijV1Hb7PB2Zd58Kyx+n/9EotvZ4Qcz2K3d0lWB8dB4nb8wN/TsOGFq3UuAm0zQZNQ4SoR7TrQ==",
1929
1929
  "dev": true
1930
1930
  },
1931
1931
  "chalk": {
@@ -4915,9 +4915,9 @@
4915
4915
  }
4916
4916
  },
4917
4917
  "graceful-fs": {
4918
- "version": "4.2.9",
4919
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
4920
- "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
4918
+ "version": "4.2.10",
4919
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
4920
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
4921
4921
  "dev": true
4922
4922
  },
4923
4923
  "growl": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.237.2",
3
+ "version": "0.238.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",
package/src/debug.test.ts CHANGED
@@ -19,7 +19,7 @@ export function inspect(result: Result<HTMLElement | string>, until: number | st
19
19
  ? until
20
20
  : ~(~node.outerHTML.indexOf(until) || -Infinity) + until.length;
21
21
  const el = html('div');
22
- assert(!node.outerHTML.match(/[\0\x7F]/));
22
+ assert(!node.outerHTML.match(/[\x00-\x08\x0B-\x1F\x7F]/));
23
23
  el.innerHTML = node.outerHTML.slice(0, until);
24
24
  if (node.outerHTML.length <= until) {
25
25
  assert(node.outerHTML === el.innerHTML);
@@ -14,7 +14,7 @@ describe('Unit: parser/block/extension/fig', () => {
14
14
  assert.deepStrictEqual(inspect(parser('[$group-name]\n !https://host')), undefined);
15
15
  assert.deepStrictEqual(inspect(parser('[$group-name]\n\n!https://host')), undefined);
16
16
  assert.deepStrictEqual(inspect(parser('[$group-name]a\nhttps://host')), undefined);
17
- assert.deepStrictEqual(inspect(parser('[$group-name]a\n!https://host')), [['<figure data-type="media" data-label="group-name" data-group="group" class="invalid"><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div><figcaption><span class="figindex"></span></figcaption></figure>'], '']);
17
+ assert.deepStrictEqual(inspect(parser('[$group-name]a\n!https://host')), undefined);
18
18
  assert.deepStrictEqual(inspect(parser('[$group-name] a\nhttps://host')), undefined);
19
19
  assert.deepStrictEqual(inspect(parser('[$group-name] a\n!https://host')), [['<figure data-type="media" data-label="group-name" data-group="group" class="invalid"><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div><figcaption><span class="figindex"></span></figcaption></figure>'], '']);
20
20
  assert.deepStrictEqual(inspect(parser('$-a\n$-b')), undefined);
@@ -13,7 +13,7 @@ import FigParser = ExtensionParser.FigParser;
13
13
 
14
14
  export const segment: FigParser.SegmentParser = block(validate(['[$', '$'],
15
15
  sequence([
16
- line(close(seg_label, /^.*\n/)),
16
+ line(close(seg_label, /^(?=\s).*\n/)),
17
17
  union([
18
18
  seg_code,
19
19
  seg_math,
@@ -24,6 +24,8 @@ describe('Unit: parser/block/extension/figure', () => {
24
24
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]a\n!https://host\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group" class="invalid"><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div><figcaption><span class="figindex"></span></figcaption></figure>'], '']);
25
25
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name] a\nhttps://host\n~~~')), undefined);
26
26
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name] a\n!https://host\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group" class="invalid"><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div><figcaption><span class="figindex"></span></figcaption></figure>'], '']);
27
+ assert.deepStrictEqual(inspect(parser('~~~figure a[$group-name]\n!https://host\n~~~')), undefined);
28
+ assert.deepStrictEqual(inspect(parser('~~~figure a [$group-name]\n!https://host\n~~~')), undefined);
27
29
  assert.deepStrictEqual(inspect(parser('~~~ [$group-name]\n!https://host\n~~~')), undefined);
28
30
  assert.deepStrictEqual(inspect(parser('~~~ $group-name\n!https://host\n~~~')), undefined);
29
31
  assert.deepStrictEqual(inspect(parser(' ~~~figure [$group-name]\n!https://host\n~~~')), undefined);
@@ -2,7 +2,7 @@ import { undefined } from 'spica/global';
2
2
  import { ExtensionParser } from '../../block';
3
3
  import { union, inits, sequence, some, block, line, rewrite, context, close, match, convert, trim, fmap } from '../../../combinator';
4
4
  import { str, contentline, emptyline } from '../../source';
5
- import { label, segment as seg_label } from '../../inline/extension/label';
5
+ import { label } from '../../inline/extension/label';
6
6
  import { ulist } from '../ulist';
7
7
  import { olist } from '../olist';
8
8
  import { table as styled_table } from '../table';
@@ -27,7 +27,7 @@ export const segment: FigureParser.SegmentParser = block(match(
27
27
  ([, fence], closer = new RegExp(String.raw`^${fence}[^\S\n]*(?:$|\n)`)) =>
28
28
  close(
29
29
  sequence([
30
- line(close(seg_label, /^.*\n/)),
30
+ contentline,
31
31
  inits([
32
32
  // All parsers which can include closing terms.
33
33
  union([
@@ -85,10 +85,6 @@ export const figure: FigureParser = block(rewrite(segment, fmap(
85
85
 
86
86
  function attributes(label: string, param: string, content: HTMLElement, caption: readonly HTMLElement[]): Record<string, string | undefined> {
87
87
  const group = label.split('-', 1)[0];
88
- const invalidLabel = /^[^-]+-(?:[0-9]+\.)*0$/.test(label);
89
- const invalidParam = param.trimStart() !== '';
90
- const invalidContent = group === '$' && (!content.classList.contains('math') || caption.length > 0);
91
- const invalid = invalidLabel || invalidParam || invalidContent || undefined;
92
88
  let type: string = content.className.split(/\s/)[0];
93
89
  switch (type || content.tagName) {
94
90
  case 'UL':
@@ -113,27 +109,28 @@ function attributes(label: string, param: string, content: HTMLElement, caption:
113
109
  default:
114
110
  assert(false);
115
111
  }
112
+ const invalid =
113
+ /^[^-]+-(?:[0-9]+\.)*0$/.test(label) && {
114
+ 'data-invalid-type': 'label',
115
+ 'data-invalid-message': 'The last part of the fixed label numbers must not be 0',
116
+ } ||
117
+ param.trimStart() !== '' && {
118
+ 'data-invalid-type': 'argument',
119
+ 'data-invalid-message': 'Invalid argument',
120
+ } ||
121
+ group === '$' && (!content.classList.contains('math') || caption.length > 0) && {
122
+ 'data-invalid-type': 'content',
123
+ 'data-invalid-message': 'A figure labeled to define a formula number can contain only a math formula and no caption',
124
+ } ||
125
+ undefined;
116
126
  return {
117
127
  'data-type': type,
118
128
  'data-label': label,
119
129
  'data-group': group,
120
- class: invalid && 'invalid',
121
- ...
122
- invalidLabel && {
123
- 'data-invalid-syntax': 'figure',
124
- 'data-invalid-type': 'label',
125
- 'data-invalid-message': 'The last part of the fixed label numbers must not be 0',
126
- } ||
127
- invalidParam && {
128
- 'data-invalid-syntax': 'figure',
129
- 'data-invalid-type': 'argument',
130
- 'data-invalid-message': 'Invalid argument',
131
- } ||
132
- invalidContent && {
133
- 'data-invalid-syntax': 'figure',
134
- 'data-invalid-type': 'content',
135
- 'data-invalid-message': 'A figure labeled to define a formula number can contain only a math formula and no caption',
136
- } ||
137
- undefined,
130
+ ...invalid && {
131
+ class: 'invalid',
132
+ 'data-invalid-syntax': 'figure',
133
+ ...invalid,
134
+ },
138
135
  };
139
136
  }
@@ -54,7 +54,7 @@ export const block: BlockParser = creator(error(
54
54
 
55
55
  function error(parser: BlockParser): BlockParser {
56
56
  return recover<BlockParser>(fallback(
57
- open('\0', source => { throw new Error(source.split('\n', 1)[0]); }),
57
+ open('\x07', source => { throw new Error(source.split('\n', 1)[0]); }),
58
58
  parser),
59
59
  (source, { id }, reason) => [[
60
60
  html('h1',
@@ -71,7 +71,7 @@ function error(parser: BlockParser): BlockParser {
71
71
  translate: 'no',
72
72
  },
73
73
  source
74
- .replace(/^\0.*\n/, '')
74
+ .replace(/^\x07.*\n/, '')
75
75
  .slice(0, 1001)
76
76
  .replace(/^(.{997}).{4}$/s, '$1...') || undefined),
77
77
  ], '']);
@@ -42,6 +42,7 @@ describe('Unit: parser/inline/extension/index', () => {
42
42
  assert.deepStrictEqual(inspect(parser('[#a ]')), [['<a class="index" href="#index:a">a</a>'], '']);
43
43
  assert.deepStrictEqual(inspect(parser('[#a b]')), [['<a class="index" href="#index:a_b">a b</a>'], '']);
44
44
  assert.deepStrictEqual(inspect(parser('[#a b]')), [['<a class="index" href="#index:a_b">a b</a>'], '']);
45
+ assert.deepStrictEqual(inspect(parser('[#a \\ ]')), [['<a class="index" href="#index:a">a</a>'], '']);
45
46
  assert.deepStrictEqual(inspect(parser('[#a &nbsp;]')), [['<a class="index" href="#index:a">a</a>'], '']);
46
47
  assert.deepStrictEqual(inspect(parser('[#a <wbr>]')), [['<a class="index" href="#index:a">a</a>'], '']);
47
48
  assert.deepStrictEqual(inspect(parser('[#a [# b #]]')), [['<a class="index" href="#index:a">a <span class="comment"><input type="checkbox"><span>[# b #]</span></span></a>'], '']);
@@ -70,21 +71,26 @@ describe('Unit: parser/inline/extension/index', () => {
70
71
  assert.deepStrictEqual(inspect(parser('[#|]')), [['<a class="index" href="#index:|">|</a>'], '']);
71
72
  assert.deepStrictEqual(inspect(parser('[#|#]')), [['<a class="index" href="#index:|#">|#</a>'], '']);
72
73
  assert.deepStrictEqual(inspect(parser('[#|#b]')), [['<a class="index" href="#index:|#b">|#b</a>'], '']);
73
- assert.deepStrictEqual(inspect(parser('[#a|#b]')), [['<a class="index" href="#index:a|#b">a|#b</a>'], '']);
74
- assert.deepStrictEqual(inspect(parser('[#a |]')), [['<a class="index" href="#index:a_|">a |</a>'], '']);
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>'], '']);
74
+ assert.deepStrictEqual(inspect(parser('[#a|]')), [['<a class="index" href="#index:a|">a|</a>'], '']);
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>'], '']);
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>'], '']);
78
87
  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>'], '']);
87
88
  assert.deepStrictEqual(inspect(parser('[#a |#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
89
+ assert.deepStrictEqual(inspect(parser('[#a \\ |#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
90
+ assert.deepStrictEqual(inspect(parser('[#a &nbsp;|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
91
+ assert.deepStrictEqual(inspect(parser('[#a <wbr>|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
92
+ assert.deepStrictEqual(inspect(parser('[#a [# b #]|#c]')), [['<a class="index" href="#index:c">a <span class="comment"><input type="checkbox"><span>[# b #]</span></span><span class="indexer" data-index="c"></span></a>'], '']);
93
+ assert.deepStrictEqual(inspect(parser('[#a\\ |#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
88
94
  });
89
95
 
90
96
  });
@@ -3,7 +3,7 @@ import { ExtensionParser } from '../../inline';
3
3
  import { union, some, validate, guard, context, creator, surround, open, lazy, fmap } from '../../../combinator';
4
4
  import { inline } from '../../inline';
5
5
  import { indexee, identity } from './indexee';
6
- import { txt, str } from '../../source';
6
+ import { txt, str, stropt } from '../../source';
7
7
  import { startTight, trimNodeEnd } from '../../util';
8
8
  import { html, define, defrag } from 'typed-dom';
9
9
  import { join } from 'spica/array';
@@ -23,10 +23,11 @@ export const index: IndexParser = lazy(() => creator(validate('[#', ']', '\n', f
23
23
  media: false,
24
24
  autolink: false,
25
25
  }}},
26
+ open(stropt('|'),
26
27
  some(union([
27
28
  signature,
28
29
  inline,
29
- ]), ']', /^\\?\n/)))),
30
+ ]), ']', /^\\?\n/), true)))),
30
31
  ']'),
31
32
  ns => [html('a', trimNodeEnd(defrag(ns)))])),
32
33
  ([el]: [HTMLAnchorElement]) => [
@@ -40,7 +41,7 @@ export const index: IndexParser = lazy(() => creator(validate('[#', ']', '\n', f
40
41
  ]))));
41
42
 
42
43
  const signature: IndexParser.SignatureParser = lazy(() => creator(fmap(open(
43
- /^\s+\|#/,
44
+ '|#',
44
45
  startTight(some(union([bracket, txt]), ']'))),
45
46
  ns => [
46
47
  html('span', { class: 'indexer', 'data-index': identity(join(ns)).slice(6) }),
@@ -6,12 +6,12 @@ import { reduce } from 'spica/memoize';
6
6
 
7
7
  export const unsafehtmlentity: UnsafeHTMLEntityParser = creator(validate('&', focus(
8
8
  /^&[0-9A-Za-z]+;/,
9
- entity => [[parse(entity) ?? `\0${entity}`], ''])));
9
+ entity => [[parse(entity) ?? `\x1B${entity}`], ''])));
10
10
 
11
11
  export const htmlentity: HTMLEntityParser = fmap(
12
12
  union([unsafehtmlentity]),
13
13
  ([test]) => [
14
- test[0] === '\0'
14
+ test[0] === '\x1B'
15
15
  ? html('span', {
16
16
  class: 'invalid',
17
17
  'data-invalid-syntax': 'htmlentity',
@@ -95,13 +95,13 @@ function sanitize(target: HTMLElement, uri: ReadonlyURL, alt: string): boolean {
95
95
  });
96
96
  return false;
97
97
  }
98
- if (alt.includes('\0')) {
98
+ if (alt.includes('\x1B')) {
99
99
  define(target, {
100
100
  class: void target.classList.add('invalid'),
101
101
  'data-invalid-syntax': 'media',
102
102
  'data-invalid-type': 'content',
103
103
  'data-invalid-message': `Cannot use invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)![0]}"`,
104
- alt: target.getAttribute('alt')?.replace(/\0/g, ''),
104
+ alt: target.getAttribute('alt')?.replace(/\x1B/g, ''),
105
105
  });
106
106
  return false;
107
107
  }
@@ -83,8 +83,8 @@ function attributes(texts: string[], rubies: string[]): Record<string, string> {
83
83
  let attrs: Record<string, string> | undefined;
84
84
  for (const ss of [texts, rubies]) {
85
85
  for (let i = 0; i < ss.length; ++i) {
86
- if (ss[i].indexOf('\0') === -1) continue;
87
- ss[i] = ss[i].replace(/\0/g, '');
86
+ if (ss[i].indexOf('\x1B') === -1) continue;
87
+ ss[i] = ss[i].replace(/\x1B/g, '');
88
88
  attrs ??= {
89
89
  class: 'invalid',
90
90
  'data-invalid-syntax': 'ruby',
@@ -21,6 +21,7 @@ describe('Unit: parser/processor/figure', () => {
21
21
  const target = parse([
22
22
  '$fig-a\n> ',
23
23
  '$fig-a',
24
+ '$fig-b',
24
25
  '$fig-a',
25
26
  ].join('\n\n'));
26
27
  for (let i = 0; i < 3; ++i) {
@@ -30,6 +31,7 @@ describe('Unit: parser/processor/figure', () => {
30
31
  [
31
32
  '<figure data-type="quote" data-label="fig-a" data-group="fig" data-number="1" id="label:fig-a"><div><blockquote></blockquote></div><figcaption><span class="figindex">Fig. 1. </span></figcaption></figure>',
32
33
  '<p><a class="label" data-label="fig-a" href="#label:fig-a">Fig. 1</a></p>',
34
+ '<p><a class="label invalid" data-label="fig-b" data-invalid-syntax="label" data-invalid-type="reference" data-invalid-message="Missing the target figure">$fig-b</a></p>',
33
35
  '<p><a class="label" data-label="fig-a" href="#label:fig-a">Fig. 1</a></p>',
34
36
  ]);
35
37
  }
@@ -98,7 +100,7 @@ describe('Unit: parser/processor/figure', () => {
98
100
  '<figure data-type="quote" data-label="fig-a" data-group="fig" data-number="1" id="label:fig-a"><div><blockquote></blockquote></div><figcaption><span class="figindex">Fig. 1. </span></figcaption></figure>',
99
101
  '<p><a class="label" data-label="fig-2" href="#label:fig-2">Fig. 2</a></p>',
100
102
  '<p><a class="label" data-label="$-4.1.1" href="#label:$-4.1.1">(4.1.1)</a></p>',
101
- '<p><a class="label disabled invalid" data-label="fig-1" data-invalid-syntax="label" data-invalid-type="reference" data-invalid-message="Missing the target figure">$fig-1</a></p>',
103
+ '<p><a class="label invalid" data-label="fig-1" data-invalid-syntax="label" data-invalid-type="reference" data-invalid-message="Missing the target figure">$fig-1</a></p>',
102
104
  ]);
103
105
  }
104
106
  });
@@ -29,7 +29,7 @@ export function* figure(
29
29
  yield;
30
30
  const def = defs[i];
31
31
  if (def.parentNode !== target) continue;
32
- const { tagName, classList } = def;
32
+ const { tagName } = def;
33
33
  if (bases.length === 1 && tagName[0] === 'H') continue;
34
34
  assert(base === '0' || bases.length > 1);
35
35
  const label = tagName === 'FIGURE'
@@ -38,7 +38,7 @@ export function* figure(
38
38
  if (label.endsWith('-')) continue;
39
39
  if (label.endsWith('-0')) {
40
40
  define(def, {
41
- class: void classList.add('invalid'),
41
+ class: void def.classList.add('invalid'),
42
42
  'data-invalid-syntax': 'figure',
43
43
  'data-invalid-type': 'argument',
44
44
  'data-invalid-message': 'Invalid base index',
@@ -50,7 +50,7 @@ export function* figure(
50
50
  // $-x.x.0 is disabled.
51
51
  if (label.lastIndexOf('.', label.length - 3) !== -1) {
52
52
  define(def, {
53
- class: void classList.add('invalid'),
53
+ class: void def.classList.add('invalid'),
54
54
  'data-invalid-syntax': 'figure',
55
55
  'data-invalid-type': 'argument',
56
56
  'data-invalid-message': 'Base index must be $-x.0 format',
@@ -61,7 +61,7 @@ export function* figure(
61
61
  // $-x.0 after h1-h6.
62
62
  if (!/^H[1-6]$/.test(def.previousElementSibling?.tagName ?? '')) {
63
63
  define(def, {
64
- class: void classList.add('invalid'),
64
+ class: void def.classList.add('invalid'),
65
65
  'data-invalid-syntax': 'figure',
66
66
  'data-invalid-type': 'position',
67
67
  'data-invalid-message': 'Base index declarations must be after level 1 to 6 headings',
@@ -69,9 +69,9 @@ export function* figure(
69
69
  });
70
70
  continue;
71
71
  }
72
- else {
73
- classList.contains('invalid') && define(def, {
74
- class: void classList.remove('invalid'),
72
+ else if (def.getAttribute('data-invalid-message') === 'Base index declarations must be after level 1 to 6 headings') {
73
+ define(def, {
74
+ class: void def.classList.remove('invalid'),
75
75
  'data-invalid-syntax': null,
76
76
  'data-invalid-type': null,
77
77
  'data-invalid-message': null,
@@ -118,7 +118,6 @@ export function* figure(
118
118
  assert(number.split('.').pop() !== '0');
119
119
  !isFixed(label) && numbers.set(group, number);
120
120
  assert(!+def.setAttribute('data-number', number));
121
- opts.id !== '' && def.setAttribute('id', `label:${opts.id ? `${opts.id}:` : ''}${label}`);
122
121
  const figindex = group === '$'
123
122
  ? `(${number})`
124
123
  : `${capitalize(group)}${group === 'fig' ? '.' : ''} ${number}`;
@@ -126,27 +125,35 @@ export function* figure(
126
125
  def.querySelector(':scope > figcaption > .figindex')!,
127
126
  group === '$' ? figindex : `${figindex}. `);
128
127
  if (labels.has(label)) {
129
- if (classList.contains('invalid') &&
130
- def.getAttribute('data-invalid-message') !== 'Duplicate label') continue;
128
+ if (def.classList.contains('invalid')) continue;
131
129
  define(def, {
132
130
  id: null,
133
- class: void classList.add('invalid'),
131
+ class: void def.classList.add('invalid'),
134
132
  'data-invalid-syntax': 'figure',
135
133
  'data-invalid-type': 'argument',
136
134
  'data-invalid-message': 'Duplicate label',
137
135
  });
138
136
  continue;
139
137
  }
140
- else {
141
- labels.add(label);
138
+ else if (def.getAttribute('data-invalid-message') === 'Duplicate label') {
142
139
  define(def, {
143
- class: void classList.remove('invalid'),
140
+ class: void def.classList.remove('invalid'),
144
141
  'data-invalid-syntax': null,
145
142
  'data-invalid-type': null,
146
143
  'data-invalid-message': null,
147
144
  });
148
145
  }
146
+ labels.add(label);
147
+ opts.id !== '' && def.setAttribute('id', `label:${opts.id ? `${opts.id}:` : ''}${label}`);
149
148
  for (const ref of refs.take(label, Infinity)) {
149
+ if (ref.getAttribute('data-invalid-message') === 'Missing the target figure') {
150
+ define(ref, {
151
+ class: void ref.classList.remove('invalid'),
152
+ 'data-invalid-syntax': null,
153
+ 'data-invalid-type': null,
154
+ 'data-invalid-message': null,
155
+ });
156
+ }
150
157
  if (ref.hash.slice(1) === def.id && ref.innerText === figindex) continue;
151
158
  yield define(ref,
152
159
  opts.id !== '' ? { href: `#${def.id}` } : { class: `${ref.className} disabled` },
@@ -154,9 +161,9 @@ export function* figure(
154
161
  }
155
162
  }
156
163
  for (const [, ref] of refs) {
157
- if (opts.id !== '') {
164
+ if (opts.id !== '' && !ref.classList.contains('invalid')) {
158
165
  define(ref, {
159
- class: `${ref.className} disabled invalid`,
166
+ class: void ref.classList.add('invalid'),
160
167
  'data-invalid-syntax': 'label',
161
168
  'data-invalid-type': 'reference',
162
169
  'data-invalid-message': 'Missing the target figure',
@@ -4,12 +4,12 @@ describe('Unit: parser/segment', () => {
4
4
  describe('segment', () => {
5
5
  it('huge input', () => {
6
6
  const result = segment(`${'\n'.repeat(10 * 1000 ** 2)}`).next().value?.split('\n', 1)[0];
7
- assert(result?.startsWith('\0Too large input'));
7
+ assert(result?.startsWith('\x07Too large input'));
8
8
  });
9
9
 
10
10
  it('huge segment', () => {
11
11
  const result = segment(`${'\n'.repeat(1000 ** 2 - 1)}`).next().value?.split('\n', 1)[0];
12
- assert(result?.startsWith('\0Too large segment'));
12
+ assert(result?.startsWith('\x07Too large segment'));
13
13
  });
14
14
 
15
15
  it('basic', () => {
@@ -23,7 +23,7 @@ const parser: SegmentParser = union([
23
23
  ]);
24
24
 
25
25
  export function* segment(source: string): Generator<string, undefined, undefined> {
26
- if (!validate(source, MAX_INPUT_SIZE)) return yield `\0Too large input over ${MAX_INPUT_SIZE.toLocaleString('en')} bytes.\n${source.slice(0, 1001)}`;
26
+ if (!validate(source, MAX_INPUT_SIZE)) return yield `\x07Too large input over ${MAX_INPUT_SIZE.toLocaleString('en')} bytes.\n${source.slice(0, 1001)}`;
27
27
  assert(source.length < Number.MAX_SAFE_INTEGER);
28
28
  while (source !== '') {
29
29
  const result = parser(source, {})!;
@@ -36,7 +36,7 @@ export function* segment(source: string): Generator<string, undefined, undefined
36
36
  const seg = segs[i];
37
37
  validate(seg, MAX_SEGMENT_SIZE)
38
38
  ? yield seg
39
- : yield `\0Too large segment over ${MAX_SEGMENT_SIZE.toLocaleString('en')} bytes.\n${seg}`
39
+ : yield `\x07Too large segment over ${MAX_SEGMENT_SIZE.toLocaleString('en')} bytes.\n${seg}`
40
40
  }
41
41
  source = rest;
42
42
  }
@@ -3,8 +3,8 @@ import { StrParser } from '../source';
3
3
  import { Parser, Context } from '../../combinator/data/parser';
4
4
  import { creator } from '../../combinator';
5
5
 
6
- export function str(pattern: string | RegExp, mustConsume?: boolean): StrParser;
7
- export function str(pattern: string | RegExp, mustConsume = true): Parser<string, Context<StrParser>, []> {
6
+ export function str(pattern: string | RegExp): StrParser;
7
+ export function str(pattern: string | RegExp): Parser<string, Context<StrParser>, []> {
8
8
  assert(pattern);
9
9
  return typeof pattern === 'string'
10
10
  ? creator(source => {
@@ -16,8 +16,27 @@ export function str(pattern: string | RegExp, mustConsume = true): Parser<string
16
16
  : creator(source => {
17
17
  if (source === '') return;
18
18
  const m = source.match(pattern);
19
- return m && (!mustConsume || m[0].length > 0)
19
+ return m && m[0].length > 0
20
20
  ? [[m[0]], source.slice(m[0].length)]
21
21
  : undefined;
22
22
  });
23
- };
23
+ }
24
+
25
+ export function stropt(pattern: string | RegExp): StrParser;
26
+ export function stropt(pattern: string | RegExp): Parser<string, Context<StrParser>, []> {
27
+ assert(pattern);
28
+ return typeof pattern === 'string'
29
+ ? creator(source => {
30
+ if (source === '') return;
31
+ return source.slice(0, pattern.length) === pattern
32
+ ? [[pattern], source.slice(pattern.length)]
33
+ : [[], source];
34
+ })
35
+ : creator(source => {
36
+ if (source === '') return;
37
+ const m = source.match(pattern);
38
+ return m
39
+ ? [[m[0]], source.slice(m[0].length)]
40
+ : [[], source];
41
+ });
42
+ }
@@ -24,6 +24,7 @@ export const text: TextParser = creator((source, context) => {
24
24
  case '。':
25
25
  case '!':
26
26
  case '?':
27
+ assert(source[0] !== '\x1B');
27
28
  return text(source.slice(1), context);
28
29
  }
29
30
  break;
@@ -39,8 +40,10 @@ export const text: TextParser = creator((source, context) => {
39
40
  case '\\':
40
41
  switch (source[1]) {
41
42
  case undefined:
43
+ assert(source[0] !== '\x1B');
42
44
  return [[], ''];
43
45
  case '\n':
46
+ assert(source[0] !== '\x1B');
44
47
  return [[html('span', { class: 'linebreak' }, ' ')], source.slice(2)];
45
48
  default:
46
49
  return [[source.slice(1, 2)], source.slice(2)];
@@ -14,5 +14,5 @@ export import AnyLineParser = SourceParser.AnyLineParser;
14
14
  export { text, txt, linebreak } from './source/text';
15
15
  export { escsource } from './source/escapable';
16
16
  export { unescsource } from './source/unescapable';
17
- export { str } from './source/str';
17
+ export { str, stropt } from './source/str';
18
18
  export { contentline, emptyline, anyline } from './source/line';
@@ -55,7 +55,7 @@ export function startLoose<T extends HTMLElement | string>(parser: Parser<T>, ex
55
55
  }
56
56
  export const isStartLoose = reduce((source: string, context: MarkdownParser.Context, except?: string): boolean => {
57
57
  return isStartTight(source.replace(/^[^\S\n]+/, ''), context, except);
58
- }, (source, _, except = '') => `${source}\0${except}`);
58
+ }, (source, _, except = '') => `${source}\x1E${except}`);
59
59
  export function startTight<P extends Parser<unknown>>(parser: P, except?: string): P;
60
60
  export function startTight<T>(parser: Parser<T>, except?: string): Parser<T> {
61
61
  return (source, context) =>
@@ -93,7 +93,7 @@ const isStartTight = reduce((source: string, context: MarkdownParser.Context, ex
93
93
  default:
94
94
  return source[0].trimStart() !== '';
95
95
  }
96
- }, (source, _, except = '') => `${source}\0${except}`);
96
+ }, (source, _, except = '') => `${source}\x1E${except}`);
97
97
  export function isStartTightNodes(nodes: readonly (HTMLElement | string)[]): boolean {
98
98
  if (nodes.length === 0) return true;
99
99
  return isVisible(nodes[0], 0);