securemark 0.297.5 → 0.297.6

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.297.6
4
+
5
+ - Refactoring.
6
+
3
7
  ## 0.297.5
4
8
 
5
9
  - Fix annotation parser.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.297.5 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.297.6 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"));
@@ -6111,7 +6111,7 @@ const parser_1 = __webpack_require__(605);
6111
6111
  class Context extends parser_1.Context {
6112
6112
  constructor(options = {}) {
6113
6113
  super(options);
6114
- this.recursion = new RecursionCounter(5);
6114
+ this.recursion = new RecursionCounter('annotation', 2);
6115
6115
  const {
6116
6116
  segment,
6117
6117
  buffer,
@@ -6134,7 +6134,8 @@ class Context extends parser_1.Context {
6134
6134
  }
6135
6135
  exports.Context = Context;
6136
6136
  class RecursionCounter {
6137
- constructor(limit) {
6137
+ constructor(syntax, limit) {
6138
+ this.syntax = syntax;
6138
6139
  this.limit = limit;
6139
6140
  this.stack = [];
6140
6141
  this.index = 0;
@@ -6144,7 +6145,8 @@ class RecursionCounter {
6144
6145
  stack
6145
6146
  } = this;
6146
6147
  for (; this.index > 0 && stack[this.index - 1] <= depth; --this.index);
6147
- if (this.index === this.limit) throw new Error('Too much recursion');
6148
+ // 内側から数えるので無効化処理できずエラーを投げるしかない。
6149
+ if (this.index === this.limit) throw new Error(`Too much ${this.syntax} recursion`);
6148
6150
  stack[this.index] = depth;
6149
6151
  ++this.index;
6150
6152
  }
@@ -6377,17 +6379,26 @@ const dom_1 = __webpack_require__(394);
6377
6379
  // 動的計画法を適用するか再帰数を制限する必要がある。
6378
6380
  // 動的計画法においては再帰的記録により指数空間計算量にならないよう下位の記録を消しながら記録しなければならない。
6379
6381
  // トリムも再帰的に行わないよう前後のトリムサイズの記録を要する。
6380
- // しかし理論的には再帰数の制限はないがポップアップテキストの記録やハッシュの計算を行う言語仕様から指数計算量を
6382
+ // しかし理論的には無制限の再帰が可能だがホバーテキストの記録やハッシュの計算を行う言語仕様から指数計算量を
6381
6383
  // 避けられないためAnnotation構文に限り再帰数の制限が必要となる。
6382
- // シグネチャやハッシュは分割計算可能にすれば解決するがポップアップテキストは記録せず動的に再計算して
6384
+ // シグネチャやハッシュは分割計算可能にすれば解決するがホバーテキストは記録せず動的に再計算して
6383
6385
  // 表示しなければ指数空間計算量を避けられない。
6384
- // 注釈は本来再帰的に行うものではないため再帰数を制限して機能を優先するのが合理的となる。
6386
+ // 注釈を除外すると重複排除により参照元が消滅し欠番が生じるため少なくとも直接注釈は残す必要があるが間接注釈は
6387
+ // 除外できる。しかしこれを効率的に行うことは難しいため最大再帰数を1回に制限することで間接注釈を行えない
6388
+ // ようにするのが合理的だろう。
6389
+ // 原理的には逆順処理により圧縮後正順で再附番すればすべて解決するはずだがテキストとシグネチャとハッシュも
6390
+ // 修正する必要があるためほぼ完全な二重処理が必要になり三重以上の注釈という不適切な使用のために
6391
+ // 常に非常に非効率な処理を行い常時低速化するより三重以上の注釈を禁止して効率性を維持するのが妥当である。
6392
+ const MAX_DEPTH = 20;
6385
6393
  exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(128 /* State.annotation */, (0, combinator_1.surround)((0, combinator_1.open)('((', visibility_1.beforeNonblank), (0, combinator_1.precedence)(1, (0, combinator_1.recursions)([4 /* Recursion.annotation */, 3 /* Recursion.inline */, 5 /* Recursion.bracket */, 5 /* Recursion.bracket */], (0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ')', [[')', 1]]))), '))', false, [], ([, ns], context) => {
6386
6394
  const {
6387
- linebreak
6395
+ linebreak,
6396
+ recursion,
6397
+ resources
6388
6398
  } = context;
6399
+ const depth = MAX_DEPTH - (resources?.recursions[4 /* Recursion.annotation */] ?? resources?.recursions.at(-1) ?? MAX_DEPTH);
6389
6400
  if (linebreak === 0) {
6390
- context.recursion.add(20 - (context.resources?.recursions[4 /* Recursion.annotation */] ?? context.resources?.recursions.at(-1) ?? 20));
6401
+ recursion.add(depth);
6391
6402
  return new parser_1.List([new parser_1.Node((0, dom_1.html)('sup', {
6392
6403
  class: 'annotation'
6393
6404
  }, [(0, dom_1.html)('span', (0, dom_1.defrag)((0, util_1.unwrap)((0, visibility_1.trimBlankNodeEnd)(ns))))]))]);
@@ -6404,8 +6415,11 @@ exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(1
6404
6415
  source,
6405
6416
  position,
6406
6417
  range,
6407
- linebreak
6418
+ linebreak,
6419
+ recursion,
6420
+ resources
6408
6421
  } = context;
6422
+ const depth = MAX_DEPTH - (resources?.recursions[4 /* Recursion.annotation */] ?? resources?.recursions.at(-1) ?? MAX_DEPTH);
6409
6423
  if (linebreak === 0 && bs.length === 1 && source[position] === ')' && typeof bs.head?.value === 'object') {
6410
6424
  const {
6411
6425
  className
@@ -6426,7 +6440,7 @@ exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(1
6426
6440
  lastChild.nodeValue = lastChild.nodeValue.slice(0, -1);
6427
6441
  }
6428
6442
  context.position += 1;
6429
- context.recursion.add(20 - (context.resources?.recursions[4 /* Recursion.annotation */] ?? context.resources?.recursions.at(-1) ?? 20));
6443
+ recursion.add(depth);
6430
6444
  return new parser_1.List([new parser_1.Node((0, dom_1.html)('span', {
6431
6445
  class: 'bracket'
6432
6446
  }, ['(', (0, dom_1.html)('sup', {
@@ -6435,7 +6449,7 @@ exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(1
6435
6449
  }
6436
6450
  if (className === 'annotation' && deepunwrap(bs)) {
6437
6451
  context.position += 1;
6438
- context.recursion.add(20 - (context.resources?.recursions[4 /* Recursion.annotation */] ?? context.resources?.recursions.at(-1) ?? 20));
6452
+ recursion.add(depth);
6439
6453
  return new parser_1.List([new parser_1.Node((0, dom_1.html)('span', {
6440
6454
  class: 'bracket'
6441
6455
  }, ['(', (0, dom_1.html)('sup', {
@@ -8498,13 +8512,14 @@ function build(syntax, list, query, marker, splitter = '') {
8498
8512
  info.queue.push(ref);
8499
8513
  break;
8500
8514
  }
8501
- yield ref.appendChild((0, dom_1.html)('a', {
8515
+ ref.appendChild((0, dom_1.html)('a', {
8502
8516
  href: refId && defId && `#${defId}`
8503
8517
  }, marker(defIndex, abbr)));
8504
8518
  def.lastElementChild.appendChild((0, dom_1.html)('a', {
8505
8519
  href: refId && `#${refId}`,
8506
8520
  title: abbr && text || undefined
8507
8521
  }, `^${++refIndex}`));
8522
+ yield;
8508
8523
  }
8509
8524
  if (note || defs.size > 0) {
8510
8525
  const splitter = splitters[iSplitters++];
@@ -9467,7 +9482,6 @@ function render(source, opts = {}) {
9467
9482
  }
9468
9483
  exports.render = render;
9469
9484
  function render_(base, source, opts) {
9470
- if (source.classList.contains('invalid')) return;
9471
9485
  try {
9472
9486
  switch (true) {
9473
9487
  case !!opts.code && !source.firstElementChild && source.matches('pre.code'):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.297.5",
3
+ "version": "0.297.6",
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",
@@ -324,40 +324,40 @@ describe('Unit: parser/api/parse', () => {
324
324
  `<pre class="error" translate="no">${'['.repeat(21)}0</pre>`,
325
325
  ]);
326
326
  assert.deepStrictEqual(
327
- [...parse(`${'(('.repeat(5)}0${'))'.repeat(5)}`).children].map(el => el.tagName),
327
+ [...parse(`${'(('.repeat(2)}0${'))'.repeat(2)}`).children].map(el => el.tagName),
328
328
  ['P', 'OL']);
329
329
  assert.deepStrictEqual(
330
- [...parse(`${'(('.repeat(6)}0${'))'.repeat(6)}`).children].map(el => el.tagName),
330
+ [...parse(`${'(('.repeat(3)}0${'))'.repeat(3)}`).children].map(el => el.tagName),
331
331
  ['H1', 'PRE']);
332
332
  assert.deepStrictEqual(
333
- [...parse(`${'(('.repeat(5)}!${'))'.repeat(5)}`).children].map(el => el.tagName),
333
+ [...parse(`${'(('.repeat(2)}!${'))'.repeat(2)}`).children].map(el => el.tagName),
334
334
  ['P', 'OL']);
335
335
  assert.deepStrictEqual(
336
- [...parse(`${'(('.repeat(6)}!${'))'.repeat(6)}`).children].map(el => el.tagName),
336
+ [...parse(`${'(('.repeat(3)}!${'))'.repeat(3)}`).children].map(el => el.tagName),
337
337
  ['H1', 'PRE']);
338
338
  assert.deepStrictEqual(
339
- [...parse(`(${'(('.repeat(5)}0${'))'.repeat(5)}`).children].map(el => el.tagName),
339
+ [...parse(`(${'(('.repeat(2)}0${'))'.repeat(2)}`).children].map(el => el.tagName),
340
340
  ['P', 'OL']);
341
341
  assert.deepStrictEqual(
342
- [...parse(`(${'(('.repeat(6)}0${'))'.repeat(6)}`).children].map(el => el.tagName),
342
+ [...parse(`(${'(('.repeat(3)}0${'))'.repeat(3)}`).children].map(el => el.tagName),
343
343
  ['H1', 'PRE']);
344
344
  assert.deepStrictEqual(
345
- [...parse(`(${'(('.repeat(5)}!${'))'.repeat(5)}`).children].map(el => el.tagName),
345
+ [...parse(`(${'(('.repeat(2)}!${'))'.repeat(2)}`).children].map(el => el.tagName),
346
346
  ['P', 'OL']);
347
347
  assert.deepStrictEqual(
348
- [...parse(`(${'(('.repeat(6)}!${'))'.repeat(6)}`).children].map(el => el.tagName),
348
+ [...parse(`(${'(('.repeat(3)}!${'))'.repeat(3)}`).children].map(el => el.tagName),
349
349
  ['H1', 'PRE']);
350
350
  assert.deepStrictEqual(
351
- [...parse(`${'(('.repeat(5)}0${'))'.repeat(5)}${'(('.repeat(5)}0${'))'.repeat(5)}`).children].map(el => el.tagName),
351
+ [...parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(2)}0${'))'.repeat(2)}`).children].map(el => el.tagName),
352
352
  ['P', 'OL']);
353
353
  assert.deepStrictEqual(
354
- [...parse(`${'(('.repeat(5)}0${'))'.repeat(5)}${'(('.repeat(6)}0${'))'.repeat(6)}`).children].map(el => el.tagName),
354
+ [...parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(3)}0${'))'.repeat(3)}`).children].map(el => el.tagName),
355
355
  ['H1', 'PRE']);
356
356
  assert.deepStrictEqual(
357
- [...parse(`${'(('.repeat(5)}0${'))'.repeat(5)}${'(('.repeat(9)}0${'))'.repeat(5)}`).children].map(el => el.tagName),
357
+ [...parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(9)}0${'))'.repeat(2)}`).children].map(el => el.tagName),
358
358
  ['P', 'OL']);
359
359
  assert.deepStrictEqual(
360
- [...parse(`${'(('.repeat(5)}0${'))'.repeat(5)}${'(('.repeat(9)}0${'))'.repeat(6)}`).children].map(el => el.tagName),
360
+ [...parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(9)}0${'))'.repeat(3)}`).children].map(el => el.tagName),
361
361
  ['H1', 'PRE']);
362
362
  });
363
363
 
@@ -28,7 +28,7 @@ export class Context extends Ctx {
28
28
  public override segment: Segment;
29
29
  public buffer: List<Node<(string | HTMLElement)>>;
30
30
  public sequential: boolean;
31
- public recursion = new RecursionCounter(5);
31
+ public recursion = new RecursionCounter('annotation', 2);
32
32
  public readonly header: boolean;
33
33
  public readonly host?: URL;
34
34
  public readonly url?: URL;
@@ -42,14 +42,18 @@ export class Context extends Ctx {
42
42
  export type Options = Partial<Context>;
43
43
 
44
44
  class RecursionCounter {
45
- constructor(private readonly limit: number) {
45
+ constructor(
46
+ private readonly syntax: string,
47
+ private readonly limit: number,
48
+ ) {
46
49
  }
47
50
  private readonly stack: number[] = [];
48
51
  private index = 0;
49
52
  public add(depth: number): void {
50
53
  const { stack } = this
51
54
  for (; this.index > 0 && stack[this.index - 1] <= depth; --this.index);
52
- if (this.index === this.limit) throw new Error('Too much recursion');
55
+ // 内側から数えるので無効化処理できずエラーを投げるしかない。
56
+ if (this.index === this.limit) throw new Error(`Too much ${this.syntax} recursion`);
53
57
  stack[this.index] = depth;
54
58
  ++this.index;
55
59
  }
@@ -12,11 +12,17 @@ import { html, defrag } from 'typed-dom/dom';
12
12
  // 動的計画法を適用するか再帰数を制限する必要がある。
13
13
  // 動的計画法においては再帰的記録により指数空間計算量にならないよう下位の記録を消しながら記録しなければならない。
14
14
  // トリムも再帰的に行わないよう前後のトリムサイズの記録を要する。
15
- // しかし理論的には再帰数の制限はないがポップアップテキストの記録やハッシュの計算を行う言語仕様から指数計算量を
15
+ // しかし理論的には無制限の再帰が可能だがホバーテキストの記録やハッシュの計算を行う言語仕様から指数計算量を
16
16
  // 避けられないためAnnotation構文に限り再帰数の制限が必要となる。
17
- // シグネチャやハッシュは分割計算可能にすれば解決するがポップアップテキストは記録せず動的に再計算して
17
+ // シグネチャやハッシュは分割計算可能にすれば解決するがホバーテキストは記録せず動的に再計算して
18
18
  // 表示しなければ指数空間計算量を避けられない。
19
- // 注釈は本来再帰的に行うものではないため再帰数を制限して機能を優先するのが合理的となる。
19
+ // 注釈を除外すると重複排除により参照元が消滅し欠番が生じるため少なくとも直接注釈は残す必要があるが間接注釈は
20
+ // 除外できる。しかしこれを効率的に行うことは難しいため最大再帰数を1回に制限することで間接注釈を行えない
21
+ // ようにするのが合理的だろう。
22
+ // 原理的には逆順処理により圧縮後正順で再附番すればすべて解決するはずだがテキストとシグネチャとハッシュも
23
+ // 修正する必要があるためほぼ完全な二重処理が必要になり三重以上の注釈という不適切な使用のために
24
+ // 常に非常に非効率な処理を行い常時低速化するより三重以上の注釈を禁止して効率性を維持するのが妥当である。
25
+ const MAX_DEPTH = 20;
20
26
  export const annotation: AnnotationParser = lazy(() => constraint(State.annotation, surround(
21
27
  open('((', beforeNonblank),
22
28
  precedence(1, recursions([Recursion.annotation, Recursion.inline, Recursion.bracket, Recursion.bracket],
@@ -24,9 +30,10 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
24
30
  '))',
25
31
  false, [],
26
32
  ([, ns], context) => {
27
- const { linebreak } = context;
33
+ const { linebreak, recursion, resources } = context;
34
+ const depth = MAX_DEPTH - (resources?.recursions[Recursion.annotation] ?? resources?.recursions.at(-1) ?? MAX_DEPTH);
28
35
  if (linebreak === 0) {
29
- context.recursion.add(20 - (context.resources?.recursions[Recursion.annotation] ?? context.resources?.recursions.at(-1) ?? 20));
36
+ recursion.add(depth);
30
37
  return new List([new Node(html('sup', { class: 'annotation' }, [html('span', defrag(unwrap(trimBlankNodeEnd(ns))))]))]);
31
38
  }
32
39
  ns.unshift(new Node('('));
@@ -34,7 +41,8 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
34
41
  return new List([new Node(html('span', { class: 'bracket' }, ['(', html('span', { class: 'bracket' }, defrag(unwrap(ns))), ')']))]);
35
42
  },
36
43
  ([, bs = new List()], context) => {
37
- const { source, position, range, linebreak } = context;
44
+ const { source, position, range, linebreak, recursion, resources } = context;
45
+ const depth = MAX_DEPTH - (resources?.recursions[Recursion.annotation] ?? resources?.recursions.at(-1) ?? MAX_DEPTH);
38
46
  if (linebreak === 0 && bs.length === 1 && source[position] === ')' && typeof bs.head?.value === 'object') {
39
47
  const { className } = bs.head.value;
40
48
  if (className === 'paren' || className === 'bracket') {
@@ -54,12 +62,12 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
54
62
  lastChild!.nodeValue = lastChild!.nodeValue!.slice(0, -1);
55
63
  }
56
64
  context.position += 1;
57
- context.recursion.add(20 - (context.resources?.recursions[Recursion.annotation] ?? context.resources?.recursions.at(-1) ?? 20));
65
+ recursion.add(depth);
58
66
  return new List([new Node(html('span', { class: 'bracket' }, ['(', html('sup', { class: 'annotation' }, [html('span', bs.head.value.childNodes)])]))]);
59
67
  }
60
68
  if (className === 'annotation' && deepunwrap(bs)) {
61
69
  context.position += 1;
62
- context.recursion.add(20 - (context.resources?.recursions[Recursion.annotation] ?? context.resources?.recursions.at(-1) ?? 20));
70
+ recursion.add(depth);
63
71
  return new List([new Node(html('span', { class: 'bracket' }, ['(', html('sup', { class: 'annotation' }, [html('span', [bs.head.value])])]))]);
64
72
  }
65
73
  }
@@ -222,72 +222,50 @@ describe('Unit: parser/processor/note', () => {
222
222
  });
223
223
 
224
224
  it('nest', () => {
225
- const target = parse('((a((b((c))))))((a))((b))((c))');
225
+ const target = parse('((a((b))))((a))((b))');
226
226
  for (let i = 0; i < 3; ++i) {
227
227
  [...note(target)];
228
228
  assert.deepStrictEqual(
229
229
  [...target.children].map(el => el.outerHTML),
230
230
  [
231
231
  html('p', [
232
- html('sup', { class: 'annotation', id: 'annotation::ref:a((b((c)))):1', title: 'a((b((c))))' }, [
233
- html('a', { href: '#annotation::def:a((b((c)))):1' }, '*1')
232
+ html('sup', { class: 'annotation', id: 'annotation::ref:a((b)):1', title: 'a((b))' }, [
233
+ html('a', { href: '#annotation::def:a((b)):1' }, '*1')
234
234
  ]),
235
235
  html('sup', { class: 'annotation', id: 'annotation::ref:a:1', title: 'a' }, [
236
- html('a', { href: '#annotation::def:a:1' }, '*4')
236
+ html('a', { href: '#annotation::def:a:1' }, '*3')
237
237
  ]),
238
- html('sup', { class: 'annotation', id: 'annotation::ref:b:1', title: 'b' }, [
239
- html('a', { href: '#annotation::def:b:1' }, '*5')
240
- ]),
241
- html('sup', { class: 'annotation', id: 'annotation::ref:c:2', title: 'c' }, [
242
- html('a', { href: '#annotation::def:c:1' }, '*3')
238
+ html('sup', { class: 'annotation', id: 'annotation::ref:b:2', title: 'b' }, [
239
+ html('a', { href: '#annotation::def:b:1' }, '*2')
243
240
  ]),
244
241
  ]).outerHTML,
245
242
  html('ol', { class: 'annotations' }, [
246
- html('li', { id: 'annotation::def:a((b((c)))):1', 'data-marker': '*1' }, [
243
+ html('li', { id: 'annotation::def:a((b)):1', 'data-marker': '*1' }, [
247
244
  html('span', [
248
245
  'a',
249
- html('sup', { class: 'annotation', id: 'annotation::ref:b((c)):1', title: 'b((c))' }, [
250
- html('a', { href: '#annotation::def:b((c)):1' }, '*2')
246
+ html('sup', { class: 'annotation', id: 'annotation::ref:b:1', title: 'b' }, [
247
+ html('a', { href: '#annotation::def:b:1' }, '*2')
251
248
  ]),
252
249
  ]),
253
250
  html('sup', [
254
- html('a', { href: '#annotation::ref:a((b((c)))):1' }, '^1'),
251
+ html('a', { href: '#annotation::ref:a((b)):1' }, '^1'),
255
252
  ])
256
253
  ]),
257
- html('li', { id: 'annotation::def:b((c)):1', 'data-marker': '*2' }, [
254
+ html('li', { id: 'annotation::def:b:1', 'data-marker': '*2' }, [
258
255
  html('span', [
259
256
  'b',
260
- html('sup', { class: 'annotation', id: 'annotation::ref:c:1', title: 'c' }, [
261
- html('a', { href: '#annotation::def:c:1' }, '*3')
262
- ]),
263
- ]),
264
- html('sup', [
265
- html('a', { href: '#annotation::ref:b((c)):1' }, '^2'),
266
- ])
267
- ]),
268
- html('li', { id: 'annotation::def:c:1', 'data-marker': '*3' }, [
269
- html('span', [
270
- 'c',
271
257
  ]),
272
258
  html('sup', [
273
- html('a', { href: '#annotation::ref:c:1' }, '^3'),
274
- html('a', { href: '#annotation::ref:c:2' }, '^6'),
259
+ html('a', { href: '#annotation::ref:b:1' }, '^2'),
260
+ html('a', { href: '#annotation::ref:b:2' }, '^4'),
275
261
  ])
276
262
  ]),
277
- html('li', { id: 'annotation::def:a:1', 'data-marker': '*4' }, [
263
+ html('li', { id: 'annotation::def:a:1', 'data-marker': '*3' }, [
278
264
  html('span', [
279
265
  'a',
280
266
  ]),
281
267
  html('sup', [
282
- html('a', { href: '#annotation::ref:a:1' }, '^4'),
283
- ])
284
- ]),
285
- html('li', { id: 'annotation::def:b:1', 'data-marker': '*5' }, [
286
- html('span', [
287
- 'b',
288
- ]),
289
- html('sup', [
290
- html('a', { href: '#annotation::ref:b:1' }, '^5'),
268
+ html('a', { href: '#annotation::ref:a:1' }, '^3'),
291
269
  ])
292
270
  ]),
293
271
  ]).outerHTML,
@@ -187,7 +187,7 @@ function build(
187
187
  info.queue.push(ref);
188
188
  break;
189
189
  }
190
- yield ref.appendChild(html('a', { href: refId && defId && `#${defId}` }, marker(defIndex, abbr)));
190
+ ref.appendChild(html('a', { href: refId && defId && `#${defId}` }, marker(defIndex, abbr)));
191
191
  assert(ref.title || ref.matches('.invalid'));
192
192
  def.lastElementChild!.appendChild(
193
193
  html('a',
@@ -196,6 +196,7 @@ function build(
196
196
  title: abbr && text || undefined,
197
197
  },
198
198
  `^${++refIndex}`));
199
+ yield;
199
200
  }
200
201
  if (note || defs.size > 0) {
201
202
  const splitter = splitters[iSplitters++];
@@ -19,7 +19,6 @@ export function render(source: HTMLElement, opts: RenderingOptions = {}): void {
19
19
  }
20
20
 
21
21
  function render_(base: string, source: HTMLElement, opts: RenderingOptions): void {
22
- if (source.classList.contains('invalid')) return;
23
22
  try {
24
23
  switch (true) {
25
24
  case !!opts.code