securemark 0.243.2 → 0.244.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,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.244.0
4
+
5
+ - Change mathblock syntax to increase the maximum number of contained lines to 300.
6
+ - Fix fence parser.
7
+
3
8
  ## 0.243.2
4
9
 
5
10
  - Refactoring.
@@ -1,4 +1,4 @@
1
- /*! securemark v0.243.2 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED */
1
+ /*! securemark v0.244.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) {
@@ -2067,24 +2067,37 @@ require = function () {
2067
2067
  return;
2068
2068
  let block = '';
2069
2069
  let closer = '';
2070
- for (let count = 1, next = (0, line_1.firstline)(rest);; ++count) {
2070
+ let overflow = '';
2071
+ for (let count = 1;; ++count) {
2071
2072
  if (rest === '')
2072
2073
  break;
2073
- const line = next;
2074
- next = (0, line_1.firstline)(rest.slice(line.length));
2075
- if (count > limit + 1 && (0, line_1.isEmpty)(line))
2076
- break;
2077
- if (count <= limit + 1 && line.slice(0, delim.length) === delim && line.trimEnd() === delim && (!separation || (0, line_1.isEmpty)(next))) {
2078
- closer = delim;
2079
- rest = rest.slice(line.length);
2074
+ const line = (0, line_1.firstline)(rest);
2075
+ if ((closer || count > limit + 1) && (0, line_1.isEmpty)(line))
2080
2076
  break;
2077
+ if (closer) {
2078
+ overflow += line;
2079
+ }
2080
+ if (!closer && count <= limit + 1 && line.slice(0, delim.length) === delim && line.trimEnd() === delim) {
2081
+ closer = line;
2082
+ if ((0, line_1.isEmpty)((0, line_1.firstline)(rest.slice(line.length)))) {
2083
+ rest = rest.slice(line.length);
2084
+ break;
2085
+ }
2086
+ if (!separation) {
2087
+ rest = rest.slice(line.length);
2088
+ break;
2089
+ }
2090
+ overflow = line;
2091
+ }
2092
+ if (!overflow) {
2093
+ block += line;
2081
2094
  }
2082
- block += line;
2083
2095
  rest = rest.slice(line.length);
2084
2096
  }
2085
2097
  return [
2086
2098
  (0, array_1.unshift)([
2087
2099
  block,
2100
+ overflow,
2088
2101
  closer
2089
2102
  ], matches),
2090
2103
  rest
@@ -2457,6 +2470,7 @@ require = function () {
2457
2470
  'use strict';
2458
2471
  Object.defineProperty(exports, '__esModule', { value: true });
2459
2472
  exports.check = exports.exec = exports.eval = exports.Delimiters = void 0;
2473
+ const global_1 = _dereq_('spica/global');
2460
2474
  class Delimiters {
2461
2475
  constructor() {
2462
2476
  this.matchers = [];
@@ -2465,7 +2479,7 @@ require = function () {
2465
2479
  push(delimiter) {
2466
2480
  const {signature, matcher, escape} = delimiter;
2467
2481
  if (this.record[signature] === !escape) {
2468
- this.matchers.unshift(() => undefined);
2482
+ this.matchers.unshift(() => global_1.undefined);
2469
2483
  } else {
2470
2484
  this.matchers.unshift(matcher);
2471
2485
  this.record[signature] = !escape;
@@ -2501,7 +2515,7 @@ require = function () {
2501
2515
  }
2502
2516
  exports.check = check;
2503
2517
  },
2504
- {}
2518
+ { 'spica/global': 13 }
2505
2519
  ],
2506
2520
  46: [
2507
2521
  function (_dereq_, module, exports) {
@@ -3403,7 +3417,7 @@ require = function () {
3403
3417
  const language = /^[0-9a-z]+(?:-[a-z][0-9a-z]*)*$/i;
3404
3418
  exports.segment = (0, combinator_1.block)((0, combinator_1.validate)('```', (0, combinator_1.clear)((0, combinator_1.fence)(opener, 300))));
3405
3419
  exports.segment_ = (0, combinator_1.block)((0, combinator_1.validate)('```', (0, combinator_1.clear)((0, combinator_1.fence)(opener, 300, false))), false);
3406
- exports.codeblock = (0, combinator_1.block)((0, combinator_1.validate)('```', (0, combinator_1.fmap)((0, combinator_1.fence)(opener, 300), ([body, closer, opener, delim, param], _, context) => {
3420
+ exports.codeblock = (0, combinator_1.block)((0, combinator_1.validate)('```', (0, combinator_1.fmap)((0, combinator_1.fence)(opener, 300), ([body, overflow, closer, opener, delim, param], _, context) => {
3407
3421
  var _a, _b, _c, _d, _e, _f;
3408
3422
  const params = (_b = (_a = param.match(/(?:\\.?|\S)+/g)) === null || _a === void 0 ? void 0 : _a.reduce((params, value, i) => {
3409
3423
  var _a, _b, _c;
@@ -3423,17 +3437,17 @@ require = function () {
3423
3437
  params.lang = file && file.includes('.', 1) ? (_c = (_b = file.split('.').pop()) === null || _b === void 0 ? void 0 : _b.match(language)) === null || _c === void 0 ? void 0 : _c[0].toLowerCase() : params.lang;
3424
3438
  }
3425
3439
  }
3426
- name in params ? params.invalid = `Duplicate ${ name } value` : params[name] = value;
3440
+ name in params ? params.invalid = `Duplicate ${ name } attribute` : params[name] = value;
3427
3441
  return params;
3428
3442
  }, {})) !== null && _b !== void 0 ? _b : {};
3429
- if (!closer || params.invalid)
3443
+ if (!closer || overflow || params.invalid)
3430
3444
  return [(0, dom_1.html)('pre', {
3431
3445
  class: 'invalid',
3432
3446
  translate: 'no',
3433
3447
  'data-invalid-syntax': 'codeblock',
3434
- 'data-invalid-type': !closer ? 'fence' : 'argument',
3435
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : params.invalid
3436
- }, `${ opener }${ body }${ closer }`)];
3448
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
3449
+ 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : overflow ? `Invalid trailing line after the closing delimiter "${ delim }"` : params.invalid
3450
+ }, `${ opener }${ body }${ overflow || closer }`)];
3437
3451
  const el = (0, dom_1.html)('pre', {
3438
3452
  class: params.lang ? `code language-${ params.lang }` : 'text',
3439
3453
  translate: params.lang ? 'no' : global_1.undefined,
@@ -3554,16 +3568,16 @@ require = function () {
3554
3568
  const indexee_1 = _dereq_('../../inline/extension/indexee');
3555
3569
  const parse_1 = _dereq_('../../api/parse');
3556
3570
  const dom_1 = _dereq_('typed-dom/dom');
3557
- exports.aside = (0, combinator_1.creator)(100, (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.fmap)((0, combinator_1.fence)(/^(~{3,})aside(?!\S)([^\n]*)(?:$|\n)/, 300), ([body, closer, opener, delim, param], _, context) => {
3571
+ exports.aside = (0, combinator_1.creator)(100, (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.fmap)((0, combinator_1.fence)(/^(~{3,})aside(?!\S)([^\n]*)(?:$|\n)/, 300), ([body, overflow, closer, opener, delim, param], _, context) => {
3558
3572
  var _a;
3559
- if (!closer || param.trimStart())
3573
+ if (!closer || overflow || param.trimStart())
3560
3574
  return [(0, dom_1.html)('pre', {
3561
3575
  class: 'invalid',
3562
3576
  translate: 'no',
3563
3577
  'data-invalid-syntax': 'aside',
3564
- 'data-invalid-type': !closer ? 'fence' : 'argument',
3565
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : 'Invalid argument'
3566
- }, `${ opener }${ body }${ closer }`)];
3578
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
3579
+ 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : overflow ? `Invalid trailing line after the closing delimiter "${ delim }"` : 'Invalid argument'
3580
+ }, `${ opener }${ body }${ overflow || closer }`)];
3567
3581
  const annotations = (0, dom_1.html)('ol', { class: 'annotations' });
3568
3582
  const references = (0, dom_1.html)('ol', { class: 'references' });
3569
3583
  const document = (0, parse_1.parse)(body.slice(0, -1), {
@@ -3610,15 +3624,15 @@ require = function () {
3610
3624
  const mathblock_1 = _dereq_('../mathblock');
3611
3625
  const dom_1 = _dereq_('typed-dom/dom');
3612
3626
  const opener = /^(~{3,})(?:example\/(\S+))?(?!\S)([^\n]*)(?:$|\n)/;
3613
- exports.example = (0, combinator_1.creator)(100, (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.fmap)((0, combinator_1.fence)(opener, 300), ([body, closer, opener, delim, type = 'markdown', param], _, context) => {
3614
- if (!closer || param.trimStart())
3627
+ exports.example = (0, combinator_1.creator)(100, (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.fmap)((0, combinator_1.fence)(opener, 300), ([body, overflow, closer, opener, delim, type = 'markdown', param], _, context) => {
3628
+ if (!closer || overflow || param.trimStart())
3615
3629
  return [(0, dom_1.html)('pre', {
3616
3630
  class: 'invalid',
3617
3631
  translate: 'no',
3618
3632
  'data-invalid-syntax': 'example',
3619
- 'data-invalid-type': !closer ? 'fence' : 'argument',
3620
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : 'Invalid argument'
3621
- }, `${ opener }${ body }${ closer }`)];
3633
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
3634
+ 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : overflow ? `Invalid trailing line after the closing delimiter "${ delim }"` : 'Invalid argument'
3635
+ }, `${ opener }${ body }${ overflow || closer }`)];
3622
3636
  switch (type) {
3623
3637
  case 'markdown': {
3624
3638
  const annotations = (0, dom_1.html)('ol', { class: 'annotations' });
@@ -3657,6 +3671,7 @@ require = function () {
3657
3671
  class: 'invalid',
3658
3672
  translate: 'no',
3659
3673
  'data-invalid-syntax': 'example',
3674
+ 'data-invalid-type': 'type',
3660
3675
  'data-invalid-message': 'Invalid example type'
3661
3676
  }, `${ opener }${ body }${ closer }`)];
3662
3677
  }
@@ -3808,7 +3823,7 @@ require = function () {
3808
3823
  ])), ([label, param, content, ...caption]) => [(0, dom_1.html)('figure', attributes(label.getAttribute('data-label'), param, content, caption), [
3809
3824
  (0, dom_1.html)('figcaption', (0, array_1.unshift)([(0, dom_1.html)('span', { class: 'figindex' })], (0, dom_1.defrag)(caption))),
3810
3825
  (0, dom_1.html)('div', [content])
3811
- ])])), (0, combinator_1.fmap)((0, combinator_1.fence)(/^(~{3,})(?:figure|\[?\$\S*)(?!\S)[^\n]*(?:$|\n)/, 300), ([body, closer, opener, delim], _, context) => {
3826
+ ])])), (0, combinator_1.fmap)((0, combinator_1.fence)(/^(~{3,})(?:figure|\[?\$\S*)(?!\S)[^\n]*(?:$|\n)/, 300), ([body, overflow, closer, opener, delim], _, context) => {
3812
3827
  var _a, _b;
3813
3828
  return [(0, dom_1.html)('pre', {
3814
3829
  class: 'invalid',
@@ -3817,6 +3832,9 @@ require = function () {
3817
3832
  ...!closer && {
3818
3833
  'data-invalid-type': 'fence',
3819
3834
  'data-invalid-message': `Missing the closing delimiter "${ delim }"`
3835
+ } || overflow && {
3836
+ 'data-invalid-type': 'fence',
3837
+ 'data-invalid-message': `Invalid trailing line after the closing delimiter "${ delim }"`
3820
3838
  } || !(0, label_1.segment)((_b = (_a = opener.match(/^~+(?:figure[^\S\n]+)?(\[?\$\S+)/)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : '', context) && {
3821
3839
  'data-invalid-type': 'label',
3822
3840
  'data-invalid-message': 'Invalid label'
@@ -3827,7 +3845,7 @@ require = function () {
3827
3845
  'data-invalid-type': 'content',
3828
3846
  'data-invalid-message': 'Invalid content'
3829
3847
  }
3830
- }, `${ opener }${ body }${ closer }`)];
3848
+ }, `${ opener }${ body }${ overflow || closer }`)];
3831
3849
  })));
3832
3850
  function attributes(label, param, content, caption) {
3833
3851
  const group = label.split('-', 1)[0];
@@ -3945,15 +3963,15 @@ require = function () {
3945
3963
  const paragraph_1 = _dereq_('../paragraph');
3946
3964
  const dom_1 = _dereq_('typed-dom/dom');
3947
3965
  const array_1 = _dereq_('spica/array');
3948
- exports.message = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.fmap)((0, combinator_1.fence)(/^(~{3,})message\/(\S+)([^\n]*)(?:$|\n)/, 300), ([body, closer, opener, delim, type, param], _, context) => {
3949
- if (!closer || param.trimStart())
3966
+ exports.message = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.fmap)((0, combinator_1.fence)(/^(~{3,})message\/(\S+)([^\n]*)(?:$|\n)/, 300), ([body, overflow, closer, opener, delim, type, param], _, context) => {
3967
+ if (!closer || overflow || param.trimStart())
3950
3968
  return [(0, dom_1.html)('pre', {
3951
3969
  class: 'invalid',
3952
3970
  translate: 'no',
3953
3971
  'data-invalid-syntax': 'message',
3954
- 'data-invalid-type': !closer ? 'fence' : 'argument',
3955
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : 'Invalid argument'
3956
- }, `${ opener }${ body }${ closer }`)];
3972
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
3973
+ 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : overflow ? `Invalid trailing line after the closing delimiter "${ delim }"` : 'Invalid argument'
3974
+ }, `${ opener }${ body }${ overflow || closer }`)];
3957
3975
  switch (type) {
3958
3976
  case 'note':
3959
3977
  case 'caution':
@@ -3964,6 +3982,7 @@ require = function () {
3964
3982
  class: 'invalid',
3965
3983
  translate: 'no',
3966
3984
  'data-invalid-syntax': 'message',
3985
+ 'data-invalid-type': 'type',
3967
3986
  'data-invalid-message': 'Invalid message type'
3968
3987
  }, `${ opener }${ body }${ closer }`)];
3969
3988
  }
@@ -4025,13 +4044,11 @@ require = function () {
4025
4044
  const opener = /^(~{3,})(?!~)[^\n]*(?:$|\n)/;
4026
4045
  exports.segment = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.clear)((0, combinator_1.fence)(opener, 300))));
4027
4046
  exports.segment_ = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.clear)((0, combinator_1.fence)(opener, 300, false))), false);
4028
- exports.placeholder = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.fmap)((0, combinator_1.fence)(opener, Infinity), ([body, closer, opener, delim]) => [(0, dom_1.html)('pre', {
4047
+ exports.placeholder = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.fmap)((0, combinator_1.fence)(opener, Infinity), ([body, overflow, closer, opener, delim]) => [(0, dom_1.html)('pre', {
4029
4048
  class: 'invalid',
4030
4049
  translate: 'no',
4031
- 'data-invalid-syntax': 'extension',
4032
- 'data-invalid-type': !closer ? 'fence' : 'syntax',
4033
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : 'Invalid extension name'
4034
- }, `${ opener }${ body }${ closer }`)])));
4050
+ 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : overflow ? `Invalid trailing line after the closing delimiter "${ delim }"` : 'Invalid argument'
4051
+ }, `${ opener }${ body }${ overflow || closer }`)])));
4035
4052
  },
4036
4053
  {
4037
4054
  '../../../combinator': 25,
@@ -4056,16 +4073,16 @@ require = function () {
4056
4073
  const opener = /^(~{3,})table(?!\S)([^\n]*)(?:$|\n)/;
4057
4074
  exports.segment = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.clear)((0, combinator_1.fence)(opener, 10000))));
4058
4075
  exports.segment_ = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.clear)((0, combinator_1.fence)(opener, 10000, false))), false);
4059
- exports.table = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.recover)((0, combinator_1.fmap)((0, combinator_1.fence)(opener, 10000), ([body, closer, opener, delim, param], _, context) => {
4076
+ exports.table = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, combinator_1.recover)((0, combinator_1.fmap)((0, combinator_1.fence)(opener, 10000), ([body, overflow, closer, opener, delim, param], _, context) => {
4060
4077
  var _a;
4061
- if (!closer || param.trimStart())
4078
+ if (!closer || overflow || param.trimStart())
4062
4079
  return [(0, dom_1.html)('pre', {
4063
4080
  class: 'invalid',
4064
4081
  translate: 'no',
4065
4082
  'data-invalid-syntax': 'table',
4066
- 'data-invalid-type': !closer ? 'fence' : 'argument',
4067
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : 'Invalid argument'
4068
- }, `${ opener }${ body }${ closer }`)];
4083
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
4084
+ 'data-invalid-message': !closer ? `Missing the closing delimiter "${ delim }"` : overflow ? `Invalid trailing line after the closing delimiter "${ delim }"` : 'Invalid argument'
4085
+ }, `${ opener }${ body }${ overflow || closer }`)];
4069
4086
  return (_a = (0, parser_1.eval)(parser(body, context))) !== null && _a !== void 0 ? _a : [(0, dom_1.html)('table')];
4070
4087
  }), (source, _, reason) => reason instanceof Error && reason.message === 'Number of columns must be 32 or less' ? [
4071
4088
  [(0, dom_1.html)('pre', {
@@ -4437,24 +4454,24 @@ require = function () {
4437
4454
  const combinator_1 = _dereq_('../../combinator');
4438
4455
  const dom_1 = _dereq_('typed-dom/dom');
4439
4456
  const opener = /^(\${2,})(?!\$)([^\n]*)(?:$|\n)/;
4440
- exports.segment = (0, combinator_1.block)((0, combinator_1.validate)('$$', (0, combinator_1.clear)((0, combinator_1.fence)(opener, 100))));
4441
- exports.segment_ = (0, combinator_1.block)((0, combinator_1.validate)('$$', (0, combinator_1.clear)((0, combinator_1.fence)(opener, 100, false))), false);
4442
- exports.mathblock = (0, combinator_1.block)((0, combinator_1.validate)('$$', (0, combinator_1.fmap)((0, combinator_1.fence)(opener, 100), ([body, closer, opener, delim, param], _, {
4457
+ exports.segment = (0, combinator_1.block)((0, combinator_1.validate)('$$', (0, combinator_1.clear)((0, combinator_1.fence)(opener, 300))));
4458
+ exports.segment_ = (0, combinator_1.block)((0, combinator_1.validate)('$$', (0, combinator_1.clear)((0, combinator_1.fence)(opener, 300, false))), false);
4459
+ exports.mathblock = (0, combinator_1.block)((0, combinator_1.validate)('$$', (0, combinator_1.fmap)((0, combinator_1.fence)(opener, 300), ([body, overflow, closer, opener, delim, param], _, {
4443
4460
  caches: {
4444
4461
  math: cache = global_1.undefined
4445
4462
  } = {}
4446
4463
  }) => {
4447
4464
  var _a;
4448
- return [delim.length === 2 && closer && param.trimStart() === '' ? ((_a = cache === null || cache === void 0 ? void 0 : cache.get(`${ delim }\n${ body }${ delim }`)) === null || _a === void 0 ? void 0 : _a.cloneNode(true)) || (0, dom_1.html)('div', {
4465
+ return [delim.length === 2 && closer && !overflow && param.trimStart() === '' ? ((_a = cache === null || cache === void 0 ? void 0 : cache.get(`${ delim }\n${ body }${ delim }`)) === null || _a === void 0 ? void 0 : _a.cloneNode(true)) || (0, dom_1.html)('div', {
4449
4466
  class: 'math',
4450
4467
  translate: 'no'
4451
4468
  }, `${ delim }\n${ body }${ delim }`) : (0, dom_1.html)('pre', {
4452
4469
  class: 'invalid',
4453
4470
  translate: 'no',
4454
4471
  'data-invalid-syntax': 'mathblock',
4455
- 'data-invalid-type': delim.length > 2 ? 'syntax' : !closer ? 'fence' : 'argument',
4456
- 'data-invalid-message': delim.length > 2 ? 'Invalid syntax' : !closer ? `Missing the closing delimiter "${ delim }"` : 'Invalid argument'
4457
- }, `${ opener }${ body }${ closer }`)];
4472
+ 'data-invalid-type': delim.length > 2 ? 'syntax' : !closer || overflow ? 'fence' : 'argument',
4473
+ 'data-invalid-message': delim.length > 2 ? 'Invalid syntax' : !closer ? `Missing the closing delimiter "${ delim }"` : overflow ? `Invalid trailing line after the closing delimiter "${ delim }"` : 'Invalid argument'
4474
+ }, `${ opener }${ body }${ overflow || closer }`)];
4458
4475
  })));
4459
4476
  },
4460
4477
  {
@@ -6284,7 +6301,7 @@ require = function () {
6284
6301
  }
6285
6302
  return (0, dom_1.html)('a', {
6286
6303
  href: uri.source,
6287
- target: undefined || uri.origin !== origin || typeof content[0] === 'object' && content[0].classList.contains('media') ? '_blank' : undefined
6304
+ target: global_1.undefined || uri.origin !== origin || typeof content[0] === 'object' && content[0].classList.contains('media') ? '_blank' : global_1.undefined
6288
6305
  }, content.length === 0 ? decode(INSECURE_URI) : content);
6289
6306
  case 'tel:':
6290
6307
  if (content.length === 0) {
@@ -8036,8 +8053,8 @@ require = function () {
8036
8053
  'use strict';
8037
8054
  Object.defineProperty(exports, '__esModule', { value: true });
8038
8055
  exports.image = void 0;
8039
- const dom_1 = _dereq_('typed-dom/dom');
8040
8056
  const alias_1 = _dereq_('spica/alias');
8057
+ const dom_1 = _dereq_('typed-dom/dom');
8041
8058
  function image(source, url, cache) {
8042
8059
  if (cache === null || cache === void 0 ? void 0 : cache.has(url.href))
8043
8060
  return (0, dom_1.define)(cache.get(url.href).cloneNode(true), (0, alias_1.ObjectFromEntries)([...source.attributes].map(attr => [
@@ -8157,8 +8174,8 @@ require = function () {
8157
8174
  'use strict';
8158
8175
  Object.defineProperty(exports, '__esModule', { value: true });
8159
8176
  exports.video = void 0;
8160
- const dom_1 = _dereq_('typed-dom/dom');
8161
8177
  const alias_1 = _dereq_('spica/alias');
8178
+ const dom_1 = _dereq_('typed-dom/dom');
8162
8179
  const extensions = [
8163
8180
  '.webm',
8164
8181
  '.ogv'
@@ -8189,6 +8206,7 @@ require = function () {
8189
8206
  'use strict';
8190
8207
  Object.defineProperty(exports, '__esModule', { value: true });
8191
8208
  exports.youtube = void 0;
8209
+ const global_1 = _dereq_('spica/global');
8192
8210
  const dom_1 = _dereq_('typed-dom/dom');
8193
8211
  function youtube(source, url) {
8194
8212
  const id = resolve(url);
@@ -8208,15 +8226,18 @@ require = function () {
8208
8226
  var _a;
8209
8227
  switch (url.origin) {
8210
8228
  case 'https://www.youtube.com':
8211
- return url.pathname.match(/^\/watch\/?$/) ? (_a = url.searchParams.get('v')) === null || _a === void 0 ? void 0 : _a.concat(url.search.replace(/([?&])v=[^&#]*&?/g, '$1'), url.hash) : undefined;
8229
+ return url.pathname.match(/^\/watch\/?$/) ? (_a = url.searchParams.get('v')) === null || _a === void 0 ? void 0 : _a.concat(url.search.replace(/([?&])v=[^&#]*&?/g, '$1'), url.hash) : global_1.undefined;
8212
8230
  case 'https://youtu.be':
8213
- return url.pathname.match(/^\/[\w-]+\/?$/) ? url.href.slice(url.origin.length) : undefined;
8231
+ return url.pathname.match(/^\/[\w-]+\/?$/) ? url.href.slice(url.origin.length) : global_1.undefined;
8214
8232
  default:
8215
8233
  return;
8216
8234
  }
8217
8235
  }
8218
8236
  },
8219
- { 'typed-dom/dom': 23 }
8237
+ {
8238
+ 'spica/global': 13,
8239
+ 'typed-dom/dom': 23
8240
+ }
8220
8241
  ],
8221
8242
  146: [
8222
8243
  function (_dereq_, module, exports) {
package/package-lock.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.243.2",
3
+ "version": "0.244.0",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -8028,9 +8028,9 @@
8028
8028
  }
8029
8029
  },
8030
8030
  "node-releases": {
8031
- "version": "2.0.3",
8032
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.3.tgz",
8033
- "integrity": "sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw==",
8031
+ "version": "2.0.4",
8032
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz",
8033
+ "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==",
8034
8034
  "dev": true
8035
8035
  },
8036
8036
  "nopt": {
@@ -8093,9 +8093,9 @@
8093
8093
  }
8094
8094
  },
8095
8095
  "npm-check-updates": {
8096
- "version": "12.5.9",
8097
- "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.9.tgz",
8098
- "integrity": "sha512-l9iOvD7EsQb96gFJL45V01YG6bP8+dmobYnSguvehPuNwgdWNMrE8RC8bSfURX5iUmX4bkobN4T8XMHXN9GMHA==",
8096
+ "version": "12.5.10",
8097
+ "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.10.tgz",
8098
+ "integrity": "sha512-GKBmgC6ZDZwshsOSuse+JYDFVQcaKj9NWNWXW9oWX0TdrKJx26/iR6d4t6LG+iNm5jX+voBoGcEIaGF8CRzWpw==",
8099
8099
  "dev": true,
8100
8100
  "requires": {
8101
8101
  "chalk": "^4.1.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.243.2",
3
+ "version": "0.244.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",
@@ -2,36 +2,46 @@ import { Parser, Ctx } from '../../data/parser';
2
2
  import { firstline, isEmpty } from '../constraint/line';
3
3
  import { unshift } from 'spica/array';
4
4
 
5
- export function fence<C extends Ctx, D extends Parser<unknown, C>[]>(opener: RegExp, limit: number, separation: boolean = true): Parser<string, C, D> {
5
+ export function fence<C extends Ctx, D extends Parser<unknown, C>[]>(opener: RegExp, limit: number, separation = true): Parser<string, C, D> {
6
6
  return source => {
7
7
  if (source === '') return;
8
8
  const matches = source.match(opener);
9
9
  if (!matches) return;
10
10
  assert(matches[0] === firstline(source));
11
11
  const delim = matches[1];
12
+ assert(delim && delim === delim.trim());
12
13
  if (matches[0].indexOf(delim, delim.length) !== -1) return;
13
14
  let rest = source.slice(matches[0].length);
14
15
  // Prevent annoying parsing in editing.
15
16
  if (isEmpty(firstline(rest)) && firstline(rest.slice(firstline(rest).length)).trimEnd() !== delim) return;
16
17
  let block = '';
17
18
  let closer = '';
18
- for (let count = 1, next = firstline(rest); ; ++count) {
19
+ let overflow = '';
20
+ for (let count = 1; ; ++count) {
19
21
  if (rest === '') break;
20
- const line = next;
21
- next = firstline(rest.slice(line.length));
22
- if (count > limit + 1 && isEmpty(line)) break;
23
- if (count <= limit + 1 &&
24
- line.slice(0, delim.length) === delim &&
25
- line.trimEnd() === delim &&
26
- (!separation || isEmpty(next))) {
27
- assert(line.trimEnd() === delim);
28
- closer = delim;
29
- rest = rest.slice(line.length);
30
- break;
22
+ const line = firstline(rest);
23
+ if ((closer || count > limit + 1) && isEmpty(line)) break;
24
+ if(closer) {
25
+ overflow += line;
26
+ }
27
+ if (!closer && count <= limit + 1 && line.slice(0, delim.length) === delim && line.trimEnd() === delim) {
28
+ closer = line;
29
+ if (isEmpty(firstline(rest.slice(line.length)))) {
30
+ rest = rest.slice(line.length);
31
+ break;
32
+ }
33
+ if (!separation) {
34
+ rest = rest.slice(line.length);
35
+ break;
36
+ }
37
+ assert(!overflow);
38
+ overflow = line;
39
+ }
40
+ if (!overflow) {
41
+ block += line;
31
42
  }
32
- block += line;
33
43
  rest = rest.slice(line.length);
34
44
  }
35
- return [unshift([block, closer], matches), rest];
45
+ return [unshift([block, overflow, closer], matches), rest];
36
46
  };
37
47
  }
@@ -1,3 +1,5 @@
1
+ import { undefined } from 'spica/global';
2
+
1
3
  export type Parser<T, C extends Ctx = Ctx, D extends Parser<unknown, C>[] = any>
2
4
  = (source: string, context: C) => Result<T, C, D>;
3
5
  export type Result<T, C extends Ctx = Ctx, D extends Parser<unknown, C>[] = any>
package/src/debug.test.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Result, eval, exec } from './combinator/data/parser';
2
2
  import { html, define } from 'typed-dom/dom';
3
+ import { querySelector, querySelectorAll } from 'typed-dom/query';
3
4
 
4
5
  export function inspect(result: Result<HTMLElement | string>, until: number | string = Infinity): Result<string> {
5
6
  return result && [
@@ -7,14 +8,15 @@ export function inspect(result: Result<HTMLElement | string>, until: number | st
7
8
  assert(node);
8
9
  if (typeof node === 'string') return node;
9
10
  node = node.cloneNode(true);
10
- assert(!node.matches('.invalid[data-invalid-message$="."]'));
11
- assert(!node.querySelector('.invalid[data-invalid-message$="."]'));
12
- [node, ...node.querySelectorAll('.invalid')].forEach(el =>
11
+ assert(!querySelector(node, '.invalid[data-invalid-message$="."]'));
12
+ querySelectorAll(node, '.invalid').forEach(el => {
13
+ assert(el.matches('[data-invalid-syntax][data-invalid-type][data-invalid-message]'));
13
14
  define(el, {
14
15
  'data-invalid-syntax': null,
15
16
  'data-invalid-type': null,
16
17
  'data-invalid-message': null,
17
- }));
18
+ });
19
+ });
18
20
  until = typeof until === 'number'
19
21
  ? until
20
22
  : ~(~node.outerHTML.indexOf(until) || -Infinity) + until.length;
@@ -17,6 +17,7 @@ describe('Unit: parser/block/codeblock', () => {
17
17
  assert.deepStrictEqual(inspect(parser('```\na\n```\nb')), [['<pre class="invalid" translate="no">```\na\n```\nb</pre>'], '']);
18
18
  assert.deepStrictEqual(inspect(parser('```\n\n\n```')), undefined);
19
19
  assert.deepStrictEqual(inspect(parser('```a ```\n```')), undefined);
20
+ assert.deepStrictEqual(inspect(parser('```\n```\n```')), [['<pre class="invalid" translate="no">```\n```\n```</pre>'], '']);
20
21
  assert.deepStrictEqual(inspect(parser('```\n````')), [['<pre class="invalid" translate="no">```\n````</pre>'], '']);
21
22
  assert.deepStrictEqual(inspect(parser('````\n```')), [['<pre class="invalid" translate="no">````\n```</pre>'], '']);
22
23
  assert.deepStrictEqual(inspect(parser(' ```\n```')), undefined);
@@ -30,7 +31,6 @@ describe('Unit: parser/block/codeblock', () => {
30
31
  assert.deepStrictEqual(inspect(parser('```\na\nb\n```')), [['<pre class="text">a<br>b</pre>'], '']);
31
32
  assert.deepStrictEqual(inspect(parser('```\n\\\n```')), [['<pre class="text">\\</pre>'], '']);
32
33
  assert.deepStrictEqual(inspect(parser('```\n`\n```')), [['<pre class="text">`</pre>'], '']);
33
- assert.deepStrictEqual(inspect(parser('```\n```\n```')), [['<pre class="text">```</pre>'], '']);
34
34
  assert.deepStrictEqual(inspect(parser('```\n```\n\n```')), [['<pre class="text"></pre>'], '\n```']);
35
35
  assert.deepStrictEqual(inspect(parser('```\n````\n```')), [['<pre class="text">````</pre>'], '']);
36
36
  assert.deepStrictEqual(inspect(parser('```\n````\n\n```')), [['<pre class="text">````<br></pre>'], '']);
@@ -17,7 +17,7 @@ export const segment_: CodeBlockParser.SegmentParser = block(validate('```',
17
17
  export const codeblock: CodeBlockParser = block(validate('```', fmap(
18
18
  fence(opener, 300),
19
19
  // Bug: Type mismatch between outer and inner.
20
- ([body, closer, opener, delim, param]: string[], _, context) => {
20
+ ([body, overflow, closer, opener, delim, param]: string[], _, context) => {
21
21
  const params = param.match(/(?:\\.?|\S)+/g)?.reduce<{
22
22
  lang?: string;
23
23
  path?: string;
@@ -45,17 +45,20 @@ export const codeblock: CodeBlockParser = block(validate('```', fmap(
45
45
  }
46
46
  }
47
47
  name in params
48
- ? params.invalid = `Duplicate ${name} value`
48
+ ? params.invalid = `Duplicate ${name} attribute`
49
49
  : params[name] = value;
50
50
  return params;
51
51
  }, {}) ?? {};
52
- if (!closer || params.invalid) return [html('pre', {
52
+ if (!closer || overflow || params.invalid) return [html('pre', {
53
53
  class: 'invalid',
54
54
  translate: 'no',
55
55
  'data-invalid-syntax': 'codeblock',
56
- 'data-invalid-type': !closer ? 'fence' : 'argument',
57
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${delim}"` : params.invalid,
58
- }, `${opener}${body}${closer}`)];
56
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
57
+ 'data-invalid-message':
58
+ !closer ? `Missing the closing delimiter "${delim}"` :
59
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
60
+ params.invalid,
61
+ }, `${opener}${body}${overflow || closer}`)];
59
62
  const el = html('pre',
60
63
  {
61
64
  class: params.lang ? `code language-${params.lang}` : 'text',
@@ -7,14 +7,17 @@ import { html } from 'typed-dom/dom';
7
7
  export const aside: ExtensionParser.AsideParser = creator(100, block(validate('~~~', fmap(
8
8
  fence(/^(~{3,})aside(?!\S)([^\n]*)(?:$|\n)/, 300),
9
9
  // Bug: Type mismatch between outer and inner.
10
- ([body, closer, opener, delim, param]: string[], _, context) => {
11
- if (!closer || param.trimStart()) return [html('pre', {
10
+ ([body, overflow, closer, opener, delim, param]: string[], _, context) => {
11
+ if (!closer || overflow || param.trimStart()) return [html('pre', {
12
12
  class: 'invalid',
13
13
  translate: 'no',
14
14
  'data-invalid-syntax': 'aside',
15
- 'data-invalid-type': !closer ? 'fence' : 'argument',
16
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${delim}"` : 'Invalid argument',
17
- }, `${opener}${body}${closer}`)];
15
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
16
+ 'data-invalid-message':
17
+ !closer ? `Missing the closing delimiter "${delim}"` :
18
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
19
+ 'Invalid argument',
20
+ }, `${opener}${body}${overflow || closer}`)];
18
21
  const annotations = html('ol', { class: 'annotations' });
19
22
  const references = html('ol', { class: 'references' });
20
23
  const document = parse(body.slice(0, -1), {
@@ -10,14 +10,17 @@ const opener = /^(~{3,})(?:example\/(\S+))?(?!\S)([^\n]*)(?:$|\n)/;
10
10
  export const example: ExtensionParser.ExampleParser = creator(100, block(validate('~~~', fmap(
11
11
  fence(opener, 300),
12
12
  // Bug: Type mismatch between outer and inner.
13
- ([body, closer, opener, delim, type = 'markdown', param]: string[], _, context) => {
14
- if (!closer || param.trimStart()) return [html('pre', {
13
+ ([body, overflow, closer, opener, delim, type = 'markdown', param]: string[], _, context) => {
14
+ if (!closer || overflow || param.trimStart()) return [html('pre', {
15
15
  class: 'invalid',
16
16
  translate: 'no',
17
17
  'data-invalid-syntax': 'example',
18
- 'data-invalid-type': !closer ? 'fence' : 'argument',
19
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${delim}"` : 'Invalid argument',
20
- }, `${opener}${body}${closer}`)];
18
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
19
+ 'data-invalid-message':
20
+ !closer ? `Missing the closing delimiter "${delim}"` :
21
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
22
+ 'Invalid argument',
23
+ }, `${opener}${body}${overflow || closer}`)];
21
24
  switch (type) {
22
25
  case 'markdown': {
23
26
  const annotations = html('ol', { class: 'annotations' });
@@ -52,6 +55,7 @@ export const example: ExtensionParser.ExampleParser = creator(100, block(validat
52
55
  class: 'invalid',
53
56
  translate: 'no',
54
57
  'data-invalid-syntax': 'example',
58
+ 'data-invalid-type': 'type',
55
59
  'data-invalid-message': 'Invalid example type',
56
60
  }, `${opener}${body}${closer}`),
57
61
  ];
@@ -31,6 +31,8 @@ describe('Unit: parser/block/extension/fig', () => {
31
31
  assert.deepStrictEqual(inspect(parser('[$group-name]\n```\n~~~\n```')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text">~~~</pre></div></figure>'], '']);
32
32
  assert.deepStrictEqual(inspect(parser('[$group-name]\n$$\n\n$$')), [['<figure data-type="math" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
33
33
  assert.deepStrictEqual(inspect(parser('[$group-name]\n$$\n\n$$\n')), [['<figure data-type="math" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
34
+ assert.deepStrictEqual(inspect(parser('[$group-name]\n~~~\n~~~')), [['<figure data-type="example" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><aside class="example" data-type="markdown"><pre translate="no"></pre><hr><section><ol class="annotations"></ol><ol class="references"></ol></section></aside></div></figure>'], '']);
35
+ assert.deepStrictEqual(inspect(parser('[$group-name]\n~~~\n~~~\n')), [['<figure data-type="example" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><aside class="example" data-type="markdown"><pre translate="no"></pre><hr><section><ol class="annotations"></ol><ol class="references"></ol></section></aside></div></figure>'], '']);
34
36
  assert.deepStrictEqual(inspect(parser('[$group-name]\n~~~example/markdown\n~~~')), [['<figure data-type="example" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><aside class="example" data-type="markdown"><pre translate="no"></pre><hr><section><ol class="annotations"></ol><ol class="references"></ol></section></aside></div></figure>'], '']);
35
37
  assert.deepStrictEqual(inspect(parser('[$group-name]\n~~~example/markdown\n~~~\n')), [['<figure data-type="example" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><aside class="example" data-type="markdown"><pre translate="no"></pre><hr><section><ol class="annotations"></ol><ol class="references"></ol></section></aside></div></figure>'], '']);
36
38
  assert.deepStrictEqual(inspect(parser('[$group-name]\n~~~table\n~~~')), [['<figure data-type="table" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><table></table></div></figure>'], '']);
@@ -33,7 +33,7 @@ describe('Unit: parser/block/extension/figure', () => {
33
33
  assert.deepStrictEqual(inspect(parser('~~~figure [$figure-name]\n> \n\n~~~')), [['<figure data-type="quote" data-label="figure-name" data-group="figure" class="invalid"><figcaption><span class="figindex"></span></figcaption><div><blockquote></blockquote></div></figure>'], '']);
34
34
  assert.deepStrictEqual(inspect(parser('~~~figure [$table-name]\n> \n\n~~~')), [['<figure data-type="quote" data-label="table-name" data-group="table" class="invalid"><figcaption><span class="figindex"></span></figcaption><div><blockquote></blockquote></div></figure>'], '']);
35
35
  assert.deepStrictEqual(inspect(parser(`~~~figure [$group-name]\n0${'\n'.repeat(301)}~~~`), '>'), [['<pre class="invalid" translate="no">'], '']);
36
- assert.deepStrictEqual(inspect(parser(`~~~figure [$group-name]\n~~~\n0${'\n'.repeat(301)}~~~\n~~~`), '>'), [['<pre class="invalid" translate="no">'], '\n~~~\n~~~']);
36
+ assert.deepStrictEqual(inspect(parser(`~~~figure [$group-name]\n~~~\n0${'\n'.repeat(301)}~~~\n~~~`), '>'), [['<pre class="invalid" translate="no">'], `${'\n'.repeat(300)}~~~\n~~~`]);
37
37
  });
38
38
 
39
39
  it('valid', () => {
@@ -52,6 +52,7 @@ describe('Unit: parser/block/extension/figure', () => {
52
52
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n$$\n\n$$\n~~~')), [['<figure data-type="math" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
53
53
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n$$\n~~~\n$$\n~~~')), [['<figure data-type="math" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><div class="math" translate="no">$$\n~~~\n$$</div></div></figure>'], '']);
54
54
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n$$\n\n$$\n\ncaption\n~~~')), [['<figure data-type="math" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span>caption</figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
55
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n~~~\n~~~\n\ncaption\n~~~')), [['<figure data-type="example" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span>caption</figcaption><div><aside class="example" data-type="markdown"><pre translate="no"></pre><hr><section><ol class="annotations"></ol><ol class="references"></ol></section></aside></div></figure>'], '']);
55
56
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n~~~example/markdown\n~~~\n\ncaption\n~~~')), [['<figure data-type="example" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span>caption</figcaption><div><aside class="example" data-type="markdown"><pre translate="no"></pre><hr><section><ol class="annotations"></ol><ol class="references"></ol></section></aside></div></figure>'], '']);
56
57
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n~~~table\n~~~\n\ncaption\n~~~')), [['<figure data-type="table" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span>caption</figcaption><div><table></table></div></figure>'], '']);
57
58
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n> \n~~~\n\n~~~')), [['<figure data-type="quote" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><blockquote><pre><br>~~~</pre></blockquote></div></figure>'], '']);
@@ -85,7 +85,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
85
85
  ])),
86
86
  fmap(
87
87
  fence(/^(~{3,})(?:figure|\[?\$\S*)(?!\S)[^\n]*(?:$|\n)/, 300),
88
- ([body, closer, opener, delim]: string[], _, context) => [
88
+ ([body, overflow, closer, opener, delim]: string[], _, context) => [
89
89
  html('pre', {
90
90
  class: 'invalid',
91
91
  translate: 'no',
@@ -95,6 +95,10 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
95
95
  'data-invalid-type': 'fence',
96
96
  'data-invalid-message': `Missing the closing delimiter "${delim}"`,
97
97
  } ||
98
+ overflow && {
99
+ 'data-invalid-type': 'fence',
100
+ 'data-invalid-message': `Invalid trailing line after the closing delimiter "${delim}"`,
101
+ } ||
98
102
  !seg_label(opener.match(/^~+(?:figure[^\S\n]+)?(\[?\$\S+)/)?.[1] ?? '', context) && {
99
103
  'data-invalid-type': 'label',
100
104
  'data-invalid-message': 'Invalid label',
@@ -107,7 +111,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
107
111
  'data-invalid-type': 'content',
108
112
  'data-invalid-message': 'Invalid content',
109
113
  },
110
- }, `${opener}${body}${closer}`),
114
+ }, `${opener}${body}${overflow || closer}`),
111
115
  ])));
112
116
 
113
117
  function attributes(label: string, param: string, content: HTMLElement, caption: readonly HTMLElement[]): Record<string, string | undefined> {
@@ -21,14 +21,17 @@ import MessageParser = ExtensionParser.MessageParser;
21
21
  export const message: MessageParser = block(validate('~~~', fmap(
22
22
  fence(/^(~{3,})message\/(\S+)([^\n]*)(?:$|\n)/, 300),
23
23
  // Bug: Type mismatch between outer and inner.
24
- ([body, closer, opener, delim, type, param]: string[], _, context) => {
25
- if (!closer || param.trimStart()) return [html('pre', {
24
+ ([body, overflow, closer, opener, delim, type, param]: string[], _, context) => {
25
+ if (!closer || overflow || param.trimStart()) return [html('pre', {
26
26
  class: 'invalid',
27
27
  translate: 'no',
28
28
  'data-invalid-syntax': 'message',
29
- 'data-invalid-type': !closer ? 'fence' : 'argument',
30
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${delim}"` : 'Invalid argument',
31
- }, `${opener}${body}${closer}`)];
29
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
30
+ 'data-invalid-message':
31
+ !closer ? `Missing the closing delimiter "${delim}"` :
32
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
33
+ 'Invalid argument',
34
+ }, `${opener}${body}${overflow || closer}`)];
32
35
  switch (type) {
33
36
  case 'note':
34
37
  case 'caution':
@@ -39,6 +42,7 @@ export const message: MessageParser = block(validate('~~~', fmap(
39
42
  class: 'invalid',
40
43
  translate: 'no',
41
44
  'data-invalid-syntax': 'message',
45
+ 'data-invalid-type': 'type',
42
46
  'data-invalid-message': 'Invalid message type',
43
47
  }, `${opener}${body}${closer}`)];
44
48
  }
@@ -12,12 +12,13 @@ export const segment_: ExtensionParser.PlaceholderParser.SegmentParser = block(v
12
12
 
13
13
  export const placeholder: ExtensionParser.PlaceholderParser = block(validate('~~~', fmap(
14
14
  fence(opener, Infinity),
15
- ([body, closer, opener, delim]) => [
15
+ ([body, overflow, closer, opener, delim]) => [
16
16
  html('pre', {
17
17
  class: 'invalid',
18
18
  translate: 'no',
19
- 'data-invalid-syntax': 'extension',
20
- 'data-invalid-type': !closer ? 'fence' : 'syntax',
21
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${delim}"` : 'Invalid extension name',
22
- }, `${opener}${body}${closer}`),
19
+ 'data-invalid-message':
20
+ !closer ? `Missing the closing delimiter "${delim}"` :
21
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
22
+ 'Invalid argument',
23
+ }, `${opener}${body}${overflow || closer}`),
23
24
  ])));
@@ -26,14 +26,17 @@ export const segment_: TableParser.SegmentParser = block(validate('~~~',
26
26
  export const table: TableParser = block(validate('~~~', recover(fmap(
27
27
  fence(opener, 10000),
28
28
  // Bug: Type mismatch between outer and inner.
29
- ([body, closer, opener, delim, param]: string[], _, context) => {
30
- if (!closer || param.trimStart()) return [html('pre', {
29
+ ([body, overflow, closer, opener, delim, param]: string[], _, context) => {
30
+ if (!closer || overflow || param.trimStart()) return [html('pre', {
31
31
  class: 'invalid',
32
32
  translate: 'no',
33
33
  'data-invalid-syntax': 'table',
34
- 'data-invalid-type': !closer ? 'fence' : 'argument',
35
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${delim}"` : 'Invalid argument',
36
- }, `${opener}${body}${closer}`)];
34
+ 'data-invalid-type': !closer || overflow ? 'fence' : 'argument',
35
+ 'data-invalid-message':
36
+ !closer ? `Missing the closing delimiter "${delim}"` :
37
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
38
+ 'Invalid argument',
39
+ }, `${opener}${body}${overflow || closer}`)];
37
40
  return eval(parser(body, context)) ?? [html('table')];
38
41
  }),
39
42
  (source, _, reason) =>
@@ -19,10 +19,12 @@ describe('Unit: parser/block/mathblock', () => {
19
19
  assert.deepStrictEqual(inspect(parser('$$ $$\n$$')), undefined);
20
20
  assert.deepStrictEqual(inspect(parser('$$lang\n$$')), [['<pre class="invalid" translate="no">$$lang\n$$</pre>'], '']);
21
21
  assert.deepStrictEqual(inspect(parser('$$ param\n$$')), [['<pre class="invalid" translate="no">$$ param\n$$</pre>'], '']);
22
+ assert.deepStrictEqual(inspect(parser('$$\n$$\n$$')), [['<pre class="invalid" translate="no">$$\n$$\n$$</pre>'], '']);
23
+ assert.deepStrictEqual(inspect(parser('$$\n$$$')), [['<pre class="invalid" translate="no">$$\n$$$</pre>'], '']);
22
24
  assert.deepStrictEqual(inspect(parser('$$$\n$$')), [['<pre class="invalid" translate="no">$$$\n$$</pre>'], '']);
23
25
  assert.deepStrictEqual(inspect(parser('$$$\n$$$')), [['<pre class="invalid" translate="no">$$$\n$$$</pre>'], '']);
24
26
  assert.deepStrictEqual(inspect(parser(' $$\n$$')), undefined);
25
- assert.deepStrictEqual(inspect(parser(`$$\n0${'\n'.repeat(101)}$$`), '>'), [['<pre class="invalid" translate="no">'], '']);
27
+ assert.deepStrictEqual(inspect(parser(`$$\n0${'\n'.repeat(301)}$$`), '>'), [['<pre class="invalid" translate="no">'], '']);
26
28
  });
27
29
 
28
30
  it('basic', () => {
@@ -34,12 +36,10 @@ describe('Unit: parser/block/mathblock', () => {
34
36
  assert.deepStrictEqual(inspect(parser('$$\n\\\n$$')), [['<div class="math" translate="no">$$\n\\\n$$</div>'], '']);
35
37
  assert.deepStrictEqual(inspect(parser('$$\n$\n$$')), [['<div class="math" translate="no">$$\n$\n$$</div>'], '']);
36
38
  assert.deepStrictEqual(inspect(parser('$$\n$\n\n$$')), [['<div class="math" translate="no">$$\n$\n\n$$</div>'], '']);
37
- assert.deepStrictEqual(inspect(parser('$$\n$$\n$$')), [['<div class="math" translate="no">$$\n$$\n$$</div>'], '']);
38
39
  assert.deepStrictEqual(inspect(parser('$$\n$$\n\n$$')), [['<div class="math" translate="no">$$\n$$</div>'], '\n$$']);
39
40
  assert.deepStrictEqual(inspect(parser('$$\n$$$\n$$')), [['<div class="math" translate="no">$$\n$$$\n$$</div>'], '']);
40
41
  assert.deepStrictEqual(inspect(parser('$$\n$$$\n\n$$')), [['<div class="math" translate="no">$$\n$$$\n\n$$</div>'], '']);
41
- assert.deepStrictEqual(inspect(parser('$$\n$$\n$$')), [['<div class="math" translate="no">$$\n$$\n$$</div>'], '']);
42
- assert.deepStrictEqual(inspect(parser(`$$\n0${'\n'.repeat(100)}$$`), '>'), [['<div class="math" translate="no">'], '']);
42
+ assert.deepStrictEqual(inspect(parser(`$$\n0${'\n'.repeat(300)}$$`), '>'), [['<div class="math" translate="no">'], '']);
43
43
  });
44
44
 
45
45
  });
@@ -6,23 +6,26 @@ import { html } from 'typed-dom/dom';
6
6
  const opener = /^(\${2,})(?!\$)([^\n]*)(?:$|\n)/;
7
7
 
8
8
  export const segment: MathBlockParser.SegmentParser = block(validate('$$',
9
- clear(fence(opener, 100))));
9
+ clear(fence(opener, 300))));
10
10
 
11
11
  export const segment_: MathBlockParser.SegmentParser = block(validate('$$',
12
- clear(fence(opener, 100, false))), false);
12
+ clear(fence(opener, 300, false))), false);
13
13
 
14
14
  export const mathblock: MathBlockParser = block(validate('$$', fmap(
15
- fence(opener, 100),
15
+ fence(opener, 300),
16
16
  // Bug: Type mismatch between outer and inner.
17
- ([body, closer, opener, delim, param]: string[], _, { caches: { math: cache = undefined } = {} }) => [
18
- delim.length === 2 && closer && param.trimStart() === ''
17
+ ([body, overflow, closer, opener, delim, param]: string[], _, { caches: { math: cache = undefined } = {} }) => [
18
+ delim.length === 2 && closer && !overflow && param.trimStart() === ''
19
19
  ? cache?.get(`${delim}\n${body}${delim}`)?.cloneNode(true) as HTMLDivElement ||
20
20
  html('div', { class: 'math', translate: 'no' }, `${delim}\n${body}${delim}`)
21
21
  : html('pre', {
22
22
  class: 'invalid',
23
23
  translate: 'no',
24
24
  'data-invalid-syntax': 'mathblock',
25
- 'data-invalid-type': delim.length > 2 ? 'syntax' : !closer ? 'fence' : 'argument',
26
- 'data-invalid-message': delim.length > 2 ? 'Invalid syntax' : !closer ? `Missing the closing delimiter "${delim}"` : 'Invalid argument',
27
- }, `${opener}${body}${closer}`),
25
+ 'data-invalid-type': delim.length > 2 ? 'syntax' : !closer || overflow ? 'fence' : 'argument',
26
+ 'data-invalid-message': delim.length > 2 ? 'Invalid syntax' :
27
+ !closer ? `Missing the closing delimiter "${delim}"` :
28
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
29
+ 'Invalid argument',
30
+ }, `${opener}${body}${overflow || closer}`),
28
31
  ])));
@@ -1,4 +1,4 @@
1
- import { location, encodeURI, decodeURI, Location } from 'spica/global';
1
+ import { undefined, location, encodeURI, decodeURI, Location } from 'spica/global';
2
2
  import { LinkParser } from '../inline';
3
3
  import { eval } from '../../combinator/data/parser';
4
4
  import { union, inits, tails, some, validate, guard, context, creator, surround, open, dup, reverse, lazy, fmap, bind } from '../../combinator';
@@ -1,6 +1,6 @@
1
- import { define } from 'typed-dom/dom';
2
- import { Collection } from 'spica/collection';
3
1
  import { ObjectFromEntries } from 'spica/alias';
2
+ import { Collection } from 'spica/collection';
3
+ import { define } from 'typed-dom/dom';
4
4
 
5
5
  export function image(source: HTMLImageElement, url: URL, cache?: Collection<string, HTMLElement>): HTMLImageElement {
6
6
  if (cache?.has(url.href)) return define(
@@ -1,5 +1,5 @@
1
- import { html } from 'typed-dom/dom';
2
1
  import { ObjectFromEntries } from 'spica/alias';
2
+ import { html } from 'typed-dom/dom';
3
3
 
4
4
  const extensions = [
5
5
  '.webm',
@@ -1,3 +1,4 @@
1
+ import { undefined } from 'spica/global';
1
2
  import { html } from 'typed-dom/dom';
2
3
 
3
4
  export function youtube(source: HTMLImageElement, url: URL): HTMLElement | undefined {