securemark 0.298.0 → 0.298.2

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.
@@ -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)),
@@ -121,7 +121,7 @@ export const block: BlockParser = reset(
121
121
  }
122
122
  },
123
123
  paragraph
124
- ]) as any));
124
+ ])));
125
125
 
126
126
  function error(parser: BlockParser): BlockParser {
127
127
  const reg = new RegExp(String.raw`^${Command.Error}[^\n]*\n`)
@@ -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;
@@ -3,7 +3,7 @@ import { State, Recursion } from '../context';
3
3
  import { List, Node } from '../../combinator/data/parser';
4
4
  import { union, some, recursions, precedence, constraint, surround, open, lazy } from '../../combinator';
5
5
  import { inline } from '../inline';
6
- import { indexA } from './bracket';
6
+ import { bracketname, indexA } from './bracket';
7
7
  import { beforeNonblank, trimBlankNodeEnd } from '../visibility';
8
8
  import { unwrap } from '../util';
9
9
  import { html, defrag } from 'typed-dom/dom';
@@ -34,14 +34,20 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
34
34
  if (linebreak !== 0) {
35
35
  ns.unshift(new Node('('));
36
36
  ns.push(new Node(')'));
37
- return new List([new Node(html('span', { class: 'bracket' }, ['(', html('span', { class: 'bracket' }, defrag(unwrap(ns))), ')']))]);
37
+ return new List([
38
+ new Node(html('span',
39
+ { class: 'bracket' },
40
+ ['(', html('span', { class: 'bracket' }, defrag(unwrap(ns))), ')']))
41
+ ]);
38
42
  }
39
43
  const depth = MAX_DEPTH - (resources?.recursions[Recursion.annotation] ?? resources?.recursions.at(-1) ?? MAX_DEPTH);
40
44
  recursion.add(depth);
41
- return new List([new Node(html('sup', { class: 'annotation' }, [html('span', defrag(unwrap(trimBlankNodeEnd(ns))))]))]);
45
+ return new List([
46
+ new Node(html('sup', { class: 'annotation' }, [html('span', defrag(unwrap(trimBlankNodeEnd(ns))))]))
47
+ ]);
42
48
  },
43
49
  ([, bs], context) => {
44
- const { source, position, range, linebreak, recursion, resources } = context;
50
+ const { source, position, linebreak, recursion, resources } = context;
45
51
  const depth = MAX_DEPTH - (resources?.recursions[Recursion.annotation] ?? resources?.recursions.at(-1) ?? MAX_DEPTH);
46
52
  if (linebreak === 0 && bs && bs.length === 1 && source[position] === ')' && typeof bs.head?.value === 'object') {
47
53
  const { className } = bs.head.value;
@@ -63,12 +69,20 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
63
69
  }
64
70
  context.position += 1;
65
71
  recursion.add(depth);
66
- return new List([new Node(html('span', { class: 'bracket' }, ['(', html('sup', { class: 'annotation' }, [html('span', bs.head.value.childNodes)])]))]);
72
+ return new List([
73
+ new Node(html('span',
74
+ { class: 'bracket' },
75
+ ['(', html('sup', { class: 'annotation' }, [html('span', bs.head.value.childNodes)])]))
76
+ ]);
67
77
  }
68
78
  if (className === 'annotation' && deepunwrap(bs)) {
69
79
  context.position += 1;
70
80
  recursion.add(depth);
71
- return new List([new Node(html('span', { class: 'bracket' }, ['(', html('sup', { class: 'annotation' }, [html('span', [bs.head.value])])]))]);
81
+ return new List([
82
+ new Node(html('span',
83
+ { class: 'bracket' },
84
+ ['(', html('sup', { class: 'annotation' }, [html('span', [bs.head.value])])]))
85
+ ]);
72
86
  }
73
87
  }
74
88
  bs ??= new List();
@@ -76,11 +90,13 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
76
90
  if (source[context.position] === ')') {
77
91
  bs.push(new Node(')'));
78
92
  context.position += 1;
93
+ context.range += 1;
79
94
  }
80
- const str = linebreak === 0 ? source.slice(position - range + 2, position) : '';
81
- bs = linebreak === 0 && (str === '' || indexA.test(str))
82
- ? new List([new Node(html('span', { class: 'paren' }, defrag(unwrap(bs))))])
83
- : new List([new Node(html('span', { class: 'bracket' }, defrag(unwrap(bs))))]);
95
+ bs = new List([
96
+ new Node(html('span',
97
+ { class: bracketname(context, indexA, 2, context.position - position) },
98
+ defrag(unwrap(bs))))
99
+ ]);
84
100
  bs.unshift(new Node('('));
85
101
  const cs = parser(context);
86
102
  if (source[context.position] === ')') {
@@ -20,9 +20,10 @@ describe('Unit: parser/inline/bracket', () => {
20
20
  assert.deepStrictEqual(inspect(parser, input('(0)-1', new Context())), [['<span class="paren">(0)</span>'], '-1']);
21
21
  assert.deepStrictEqual(inspect(parser, input('(0.1)', new Context())), [['<span class="paren">(0.1)</span>'], '']);
22
22
  assert.deepStrictEqual(inspect(parser, input('(0.1.2)', new Context())), [['<span class="paren">(0.1.2)</span>'], '']);
23
- assert.deepStrictEqual(inspect(parser, input('(1.1, 1.2-1.3, 1.4)', new Context())), [['<span class="paren">(1.1, 1.2-1.3, 1.4)</span>'], '']);
24
- assert.deepStrictEqual(inspect(parser, input('(1 2)', new Context())), [['<span class="bracket">(1 2)</span>'], '']);
25
23
  assert.deepStrictEqual(inspect(parser, input('(1, 2)', new Context())), [['<span class="paren">(1, 2)</span>'], '']);
24
+ assert.deepStrictEqual(inspect(parser, input('(1.1-1.2)', new Context())), [['<span class="paren">(1.1-1.2)</span>'], '']);
25
+ assert.deepStrictEqual(inspect(parser, input('(1.1, 1.2)', new Context())), [['<span class="paren">(1.1, 1.2)</span>'], '']);
26
+ assert.deepStrictEqual(inspect(parser, input('(1 2)', new Context())), [['<span class="bracket">(1 2)</span>'], '']);
26
27
  assert.deepStrictEqual(inspect(parser, input('(1a)', new Context())), [['<span class="paren">(1a)</span>'], '']);
27
28
  assert.deepStrictEqual(inspect(parser, input('(a)', new Context())), [['<span class="paren">(a)</span>'], '']);
28
29
  assert.deepStrictEqual(inspect(parser, input('(a1)', new Context())), [['<span class="paren">(a1)</span>'], '']);
@@ -39,6 +40,8 @@ describe('Unit: parser/inline/bracket', () => {
39
40
  assert.deepStrictEqual(inspect(parser, input('(Name, Name)', new Context())), [['<span class="paren">(Name, Name)</span>'], '']);
40
41
  assert.deepStrictEqual(inspect(parser, input('(ABBR)', new Context())), [['<span class="paren">(ABBR)</span>'], '']);
41
42
  assert.deepStrictEqual(inspect(parser, input('(ABBR, ABBR)', new Context())), [['<span class="paren">(ABBR, ABBR)</span>'], '']);
43
+ assert.deepStrictEqual(inspect(parser, input(`(${'0'.repeat(16)})`, new Context())), [[`<span class="paren">(${'0'.repeat(16)})</span>`], '']);
44
+ assert.deepStrictEqual(inspect(parser, input(`(${'0'.repeat(17)})`, new Context())), [[`<span class="bracket">(${'0'.repeat(17)})</span>`], '']);
42
45
  assert.deepStrictEqual(inspect(parser, input('(\\a)', new Context())), [['<span class="bracket">(a)</span>'], '']);
43
46
  assert.deepStrictEqual(inspect(parser, input('(==)', new Context())), [['<span class="bracket">(==)</span>'], '']);
44
47
  assert.deepStrictEqual(inspect(parser, input('(()', new Context())), [['<span class="bracket">(<span class="paren">()</span></span>'], '']);
@@ -1,5 +1,5 @@
1
1
  import { BracketParser } from '../inline';
2
- import { State, Recursion, Backtrack } from '../context';
2
+ import { Context, State, Recursion, Backtrack } from '../context';
3
3
  import { List, Node } from '../../combinator/data/parser';
4
4
  import { union, some, recursion, precedence, surround, isBacktrack, setBacktrack, lazy } from '../../combinator';
5
5
  import { inline } from '../inline';
@@ -8,9 +8,22 @@ import { str } from '../source';
8
8
  import { unwrap } from '../util';
9
9
  import { html, defrag } from 'typed-dom/dom';
10
10
 
11
- export const indexA = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*$/;
12
- const indexF = new RegExp(indexA.source.replace(', ', '[,、]')
13
- .replace(/[09AZaz.]|\-(?!\w)/g, c => String.fromCodePoint(c.codePointAt(0)! + 0xFEE0)));
11
+ export const indexA = /[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*/y;
12
+ const indexF = new RegExp(
13
+ indexA.source.replace(', ', '[,、]')
14
+ .replace(/[09AZaz.]|\-(?!\w)/g, c => String.fromCodePoint(c.codePointAt(0)! + 0xFEE0)),
15
+ 'y');
16
+ export function bracketname(context: Context, syntax: RegExp, opener: number, closer: number): string {
17
+ const { source, position, range, linebreak } = context;
18
+ syntax.lastIndex = position - range + opener;
19
+ return range - opener - closer === 0
20
+ || linebreak === 0
21
+ && range - opener - closer <= 16
22
+ && syntax.test(source)
23
+ && syntax.lastIndex === position - closer
24
+ ? 'paren'
25
+ : 'bracket';
26
+ }
14
27
 
15
28
  export const bracket: BracketParser = lazy(() => union([
16
29
  input => {
@@ -32,45 +45,39 @@ export const bracket: BracketParser = lazy(() => union([
32
45
  return d1(input);
33
46
  }
34
47
  }
35
- ])) as any;
48
+ ]));
36
49
 
37
50
  const p1 = lazy(() => surround(
38
51
  str('('),
39
52
  precedence(1, recursion(Recursion.bracket, some(inline, ')', [[')', 1]]))),
40
53
  str(')'),
41
54
  true, [],
42
- ([as, bs = [], cs], { source, position, range, linebreak }) => {
43
- const str = linebreak === 0 ? source.slice(position - range + 1, position - 1) : '';
44
- return linebreak === 0 && (str === '' || indexA.test(str))
45
- ? new List([new Node(html('span', { class: 'paren' }, `(${str})`))])
46
- : new List([new Node(html('span', { class: 'bracket' }, defrag(unwrap(as.import(bs as List<Node<string>>).import(cs)))))]);
47
- },
48
- ([as, bs = new List()], context) => {
49
- const { source, position, range, linebreak } = context;
50
- const str = linebreak === 0 ? source.slice(position - range + 1, position) : '';
51
- return linebreak === 0 && (str === '' || indexA.test(str))
52
- ? new List([new Node(html('span', { class: 'paren' }, `(${str}`))])
53
- : new List([new Node(html('span', { class: 'bracket' }, defrag(unwrap(as.import(bs as List<Node<string>>)))))]);
54
- }));
55
+ ([as, bs = new List(), cs], context) => new List([
56
+ new Node(html('span',
57
+ { class: bracketname(context, indexA, 1, 1) },
58
+ defrag(unwrap(as.import(bs as List<Node<string>>).import(cs)))))
59
+ ]),
60
+ ([as, bs = new List()], context) => new List([
61
+ new Node(html('span',
62
+ { class: bracketname(context, indexA, 1, 0) },
63
+ defrag(unwrap(as.import(bs as List<Node<string>>)))))
64
+ ])));
55
65
 
56
66
  const p2 = lazy(() => surround(
57
67
  str('('),
58
68
  precedence(1, recursion(Recursion.bracket, some(inline, ')', [[')', 1]]))),
59
69
  str(')'),
60
70
  true, [],
61
- ([as, bs = [], cs], { source, position, range, linebreak }) => {
62
- const str = linebreak === 0 ? source.slice(position - range + 1, position - 1) : '';
63
- return linebreak === 0 && (str === '' || indexF.test(str))
64
- ? new List([new Node(html('span', { class: 'paren' }, `(${str})`))])
65
- : new List([new Node(html('span', { class: 'bracket' }, defrag(unwrap(as.import(bs as List<Node<string>>).import(cs)))))]);
66
- },
67
- ([as, bs = new List()], context) => {
68
- const { source, position, range, linebreak } = context;
69
- const str = linebreak === 0 ? source.slice(position - range + 1, position) : '';
70
- return linebreak === 0 && (str === '' || indexF.test(str))
71
- ? new List([new Node(html('span', { class: 'paren' }, `(${str}`))])
72
- : new List([new Node(html('span', { class: 'bracket' }, defrag(unwrap(as.import(bs as List<Node<string>>)))))]);
73
- }));
71
+ ([as, bs = new List(), cs], context) => new List([
72
+ new Node(html('span',
73
+ { class: bracketname(context, indexF, 1, 1) },
74
+ defrag(unwrap(as.import(bs as List<Node<string>>).import(cs)))))
75
+ ]),
76
+ ([as, bs = new List()], context) => new List([
77
+ new Node(html('span',
78
+ { class: bracketname(context, indexF, 1, 0) },
79
+ defrag(unwrap(as.import(bs as List<Node<string>>)))))
80
+ ])));
74
81
 
75
82
  const s1 = lazy(() => surround(
76
83
  str('['),
@@ -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
 
@@ -123,7 +123,7 @@ export const inline: InlineParser = lazy(() => union([
123
123
  },
124
124
  autolink,
125
125
  text
126
- ])) as any;
126
+ ]));
127
127
 
128
128
  export { indexee } from './inline/extension/indexee';
129
129
  export { indexer } from './inline/extension/indexer';