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.
- package/CHANGELOG.md +8 -0
- package/dist/index.js +75 -96
- package/markdown.d.ts +43 -43
- package/package.json +1 -1
- package/src/debug.test.ts +2 -2
- package/src/parser/api/parse.test.ts +3 -2
- package/src/parser/api/parse.ts +2 -0
- package/src/parser/block/blockquote.test.ts +5 -5
- package/src/parser/block/blockquote.ts +3 -2
- package/src/parser/block/extension/aside.test.ts +3 -3
- package/src/parser/block/extension/aside.ts +3 -3
- package/src/parser/block/extension/example.test.ts +5 -5
- package/src/parser/block/extension/example.ts +3 -3
- package/src/parser/block.ts +1 -1
- package/src/parser/context.ts +6 -3
- package/src/parser/inline/annotation.ts +26 -10
- package/src/parser/inline/bracket.test.ts +5 -2
- package/src/parser/inline/bracket.ts +38 -31
- package/src/parser/inline/extension/indexee.ts +17 -9
- package/src/parser/inline.ts +1 -1
- package/src/parser/processor/figure.test.ts +27 -27
- package/src/parser/processor/figure.ts +15 -7
- package/src/parser/processor/note.test.ts +19 -18
- package/src/parser/processor/note.ts +29 -17
- package/src/parser/segment.ts +1 -1
- package/src/parser/util.ts +5 -0
- package/src/util/toc.ts +1 -1
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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)),
|
package/src/parser/block.ts
CHANGED
package/src/parser/context.ts
CHANGED
|
@@ -8,8 +8,9 @@ export class Context extends Ctx {
|
|
|
8
8
|
super(options);
|
|
9
9
|
const {
|
|
10
10
|
segment,
|
|
11
|
-
|
|
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.
|
|
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
|
|
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([
|
|
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([
|
|
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,
|
|
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([
|
|
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([
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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 =
|
|
12
|
-
const indexF = new RegExp(
|
|
13
|
-
.replace(
|
|
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
|
-
]))
|
|
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 =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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 =
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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, {
|
|
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=
|
|
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=
|
|
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
|
|
package/src/parser/inline.ts
CHANGED