securemark 0.265.0 → 0.267.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +1 -1
  3. package/dist/index.js +49 -42
  4. package/index.d.ts +7 -7
  5. package/markdown.d.ts +4 -4
  6. package/package.json +1 -1
  7. package/src/parser/api/bind.test.ts +17 -17
  8. package/src/parser/api/bind.ts +1 -0
  9. package/src/parser/api/parse.test.ts +6 -8
  10. package/src/parser/api/parse.ts +2 -1
  11. package/src/parser/block/dlist.test.ts +34 -34
  12. package/src/parser/block/extension/aside.test.ts +3 -3
  13. package/src/parser/block/extension/aside.ts +2 -2
  14. package/src/parser/block/extension/figure.test.ts +2 -2
  15. package/src/parser/block/heading.test.ts +47 -47
  16. package/src/parser/block/olist.test.ts +29 -29
  17. package/src/parser/block/pagebreak.test.ts +31 -0
  18. package/src/parser/block/pagebreak.ts +7 -0
  19. package/src/parser/block/reply/cite.test.ts +1 -1
  20. package/src/parser/block/ulist.test.ts +25 -25
  21. package/src/parser/block.ts +3 -3
  22. package/src/parser/inline/autolink/account.ts +3 -5
  23. package/src/parser/inline/autolink/anchor.test.ts +2 -2
  24. package/src/parser/inline/autolink/anchor.ts +4 -3
  25. package/src/parser/inline/autolink/channel.test.ts +0 -2
  26. package/src/parser/inline/autolink/channel.ts +0 -1
  27. package/src/parser/inline/autolink/hashnum.test.ts +1 -1
  28. package/src/parser/inline/autolink/hashtag.test.ts +2 -6
  29. package/src/parser/inline/autolink/hashtag.ts +7 -20
  30. package/src/parser/inline/extension/index.test.ts +48 -48
  31. package/src/parser/inline/extension/index.ts +1 -1
  32. package/src/parser/inline/extension/indexee.ts +15 -11
  33. package/src/parser/inline/extension/indexer.ts +1 -1
  34. package/src/parser/inline/link.ts +1 -0
  35. package/src/parser/inline/mark.test.ts +9 -9
  36. package/src/parser/inline/mark.ts +1 -1
  37. package/src/parser/inline.test.ts +9 -6
  38. package/src/parser/processor/figure.test.ts +19 -19
  39. package/src/parser/processor/footnote.test.ts +66 -66
  40. package/src/parser/processor/footnote.ts +11 -11
  41. package/src/util/toc.test.ts +28 -28
  42. package/src/parser/block/horizontalrule.test.ts +0 -31
  43. package/src/parser/block/horizontalrule.ts +0 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.267.0
4
+
5
+ - Change horizontalrule syntax to pagebreak syntax.
6
+
7
+ ## 0.266.0
8
+
9
+ - Change index schemas.
10
+ - Fix footnote processing.
11
+
3
12
  ## 0.265.0
4
13
 
5
14
  - Change ulist and olist parsers to index list items.
package/README.md CHANGED
@@ -50,7 +50,7 @@ https://falsandtru.github.io/securemark/
50
50
  - Table (| |)
51
51
  - Blockquote (>, !>)
52
52
  - Preformattedtext (```)
53
- - HorizontalRule (---)
53
+ - Pagebreak (===)
54
54
  - Inline markups (_, *, `, []{}, {}, ![]{}, !{}, \[](), ++, ~~, (()), ...)
55
55
  - Inline HTML tags (\<bdi>, \<bdo>)
56
56
  - Autolink (https://host, user@host, @user)
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.265.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.267.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
2
2
  (function webpackUniversalModuleDefinition(root, factory) {
3
3
  if(typeof exports === 'object' && typeof module === 'object')
4
4
  module.exports = factory(require("Prism"), require("DOMPurify"));
@@ -3908,6 +3908,7 @@ function bind(target, settings) {
3908
3908
  })
3909
3909
  };
3910
3910
 
3911
+ if (context.id?.match(/[^0-9a-z-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
3911
3912
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
3912
3913
  const blocks = [];
3913
3914
  const adds = [];
@@ -4224,7 +4225,7 @@ const footnote_1 = __webpack_require__(7529);
4224
4225
  const url_1 = __webpack_require__(2261);
4225
4226
  const dom_1 = __webpack_require__(3252);
4226
4227
  function parse(source, opts = {}, context) {
4227
- if (!(0, segment_1.validate)(source, segment_1.MAX_SEGMENT_SIZE)) throw new Error(`Too large input over ${segment_1.MAX_SEGMENT_SIZE.toLocaleString('en')} bytes.`);
4228
+ if (!(0, segment_1.validate)(source, segment_1.MAX_SEGMENT_SIZE)) throw new Error(`Too large input over ${segment_1.MAX_SEGMENT_SIZE.toLocaleString('en')} bytes`);
4228
4229
  const url = (0, header_2.headers)(source).find(field => field.toLowerCase().startsWith('url:'))?.slice(4).trim() ?? '';
4229
4230
  source = !context ? (0, normalize_1.normalize)(source) : source;
4230
4231
  context = {
@@ -4240,6 +4241,7 @@ function parse(source, opts = {}, context) {
4240
4241
  })
4241
4242
  };
4242
4243
 
4244
+ if (context.id?.match(/[^0-9a-z-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
4243
4245
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
4244
4246
  const node = (0, dom_1.frag)();
4245
4247
  let index = 0;
@@ -4312,7 +4314,7 @@ Object.defineProperty(exports, "__esModule", ({
4312
4314
  exports.block = void 0;
4313
4315
  const combinator_1 = __webpack_require__(2087);
4314
4316
  const source_1 = __webpack_require__(6743);
4315
- const horizontalrule_1 = __webpack_require__(9967);
4317
+ const pagebreak_1 = __webpack_require__(4107);
4316
4318
  const heading_1 = __webpack_require__(4623);
4317
4319
  const ulist_1 = __webpack_require__(5425);
4318
4320
  const olist_1 = __webpack_require__(7471);
@@ -4333,7 +4335,7 @@ exports.block = (0, combinator_1.creation)(1, false, error((0, combinator_1.rese
4333
4335
  clock: 50 * 1000,
4334
4336
  recursion: 20
4335
4337
  }
4336
- }, (0, combinator_1.union)([source_1.emptyline, horizontalrule_1.horizontalrule, heading_1.heading, ulist_1.ulist, olist_1.olist, ilist_1.ilist, dlist_1.dlist, table_1.table, codeblock_1.codeblock, mathblock_1.mathblock, extension_1.extension, sidefence_1.sidefence, blockquote_1.blockquote, reply_1.reply, paragraph_1.paragraph]))));
4338
+ }, (0, combinator_1.union)([source_1.emptyline, pagebreak_1.pagebreak, heading_1.heading, ulist_1.ulist, olist_1.olist, ilist_1.ilist, dlist_1.dlist, table_1.table, codeblock_1.codeblock, mathblock_1.mathblock, extension_1.extension, sidefence_1.sidefence, blockquote_1.blockquote, reply_1.reply, paragraph_1.paragraph]))));
4337
4339
  function error(parser) {
4338
4340
  return (0, combinator_1.recover)((0, combinator_1.fallback)((0, combinator_1.open)('\x07', ({
4339
4341
  source
@@ -4548,7 +4550,7 @@ exports.aside = (0, combinator_1.block)((0, combinator_1.validate)('~~~', (0, co
4548
4550
  'data-invalid-message': 'Missing the title at the first line'
4549
4551
  }, `${opener}${body}${closer}`)];
4550
4552
  return [(0, dom_1.html)('aside', {
4551
- id: (0, indexee_1.identity)((0, indexee_1.text)(heading)),
4553
+ id: (0, indexee_1.identity)(context.id, (0, indexee_1.text)(heading)),
4552
4554
  class: 'aside'
4553
4555
  }, [document, (0, dom_1.html)('h2', 'References'), references])];
4554
4556
  })));
@@ -5166,22 +5168,6 @@ exports.heading = (0, combinator_1.block)((0, combinator_1.rewrite)(exports.segm
5166
5168
 
5167
5169
  /***/ }),
5168
5170
 
5169
- /***/ 9967:
5170
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
5171
-
5172
- "use strict";
5173
-
5174
-
5175
- Object.defineProperty(exports, "__esModule", ({
5176
- value: true
5177
- }));
5178
- exports.horizontalrule = void 0;
5179
- const combinator_1 = __webpack_require__(2087);
5180
- const dom_1 = __webpack_require__(3252);
5181
- exports.horizontalrule = (0, combinator_1.block)((0, combinator_1.line)((0, combinator_1.focus)(/^-{3,}[^\S\n]*(?:$|\n)/, () => [[(0, dom_1.html)('hr')], ''])));
5182
-
5183
- /***/ }),
5184
-
5185
5171
  /***/ 238:
5186
5172
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
5187
5173
 
@@ -5354,6 +5340,22 @@ function format(el, type, form) {
5354
5340
 
5355
5341
  /***/ }),
5356
5342
 
5343
+ /***/ 4107:
5344
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
5345
+
5346
+ "use strict";
5347
+
5348
+
5349
+ Object.defineProperty(exports, "__esModule", ({
5350
+ value: true
5351
+ }));
5352
+ exports.pagebreak = void 0;
5353
+ const combinator_1 = __webpack_require__(2087);
5354
+ const dom_1 = __webpack_require__(3252);
5355
+ exports.pagebreak = (0, combinator_1.block)((0, combinator_1.line)((0, combinator_1.focus)(/^={3,}[^\S\n]*(?:$|\n)/, () => [[(0, dom_1.html)('hr')], ''])));
5356
+
5357
+ /***/ }),
5358
+
5357
5359
  /***/ 6457:
5358
5360
  /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
5359
5361
 
@@ -5803,7 +5805,7 @@ const link_1 = __webpack_require__(9628);
5803
5805
  const source_1 = __webpack_require__(6743);
5804
5806
  const dom_1 = __webpack_require__(3252);
5805
5807
  // https://example/@user must be a user page or a redirect page going there.
5806
- exports.account = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.constraint)(1 /* State.shortcut */, false, (0, combinator_1.open)('@', (0, combinator_1.tails)([(0, combinator_1.verify)((0, source_1.str)(/^[0-9a-z](?:(?:[0-9a-z]|-(?=\w)){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=\w)){0,61}[0-9a-z])?)*\//i), ([source]) => source.length <= 253 + 1), (0, source_1.str)(/^[a-z](?:-(?=[0-9a-z])|[0-9a-z]){0,63}/i)]))), (0, combinator_1.convert)(source => `[${source}]{ ${source.includes('/') ? `https://${source.slice(1).replace('/', '/@')}` : `/${source}`} }`, (0, combinator_1.union)([link_1.unsafelink]))), ([el]) => [(0, dom_1.define)(el, {
5808
+ exports.account = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.constraint)(1 /* State.shortcut */, false, (0, combinator_1.open)('@', (0, combinator_1.tails)([(0, source_1.str)(/^[0-9a-z](?:(?:[0-9a-z]|-(?=\w)){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=\w)){0,61}[0-9a-z])?)*\//i), (0, source_1.str)(/^[a-z][0-9a-z]*(?:-[0-9a-z]+)*/i)]))), (0, combinator_1.convert)(source => `[${source}]{ ${source.includes('/') ? `https://${source.slice(1).replace('/', '/@')}` : `/${source}`} }`, (0, combinator_1.union)([link_1.unsafelink]))), ([el]) => [(0, dom_1.define)(el, {
5807
5809
  class: 'account'
5808
5810
  })]));
5809
5811
 
@@ -5824,11 +5826,12 @@ const link_1 = __webpack_require__(9628);
5824
5826
  const dom_1 = __webpack_require__(3252);
5825
5827
  // Timeline(pseudonym): user/tid
5826
5828
  // Thread(anonymous): cid
5827
- // tid: YYYY-MM-DD-HH-MM-SS-TMZ
5828
- // cid: YYYY-MM-DD-HH-MM-SS-mmm-TMZ
5829
+ // UTC
5830
+ // tid: YYYY-MMDD-HHMM-SS
5831
+ // cid: YYYY-MMDD-HHMM-SSmmm
5829
5832
  // 内部表現はUnixTimeに統一する(時系列順)
5830
5833
  // 外部表現は投稿ごとに投稿者の投稿時のタイムゾーンに統一する(非時系列順)
5831
- exports.anchor = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('>>', (0, combinator_1.fmap)((0, combinator_1.constraint)(1 /* State.shortcut */, false, (0, combinator_1.focus)(/^>>(?:[a-z][0-9a-z]*(?:-[0-9a-z]+)*\/)?[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9a-z@#:])/i, (0, combinator_1.convert)(source => `[${source}]{ ${source.includes('/') ? `/@${source.slice(2).replace('/', '/timeline/')}` : `?at=${source.slice(2)}`} }`, (0, combinator_1.union)([link_1.unsafelink])))), ([el]) => [(0, dom_1.define)(el, {
5834
+ exports.anchor = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('>>', (0, combinator_1.fmap)((0, combinator_1.constraint)(1 /* State.shortcut */, false, (0, combinator_1.focus)(/^>>(?:[a-z][0-9a-z]*(?:-[0-9a-z]+)*\/)?[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9a-z@#:])/i, (0, combinator_1.convert)(source => `[${source}]{ ${source.includes('/') ? `/@${source.slice(2).replace('/', '/timeline?at=')}` : `?at=${source.slice(2)}`} }`, (0, combinator_1.union)([link_1.unsafelink])))), ([el]) => [(0, dom_1.define)(el, {
5832
5835
  class: 'anchor'
5833
5836
  })])));
5834
5837
 
@@ -5852,7 +5855,6 @@ const dom_1 = __webpack_require__(3252);
5852
5855
  // https://example/@user?ch=a+b must be a user channel page or a redirect page going there.
5853
5856
  exports.channel = (0, combinator_1.validate)('@', (0, combinator_1.bind)((0, combinator_1.sequence)([account_1.account, (0, combinator_1.some)(hashtag_1.hashtag)]), (es, rest) => {
5854
5857
  const source = (0, util_1.stringify)(es);
5855
- if (source.includes('/', source.indexOf('#'))) return;
5856
5858
  const el = es[0];
5857
5859
  const url = `${el.getAttribute('href')}?ch=${source.slice(source.indexOf('#') + 1).replace(/#/g, '+')}`;
5858
5860
  return [[(0, dom_1.define)(el, {
@@ -5925,9 +5927,9 @@ const dom_1 = __webpack_require__(3252);
5925
5927
  // https://example/hashtags/a must be a hashtag page or a redirect page going there.
5926
5928
  // https://github.com/tc39/proposal-regexp-unicode-property-escapes#matching-emoji
5927
5929
  exports.emoji = String.raw`\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F`;
5928
- exports.hashtag = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.constraint)(1 /* State.shortcut */, false, (0, combinator_1.open)('#', (0, combinator_1.tails)([(0, combinator_1.verify)((0, source_1.str)(/^[0-9a-z](?:(?:[0-9a-z]|-(?=\w)){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=\w)){0,61}[0-9a-z])?)*\//i), ([source]) => source.length <= 253 + 1), (0, combinator_1.verify)((0, source_1.str)(new RegExp([/^(?=(?:[0-9]{1,127}_?)?(?:[^\d\p{C}\p{S}\p{P}\s]|emoji|'))/u.source, /(?:[^\p{C}\p{S}\p{P}\s]|emoji|(?<!')'|_(?=[^\p{C}\p{S}\p{P}\s]|emoji|')){1,128}/u.source, /(?!_?(?:[^\p{C}\p{S}\p{P}\s]|emoji|(?<!')'))/u.source].join('').replace(/emoji/g, exports.emoji), 'u')), ([source]) => source.length <= 128)]))), (0, combinator_1.convert)(source => `[${source}]{ ${source.includes('/') ? `https://${source.slice(1).replace('/', '/hashtags/')}` : `/hashtags/${source.slice(1)}`} }`, (0, combinator_1.union)([link_1.unsafelink]))), ([el]) => [(0, dom_1.define)(el, {
5930
+ exports.hashtag = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combinator_1.rewrite)((0, combinator_1.constraint)(1 /* State.shortcut */, false, (0, combinator_1.open)('#', (0, source_1.str)(new RegExp([/^(?=(?:[0-9]{1,15})?(?:[^\d\p{C}\p{S}\p{P}\s]|emoji|'))/u.source, /(?:[^\p{C}\p{S}\p{P}\s]|emoji|(?<!')'|_(?=[^\p{C}\p{S}\p{P}\s]|emoji|'))+/u.source].join('').replace(/emoji/g, exports.emoji), 'u')))), (0, combinator_1.convert)(source => `[${source}]{ ${`/hashtags/${source.slice(1)}`} }`, (0, combinator_1.union)([link_1.unsafelink]))), ([el]) => [(0, dom_1.define)(el, {
5929
5931
  class: 'hashtag'
5930
- }, el.innerText)]));
5932
+ })]));
5931
5933
 
5932
5934
  /***/ }),
5933
5935
 
@@ -6104,7 +6106,7 @@ exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('[#', (0
6104
6106
  }, el.childNodes)])));
6105
6107
  const signature = (0, combinator_1.lazy)(() => (0, combinator_1.creation)((0, combinator_1.fmap)((0, combinator_1.open)('|', (0, visibility_1.startTight)((0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ']'))), ns => [(0, dom_1.html)('span', {
6106
6108
  class: 'indexer',
6107
- 'data-index': (0, indexee_1.identity)(ns.join('')).slice(6)
6109
+ 'data-index': (0, indexee_1.identity)(undefined, ns.join('')).slice(7)
6108
6110
  })])));
6109
6111
  const bracket = (0, combinator_1.lazy)(() => (0, combinator_1.creation)((0, combinator_1.union)([(0, combinator_1.surround)((0, source_1.str)('('), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ')'), (0, source_1.str)(')'), true), (0, combinator_1.surround)((0, source_1.str)('['), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), ']'), (0, source_1.str)(']'), true), (0, combinator_1.surround)((0, source_1.str)('{'), (0, combinator_1.some)((0, combinator_1.union)([bracket, source_1.txt]), '}'), (0, source_1.str)('}'), true), (0, combinator_1.surround)((0, source_1.str)('"'), (0, combinator_1.precedence)(8, (0, combinator_1.some)(source_1.txt, '"')), (0, source_1.str)('"'), true)])));
6110
6112
 
@@ -6126,18 +6128,20 @@ function indexee(parser, optional) {
6126
6128
  return (0, combinator_1.fmap)(parser, ([el], _, {
6127
6129
  id
6128
6130
  }) => [(0, dom_1.define)(el, {
6129
- id: id !== '' && identity(text(el, optional)) || undefined
6131
+ id: identity(id, text(el, optional))
6130
6132
  })]);
6131
6133
  }
6132
6134
  exports.indexee = indexee;
6133
- function identity(text, name = 'index') {
6135
+ function identity(id, text, name = 'index') {
6136
+ if (id === '') return undefined;
6134
6137
  text &&= text.trim().replace(/\s+/g, '_');
6135
- if (text.length <= 100) return text && `${name}:${text}`;
6138
+ if (text === '') return undefined;
6139
+ if (text.length <= 100) return `${name}:${id ?? ''}:${text}`;
6136
6140
  switch (name) {
6137
6141
  case 'index':
6138
- return `${name}:${text.slice(0, 97)}...`;
6142
+ return `${name}:${id ?? ''}:${text.slice(0, 97)}...`;
6139
6143
  case 'mark':
6140
- return `${name}:${text.slice(0, 50)}...${text.slice(-47)}`;
6144
+ return `${name}:${id ?? ''}:${text.slice(0, 50)}...${text.slice(-47)}`;
6141
6145
  }
6142
6146
  }
6143
6147
  exports.identity = identity;
@@ -6200,7 +6204,7 @@ exports.indexer = (0, combinator_1.creation)((0, combinator_1.fmap)((0, combinat
6200
6204
  // Indexer is invisible but invalids must be visible.
6201
6205
  ([el]) => el.getElementsByClassName('invalid').length === 0), ([el]) => [(0, dom_1.html)('span', {
6202
6206
  class: 'indexer',
6203
- 'data-index': el.getAttribute('href').slice(7)
6207
+ 'data-index': el.getAttribute('href').slice(1).replace(/^\w+:\w*:/, '')
6204
6208
  })]));
6205
6209
 
6206
6210
  /***/ }),
@@ -6485,6 +6489,7 @@ function resolve(uri, host, source) {
6485
6489
  case uri.slice(0, 2) === '^/':
6486
6490
  const last = host.pathname.slice(host.pathname.lastIndexOf('/') + 1);
6487
6491
  return last.includes('.') // isFile
6492
+ // Exclude ISO 6709.
6488
6493
  && /^[0-9]*[a-z][0-9a-z]*$/i.test(last.slice(last.lastIndexOf('.') + 1)) ? `${host.pathname.slice(0, -last.length)}${uri.slice(2)}` : `${host.pathname.replace(/\/?$/, '/')}${uri.slice(2)}`;
6489
6494
  case host.origin === source.origin && host.pathname === source.pathname:
6490
6495
  case uri.slice(0, 2) === '//':
@@ -6533,7 +6538,7 @@ exports.mark = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, sourc
6533
6538
  }) => {
6534
6539
  const el = (0, dom_1.html)('mark', (0, dom_1.defrag)(bs));
6535
6540
  (0, dom_1.define)(el, {
6536
- id: id !== '' && (0, indexee_1.identity)((0, indexee_1.text)(el), 'mark') || undefined
6541
+ id: (0, indexee_1.identity)(id, (0, indexee_1.text)(el), 'mark')
6537
6542
  });
6538
6543
  return [[el, (0, dom_1.html)('a', {
6539
6544
  href: el.id ? `#${el.id}` : undefined
@@ -7071,16 +7076,18 @@ function build(syntax, marker, splitter) {
7071
7076
  for (let refs = target.querySelectorAll(`sup.${syntax}:not(.disabled)`), len = refs.length, i = 0; i < len; ++i) {
7072
7077
  yield;
7073
7078
  const ref = refs[i];
7074
- while (+splitters[0]?.compareDocumentPosition(ref) & Node.DOCUMENT_POSITION_FOLLOWING) {
7079
+ while (splitters.length > 0 && splitters[0].compareDocumentPosition(ref) & Node.DOCUMENT_POSITION_FOLLOWING) {
7075
7080
  if (defs.size > 0) {
7076
7081
  total += defs.size;
7077
7082
  yield* proc(defs, target.insertBefore((0, dom_1.html)('ol', {
7078
7083
  class: `${syntax}s`
7079
- }), splitters[0] ?? null));
7084
+ }), splitters[0]));
7085
+ } else if (splitters.length % 100 === 0) {
7086
+ yield;
7080
7087
  }
7081
7088
  splitters.shift();
7082
7089
  }
7083
- const identifier = `${+!ref.querySelector('.label')}:${ref.getAttribute('data-abbr') || '_' + ref.firstElementChild.innerHTML}`;
7090
+ const identifier = ref.getAttribute('data-abbr') || ` ${ref.firstElementChild.innerHTML}`;
7084
7091
  const abbr = ref.getAttribute('data-abbr') || undefined;
7085
7092
  const content = (0, dom_1.frag)(ref.firstElementChild.cloneNode(true).childNodes);
7086
7093
  style ??= abbr ? 'abbr' : 'count';
@@ -7104,13 +7111,13 @@ function build(syntax, marker, splitter) {
7104
7111
  } else {
7105
7112
  ref.lastChild?.remove();
7106
7113
  }
7107
- const title = false || titles.get(identifier) || +identifier[0] && ref.title || (0, indexee_1.text)(content).trim() || content.textContent.trim() || undefined;
7114
+ const title = titles.get(identifier) || (0, indexee_1.text)(content).trim() || undefined;
7108
7115
  title ? !titles.has(identifier) && titles.set(identifier, title) : buffer.set(identifier, ref);
7109
7116
  const blank = !!abbr && !content.firstChild;
7110
7117
  const refIndex = ++count;
7111
- const refId = opts.id !== '' ? ref.id || `${syntax}:${opts.id ? `${opts.id}:` : ''}ref:${refIndex}` : undefined;
7118
+ const refId = opts.id !== '' ? `${syntax}:${opts.id ?? ''}:ref:${refIndex}` : undefined;
7112
7119
  const def = false || defs.get(identifier) || defs.set(identifier, (0, dom_1.html)('li', {
7113
- id: opts.id !== '' ? `${syntax}:${opts.id ? `${opts.id}:` : ''}def:${total + defs.size + 1}` : undefined,
7120
+ id: opts.id !== '' ? `${syntax}:${opts.id ?? ''}:def:${total + defs.size + 1}` : undefined,
7114
7121
  'data-marker': !footnote ? marker(total + defs.size + 1, abbr) : undefined
7115
7122
  }, [content.cloneNode(true), (0, dom_1.html)('sup')])).get(identifier);
7116
7123
  if (title && !blank && def.childNodes.length === 1) {
package/index.d.ts CHANGED
@@ -28,7 +28,7 @@ export type ParserOptions = Omit<Partial<ParserSettings>, 'chunk'>;
28
28
  export interface ParserSettings {
29
29
  // Host URL.
30
30
  readonly host?: URL;
31
- // Id of comments and timelines.
31
+ // Alphanumeric ID of comments and timelines.
32
32
  readonly id?: string;
33
33
  // For editing.
34
34
  readonly caches?: Partial<Caches>;
@@ -39,12 +39,12 @@ export interface ParserSettings {
39
39
  }
40
40
 
41
41
  export type Progress =
42
- | { type: 'segment', value: string; }
43
- | { type: 'block', value: HTMLElement }
44
- | { type: 'figure', value: HTMLAnchorElement }
45
- | { type: 'footnote', value: HTMLLIElement | HTMLElement }
46
- | { type: 'break' }
47
- | { type: 'cancel' };
42
+ | { readonly type: 'segment'; readonly value: string; }
43
+ | { readonly type: 'block'; readonly value: HTMLElement; }
44
+ | { readonly type: 'figure'; readonly value: HTMLAnchorElement; }
45
+ | { readonly type: 'footnote'; readonly value: HTMLLIElement | HTMLElement; }
46
+ | { readonly type: 'break'; }
47
+ | { readonly type: 'cancel'; };
48
48
 
49
49
  export interface RenderingOptions {
50
50
  readonly code?: (target: HTMLElement, cache?: Dict<string, HTMLElement>) => void;
package/markdown.d.ts CHANGED
@@ -59,7 +59,7 @@ export namespace MarkdownParser {
59
59
  Markdown<'block'>,
60
60
  Parser<HTMLElement, Context, [
61
61
  SourceParser.EmptyLineParser,
62
- BlockParser.HorizontalRuleParser,
62
+ BlockParser.PagebreakParser,
63
63
  BlockParser.HeadingParser,
64
64
  BlockParser.UListParser,
65
65
  BlockParser.OListParser,
@@ -77,9 +77,9 @@ export namespace MarkdownParser {
77
77
  }
78
78
  export namespace BlockParser {
79
79
  interface Block<T extends string> extends Markdown<`block/${T}`> { }
80
- export interface HorizontalRuleParser extends
81
- // ---
82
- Block<'horizontalrule'>,
80
+ export interface PagebreakParser extends
81
+ // ===
82
+ Block<'pagebreak'>,
83
83
  Parser<HTMLHRElement, Context, [
84
84
  SourceParser.StrParser,
85
85
  ]> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.265.0",
3
+ "version": "0.267.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",
@@ -122,7 +122,7 @@ describe('Unit: parser/api/bind', () => {
122
122
  });
123
123
 
124
124
  it('complex', () => {
125
- assert.deepStrictEqual(inspect(bind(html('div'), cfgs).parse('# a\n# b')), ['<h1 id="index:a">a</h1>', '<h1 id="index:b">b</h1>']);
125
+ assert.deepStrictEqual(inspect(bind(html('div'), cfgs).parse('# a\n# b')), ['<h1 id="index::a">a</h1>', '<h1 id="index::b">b</h1>']);
126
126
  });
127
127
 
128
128
  it('normalize', () => {
@@ -158,10 +158,10 @@ describe('Unit: parser/api/bind', () => {
158
158
  assert(el.innerHTML === '<p>1</p><p>2</p><p>4</p>');
159
159
  [...update('')];
160
160
  assert(el.innerHTML === '');
161
- assert.deepStrictEqual(inspect(update('# a\n# b'), 1), ['<h1 id="index:a">a</h1>']);
162
- assert(el.innerHTML === '<h1 id="index:a">a</h1>');
163
- assert.deepStrictEqual(inspect(update('# a\n# b'), 2), ['<h1 id="index:b">b</h1>']);
164
- assert(el.innerHTML === '<h1 id="index:a">a</h1><h1 id="index:b">b</h1>');
161
+ assert.deepStrictEqual(inspect(update('# a\n# b'), 1), ['<h1 id="index::a">a</h1>']);
162
+ assert(el.innerHTML === '<h1 id="index::a">a</h1>');
163
+ assert.deepStrictEqual(inspect(update('# a\n# b'), 2), ['<h1 id="index::b">b</h1>']);
164
+ assert(el.innerHTML === '<h1 id="index::a">a</h1><h1 id="index::b">b</h1>');
165
165
  });
166
166
 
167
167
  it('chunk', () => {
@@ -192,38 +192,38 @@ describe('Unit: parser/api/bind', () => {
192
192
  [...el.children].map(el => el.outerHTML),
193
193
  [
194
194
  html('p', [
195
- html('sup', { class: "reference", id: "reference:ref:1", title: "1" }, [
195
+ html('sup', { class: "reference", id: "reference::ref:1", title: "1" }, [
196
196
  html('span', { hidden: '' }, '1'),
197
- html('a', { href: "#reference:def:1" }, '[1]'),
197
+ html('a', { href: "#reference::def:1" }, '[1]'),
198
198
  ]),
199
199
  ]).outerHTML,
200
200
  html('p', [
201
- html('sup', { class: "reference", id: "reference:ref:2", title: "2" }, [
201
+ html('sup', { class: "reference", id: "reference::ref:2", title: "2" }, [
202
202
  html('span', { hidden: '' }, '2'),
203
- html('a', { href: "#reference:def:2" }, '[2]'),
203
+ html('a', { href: "#reference::def:2" }, '[2]'),
204
204
  ]),
205
205
  ]).outerHTML,
206
206
  html('p', [
207
- html('sup', { class: "reference", id: "reference:ref:3", title: "3" }, [
207
+ html('sup', { class: "reference", id: "reference::ref:3", title: "3" }, [
208
208
  html('span', { hidden: '' }, '3'),
209
- html('a', { href: "#reference:def:3" }, '[3]'),
209
+ html('a', { href: "#reference::def:3" }, '[3]'),
210
210
  ]),
211
211
  ]).outerHTML,
212
212
  ]);
213
213
  assert.deepStrictEqual(
214
214
  cfgs.footnotes.references?.outerHTML,
215
215
  html('ol', [
216
- html('li', { id: 'reference:def:1' }, [
216
+ html('li', { id: 'reference::def:1' }, [
217
217
  '1',
218
- html('sup', [html('a', { href: '#reference:ref:1' }, '^1')]),
218
+ html('sup', [html('a', { href: '#reference::ref:1' }, '^1')]),
219
219
  ]),
220
- html('li', { id: 'reference:def:2' }, [
220
+ html('li', { id: 'reference::def:2' }, [
221
221
  '2',
222
- html('sup', [html('a', { href: '#reference:ref:2' }, '^2')]),
222
+ html('sup', [html('a', { href: '#reference::ref:2' }, '^2')]),
223
223
  ]),
224
- html('li', { id: 'reference:def:3' }, [
224
+ html('li', { id: 'reference::def:3' }, [
225
225
  '3',
226
- html('sup', [html('a', { href: '#reference:ref:3' }, '^3')]),
226
+ html('sup', [html('a', { href: '#reference::ref:3' }, '^3')]),
227
227
  ]),
228
228
  ]).outerHTML);
229
229
  assert.throws(() => update('').next());
@@ -26,6 +26,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
26
26
  host: settings.host ?? new ReadonlyURL(location.pathname, location.origin),
27
27
  memo: new Memo({ targets: State.backtrackers }),
28
28
  };
29
+ if (context.id?.match(/[^0-9a-z-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
29
30
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
30
31
  assert(!settings.id);
31
32
  type Block = readonly [segment: string, blocks: readonly HTMLElement[], url: string];
@@ -99,7 +99,6 @@ describe('Unit: parser/api/parse', () => {
99
99
  '@a#b',
100
100
  '@domain/a#b',
101
101
  '#a',
102
- '#domain/a',
103
102
  '[#a]',
104
103
  '$-a\n$$\n$$',
105
104
  '$-a',
@@ -122,11 +121,10 @@ describe('Unit: parser/api/parse', () => {
122
121
  '<p><a class="channel" href="https://source/@a?ch=b" target="_blank">@a#b</a></p>',
123
122
  '<p><a class="channel" href="https://domain/@a?ch=b" target="_blank">@domain/a#b</a></p>',
124
123
  '<p><a class="hashtag" href="https://source/hashtags/a" target="_blank">#a</a></p>',
125
- '<p><a class="hashtag" href="https://domain/hashtags/a" target="_blank">#domain/a</a></p>',
126
- '<p><a class="index" href="#index:a">a</a></p>',
124
+ '<p><a class="index" href="#index::a">a</a></p>',
127
125
  '<figure data-type="math" data-label="$-a" data-group="$" data-number="1" id="label:$-a"><figcaption><span class="figindex">(1)</span><span class="figtext"></span></figcaption><div><div class="math" translate="no">$$\n$$</div></div></figure>',
128
126
  '<p><a class="label" data-label="$-a" href="#label:$-a">(1)</a></p>',
129
- '<p><sup class="annotation" id="annotation:ref:1" title="a"><span hidden="">a</span><a href="#annotation:def:1">*1</a></sup></p>',
127
+ '<p><sup class="annotation" id="annotation::ref:1" title="a"><span hidden="">a</span><a href="#annotation::def:1">*1</a></sup></p>',
130
128
  '<p><a class="url" href="https://source/x/a" target="_blank">a</a></p>',
131
129
  '<p><a class="url" href="https://source/a" target="_blank">/a</a></p>',
132
130
  '<p><a class="url" href="/z/a">^/a</a></p>',
@@ -137,7 +135,7 @@ describe('Unit: parser/api/parse', () => {
137
135
  '<p><a href="https://source/x/a" target="_blank"><img class="media" data-src="https://source/x/a" alt=""></a></p>',
138
136
  '<p><a href="/z/a" target="_blank"><img class="media" data-src="/z/a" alt=""></a></p>',
139
137
  '<p><a href="https://source/a" target="_blank"><img class="media" data-src="https://source/a" alt=""></a></p>',
140
- '<ol class="annotations"><li id="annotation:def:1" data-marker="*1">a<sup><a href="#annotation:ref:1">^1</a></sup></li></ol>',
138
+ '<ol class="annotations"><li id="annotation::def:1" data-marker="*1">a<sup><a href="#annotation::ref:1">^1</a></sup></li></ol>',
141
139
  ]);
142
140
  assert.deepStrictEqual(
143
141
  [...parse([
@@ -209,12 +207,12 @@ describe('Unit: parser/api/parse', () => {
209
207
  [...parse('$-a\n$$\n$$\n\n(($-a[[b]][[c_d_]]))', { footnotes }).children].map(el => el.outerHTML),
210
208
  [
211
209
  '<figure data-type="math" data-label="$-a" data-group="$" data-number="1" id="label:$-a"><figcaption><span class="figindex">(1)</span><span class="figtext"></span></figcaption><div><div class="math" translate="no">$$\n$$</div></div></figure>',
212
- '<p><sup class="annotation" id="annotation:ref:1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" id="reference:ref:1" title="b"><span hidden="">b</span><a href="#reference:def:1">[1]</a></sup><sup class="reference" id="reference:ref:2" title="cd"><span hidden="">c<em>d</em></span><a href="#reference:def:2">[2]</a></sup></span><a href="#annotation:def:1">*1</a></sup></p>',
213
- '<ol class="annotations"><li id="annotation:def:1" data-marker="*1"><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" id="reference:ref:1" title="b"><span hidden="">b</span><a href="#reference:def:1">[1]</a></sup><sup class="reference" id="reference:ref:2" title="cd"><span hidden="">c<em>d</em></span><a href="#reference:def:2">[2]</a></sup><sup><a href="#annotation:ref:1">^1</a></sup></li></ol>',
210
+ '<p><sup class="annotation" id="annotation::ref:1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" id="reference::ref:1" title="b"><span hidden="">b</span><a href="#reference::def:1">[1]</a></sup><sup class="reference" id="reference::ref:2" title="cd"><span hidden="">c<em>d</em></span><a href="#reference::def:2">[2]</a></sup></span><a href="#annotation::def:1">*1</a></sup></p>',
211
+ '<ol class="annotations"><li id="annotation::def:1" data-marker="*1"><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" id="reference::ref:1" title="b"><span hidden="">b</span><a href="#reference::def:1">[1]</a></sup><sup class="reference" id="reference::ref:2" title="cd"><span hidden="">c<em>d</em></span><a href="#reference::def:2">[2]</a></sup><sup><a href="#annotation::ref:1">^1</a></sup></li></ol>',
214
212
  ]);
215
213
  assert.deepStrictEqual(
216
214
  footnotes.references.outerHTML,
217
- '<ol><li id="reference:def:1">b<sup><a href="#reference:ref:1">^1</a></sup></li><li id="reference:def:2">c<em>d</em><sup><a href="#reference:ref:2">^2</a></sup></li></ol>');
215
+ '<ol><li id="reference::def:1">b<sup><a href="#reference::ref:1">^1</a></sup></li><li id="reference::def:2">c<em>d</em><sup><a href="#reference::ref:2">^2</a></sup></li></ol>');
218
216
  });
219
217
 
220
218
  it('normalize', () => {
@@ -18,7 +18,7 @@ interface Options extends ParserOptions {
18
18
  }
19
19
 
20
20
  export function parse(source: string, opts: Options = {}, context?: MarkdownParser.Context): DocumentFragment {
21
- if (!validate(source, MAX_SEGMENT_SIZE)) throw new Error(`Too large input over ${MAX_SEGMENT_SIZE.toLocaleString('en')} bytes.`);
21
+ if (!validate(source, MAX_SEGMENT_SIZE)) throw new Error(`Too large input over ${MAX_SEGMENT_SIZE.toLocaleString('en')} bytes`);
22
22
  const url = headers(source).find(field => field.toLowerCase().startsWith('url:'))?.slice(4).trim() ?? '';
23
23
  source = !context ? normalize(source) : source;
24
24
  assert(!context?.delimiters);
@@ -32,6 +32,7 @@ export function parse(source: string, opts: Options = {}, context?: MarkdownPars
32
32
  },
33
33
  memo: new Memo({ targets: State.backtrackers }),
34
34
  };
35
+ if (context.id?.match(/[^0-9a-z-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
35
36
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
36
37
  const node = frag();
37
38
  let index = 0;
@@ -31,46 +31,46 @@ describe('Unit: parser/block/dlist', () => {
31
31
  });
32
32
 
33
33
  it('single', () => {
34
- assert.deepStrictEqual(inspect(parser('~ a')), [['<dl><dt id="index:a">a</dt><dd></dd></dl>'], '']);
35
- assert.deepStrictEqual(inspect(parser('~ \\')), [['<dl><dt id="index:\\">\\</dt><dd></dd></dl>'], '']);
36
- assert.deepStrictEqual(inspect(parser('~ \\ a')), [['<dl><dt id="index:a">a</dt><dd></dd></dl>'], '']);
37
- assert.deepStrictEqual(inspect(parser('~ a\nb')), [['<dl><dt id="index:a">a</dt><dd>b</dd></dl>'], '']);
38
- assert.deepStrictEqual(inspect(parser('~ a\nb\n')), [['<dl><dt id="index:a">a</dt><dd>b</dd></dl>'], '']);
39
- assert.deepStrictEqual(inspect(parser('~ a\nb\nc')), [['<dl><dt id="index:a">a</dt><dd>b<br>c</dd></dl>'], '']);
40
- assert.deepStrictEqual(inspect(parser('~ a\nb\n\\\nc')), [['<dl><dt id="index:a">a</dt><dd>b<br>\\<br>c</dd></dl>'], '']);
41
- assert.deepStrictEqual(inspect(parser('~ a\n~')), [['<dl><dt id="index:a">a</dt><dd>~</dd></dl>'], '']);
42
- assert.deepStrictEqual(inspect(parser('~ a\n~b')), [['<dl><dt id="index:a">a</dt><dd>~b</dd></dl>'], '']);
43
- assert.deepStrictEqual(inspect(parser('~ a\n~ b')), [['<dl><dt id="index:a">a</dt><dt id="index:b">b</dt><dd></dd></dl>'], '']);
44
- assert.deepStrictEqual(inspect(parser('~ a\n:')), [['<dl><dt id="index:a">a</dt><dd>:</dd></dl>'], '']);
45
- assert.deepStrictEqual(inspect(parser('~ a\n: ')), [['<dl><dt id="index:a">a</dt><dd>:</dd></dl>'], '']);
46
- assert.deepStrictEqual(inspect(parser('~ a\n: \n')), [['<dl><dt id="index:a">a</dt><dd>:</dd></dl>'], '']);
47
- assert.deepStrictEqual(inspect(parser('~ a\n: \\')), [['<dl><dt id="index:a">a</dt><dd>\\</dd></dl>'], '']);
48
- assert.deepStrictEqual(inspect(parser('~ a\n:b')), [['<dl><dt id="index:a">a</dt><dd>:b</dd></dl>'], '']);
49
- assert.deepStrictEqual(inspect(parser('~ a\n: b')), [['<dl><dt id="index:a">a</dt><dd>b</dd></dl>'], '']);
50
- assert.deepStrictEqual(inspect(parser('~ a\n: b\n')), [['<dl><dt id="index:a">a</dt><dd>b</dd></dl>'], '']);
51
- assert.deepStrictEqual(inspect(parser('~ a\n: b\nc')), [['<dl><dt id="index:a">a</dt><dd>b<br>c</dd></dl>'], '']);
52
- assert.deepStrictEqual(inspect(parser('~ a\n: b\n\\\nc')), [['<dl><dt id="index:a">a</dt><dd>b<br>\\<br>c</dd></dl>'], '']);
53
- assert.deepStrictEqual(inspect(parser('~ a~ b')), [['<dl><dt id="index:a~_b">a~ b</dt><dd></dd></dl>'], '']);
54
- assert.deepStrictEqual(inspect(parser('~ a: b')), [['<dl><dt id="index:a:_b">a: b</dt><dd></dd></dl>'], '']);
55
- assert.deepStrictEqual(inspect(parser('~ a \n: b \nc ')), [['<dl><dt id="index:a">a</dt><dd>b<br>c</dd></dl>'], '']);
56
- assert.deepStrictEqual(inspect(parser('~ a \n: b\n c ')), [['<dl><dt id="index:a">a</dt><dd>b<br> c</dd></dl>'], '']);
34
+ assert.deepStrictEqual(inspect(parser('~ a')), [['<dl><dt id="index::a">a</dt><dd></dd></dl>'], '']);
35
+ assert.deepStrictEqual(inspect(parser('~ \\')), [['<dl><dt id="index::\\">\\</dt><dd></dd></dl>'], '']);
36
+ assert.deepStrictEqual(inspect(parser('~ \\ a')), [['<dl><dt id="index::a">a</dt><dd></dd></dl>'], '']);
37
+ assert.deepStrictEqual(inspect(parser('~ a\nb')), [['<dl><dt id="index::a">a</dt><dd>b</dd></dl>'], '']);
38
+ assert.deepStrictEqual(inspect(parser('~ a\nb\n')), [['<dl><dt id="index::a">a</dt><dd>b</dd></dl>'], '']);
39
+ assert.deepStrictEqual(inspect(parser('~ a\nb\nc')), [['<dl><dt id="index::a">a</dt><dd>b<br>c</dd></dl>'], '']);
40
+ assert.deepStrictEqual(inspect(parser('~ a\nb\n\\\nc')), [['<dl><dt id="index::a">a</dt><dd>b<br>\\<br>c</dd></dl>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('~ a\n~')), [['<dl><dt id="index::a">a</dt><dd>~</dd></dl>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('~ a\n~b')), [['<dl><dt id="index::a">a</dt><dd>~b</dd></dl>'], '']);
43
+ assert.deepStrictEqual(inspect(parser('~ a\n~ b')), [['<dl><dt id="index::a">a</dt><dt id="index::b">b</dt><dd></dd></dl>'], '']);
44
+ assert.deepStrictEqual(inspect(parser('~ a\n:')), [['<dl><dt id="index::a">a</dt><dd>:</dd></dl>'], '']);
45
+ assert.deepStrictEqual(inspect(parser('~ a\n: ')), [['<dl><dt id="index::a">a</dt><dd>:</dd></dl>'], '']);
46
+ assert.deepStrictEqual(inspect(parser('~ a\n: \n')), [['<dl><dt id="index::a">a</dt><dd>:</dd></dl>'], '']);
47
+ assert.deepStrictEqual(inspect(parser('~ a\n: \\')), [['<dl><dt id="index::a">a</dt><dd>\\</dd></dl>'], '']);
48
+ assert.deepStrictEqual(inspect(parser('~ a\n:b')), [['<dl><dt id="index::a">a</dt><dd>:b</dd></dl>'], '']);
49
+ assert.deepStrictEqual(inspect(parser('~ a\n: b')), [['<dl><dt id="index::a">a</dt><dd>b</dd></dl>'], '']);
50
+ assert.deepStrictEqual(inspect(parser('~ a\n: b\n')), [['<dl><dt id="index::a">a</dt><dd>b</dd></dl>'], '']);
51
+ assert.deepStrictEqual(inspect(parser('~ a\n: b\nc')), [['<dl><dt id="index::a">a</dt><dd>b<br>c</dd></dl>'], '']);
52
+ assert.deepStrictEqual(inspect(parser('~ a\n: b\n\\\nc')), [['<dl><dt id="index::a">a</dt><dd>b<br>\\<br>c</dd></dl>'], '']);
53
+ assert.deepStrictEqual(inspect(parser('~ a~ b')), [['<dl><dt id="index::a~_b">a~ b</dt><dd></dd></dl>'], '']);
54
+ assert.deepStrictEqual(inspect(parser('~ a: b')), [['<dl><dt id="index::a:_b">a: b</dt><dd></dd></dl>'], '']);
55
+ assert.deepStrictEqual(inspect(parser('~ a \n: b \nc ')), [['<dl><dt id="index::a">a</dt><dd>b<br>c</dd></dl>'], '']);
56
+ assert.deepStrictEqual(inspect(parser('~ a \n: b\n c ')), [['<dl><dt id="index::a">a</dt><dd>b<br> c</dd></dl>'], '']);
57
57
  });
58
58
 
59
59
  it('multiple', () => {
60
- assert.deepStrictEqual(inspect(parser('~ a\n: b\n~ c\n: d')), [['<dl><dt id="index:a">a</dt><dd>b</dd><dt id="index:c">c</dt><dd>d</dd></dl>'], '']);
61
- assert.deepStrictEqual(inspect(parser('~ a\n b\nc\n d')), [['<dl><dt id="index:a">a</dt><dd> b<br>c<br> d</dd></dl>'], '']);
62
- assert.deepStrictEqual(inspect(parser('~ a\n: b\nc\n: d')), [['<dl><dt id="index:a">a</dt><dd>b<br>c</dd><dd>d</dd></dl>'], '']);
63
- assert.deepStrictEqual(inspect(parser('~ a\n: b\nc\n~ d\n: e')), [['<dl><dt id="index:a">a</dt><dd>b<br>c</dd><dt id="index:d">d</dt><dd>e</dd></dl>'], '']);
64
- assert.deepStrictEqual(inspect(parser('~ a\n: b\n~ c\n: d\n~ e\n: f')), [['<dl><dt id="index:a">a</dt><dd>b</dd><dt id="index:c">c</dt><dd>d</dd><dt id="index:e">e</dt><dd>f</dd></dl>'], '']);
60
+ assert.deepStrictEqual(inspect(parser('~ a\n: b\n~ c\n: d')), [['<dl><dt id="index::a">a</dt><dd>b</dd><dt id="index::c">c</dt><dd>d</dd></dl>'], '']);
61
+ assert.deepStrictEqual(inspect(parser('~ a\n b\nc\n d')), [['<dl><dt id="index::a">a</dt><dd> b<br>c<br> d</dd></dl>'], '']);
62
+ assert.deepStrictEqual(inspect(parser('~ a\n: b\nc\n: d')), [['<dl><dt id="index::a">a</dt><dd>b<br>c</dd><dd>d</dd></dl>'], '']);
63
+ assert.deepStrictEqual(inspect(parser('~ a\n: b\nc\n~ d\n: e')), [['<dl><dt id="index::a">a</dt><dd>b<br>c</dd><dt id="index::d">d</dt><dd>e</dd></dl>'], '']);
64
+ assert.deepStrictEqual(inspect(parser('~ a\n: b\n~ c\n: d\n~ e\n: f')), [['<dl><dt id="index::a">a</dt><dd>b</dd><dt id="index::c">c</dt><dd>d</dd><dt id="index::e">e</dt><dd>f</dd></dl>'], '']);
65
65
  });
66
66
 
67
67
  it('index', () => {
68
- assert.deepStrictEqual(inspect(parser('~ a [#b]')), [['<dl><dt id="index:b">a<span class="indexer" data-index="b"></span></dt><dd></dd></dl>'], '']);
69
- assert.deepStrictEqual(inspect(parser('~ a [#b]\\')), [['<dl><dt id="index:a_[#b]">a [<a class="hashtag" href="/hashtags/b">#b</a>]</dt><dd></dd></dl>'], '']);
70
- assert.deepStrictEqual(inspect(parser('~ A')), [['<dl><dt id="index:A">A</dt><dd></dd></dl>'], '']);
71
- assert.deepStrictEqual(inspect(parser('~ _A_')), [['<dl><dt id="index:A"><em>A</em></dt><dd></dd></dl>'], '']);
72
- assert.deepStrictEqual(inspect(parser('~ `A`')), [['<dl><dt id="index:`A`"><code data-src="`A`">A</code></dt><dd></dd></dl>'], '']);
73
- assert.deepStrictEqual(inspect(parser('~ ${A}$')), [['<dl><dt id="index:${A}$"><span class="math" translate="no" data-src="${A}$">${A}$</span></dt><dd></dd></dl>'], '']);
68
+ assert.deepStrictEqual(inspect(parser('~ a [#b]')), [['<dl><dt id="index::b">a<span class="indexer" data-index="b"></span></dt><dd></dd></dl>'], '']);
69
+ assert.deepStrictEqual(inspect(parser('~ a [#b]\\')), [['<dl><dt id="index::a_[#b]">a [<a class="hashtag" href="/hashtags/b">#b</a>]</dt><dd></dd></dl>'], '']);
70
+ assert.deepStrictEqual(inspect(parser('~ A')), [['<dl><dt id="index::A">A</dt><dd></dd></dl>'], '']);
71
+ assert.deepStrictEqual(inspect(parser('~ _A_')), [['<dl><dt id="index::A"><em>A</em></dt><dd></dd></dl>'], '']);
72
+ assert.deepStrictEqual(inspect(parser('~ `A`')), [['<dl><dt id="index::`A`"><code data-src="`A`">A</code></dt><dd></dd></dl>'], '']);
73
+ assert.deepStrictEqual(inspect(parser('~ ${A}$')), [['<dl><dt id="index::${A}$"><span class="math" translate="no" data-src="${A}$">${A}$</span></dt><dd></dd></dl>'], '']);
74
74
  });
75
75
 
76
76
  });
@@ -14,9 +14,9 @@ describe('Unit: parser/block/extension/aside', () => {
14
14
  });
15
15
 
16
16
  it('valid', () => {
17
- assert.deepStrictEqual(inspect(parser('~~~aside\n# 0\n~~~')), [['<aside id="index:0" class="aside"><h1>0</h1><h2>References</h2><ol class="references"></ol></aside>'], '']);
18
- assert.deepStrictEqual(inspect(parser('~~~aside\n## 0\n~~~')), [['<aside id="index:0" class="aside"><h2>0</h2><h2>References</h2><ol class="references"></ol></aside>'], '']);
19
- assert.deepStrictEqual(inspect(parser('~~~aside\n# 0\n\n$-0.0\n\n## 1\n\n$test-a\n> \n~~~')), [['<aside id="index:0" class="aside"><h1>0</h1><figure data-label="$-0.0" data-group="$" hidden="" data-number="0.0"></figure><h2>1</h2><figure data-type="quote" data-label="test-a" data-group="test" data-number="1.1"><figcaption><span class="figindex">Test 1.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure><h2>References</h2><ol class="references"></ol></aside>'], '']);
17
+ assert.deepStrictEqual(inspect(parser('~~~aside\n# 0\n~~~')), [['<aside id="index::0" class="aside"><h1>0</h1><h2>References</h2><ol class="references"></ol></aside>'], '']);
18
+ assert.deepStrictEqual(inspect(parser('~~~aside\n## 0\n~~~')), [['<aside id="index::0" class="aside"><h2>0</h2><h2>References</h2><ol class="references"></ol></aside>'], '']);
19
+ assert.deepStrictEqual(inspect(parser('~~~aside\n# 0\n\n$-0.0\n\n## 1\n\n$test-a\n> \n~~~')), [['<aside id="index::0" class="aside"><h1>0</h1><figure data-label="$-0.0" data-group="$" hidden="" data-number="0.0"></figure><h2>1</h2><figure data-type="quote" data-label="test-a" data-group="test" data-number="1.1"><figcaption><span class="figindex">Test 1.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure><h2>References</h2><ol class="references"></ol></aside>'], '']);
20
20
  });
21
21
 
22
22
  });