securemark 0.298.0 → 0.298.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.298.1
4
+
5
+ - Refactoring.
6
+
3
7
  ## 0.298.0
4
8
 
5
9
  - Refactoring.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.298.0 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.298.1 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"));
@@ -4518,6 +4518,7 @@ function parse(source, options = {}, context) {
4518
4518
  host: options.host ?? context?.host ?? new url_1.ReadonlyURL(location.pathname, location.origin),
4519
4519
  url: url ? new url_1.ReadonlyURL(url) : context?.url,
4520
4520
  id: options.id ?? context?.id,
4521
+ local: options.local ?? context?.local,
4521
4522
  caches: context?.caches,
4522
4523
  resources: context?.resources
4523
4524
  });
@@ -4713,7 +4714,8 @@ const markdown = (0, combinator_1.lazy)(() => (0, combinator_1.fmap)((0, combina
4713
4714
  class: 'references'
4714
4715
  });
4715
4716
  const document = (0, parse_1.parse)(source, {
4716
- id: '',
4717
+ local: true,
4718
+ id: context.id === '' ? '' : (0, util_1.randomID)(),
4717
4719
  notes: {
4718
4720
  references
4719
4721
  }
@@ -4867,7 +4869,8 @@ exports.aside = (0, combinator_1.block)((0, combinator_1.recursion)(0 /* Recursi
4867
4869
  class: 'references'
4868
4870
  });
4869
4871
  const document = (0, parse_1.parse)(body.slice(0, -1), {
4870
- id: '',
4872
+ local: true,
4873
+ id: context.id === '' ? '' : (0, util_1.randomID)(),
4871
4874
  notes: {
4872
4875
  references
4873
4876
  }
@@ -4918,7 +4921,8 @@ exports.example = (0, combinator_1.block)((0, combinator_1.recursion)(0 /* Recur
4918
4921
  class: 'references'
4919
4922
  });
4920
4923
  const document = (0, parse_1.parse)(body.slice(0, -1), {
4921
- id: '',
4924
+ local: true,
4925
+ id: context.id === '' ? '' : (0, util_1.randomID)(),
4922
4926
  notes: {
4923
4927
  references
4924
4928
  }
@@ -6014,8 +6018,9 @@ class Context extends parser_1.Context {
6014
6018
  this.recursion = new RecursionCounter('annotation', 2);
6015
6019
  const {
6016
6020
  segment,
6017
- buffer,
6021
+ local,
6018
6022
  sequential,
6023
+ buffer,
6019
6024
  header,
6020
6025
  host,
6021
6026
  url,
@@ -6023,8 +6028,9 @@ class Context extends parser_1.Context {
6023
6028
  caches
6024
6029
  } = options;
6025
6030
  this.segment = segment ?? 0 /* Segment.unknown */;
6026
- this.buffer = buffer ?? new parser_1.List();
6031
+ this.local = local ?? false;
6027
6032
  this.sequential = sequential ?? false;
6033
+ this.buffer = buffer ?? new parser_1.List();
6028
6034
  this.header = header ?? true;
6029
6035
  this.host = host;
6030
6036
  this.url = url;
@@ -7069,18 +7075,20 @@ const combinator_1 = __webpack_require__(3484);
7069
7075
  const dom_1 = __webpack_require__(394);
7070
7076
  function indexee(parser) {
7071
7077
  return (0, combinator_1.fmap)(parser, (ns, {
7072
- id
7078
+ id,
7079
+ local
7073
7080
  }) => ns.length === 1 ? new parser_1.List([new parser_1.Node((0, dom_1.define)(ns.head.value, {
7074
7081
  id: identity('index', id, ns.head.value),
7082
+ class: local ? `${ns.head.value.className} local`.trimStart() : undefined,
7075
7083
  'data-index': null
7076
7084
  }))]) : ns);
7077
7085
  }
7078
7086
  exports.indexee = indexee;
7079
- const MAX = 60;
7087
+ const table = [...[...Array(36)].map((_, i) => i.toString(36)), ...[...Array(36)].map((_, i) => i.toString(36).toUpperCase()).slice(-26), '-', '='].join('');
7088
+ const MAX = 64 - '='.length - Math.ceil(Math.log(~0 >>> 0) / Math.log(table.length));
7080
7089
  const ELLIPSIS = '...';
7081
7090
  const PART = (MAX - ELLIPSIS.length) / 2 | 0;
7082
7091
  const REM = MAX - PART * 2 - ELLIPSIS.length;
7083
- const table = [...[...Array(36)].map((_, i) => i.toString(36)), ...[...Array(36)].map((_, i) => i.toString(36).toUpperCase()).slice(-26), '-', '='].join('');
7084
7092
  function identity(type, id, text) {
7085
7093
  if (id === '') return undefined;
7086
7094
  if (typeof text !== 'string') {
@@ -7112,7 +7120,9 @@ function hash(source) {
7112
7120
  }
7113
7121
  return baseR(x >>> 0, 62);
7114
7122
  }
7123
+
7115
7124
  // 62も64も最大6桁
7125
+
7116
7126
  function baseR(n, r) {
7117
7127
  let acc = '';
7118
7128
  do {
@@ -8137,7 +8147,7 @@ const array_1 = __webpack_require__(6876);
8137
8147
  const dom_1 = __webpack_require__(394);
8138
8148
  const query_1 = __webpack_require__(2282);
8139
8149
  function* figure(target, notes, opts = {}) {
8140
- const refs = new queue_1.MultiQueue((0, array_1.push)((0, query_1.querySelectorAll)(target, 'a.label:not(.disabled)[data-label]'), notes && (0, query_1.querySelectorAll)(notes.references, 'a.label:not(.disabled)') || []).map(el => [el.getAttribute('data-label'), el]));
8150
+ const refs = new queue_1.MultiQueue((0, array_1.push)((0, query_1.querySelectorAll)(target, 'a.label:not(.local)[data-label]'), notes && (0, query_1.querySelectorAll)(notes.references, 'a.label:not(.local)') || []).map(el => [el.getAttribute('data-label'), el]));
8141
8151
  const labels = new Set();
8142
8152
  const numbers = new Map();
8143
8153
  const scope = target instanceof Element ? ':scope > ' : '';
@@ -8219,10 +8229,9 @@ function* figure(target, notes, opts = {}) {
8219
8229
  (0, util_1.unmarkInvalid)(ref);
8220
8230
  }
8221
8231
  if (ref.hash.slice(1) === def.id && ref.innerText === figindex) continue;
8222
- yield (0, dom_1.define)(ref, opts.id !== '' ? {
8223
- href: `#${def.id}`
8224
- } : {
8225
- class: `${ref.className} disabled`
8232
+ yield (0, dom_1.define)(ref, {
8233
+ class: opts.local ? `${ref.className} local` : undefined,
8234
+ href: opts.id !== '' ? `#${def.id}` : undefined
8226
8235
  }, figindex);
8227
8236
  }
8228
8237
  }
@@ -8289,8 +8298,8 @@ function* note(target, notes, opts = {}, bottom = null) {
8289
8298
  exports.note = note;
8290
8299
  const annotationRefsMemoryCaller = (0, memoize_1.memoize)(target => new Map() ?? target, new WeakMap());
8291
8300
  const referenceRefsMemoryCaller = (0, memoize_1.memoize)(target => new Map() ?? target, new WeakMap());
8292
- const annotation = build('annotation', 'annotations', '.annotation:not(:is(.annotations, .references) .annotation, .disabled)', n => `*${n}`, 'h1, h2, h3, h4, h5, h6, aside.aside, hr');
8293
- const reference = build('reference', 'references', '.reference:not(:is(.annotations, .references) .reference, .disabled)', (n, abbr) => `[${abbr || n}]`);
8301
+ const annotation = build('annotation', 'annotations', '.annotation:not(:is(.annotations, .references) .annotation, .local)', n => `*${n}`, 'h1, h2, h3, h4, h5, h6, aside.aside, hr');
8302
+ const reference = build('reference', 'references', '.reference:not(:is(.annotations, .references) .reference, .local)', (n, abbr) => `[${abbr || n}]`);
8294
8303
  function build(syntax, list, query, marker, splitter = '') {
8295
8304
  splitter &&= `${splitter}, .${list}`;
8296
8305
  return function* (memory, target, note, opts = {}, bottom = null) {
@@ -8364,7 +8373,7 @@ function build(syntax, list, query, marker, splitter = '') {
8364
8373
  const title = info.title ||= text;
8365
8374
  (0, dom_1.define)(ref, {
8366
8375
  id: refId,
8367
- class: opts.id !== '' ? undefined : void ref.classList.add('disabled'),
8376
+ class: opts.local ? `${ref.className} local` : undefined,
8368
8377
  title
8369
8378
  }, []);
8370
8379
  if (title && info.queue.length > 0) {
@@ -9046,10 +9055,11 @@ exports.unescsource = unescsource;
9046
9055
  Object.defineProperty(exports, "__esModule", ({
9047
9056
  value: true
9048
9057
  }));
9049
- exports.stringify = exports.unmarkInvalid = exports.markInvalid = exports.invalid = exports.repeat = exports.unwrap = void 0;
9058
+ exports.randomID = exports.stringify = exports.unmarkInvalid = exports.markInvalid = exports.invalid = exports.repeat = exports.unwrap = void 0;
9050
9059
  const parser_1 = __webpack_require__(605);
9051
9060
  const delimiter_1 = __webpack_require__(385);
9052
9061
  const alias_1 = __webpack_require__(5413);
9062
+ const random_1 = __webpack_require__(3158);
9053
9063
  const dom_1 = __webpack_require__(394);
9054
9064
  function* unwrap(nodes) {
9055
9065
  if (nodes === undefined) return;
@@ -9167,6 +9177,10 @@ function stringify(nodes) {
9167
9177
  return acc;
9168
9178
  }
9169
9179
  exports.stringify = stringify;
9180
+ function randomID() {
9181
+ return `random-${(0, random_1.rnd0Z)(6)}`;
9182
+ }
9183
+ exports.randomID = randomID;
9170
9184
 
9171
9185
  /***/ },
9172
9186
 
@@ -9868,7 +9882,7 @@ Object.defineProperty(exports, "__esModule", ({
9868
9882
  exports.toc = void 0;
9869
9883
  const array_1 = __webpack_require__(6876);
9870
9884
  const dom_1 = __webpack_require__(394);
9871
- const selector = ':is(h1, h2, h3, h4, h5, h6, aside.aside)[id]';
9885
+ const selector = ':is(h1, h2, h3, h4, h5, h6, aside.aside)[id]:not(.local)';
9872
9886
  function toc(source) {
9873
9887
  const hs = [];
9874
9888
  for (let es = source.querySelectorAll(selector), len = es.length, i = 0; i < len; ++i) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.298.0",
3
+ "version": "0.298.1",
4
4
  "description": "Secure markdown renderer working on browsers for user input data.",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/falsandtru/securemark",
package/src/debug.test.ts CHANGED
@@ -43,6 +43,6 @@ export function inspect(parser: Parser<DocumentFragment | HTMLElement | string>,
43
43
  // Bug: Firefox
44
44
  export function normalize(html: string): string {
45
45
  return html
46
- .replace(/(data-number="[\w.]+") (hidden="")/g, '$2 $1')
47
- .replace(/(data-type="[\w-]+") (type="\w+")/g, '$2 $1');
46
+ .replace(/:random-\w+:/g, ':random:')
47
+ .replace(/ data-invalid-\w+="[^"]*"/g, '');
48
48
  }
@@ -1,6 +1,7 @@
1
1
  import { parse } from './parse';
2
2
  import { Context } from '../context';
3
3
  import { html } from 'typed-dom/dom';
4
+ import { normalize } from '../../debug.test';
4
5
 
5
6
  describe('Unit: parser/api/parse', () => {
6
7
  describe('parse', () => {
@@ -201,10 +202,10 @@ describe('Unit: parser/api/parse', () => {
201
202
  '~~~',
202
203
  ].join('\n'),
203
204
  '{#}',
204
- ].join('\n\n'), { host: new URL(`${location.origin}/z`) }).children].map(el => el.outerHTML),
205
+ ].join('\n\n'), { host: new URL(`${location.origin}/z`) }).children].map(el => normalize(el.outerHTML)),
205
206
  [
206
207
  `<aside class="header"><details open=""><summary>Header</summary><span class="field" data-name="url" data-value="https://example/x"><span class="field-name">URL</span>: <span class="field-value">https://example/x</span>\n</span></details></aside>`,
207
- '<pre class="invalid" translate="no" data-invalid-syntax="header" data-invalid-type="syntax" data-invalid-message="Invalid syntax">---\nURL: https://example/y\n---\n</pre>',
208
+ '<pre class="invalid" translate="no">---\nURL: https://example/y\n---\n</pre>',
208
209
  '<aside class="example" data-type="markdown"><pre translate="no">---\nURL: https://example/y\n---\n\n{#}</pre><hr><section><aside class="header"><details open=""><summary>Header</summary><span class="field" data-name="url" data-value="https://example/y"><span class="field-name">URL</span>: <span class="field-value">https://example/y</span>\n</span></details></aside><p><a class="url" href="https://example/y#" target="_blank">#</a></p><h2>References</h2><ol class="references"></ol></section></aside>',
209
210
  '<p><a class="url" href="https://example/x#" target="_blank">#</a></p>',
210
211
  ]);
@@ -11,6 +11,7 @@ import { ReadonlyURL } from 'spica/url';
11
11
  import { frag } from 'typed-dom/dom';
12
12
 
13
13
  interface Options extends ParserOptions {
14
+ readonly local?: boolean;
14
15
  readonly test?: boolean;
15
16
  }
16
17
 
@@ -21,6 +22,7 @@ export function parse(source: string, options: Options = {}, context?: Context):
21
22
  host: options.host ?? context?.host ?? new ReadonlyURL(location.pathname, location.origin),
22
23
  url: url ? new ReadonlyURL(url as ':') : context?.url,
23
24
  id: options.id ?? context?.id,
25
+ local: options.local ?? context?.local,
24
26
  caches: context?.caches,
25
27
  resources: context?.resources,
26
28
  });
@@ -78,7 +78,7 @@ describe('Unit: parser/block/blockquote', () => {
78
78
  assert.deepStrictEqual(inspect(parser, input('!> a \n b c ', new Context())), [['<blockquote><section><p> a<br> b c</p><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
79
79
  assert.deepStrictEqual(inspect(parser, input('!>> a', new Context())), [['<blockquote><blockquote><section><p>a</p><h2>References</h2><ol class="references"></ol></section></blockquote></blockquote>'], '']);
80
80
  assert.deepStrictEqual(inspect(parser, input('!>> a\n> b', new Context())), [['<blockquote><blockquote><section><p>a</p><h2>References</h2><ol class="references"></ol></section></blockquote><section><p>b</p><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
81
- assert.deepStrictEqual(inspect(parser, input('!> - a', new Context())), [['<blockquote><section><ul><li>a</li></ul><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
81
+ assert.deepStrictEqual(inspect(parser, input('!> - a', new Context())), [['<blockquote><section><ul><li id="index:random:a" class="local">a</li></ul><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
82
82
  assert.deepStrictEqual(inspect(parser, input('!> ```\na\n```', new Context())), [['<blockquote><section><pre class="text">a</pre><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
83
83
  assert.deepStrictEqual(inspect(parser, input('!> ```\n> a\n```', new Context())), [['<blockquote><section><pre class="text">a</pre><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
84
84
  assert.deepStrictEqual(inspect(parser, input('!> ```\n> a\n> ```', new Context())), [['<blockquote><section><pre class="text">a</pre><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
@@ -91,10 +91,10 @@ describe('Unit: parser/block/blockquote', () => {
91
91
  assert.deepStrictEqual(inspect(parser, input('!>> > a\n> b', new Context())), [['<blockquote><blockquote><section><blockquote><pre>a</pre></blockquote><h2>References</h2><ol class="references"></ol></section></blockquote><section><p>b</p><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
92
92
  assert.deepStrictEqual(inspect(parser, input('!> !> a', new Context())), [['<blockquote><section><blockquote><section><p>a</p><h2>References</h2><ol class="references"></ol></section></blockquote><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
93
93
  assert.deepStrictEqual(inspect(parser, input('!> \na', new Context())), [['<blockquote><section><p>a</p><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
94
- assert.deepStrictEqual(inspect(parser, input('!>> ## a\n> ## a', new Context())), [['<blockquote><blockquote><section><h2>a</h2><h2>References</h2><ol class="references"></ol></section></blockquote><section><h2>a</h2><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
95
- assert.deepStrictEqual(inspect(parser, input('!>> ~ a\n> ~ a', new Context())), [['<blockquote><blockquote><section><dl><dt>a</dt><dd></dd></dl><h2>References</h2><ol class="references"></ol></section></blockquote><section><dl><dt>a</dt><dd></dd></dl><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
96
- assert.deepStrictEqual(inspect(parser, input('!>> ~~~figure $test-a\n>> > \n>>\n~~~\n> ~~~figure $test-a\n> > \n>\n[#a]\n~~~', new Context())), [['<blockquote><blockquote><section><figure data-type="quote" data-label="test-a" data-group="test" data-number="1"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure><h2>References</h2><ol class="references"></ol></section></blockquote><section><figure data-type="quote" data-label="test-a" data-group="test" data-number="1"><figcaption><span class="figindex">Test 1. </span><span class="figtext"><a class="index">a</a></span></figcaption><div><blockquote></blockquote></div></figure><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
97
- assert.deepStrictEqual(inspect(parser, input('!>> ((a))\n> ((a))', new Context())), [['<blockquote><blockquote><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup></p><ol class="annotations"><li data-marker="*1"><span>a</span><sup><a>^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></blockquote><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup></p><ol class="annotations"><li data-marker="*1"><span>a</span><sup><a>^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
94
+ assert.deepStrictEqual(inspect(parser, input('!>> ## a\n> ## a', new Context())), [['<blockquote><blockquote><section><h2 id="index:random:a" class="local">a</h2><h2>References</h2><ol class="references"></ol></section></blockquote><section><h2 id="index:random:a" class="local">a</h2><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
95
+ assert.deepStrictEqual(inspect(parser, input('!>> ~ a\n> ~ a', new Context())), [['<blockquote><blockquote><section><dl><dt id="index:random:a" class="local">a</dt><dd></dd></dl><h2>References</h2><ol class="references"></ol></section></blockquote><section><dl><dt id="index:random:a" class="local">a</dt><dd></dd></dl><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
96
+ assert.deepStrictEqual(inspect(parser, input('!>> ~~~figure $test-a\n>> > \n>>\n~~~\n> ~~~figure $test-a\n> > \n>\n[#a]\n~~~', new Context())), [['<blockquote><blockquote><section><figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:random:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure><h2>References</h2><ol class="references"></ol></section></blockquote><section><figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:random:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"><a class="index" href="#index:random:a">a</a></span></figcaption><div><blockquote></blockquote></div></figure><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
97
+ assert.deepStrictEqual(inspect(parser, input('!>> ((a))\n> ((a))', new Context())), [['<blockquote><blockquote><section><p><sup class="annotation local" id="annotation:random:ref:a:1" title="a"><a href="#annotation:random:def:a:1">*1</a></sup></p><ol class="annotations"><li id="annotation:random:def:a:1" data-marker="*1"><span>a</span><sup><a href="#annotation:random:ref:a:1">^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></blockquote><section><p><sup class="annotation local" id="annotation:random:ref:a:1" title="a"><a href="#annotation:random:def:a:1">*1</a></sup></p><ol class="annotations"><li id="annotation:random:def:a:1" data-marker="*1"><span>a</span><sup><a href="#annotation:random:ref:a:1">^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
98
98
  });
99
99
 
100
100
  });
@@ -4,7 +4,7 @@ import { List, Node } from '../../combinator/data/parser';
4
4
  import { union, some, consume, recursion, block, validate, rewrite, open, convert, lazy, fmap } from '../../combinator';
5
5
  import { autolink } from '../autolink';
6
6
  import { contentline } from '../source';
7
- import { unwrap } from '../util';
7
+ import { unwrap, randomID } from '../util';
8
8
  import { parse } from '../api/parse';
9
9
  import { html, defrag } from 'typed-dom/dom';
10
10
 
@@ -44,7 +44,8 @@ const markdown: BlockquoteParser.MarkdownParser = lazy(() => fmap(
44
44
  const { source } = context;
45
45
  const references = html('ol', { class: 'references' });
46
46
  const document = parse(source, {
47
- id: '',
47
+ local: true,
48
+ id: context.id === '' ? '' : randomID(),
48
49
  notes: {
49
50
  references,
50
51
  },
@@ -16,9 +16,9 @@ describe('Unit: parser/block/extension/aside', () => {
16
16
  });
17
17
 
18
18
  it('valid', () => {
19
- assert.deepStrictEqual(inspect(parser, input('~~~aside\n# 0\n~~~', new Context())), [['<aside id="index::0" class="aside"><h1>0</h1><h2>References</h2><ol class="references"></ol></aside>'], '']);
20
- assert.deepStrictEqual(inspect(parser, input('~~~aside\n## 0\n~~~', new Context())), [['<aside id="index::0" class="aside"><h2>0</h2><h2>References</h2><ol class="references"></ol></aside>'], '']);
21
- assert.deepStrictEqual(inspect(parser, input('~~~aside\n# 0\n\n$-0.0\n\n## 1\n\n$test-a\n> \n~~~', new Context())), [['<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>'], '']);
19
+ assert.deepStrictEqual(inspect(parser, input('~~~aside\n# 0\n~~~', new Context())), [['<aside id="index::0" class="aside"><h1 id="index:random:0" class="local">0</h1><h2>References</h2><ol class="references"></ol></aside>'], '']);
20
+ assert.deepStrictEqual(inspect(parser, input('~~~aside\n## 0\n~~~', new Context())), [['<aside id="index::0" class="aside"><h2 id="index:random:0" class="local">0</h2><h2>References</h2><ol class="references"></ol></aside>'], '']);
21
+ assert.deepStrictEqual(inspect(parser, input('~~~aside\n# 0\n\n$-0.0\n\n## 1\n\n$test-a\n> \n~~~', new Context())), [['<aside id="index::0" class="aside"><h1 id="index:random:0" class="local">0</h1><figure data-label="$-0.0" data-group="$" hidden="" data-number="0.0"></figure><h2 id="index:random:1" class="local">1</h2><figure data-type="quote" data-label="test-a" data-group="test" data-number="1.1" id="label:random:test-a"><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>'], '']);
22
22
  });
23
23
 
24
24
  });
@@ -3,7 +3,7 @@ import { Recursion } from '../../context';
3
3
  import { List, Node } from '../../../combinator/data/parser';
4
4
  import { recursion, block, fence, fmap } from '../../../combinator';
5
5
  import { identity } from '../../inline/extension/indexee';
6
- import { unwrap, invalid } from '../../util';
6
+ import { unwrap, invalid, randomID } from '../../util';
7
7
  import { parse } from '../../api/parse';
8
8
  import { html } from 'typed-dom/dom';
9
9
 
@@ -26,12 +26,12 @@ export const aside: ExtensionParser.AsideParser = block(recursion(Recursion.bloc
26
26
  ]);
27
27
  const references = html('ol', { class: 'references' });
28
28
  const document = parse(body.slice(0, -1), {
29
- id: '',
29
+ local: true,
30
+ id: context.id === '' ? '' : randomID(),
30
31
  notes: {
31
32
  references,
32
33
  },
33
34
  }, context);
34
- assert(!document.querySelector('[id]'));
35
35
  const heading = 'H1 H2 H3 H4 H5 H6'.split(' ').includes(document.firstElementChild?.tagName!) && document.firstElementChild as HTMLHeadingElement;
36
36
  if (!heading) return new List([
37
37
  new Node(html('pre', {
@@ -21,11 +21,11 @@ describe('Unit: parser/block/extension/example', () => {
21
21
  assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no"></pre><hr><section><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
22
22
  assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\na\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">a</pre><hr><section><p>a</p><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
23
23
  assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n++a\nb++\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">++a\nb++</pre><hr><section><p><ins>a<br>b</ins></p><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
24
- assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n$fig-a\n!https://host\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">$fig-a\n!https://host</pre><hr><section><figure data-type="media" data-label="fig-a" data-group="fig" data-number="1"><figcaption><span class="figindex">Fig. 1. </span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt="https://host"></a></div></figure><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
25
- assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n[$fig-a]\n!https://host\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">[$fig-a]\n!https://host</pre><hr><section><figure data-type="media" data-label="fig-a" data-group="fig" data-number="1"><figcaption><span class="figindex">Fig. 1. </span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt="https://host"></a></div></figure><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
26
- assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n## a\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">## a</pre><hr><section><h2>a</h2><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
27
- assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n~ a\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">~ a</pre><hr><section><dl><dt>a</dt><dd></dd></dl><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
28
- assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n((a))[[b]]\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">((a))[[b]]</pre><hr><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup><sup class="reference disabled" title="b"><a>[1]</a></sup></p><ol class="annotations"><li data-marker="*1"><span>a</span><sup><a>^1</a></sup></li></ol><h2>References</h2><ol class="references"><li><span>b</span><sup><a>^1</a></sup></li></ol></section></aside>'], '']);
24
+ assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n$fig-a\n!https://host\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">$fig-a\n!https://host</pre><hr><section><figure data-type="media" data-label="fig-a" data-group="fig" data-number="1" id="label:random:fig-a"><figcaption><span class="figindex">Fig. 1. </span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt="https://host"></a></div></figure><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
25
+ assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n[$fig-a]\n!https://host\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">[$fig-a]\n!https://host</pre><hr><section><figure data-type="media" data-label="fig-a" data-group="fig" data-number="1" id="label:random:fig-a"><figcaption><span class="figindex">Fig. 1. </span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt="https://host"></a></div></figure><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
26
+ assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n## a\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">## a</pre><hr><section><h2 id="index:random:a" class="local">a</h2><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
27
+ assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n~ a\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">~ a</pre><hr><section><dl><dt id="index:random:a" class="local">a</dt><dd></dd></dl><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
28
+ assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n((a))[[b]]\n~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">((a))[[b]]</pre><hr><section><p><sup class="annotation local" id="annotation:random:ref:a:1" title="a"><a href="#annotation:random:def:a:1">*1</a></sup><sup class="reference local" id="reference:random:ref:b:1" title="b"><a href="#reference:random:def:b">[1]</a></sup></p><ol class="annotations"><li id="annotation:random:def:a:1" data-marker="*1"><span>a</span><sup><a href="#annotation:random:ref:a:1">^1</a></sup></li></ol><h2>References</h2><ol class="references"><li id="reference:random:def:b"><span>b</span><sup><a href="#reference:random:ref:b:1">^1</a></sup></li></ol></section></aside>'], '']);
29
29
  assert.deepStrictEqual(inspect(parser, input('~~~~example/markdown\na\n~~~~', new Context())), [['<aside class="example" data-type="markdown"><pre translate="no">a</pre><hr><section><p>a</p><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
30
30
  assert.deepStrictEqual(inspect(parser, input('~~~example/math\na\n~~~', new Context())), [['<aside class="example" data-type="math"><pre translate="no">a</pre><hr><div class="math" translate="no">$$\na\n$$</div></aside>'], '']);
31
31
  assert.deepStrictEqual(inspect(parser, input(`~~~example/math\n0${'\n'.repeat(100)}~~~`, new Context()), '>'), [['<aside class="example" data-type="math">'], '']);
@@ -3,7 +3,7 @@ import { Recursion } from '../../context';
3
3
  import { List, Node, subinput } from '../../../combinator/data/parser';
4
4
  import { recursion, block, fence, fmap } from '../../../combinator';
5
5
  import { mathblock } from '../mathblock';
6
- import { unwrap, invalid } from '../../util';
6
+ import { unwrap, invalid, randomID } from '../../util';
7
7
  import { parse } from '../../api/parse';
8
8
  import { html } from 'typed-dom/dom';
9
9
 
@@ -28,12 +28,12 @@ export const example: ExtensionParser.ExampleParser = block(recursion(Recursion.
28
28
  case 'markdown': {
29
29
  const references = html('ol', { class: 'references' });
30
30
  const document = parse(body.slice(0, -1), {
31
- id: '',
31
+ local: true,
32
+ id: context.id === '' ? '' : randomID(),
32
33
  notes: {
33
34
  references,
34
35
  },
35
36
  }, context);
36
- assert(!document.querySelector('[id]'));
37
37
  return new List([
38
38
  new Node(html('aside', { class: 'example', 'data-type': 'markdown' }, [
39
39
  html('pre', { translate: 'no' }, body.slice(0, -1)),
@@ -8,8 +8,9 @@ export class Context extends Ctx {
8
8
  super(options);
9
9
  const {
10
10
  segment,
11
- buffer,
11
+ local,
12
12
  sequential,
13
+ buffer,
13
14
  header,
14
15
  host,
15
16
  url,
@@ -17,8 +18,9 @@ export class Context extends Ctx {
17
18
  caches,
18
19
  } = options;
19
20
  this.segment = segment ?? Segment.unknown;
20
- this.buffer = buffer ?? new List();
21
+ this.local = local ?? false;
21
22
  this.sequential = sequential ?? false;
23
+ this.buffer = buffer ?? new List();
22
24
  this.header = header ?? true;
23
25
  this.host = host;
24
26
  this.url = url;
@@ -26,8 +28,9 @@ export class Context extends Ctx {
26
28
  this.caches = caches;
27
29
  }
28
30
  public override segment: Segment;
29
- public buffer: List<Node<(string | HTMLElement)>>;
31
+ public local: boolean;
30
32
  public sequential: boolean;
33
+ public buffer: List<Node<(string | HTMLElement)>>;
31
34
  public recursion = new RecursionCounter('annotation', 2);
32
35
  public readonly header: boolean;
33
36
  public readonly host?: URL;
@@ -5,23 +5,28 @@ import { define } from 'typed-dom/dom';
5
5
 
6
6
  export function indexee<P extends Parser<HTMLElement, Context>>(parser: P): P;
7
7
  export function indexee(parser: Parser<HTMLElement, Context>): Parser<HTMLElement> {
8
- return fmap(parser, (ns, { id }) =>
8
+ return fmap(parser, (ns, { id, local }) =>
9
9
  ns.length === 1
10
- ? new List([new Node(define(ns.head!.value, { id: identity('index', id, ns.head!.value), 'data-index': null }))])
10
+ ? new List([new Node(define(ns.head!.value, {
11
+ id: identity('index', id, ns.head!.value),
12
+ class: local ? `${ns.head!.value.className} local`.trimStart() : undefined,
13
+ 'data-index': null
14
+ }))])
11
15
  : ns);
12
16
  }
13
17
 
14
- const MAX = 60;
15
- const ELLIPSIS = '...';
16
- const PART = (MAX - ELLIPSIS.length) / 2 | 0;
17
- const REM = MAX - PART * 2 - ELLIPSIS.length;
18
- assert(PART * 2 + REM + ELLIPSIS.length === MAX);
19
18
  const table = [
20
19
  ...[...Array(36)].map((_, i) => i.toString(36)),
21
20
  ...[...Array(36)].map((_, i) => i.toString(36).toUpperCase()).slice(-26),
22
21
  '-', '=',
23
22
  ].join('');
24
23
  assert(table.length === 64);
24
+ const MAX = 64 - '='.length - Math.ceil(Math.log(~0 >>> 0) / Math.log(table.length));
25
+ assert(MAX === 57);
26
+ const ELLIPSIS = '...';
27
+ const PART = (MAX - ELLIPSIS.length) / 2 | 0;
28
+ const REM = MAX - PART * 2 - ELLIPSIS.length;
29
+ assert(PART * 2 + REM + ELLIPSIS.length === MAX);
25
30
  export function identity(
26
31
  type: 'index' | 'mark' | '',
27
32
  id: string | undefined,
@@ -68,10 +73,10 @@ assert.deepStrictEqual(
68
73
  `${'0'.repeat(MAX - 1)}1`);
69
74
  assert.deepStrictEqual(
70
75
  identity('index', undefined, `0${'1'.repeat(MAX / 2)}${'2'.repeat(MAX / 2)}3`)!.slice(7),
71
- `0${'1'.repeat(PART + REM - 1)}${ELLIPSIS}${'2'.repeat(PART - 1)}3=MYkmc`);
76
+ `0${'1'.repeat(PART + REM - 1)}${ELLIPSIS}${'2'.repeat(PART - 1)}3=E0deO`);
72
77
  assert.deepStrictEqual(
73
78
  identity('index', undefined, `0${'1'.repeat(MAX * 2)}${'2'.repeat(MAX * 2)}3`)!.slice(7),
74
- `0${'1'.repeat(PART + REM - 1)}${ELLIPSIS}${'2'.repeat(PART - 1)}3=3bF8VU`);
79
+ `0${'1'.repeat(PART + REM - 1)}${ELLIPSIS}${'2'.repeat(PART - 1)}3=2RHwOS`);
75
80
  function hash(source: string): string {
76
81
  let x = 0;
77
82
  for (let i = 0; i < source.length; ++i) {
@@ -88,6 +93,8 @@ assert(hash('\x00') !== '0');
88
93
  assert(hash('\x01') !== '0');
89
94
  assert(hash('\x00') !== hash(String.fromCharCode(1 << 15)));
90
95
  // 62も64も最大6桁
96
+ assert(Math.ceil(Math.log(~0 >>> 0) / Math.log(62)) === 6);
97
+ assert(Math.ceil(Math.log(~0 >>> 0) / Math.log(64)) === 6);
91
98
  function baseR(n: number, r: number): string {
92
99
  assert(n >= 0);
93
100
  assert(Math.floor(n) === n);
@@ -104,6 +111,7 @@ function baseR(n: number, r: number): string {
104
111
  }
105
112
  assert(baseR(0, 36) === (0).toString(36));
106
113
  assert(baseR(~0 >>> 0, 36) === (~0 >>> 0).toString(36));
114
+ assert(baseR(0, 62) === '0');
107
115
  assert(baseR(61, 62) === 'Z');
108
116
  assert(baseR(62, 62) === '10');
109
117
 
@@ -13,7 +13,7 @@ describe('Unit: parser/processor/figure', () => {
13
13
  for (let i = 0; i < 3; ++i) {
14
14
  [...figure(target)];
15
15
  assert.deepStrictEqual(
16
- [...target.children].map(el => el.outerHTML),
16
+ [...target.children].map(el => normalize(el.outerHTML)),
17
17
  []);
18
18
  }
19
19
  });
@@ -28,11 +28,11 @@ describe('Unit: parser/processor/figure', () => {
28
28
  for (let i = 0; i < 3; ++i) {
29
29
  [...figure(target)];
30
30
  assert.deepStrictEqual(
31
- [...target.children].map(el => el.outerHTML),
31
+ [...target.children].map(el => normalize(el.outerHTML)),
32
32
  [
33
33
  '<figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
34
34
  '<p><a class="label" data-label="test-a" href="#label:test-a">Test 1</a></p>',
35
- '<p><a class="label invalid" data-label="test-b" data-invalid-syntax="label" data-invalid-type="reference" data-invalid-message="Missing the target figure">$test-b</a></p>',
35
+ '<p><a class="label invalid" data-label="test-b">$test-b</a></p>',
36
36
  '<p><a class="label" data-label="test-a" href="#label:test-a">Test 1</a></p>',
37
37
  ]);
38
38
  }
@@ -50,13 +50,13 @@ describe('Unit: parser/processor/figure', () => {
50
50
  for (let i = 0; i < 3; ++i) {
51
51
  [...figure(target)];
52
52
  assert.deepStrictEqual(
53
- [...target.children].map(el => el.outerHTML),
53
+ [...target.children].map(el => normalize(el.outerHTML)),
54
54
  [
55
55
  '<figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
56
56
  '<h2 id="index::0">0</h2>',
57
57
  '<figure data-type="quote" data-label="test-b" data-group="test" data-number="2" id="label:test-b"><figcaption><span class="figindex">Test 2. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
58
58
  '<figure data-type="quote" data-label="quote-a" data-group="quote" data-number="1" id="label:quote-a"><figcaption><span class="figindex">Quote 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
59
- '<figure data-type="quote" data-label="test-b" data-group="test" data-number="3" class="invalid" data-invalid-syntax="figure" data-invalid-type="argument" data-invalid-message="Duplicate label"><figcaption><span class="figindex">Test 3. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
59
+ '<figure data-type="quote" data-label="test-b" data-group="test" data-number="3" class="invalid"><figcaption><span class="figindex">Test 3. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
60
60
  '<figure data-type="quote" data-label="test-c" data-group="test" data-number="4" id="label:test-c"><figcaption><span class="figindex">Test 4. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
61
61
  ]);
62
62
  }
@@ -70,7 +70,7 @@ describe('Unit: parser/processor/figure', () => {
70
70
  for (let i = 0; i < 3; ++i) {
71
71
  [...figure(target)];
72
72
  assert.deepStrictEqual(
73
- [...target.children].map(el => el.outerHTML),
73
+ [...target.children].map(el => normalize(el.outerHTML)),
74
74
  [
75
75
  '<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>',
76
76
  '<p><a class="label" data-label="$-a" href="#label:$-a">(1)</a></p>',
@@ -92,7 +92,7 @@ describe('Unit: parser/processor/figure', () => {
92
92
  for (let i = 0; i < 3; ++i) {
93
93
  [...figure(target)];
94
94
  assert.deepStrictEqual(
95
- [...target.children].map(el => el.outerHTML),
95
+ [...target.children].map(el => normalize(el.outerHTML)),
96
96
  [
97
97
  '<figure data-type="quote" data-label="test-2" data-group="test" data-number="2" id="label:test-2"><figcaption><span class="figindex">Test 2. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
98
98
  '<figure data-type="quote" data-label="test-3.1" data-group="test" data-number="3.1" id="label:test-3.1"><figcaption><span class="figindex">Test 3.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
@@ -101,7 +101,7 @@ describe('Unit: parser/processor/figure', () => {
101
101
  '<figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
102
102
  '<p><a class="label" data-label="test-2" href="#label:test-2">Test 2</a></p>',
103
103
  '<p><a class="label" data-label="$-4.1.1" href="#label:$-4.1.1">(4.1.1)</a></p>',
104
- '<p><a class="label invalid" data-label="test-1" data-invalid-syntax="label" data-invalid-type="reference" data-invalid-message="Missing the target figure">$test-1</a></p>',
104
+ '<p><a class="label invalid" data-label=\"test-1\">$test-1</a></p>',
105
105
  ]);
106
106
  }
107
107
  });
@@ -116,10 +116,10 @@ describe('Unit: parser/processor/figure', () => {
116
116
  for (let i = 0; i < 3; ++i) {
117
117
  [...figure(target)];
118
118
  assert.deepStrictEqual(
119
- [...target.children].map(el => el.outerHTML),
119
+ [...target.children].map(el => normalize(el.outerHTML)),
120
120
  [
121
- '<blockquote><blockquote><section><figure data-type="quote" data-label="test-a" data-group="test" data-number="1"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure><h2>References</h2><ol class="references"></ol></section></blockquote><section><figure data-type="quote" data-label="test-a" data-group="test" data-number="1"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure><h2>References</h2><ol class="references"></ol></section></blockquote>',
122
- '<aside class="example" data-type="markdown"><pre translate="no">~~~figure $test-a\n&gt; \n\n~~~\n\n$test-a</pre><hr><section><figure data-type="quote" data-label="test-a" data-group="test" data-number="1"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure><p><a class="label disabled" data-label="test-a">Test 1</a></p><h2>References</h2><ol class="references"></ol></section></aside>',
121
+ '<blockquote><blockquote><section><figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:random:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure><h2>References</h2><ol class="references"></ol></section></blockquote><section><figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:random:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure><h2>References</h2><ol class="references"></ol></section></blockquote>',
122
+ '<aside class="example" data-type="markdown"><pre translate="no">~~~figure $test-a\n&gt; \n\n~~~\n\n$test-a</pre><hr><section><figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:random:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure><p><a class="label local" data-label="test-a" href="#label:random:test-a">Test 1</a></p><h2>References</h2><ol class="references"></ol></section></aside>',
123
123
  '<figure data-type="quote" data-label="test-b" data-group="test" data-number="1" id="label:test-b"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
124
124
  '<figure data-type="quote" data-label="test-a" data-group="test" data-number="2" id="label:test-a"><figcaption><span class="figindex">Test 2. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
125
125
  ]);
@@ -174,20 +174,20 @@ describe('Unit: parser/processor/figure', () => {
174
174
  '<h2 id="index::0">0</h2>',
175
175
  '<figure data-type="quote" data-label="test-1" data-group="test" data-number="1" id="label:test-1"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
176
176
  '<h2 id="index::0">0</h2>',
177
- '<blockquote><section><h2>0</h2><h2>References</h2><ol class="references"></ol></section></blockquote>',
177
+ '<blockquote><section><h2 id="index:random:0" class="local">0</h2><h2>References</h2><ol class="references"></ol></section></blockquote>',
178
178
  '<figure data-type="quote" data-label="test-b" data-group="test" data-number="2.1" id="label:test-b"><figcaption><span class="figindex">Test 2.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
179
179
  '<h2 id="index::0">0</h2>',
180
- '<figure data-label="$-0.0.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="argument" data-invalid-message="Base index must be $-x.0 format"></figure>',
180
+ '<figure data-label="$-0.0.0" data-group="$" class="invalid"></figure>',
181
181
  '<h3 id="index::0">0</h3>',
182
182
  '<figure data-label="$-0.0" data-group="$" hidden="" data-number="3.0"></figure>',
183
183
  '<figure data-type="quote" data-label="test-c" data-group="test" data-number="3.1" id="label:test-c"><figcaption><span class="figindex">Test 3.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
184
184
  '<h2 id="index::0">0</h2>',
185
- '<figure data-label="$-0.1.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="argument" data-invalid-message="Base index must be $-x.0 format"></figure>',
185
+ '<figure data-label="$-0.1.0" data-group="$" class="invalid"></figure>',
186
186
  '<figure data-type="quote" data-label="test-d" data-group="test" data-number="4.1" id="label:test-d"><figcaption><span class="figindex">Test 4.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
187
- '<figure data-label="$-0.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="position" data-invalid-message="Base index declarations must be after level 1 to 6 headings"></figure>',
188
- '<figure data-label="$-0.1.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="argument" data-invalid-message="Base index must be $-x.0 format"></figure>',
189
- '<figure data-label="$-0.4.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="argument" data-invalid-message="Base index must be $-x.0 format"></figure>',
190
- '<figure data-label="$-0.1.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="argument" data-invalid-message="Base index must be $-x.0 format"></figure>',
187
+ '<figure data-label="$-0.0" data-group="$" class="invalid"></figure>',
188
+ '<figure data-label="$-0.1.0" data-group="$" class="invalid"></figure>',
189
+ '<figure data-label="$-0.4.0" data-group="$" class="invalid"></figure>',
190
+ '<figure data-label="$-0.1.0" data-group="$" class="invalid"></figure>',
191
191
  '<h2 id="index::0">0</h2>',
192
192
  '<h2 id="index::0">0</h2>',
193
193
  '<figure data-label="$-0.0" data-group="$" hidden="" data-number="6.0"></figure>',
@@ -195,15 +195,15 @@ describe('Unit: parser/processor/figure', () => {
195
195
  '<h2 id="index::0">0</h2>',
196
196
  '<figure data-label="$-5.0" data-group="$" hidden="" data-number="5.0"></figure>',
197
197
  '<figure data-type="quote" data-label="test-f" data-group="test" data-number="5.1" id="label:test-f"><figcaption><span class="figindex">Test 5.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
198
- '<figure data-label="$-0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="argument" data-invalid-message="Invalid base index"></figure>',
198
+ '<figure data-label="$-0" data-group="$" class="invalid"></figure>',
199
199
  '<figure data-type="quote" data-label="test-g" data-group="test" data-number="5.2" id="label:test-g"><figcaption><span class="figindex">Test 5.2. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
200
200
  '<h3 id="index::0">0</h3>',
201
- '<figure data-label="$-0.0.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="argument" data-invalid-message="Base index must be $-x.0 format"></figure>',
201
+ '<figure data-label="$-0.0.0" data-group="$" class="invalid"></figure>',
202
202
  '<figure data-type="quote" data-label="test-h" data-group="test" data-number="5.3" id="label:test-h"><figcaption><span class="figindex">Test 5.3. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
203
203
  '<h3 id="index::0">0</h3>',
204
204
  '<figure data-type="quote" data-label="test-i" data-group="test" data-number="5.4" id="label:test-i"><figcaption><span class="figindex">Test 5.4. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
205
205
  '<h1 id="index::0">0</h1>',
206
- '<figure data-type="quote" data-label="test-j" data-group="test" data-number="6.1" id="label:test-j"><figcaption><span class="figindex">Test 6.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
206
+ '<figure data-type="quote" data-label="test-j" data-group="test" data-number="6.1" id="label:test-j"><figcaption><span class="figindex">Test 6.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>'
207
207
  ]);
208
208
  }
209
209
  });
@@ -235,17 +235,17 @@ describe('Unit: parser/processor/figure', () => {
235
235
  assert.deepStrictEqual(
236
236
  [...target.children].map(el => normalize(el.outerHTML)),
237
237
  [
238
- '<figure data-label="$-0.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="position" data-invalid-message="Base index declarations must be after level 1 to 6 headings"></figure>',
238
+ '<figure data-label="$-0.0" data-group="$" class="invalid"></figure>',
239
239
  '<h2 id="index::0">0</h2>',
240
240
  '<figure data-label="$-0.0" data-group="$" hidden="" data-number="0.0"></figure>',
241
241
  '<figure data-type="quote" data-label="test-a" data-group="test" data-number="0.1" id="label:test-a"><figcaption><span class="figindex">Test 0.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
242
- '<figure data-label="$-0.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="position" data-invalid-message="Base index declarations must be after level 1 to 6 headings"></figure>',
242
+ '<figure data-label="$-0.0" data-group="$" class="invalid"></figure>',
243
243
  '<h2 id="index::0">0</h2>',
244
244
  '<figure data-type="quote" data-label="test-b" data-group="test" data-number="1.1" id="label:test-b"><figcaption><span class="figindex">Test 1.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
245
- '<figure data-label="$-0.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="position" data-invalid-message="Base index declarations must be after level 1 to 6 headings"></figure>',
245
+ '<figure data-label="$-0.0" data-group="$" class="invalid"></figure>',
246
246
  '<h3 id="index::0">0</h3>',
247
247
  '<figure data-type="quote" data-label="test-c" data-group="test" data-number="1.2" id="label:test-c"><figcaption><span class="figindex">Test 1.2. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
248
- '<figure data-label="$-1.0" data-group="$" class="invalid" data-invalid-syntax="figure" data-invalid-type="position" data-invalid-message="Base index declarations must be after level 1 to 6 headings"></figure>',
248
+ '<figure data-label="$-1.0" data-group="$" class="invalid"></figure>',
249
249
  '<h2 id="index::0">0</h2>',
250
250
  '<figure data-label="$-0.0" data-group="$" hidden="" data-number="2.0"></figure>',
251
251
  '<figure data-type="quote" data-label="test-d" data-group="test" data-number="2.1" id="label:test-d"><figcaption><span class="figindex">Test 2.1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
@@ -267,7 +267,7 @@ describe('Unit: parser/processor/figure', () => {
267
267
  for (let i = 0; i < 3; ++i) {
268
268
  [...figure(target)];
269
269
  assert.deepStrictEqual(
270
- [...target.children].map(el => el.outerHTML),
270
+ [...target.children].map(el => normalize(el.outerHTML)),
271
271
  [
272
272
  '<figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
273
273
  '<p><a class="label" data-label="test-a" href="#label:test-a">Test 1</a></p>',
@@ -285,7 +285,7 @@ describe('Unit: parser/processor/figure', () => {
285
285
  for (let i = 0; i < 3; ++i) {
286
286
  [...figure(target, undefined, { id: '0' })];
287
287
  assert.deepStrictEqual(
288
- [...target.children].map(el => el.outerHTML),
288
+ [...target.children].map(el => normalize(el.outerHTML)),
289
289
  [
290
290
  '<figure data-type="quote" data-label="test-a" data-group="test" data-number="1" id="label:0:test-a"><figcaption><span class="figindex">Test 1. </span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>',
291
291
  '<p><mark id="mark:0:[$test-a]"><a class="label" data-label="test-a" href="#label:0:test-a">Test 1</a></mark><a href="#mark:0:[$test-a]"></a></p>',
@@ -8,11 +8,14 @@ import { querySelectorAll } from 'typed-dom/query';
8
8
  export function* figure(
9
9
  target: ParentNode & Node,
10
10
  notes?: { readonly references: HTMLOListElement; },
11
- opts: { readonly id?: string; } = {},
11
+ opts: {
12
+ readonly id?: string;
13
+ readonly local?: boolean;
14
+ } = {},
12
15
  ): Generator<HTMLAnchorElement | undefined, undefined, undefined> {
13
16
  const refs = new MultiQueue<string, HTMLAnchorElement>(push(
14
- querySelectorAll(target, 'a.label:not(.disabled)[data-label]'),
15
- notes && querySelectorAll(notes.references, 'a.label:not(.disabled)') || [])
17
+ querySelectorAll(target, 'a.label:not(.local)[data-label]'),
18
+ notes && querySelectorAll(notes.references, 'a.label:not(.local)') || [])
16
19
  .map(el => [el.getAttribute('data-label')!, el]));
17
20
  const labels = new Set<string>();
18
21
  const numbers = new Map<string, string>();
@@ -117,7 +120,10 @@ export function* figure(
117
120
  }
118
121
  if (ref.hash.slice(1) === def.id && ref.innerText === figindex) continue;
119
122
  yield define(ref,
120
- opts.id !== '' ? { href: `#${def.id}` } : { class: `${ref.className} disabled` },
123
+ {
124
+ class: opts.local ? `${ref.className} local` : undefined,
125
+ href: opts.id !== '' ? `#${def.id}` : undefined,
126
+ },
121
127
  figindex);
122
128
  }
123
129
  }
@@ -1,6 +1,7 @@
1
1
  import { note } from './note';
2
2
  import { parse as parse_ } from '../../parser';
3
3
  import { html } from 'typed-dom/dom';
4
+ import { normalize } from '../../debug.test';
4
5
 
5
6
  const parse = (s: string) => parse_(s, { test: true });
6
7
 
@@ -10,7 +11,7 @@ describe('Unit: parser/processor/note', () => {
10
11
  const target = parse('');
11
12
  [...note(target)];
12
13
  assert.deepStrictEqual(
13
- [...target.children].map(el => el.outerHTML),
14
+ [...target.children].map(el => normalize(el.outerHTML)),
14
15
  []);
15
16
  });
16
17
 
@@ -19,7 +20,7 @@ describe('Unit: parser/processor/note', () => {
19
20
  for (let i = 0; i < 3; ++i) {
20
21
  assert.deepStrictEqual([...note(target)].length, i === 0 ? 2 : 3);
21
22
  assert.deepStrictEqual(
22
- [...target.children].map(el => el.outerHTML),
23
+ [...target.children].map(el => normalize(el.outerHTML)),
23
24
  [
24
25
  html('p', [
25
26
  html('sup', { class: 'annotation', id: 'annotation::ref:a_b:1', title: 'a b' }, [
@@ -41,7 +42,7 @@ describe('Unit: parser/processor/note', () => {
41
42
  for (let i = 0; i < 3; ++i) {
42
43
  assert.deepStrictEqual([...note(target)].length, i === 0 ? 4 : 6);
43
44
  assert.deepStrictEqual(
44
- [...target.children].map(el => el.outerHTML),
45
+ [...target.children].map(el => normalize(el.outerHTML)),
45
46
  [
46
47
  html('p', [
47
48
  html('sup', { class: 'annotation', id: 'annotation::ref:1:1', title: '1' }, [
@@ -70,7 +71,7 @@ describe('Unit: parser/processor/note', () => {
70
71
  for (let i = 0; i < 3; ++i) {
71
72
  [...note(target)];
72
73
  assert.deepStrictEqual(
73
- [...target.children].map(el => el.outerHTML),
74
+ [...target.children].map(el => normalize(el.outerHTML)),
74
75
  [
75
76
  html('p', [
76
77
  html('sup', { class: 'annotation', id: 'annotation::ref:1:1', title: '1' }, [
@@ -123,10 +124,10 @@ describe('Unit: parser/processor/note', () => {
123
124
  for (let i = 0; i < 3; ++i) {
124
125
  [...note(target)];
125
126
  assert.deepStrictEqual(
126
- [...target.children].map(el => el.outerHTML),
127
+ [...target.children].map(el => normalize(el.outerHTML)),
127
128
  [
128
- '<blockquote><blockquote><section><p><sup class="annotation disabled" title="1"><a>*1</a></sup></p><ol class="annotations"><li data-marker="*1"><span>1</span><sup><a>^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></blockquote><section><p><sup class="annotation disabled" title="2"><a>*1</a></sup><br>~~~</p><ol class="annotations"><li data-marker="*1"><span>2</span><sup><a>^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></blockquote>',
129
- '<aside class="example" data-type="markdown"><pre translate="no">((3))</pre><hr><section><p><sup class="annotation disabled" title="3"><a>*1</a></sup></p><ol class="annotations"><li data-marker="*1"><span>3</span><sup><a>^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></aside>',
129
+ '<blockquote><blockquote><section><p><sup class="annotation local" id="annotation:random:ref:1:1" title="1"><a href="#annotation:random:def:1:1">*1</a></sup></p><ol class="annotations"><li id="annotation:random:def:1:1" data-marker="*1"><span>1</span><sup><a href="#annotation:random:ref:1:1">^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></blockquote><section><p><sup class="annotation local" id="annotation:random:ref:2:1" title="2"><a href="#annotation:random:def:2:1">*1</a></sup><br>~~~</p><ol class="annotations"><li id="annotation:random:def:2:1" data-marker="*1"><span>2</span><sup><a href="#annotation:random:ref:2:1">^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></blockquote>',
130
+ '<aside class="example" data-type="markdown"><pre translate="no">((3))</pre><hr><section><p><sup class="annotation local" id="annotation:random:ref:3:1" title="3"><a href="#annotation:random:def:3:1">*1</a></sup></p><ol class="annotations"><li id="annotation:random:def:3:1" data-marker="*1"><span>3</span><sup><a href="#annotation:random:ref:3:1">^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></aside>',
130
131
  '<p><sup class="annotation" id="annotation::ref:4:1" title="4"><a href="#annotation::def:4:1">*1</a></sup></p>',
131
132
  '<ol class="annotations"><li id="annotation::def:4:1" data-marker="*1"><span>4</span><sup><a href="#annotation::ref:4:1">^1</a></sup></li></ol>',
132
133
  ]);
@@ -138,7 +139,7 @@ describe('Unit: parser/processor/note', () => {
138
139
  for (let i = 0; i < 3; ++i) {
139
140
  [...note(target)];
140
141
  assert.deepStrictEqual(
141
- [...target.children].map(el => el.outerHTML),
142
+ [...target.children].map(el => normalize(el.outerHTML)),
142
143
  [
143
144
  html('p', [
144
145
  html('sup', { class: 'annotation', id: 'annotation::ref:1:1', title: '1' }, [
@@ -204,7 +205,7 @@ describe('Unit: parser/processor/note', () => {
204
205
  for (let i = 0; i < 3; ++i) {
205
206
  assert.deepStrictEqual([...note(target, undefined, { id: '0' })].length, i === 0 ? 2 : 3);
206
207
  assert.deepStrictEqual(
207
- [...target.children].map(el => el.outerHTML),
208
+ [...target.children].map(el => normalize(el.outerHTML)),
208
209
  [
209
210
  html('p', [
210
211
  html('sup', { class: 'annotation', id: 'annotation:0:ref:a_b:1', title: 'a b' }, [
@@ -226,7 +227,7 @@ describe('Unit: parser/processor/note', () => {
226
227
  for (let i = 0; i < 3; ++i) {
227
228
  [...note(target)];
228
229
  assert.deepStrictEqual(
229
- [...target.children].map(el => el.outerHTML),
230
+ [...target.children].map(el => normalize(el.outerHTML)),
230
231
  [
231
232
  html('p', [
232
233
  html('sup', { class: 'annotation', id: 'annotation::ref:a((b)):1', title: 'a((b))' }, [
@@ -282,7 +283,7 @@ describe('Unit: parser/processor/note', () => {
282
283
  for (let i = 0; i < 3; ++i) {
283
284
  [...note(target, notes)];
284
285
  assert.deepStrictEqual(
285
- [...target.children].map(el => el.outerHTML),
286
+ [...target.children].map(el => normalize(el.outerHTML)),
286
287
  [
287
288
  html('p', [
288
289
  html('sup', { class: 'reference', id: 'reference::ref:a_b:1', title: 'a b' }, [
@@ -291,7 +292,7 @@ describe('Unit: parser/processor/note', () => {
291
292
  ]).outerHTML,
292
293
  ]);
293
294
  assert.deepStrictEqual(
294
- [notes.references.outerHTML],
295
+ [normalize(notes.references.outerHTML)],
295
296
  [
296
297
  html('ol', [
297
298
  html('li', { id: 'reference::def:a_b' }, [
@@ -309,7 +310,7 @@ describe('Unit: parser/processor/note', () => {
309
310
  for (let i = 0; i < 3; ++i) {
310
311
  [...note(target, notes)];
311
312
  assert.deepStrictEqual(
312
- [...target.children].map(el => el.outerHTML),
313
+ [...target.children].map(el => normalize(el.outerHTML)),
313
314
  [
314
315
  html('p', [
315
316
  html('sup', { class: 'reference', 'data-abbr': 'A 1', id: 'reference::ref:A_1:1', title: 'b' }, [
@@ -324,7 +325,7 @@ describe('Unit: parser/processor/note', () => {
324
325
  ]).outerHTML,
325
326
  ]);
326
327
  assert.deepStrictEqual(
327
- [notes.references.outerHTML],
328
+ [normalize(notes.references.outerHTML)],
328
329
  [
329
330
  html('ol', [
330
331
  html('li', { id: 'reference::def:A_1' }, [
@@ -346,7 +347,7 @@ describe('Unit: parser/processor/note', () => {
346
347
  for (let i = 0; i < 3; ++i) {
347
348
  [...note(target, notes)];
348
349
  assert.deepStrictEqual(
349
- [...target.children].map(el => el.outerHTML),
350
+ [...target.children].map(el => normalize(el.outerHTML)),
350
351
  [
351
352
  html('p', [
352
353
  html('sup', { class: 'annotation', id: 'annotation::ref:a[[^B]]:1', title: 'a[[^B]]' }, [
@@ -369,7 +370,7 @@ describe('Unit: parser/processor/note', () => {
369
370
  ]).outerHTML,
370
371
  ]);
371
372
  assert.deepStrictEqual(
372
- [notes.references.outerHTML],
373
+ [normalize(notes.references.outerHTML)],
373
374
  [
374
375
  html('ol', [
375
376
  html('li', { id: 'reference::def:B' }, [
@@ -9,7 +9,10 @@ export function* note(
9
9
  readonly annotations?: HTMLOListElement;
10
10
  readonly references: HTMLOListElement;
11
11
  },
12
- opts: { readonly id?: string; } = {},
12
+ opts: {
13
+ readonly id?: string;
14
+ readonly local?: boolean;
15
+ } = {},
13
16
  bottom: Node | null = null,
14
17
  ): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
15
18
  const referenceRefMemory = referenceRefsMemoryCaller(target);
@@ -47,13 +50,13 @@ const referenceRefsMemoryCaller = memoize((target: Node) =>
47
50
  const annotation = build(
48
51
  'annotation',
49
52
  'annotations',
50
- '.annotation:not(:is(.annotations, .references) .annotation, .disabled)',
53
+ '.annotation:not(:is(.annotations, .references) .annotation, .local)',
51
54
  n => `*${n}`,
52
55
  'h1, h2, h3, h4, h5, h6, aside.aside, hr');
53
56
  const reference = build(
54
57
  'reference',
55
58
  'references',
56
- '.reference:not(:is(.annotations, .references) .reference, .disabled)',
59
+ '.reference:not(:is(.annotations, .references) .reference, .local)',
57
60
  (n, abbr) => `[${abbr || n}]`);
58
61
 
59
62
  function build(
@@ -69,7 +72,10 @@ function build(
69
72
  memory: Map<HTMLElement, RefMemory>,
70
73
  target: ParentNode & Node,
71
74
  note?: HTMLOListElement,
72
- opts: { readonly id?: string } = {},
75
+ opts: {
76
+ readonly id?: string;
77
+ readonly local?: boolean;
78
+ } = {},
73
79
  bottom: Node | null = null,
74
80
  ): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
75
81
  const refInfoCaller = memoize((ref: HTMLElement) => {
@@ -164,7 +170,7 @@ function build(
164
170
  assert(syntax !== 'annotation' || title);
165
171
  define(ref, {
166
172
  id: refId,
167
- class: opts.id !== '' ? undefined : void ref.classList.add('disabled'),
173
+ class: opts.local ? `${ref.className} local` : undefined,
168
174
  title,
169
175
  }, []);
170
176
  if (title && info.queue.length > 0) {
@@ -2,6 +2,7 @@ import { Parser, Result, List, Node, failsafe } from '../combinator/data/parser'
2
2
  import { tester } from '../combinator/data/delimiter';
3
3
  import { Context, Command } from './context';
4
4
  import { min } from 'spica/alias';
5
+ import { rnd0Z } from 'spica/random';
5
6
  import { define } from 'typed-dom/dom';
6
7
 
7
8
  export function* unwrap<N>(nodes: List<Node<N>> | undefined): Iterable<N> {
@@ -129,3 +130,7 @@ export function stringify(nodes: Iterable<HTMLElement | string>): string {
129
130
  }
130
131
  return acc;
131
132
  }
133
+
134
+ export function randomID(): string {
135
+ return `random-${rnd0Z(6)}`;
136
+ }
package/src/util/toc.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { push } from 'spica/array';
2
2
  import { html } from 'typed-dom/dom';
3
3
 
4
- const selector = ':is(h1, h2, h3, h4, h5, h6, aside.aside)[id]';
4
+ const selector = ':is(h1, h2, h3, h4, h5, h6, aside.aside)[id]:not(.local)';
5
5
 
6
6
  export function toc(source: DocumentFragment | HTMLElement | ShadowRoot): HTMLUListElement {
7
7
  const hs: HTMLHeadingElement[] = [];