securemark 0.261.1 → 0.262.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 +12 -0
- package/dist/index.js +1228 -665
- package/package.json +9 -9
- package/src/combinator/control/constraint/contract.ts +6 -8
- package/src/combinator/data/parser/context/memo.ts +1 -1
- package/src/combinator/data/parser/inits.ts +1 -1
- package/src/combinator/data/parser/sequence.ts +1 -1
- package/src/combinator/data/parser/union.ts +12 -7
- package/src/debug.test.ts +3 -3
- package/src/parser/api/bind.ts +2 -2
- package/src/parser/api/parse.test.ts +1 -1
- package/src/parser/api/parse.ts +1 -1
- package/src/parser/block/blockquote.test.ts +31 -31
- package/src/parser/block/blockquote.ts +1 -1
- package/src/parser/block/dlist.ts +1 -1
- package/src/parser/block/extension/aside.test.ts +3 -3
- package/src/parser/block/extension/aside.ts +1 -0
- package/src/parser/block/extension/example.test.ts +11 -11
- package/src/parser/block/extension/example.ts +1 -1
- package/src/parser/block/extension/fig.test.ts +5 -5
- package/src/parser/block/extension/figure.test.ts +2 -2
- package/src/parser/block/extension/figure.ts +1 -1
- package/src/parser/block/extension/message.ts +1 -1
- package/src/parser/block/extension/table.ts +1 -1
- package/src/parser/block/olist.ts +5 -7
- package/src/parser/block/reply.ts +1 -1
- package/src/parser/block/table.ts +8 -8
- package/src/parser/block/ulist.ts +1 -1
- package/src/parser/block.ts +1 -1
- package/src/parser/inline/bracket.ts +1 -1
- package/src/parser/inline/comment.ts +1 -1
- package/src/parser/inline/deletion.ts +1 -1
- package/src/parser/inline/emphasis.ts +1 -1
- package/src/parser/inline/extension/indexee.ts +9 -8
- package/src/parser/inline/extension/placeholder.ts +1 -1
- package/src/parser/inline/html.ts +1 -1
- package/src/parser/inline/insertion.ts +1 -1
- package/src/parser/inline/link.ts +1 -1
- package/src/parser/inline/mark.ts +1 -1
- package/src/parser/inline/media.ts +1 -1
- package/src/parser/inline/ruby.ts +1 -1
- package/src/parser/inline/strong.ts +1 -1
- package/src/parser/inline/template.ts +1 -1
- package/src/parser/locale.test.ts +1 -1
- package/src/parser/locale.ts +5 -4
- package/src/parser/processor/figure.test.ts +3 -3
- package/src/parser/processor/figure.ts +10 -8
- package/src/parser/processor/footnote.test.ts +2 -2
- package/src/parser/processor/footnote.ts +17 -12
- package/src/renderer/render.ts +3 -3
- package/src/util/info.ts +7 -5
- package/src/util/quote.ts +14 -12
- package/src/util/toc.ts +14 -8
|
@@ -5,8 +5,8 @@ import { ilist_ } from './ilist';
|
|
|
5
5
|
import { inline, indexer, indexee } from '../inline';
|
|
6
6
|
import { State } from '../context';
|
|
7
7
|
import { trimBlank } from '../visibility';
|
|
8
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
9
8
|
import { unshift } from 'spica/array';
|
|
9
|
+
import { html, defrag } from 'typed-dom/dom';
|
|
10
10
|
|
|
11
11
|
export const ulist: UListParser = lazy(() => block(validate(
|
|
12
12
|
/^-(?=[^\S\n]|\n[^\S\n]*\S)/,
|
package/src/parser/block.ts
CHANGED
|
@@ -16,8 +16,8 @@ import { sidefence } from './block/sidefence';
|
|
|
16
16
|
import { blockquote } from './block/blockquote';
|
|
17
17
|
import { reply } from './block/reply';
|
|
18
18
|
import { paragraph } from './block/paragraph';
|
|
19
|
-
import { html } from 'typed-dom/dom';
|
|
20
19
|
import { rnd0Z } from 'spica/random';
|
|
20
|
+
import { html } from 'typed-dom/dom';
|
|
21
21
|
|
|
22
22
|
export import BlockParser = MarkdownParser.BlockParser;
|
|
23
23
|
export import HorizontalRuleParser = BlockParser.HorizontalRuleParser;
|
|
@@ -4,8 +4,8 @@ import { union, some, syntax, surround, lazy } from '../../combinator';
|
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
6
6
|
import { Syntax, State } from '../context';
|
|
7
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
8
7
|
import { unshift, push } from 'spica/array';
|
|
8
|
+
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
const index = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*/;
|
|
11
11
|
|
|
@@ -3,9 +3,9 @@ import { union, some, syntax, validate, surround, open, close, match, lazy } fro
|
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { text, str } from '../source';
|
|
5
5
|
import { Syntax, State } from '../context';
|
|
6
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
7
6
|
import { memoize } from 'spica/memoize';
|
|
8
7
|
import { unshift, push } from 'spica/array';
|
|
8
|
+
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const comment: CommentParser = lazy(() => validate('[%', syntax(Syntax.none, 4, 1, State.none, match(
|
|
11
11
|
/^\[(%+)\s/,
|
|
@@ -4,8 +4,8 @@ import { inline } from '../inline';
|
|
|
4
4
|
import { str } from '../source';
|
|
5
5
|
import { Syntax, State } from '../context';
|
|
6
6
|
import { blankWith } from '../visibility';
|
|
7
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
8
7
|
import { unshift } from 'spica/array';
|
|
8
|
+
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const deletion: DeletionParser = lazy(() => surround(
|
|
11
11
|
str('~~', '~'),
|
|
@@ -4,8 +4,8 @@ import { inline } from '../inline';
|
|
|
4
4
|
import { str } from '../source';
|
|
5
5
|
import { Syntax, State } from '../context';
|
|
6
6
|
import { startTight, blankWith } from '../visibility';
|
|
7
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
8
7
|
import { unshift } from 'spica/array';
|
|
8
|
+
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const emphasis: EmphasisParser = lazy(() => surround(
|
|
11
11
|
str('_', '_'),
|
|
@@ -3,7 +3,7 @@ import { MarkdownParser } from '../../../../markdown';
|
|
|
3
3
|
import { Parser } from '../../../combinator/data/parser';
|
|
4
4
|
import { fmap } from '../../../combinator';
|
|
5
5
|
import { define } from 'typed-dom/dom';
|
|
6
|
-
import {
|
|
6
|
+
import { querySelectorAll } from 'typed-dom/query';
|
|
7
7
|
|
|
8
8
|
export function indexee<P extends Parser<unknown, MarkdownParser.Context>>(parser: P, optional?: boolean): P;
|
|
9
9
|
export function indexee(parser: Parser<HTMLElement, MarkdownParser.Context>, optional?: boolean): Parser<HTMLElement> {
|
|
@@ -28,32 +28,33 @@ export function text(source: HTMLElement | DocumentFragment, optional = false):
|
|
|
28
28
|
if (index) return index;
|
|
29
29
|
assert(!source.querySelector('.annotation, br'));
|
|
30
30
|
const target = source.cloneNode(true) as typeof source;
|
|
31
|
-
|
|
31
|
+
for (let es = querySelectorAll(target, 'code[data-src], .math[data-src], .comment, rt, rp, .reference, .checkbox, ul, ol'), i = 0; i < es.length; ++i) {
|
|
32
|
+
const el = es[i];
|
|
32
33
|
switch (el.tagName) {
|
|
33
34
|
case 'CODE':
|
|
34
35
|
define(el, el.getAttribute('data-src')!);
|
|
35
|
-
|
|
36
|
+
continue;
|
|
36
37
|
case 'RT':
|
|
37
38
|
case 'RP':
|
|
38
39
|
case 'UL':
|
|
39
40
|
case 'OL':
|
|
40
41
|
el.remove();
|
|
41
|
-
|
|
42
|
+
continue;
|
|
42
43
|
}
|
|
43
44
|
switch (el.className) {
|
|
44
45
|
case 'math':
|
|
45
46
|
define(el, el.getAttribute('data-src')!);
|
|
46
|
-
|
|
47
|
+
continue;
|
|
47
48
|
case 'comment':
|
|
48
49
|
case 'checkbox':
|
|
49
50
|
el.remove();
|
|
50
|
-
|
|
51
|
+
continue;
|
|
51
52
|
case 'reference':
|
|
52
53
|
assert(el.firstElementChild?.hasAttribute('hidden'));
|
|
53
54
|
el.firstChild!.remove();
|
|
54
|
-
|
|
55
|
+
continue;
|
|
55
56
|
}
|
|
56
|
-
}
|
|
57
|
+
}
|
|
57
58
|
// Better:
|
|
58
59
|
//return target.innerText;
|
|
59
60
|
return target.textContent!;
|
|
@@ -4,8 +4,8 @@ import { inline } from '../../inline';
|
|
|
4
4
|
import { str } from '../../source';
|
|
5
5
|
import { Syntax, State } from '../../context';
|
|
6
6
|
import { startTight } from '../../visibility';
|
|
7
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
8
7
|
import { unshift } from 'spica/array';
|
|
8
|
+
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
// Don't use the symbols already used: !#$%@&*+~=
|
|
11
11
|
|
|
@@ -5,10 +5,10 @@ import { inline } from '../inline';
|
|
|
5
5
|
import { str } from '../source';
|
|
6
6
|
import { Syntax, State } from '../context';
|
|
7
7
|
import { isStartLooseNodes, blankWith } from '../visibility';
|
|
8
|
-
import { html as h, defrag } from 'typed-dom/dom';
|
|
9
8
|
import { memoize } from 'spica/memoize';
|
|
10
9
|
import { Cache } from 'spica/cache';
|
|
11
10
|
import { unshift, push, splice } from 'spica/array';
|
|
11
|
+
import { html as h, defrag } from 'typed-dom/dom';
|
|
12
12
|
|
|
13
13
|
const tags = Object.freeze(['bdo', 'bdi']);
|
|
14
14
|
const attrspecs = {
|
|
@@ -4,8 +4,8 @@ import { inline } from '../inline';
|
|
|
4
4
|
import { str } from '../source';
|
|
5
5
|
import { Syntax, State } from '../context';
|
|
6
6
|
import { blankWith } from '../visibility';
|
|
7
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
8
7
|
import { unshift } from 'spica/array';
|
|
8
|
+
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const insertion: InsertionParser = lazy(() => surround(
|
|
11
11
|
str('++', '+'),
|
|
@@ -10,8 +10,8 @@ import { unescsource, str } from '../source';
|
|
|
10
10
|
import { Syntax, State } from '../context';
|
|
11
11
|
import { trimNode } from '../visibility';
|
|
12
12
|
import { stringify } from '../util';
|
|
13
|
-
import { html, define, defrag } from 'typed-dom/dom';
|
|
14
13
|
import { ReadonlyURL } from 'spica/url';
|
|
14
|
+
import { html, define, defrag } from 'typed-dom/dom';
|
|
15
15
|
|
|
16
16
|
const optspec = {
|
|
17
17
|
rel: ['nofollow'],
|
|
@@ -4,8 +4,8 @@ import { inline } from '../inline';
|
|
|
4
4
|
import { str } from '../source';
|
|
5
5
|
import { startTight, blankWith } from '../visibility';
|
|
6
6
|
import { Syntax, State } from '../context';
|
|
7
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
8
7
|
import { unshift } from 'spica/array';
|
|
8
|
+
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const mark: MarkParser = lazy(() => surround(
|
|
11
11
|
str('==', '='),
|
|
@@ -6,9 +6,9 @@ import { attributes } from './html';
|
|
|
6
6
|
import { unsafehtmlentity } from './htmlentity';
|
|
7
7
|
import { txt, str } from '../source';
|
|
8
8
|
import { Syntax, State } from '../context';
|
|
9
|
-
import { html, define } from 'typed-dom/dom';
|
|
10
9
|
import { ReadonlyURL } from 'spica/url';
|
|
11
10
|
import { unshift, push } from 'spica/array';
|
|
11
|
+
import { html, define } from 'typed-dom/dom';
|
|
12
12
|
|
|
13
13
|
const optspec = {
|
|
14
14
|
'width': [],
|
|
@@ -6,8 +6,8 @@ import { unsafehtmlentity } from './htmlentity';
|
|
|
6
6
|
import { text as txt, str } from '../source';
|
|
7
7
|
import { Syntax, State } from '../context';
|
|
8
8
|
import { isStartTightNodes } from '../visibility';
|
|
9
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
10
9
|
import { unshift, push } from 'spica/array';
|
|
10
|
+
import { html, defrag } from 'typed-dom/dom';
|
|
11
11
|
|
|
12
12
|
export const ruby: RubyParser = lazy(() => validate('[', syntax(Syntax.ruby, 2, 1, State.all, fmap(verify(fmap(
|
|
13
13
|
sequence([
|
|
@@ -4,8 +4,8 @@ import { inline } from '../inline';
|
|
|
4
4
|
import { str } from '../source';
|
|
5
5
|
import { Syntax, State } from '../context';
|
|
6
6
|
import { startTight, blankWith } from '../visibility';
|
|
7
|
-
import { html, defrag } from 'typed-dom/dom';
|
|
8
7
|
import { unshift } from 'spica/array';
|
|
8
|
+
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const strong: StrongParser = lazy(() => surround(
|
|
11
11
|
str('*', '*'),
|
|
@@ -3,8 +3,8 @@ import { TemplateParser } from '../inline';
|
|
|
3
3
|
import { union, some, syntax, creation, precedence, surround, lazy } from '../../combinator';
|
|
4
4
|
import { escsource, str } from '../source';
|
|
5
5
|
import { Syntax, State } from '../context';
|
|
6
|
-
import { html } from 'typed-dom/dom';
|
|
7
6
|
import { unshift } from 'spica/array';
|
|
7
|
+
import { html } from 'typed-dom/dom';
|
|
8
8
|
|
|
9
9
|
export const template: TemplateParser = lazy(() => surround(
|
|
10
10
|
'{{', syntax(Syntax.none, 2, 1, State.all, some(union([bracket, escsource]), '}')), '}}', true,
|
|
@@ -10,7 +10,7 @@ describe('Unit: parser/locale', () => {
|
|
|
10
10
|
assert.deepStrictEqual(inspect(parser('。\\\n0')), [['<p>。<span class="linebreak"></span>0</p>'], '']);
|
|
11
11
|
assert.deepStrictEqual(inspect(parser('。 \\\n0')), [['<p>。<span class="linebreak"></span>0</p>'], '']);
|
|
12
12
|
assert.deepStrictEqual(inspect(parser('_。_\\\n0')), [['<p><em>。</em><span class="linebreak"></span>0</p>'], '']);
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('!> 。\\\n0')), [['<blockquote><section><p>。<span class="linebreak"></span>0</p><ol class="references"></ol></section></blockquote>'], '']);
|
|
13
|
+
assert.deepStrictEqual(inspect(parser('!> 。\\\n0')), [['<blockquote><section><p>。<span class="linebreak"></span>0</p><h2>References</h2><ol class="references"></ol></section></blockquote>'], '']);
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('[。](a)\\\n0')), [['<p><ruby>。<rp>(</rp><rt>a</rt><rp>)</rp></ruby><span class="linebreak"></span>0</p>'], '']);
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('[。 ](a )\\\n0')), [['<p><ruby>。<rp>(</rp><rt>a</rt><rp>)</rp></ruby><span class="linebreak"></span>0</p>'], '']);
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('。<wbr>\\\n0')), [['<p>。<wbr><span class="linebreak"></span>0</p>'], '']);
|
package/src/parser/locale.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Parser } from '../combinator/data/parser';
|
|
|
2
2
|
import { fmap } from '../combinator';
|
|
3
3
|
import { japanese } from './locale/ja';
|
|
4
4
|
import { html } from 'typed-dom/dom';
|
|
5
|
-
import {
|
|
5
|
+
import { querySelectorAll } from 'typed-dom/query';
|
|
6
6
|
|
|
7
7
|
export function localize<P extends Parser<HTMLElement | string>>(parser: P): P;
|
|
8
8
|
export function localize(parser: Parser<HTMLElement | string>): Parser<HTMLElement | string> {
|
|
@@ -11,11 +11,12 @@ export function localize(parser: Parser<HTMLElement | string>): Parser<HTMLEleme
|
|
|
11
11
|
const el = ns.length === 1 && typeof ns[0] === 'object'
|
|
12
12
|
? ns[0]
|
|
13
13
|
: html('div', ns);
|
|
14
|
-
|
|
14
|
+
for (let es = querySelectorAll(el, '.linebreak:not(:empty)'), i = 0; i < es.length; ++i) {
|
|
15
|
+
const el = es[i];
|
|
15
16
|
assert(el.firstChild!.textContent === ' ');
|
|
16
|
-
if (!check(el))
|
|
17
|
+
if (!check(el)) continue;
|
|
17
18
|
el.firstChild!.remove();
|
|
18
|
-
}
|
|
19
|
+
}
|
|
19
20
|
return ns;
|
|
20
21
|
});
|
|
21
22
|
}
|
|
@@ -117,8 +117,8 @@ describe('Unit: parser/processor/figure', () => {
|
|
|
117
117
|
assert.deepStrictEqual(
|
|
118
118
|
[...target.children].map(el => el.outerHTML),
|
|
119
119
|
[
|
|
120
|
-
'<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><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><ol class="references"></ol></section></blockquote>',
|
|
121
|
-
'<aside class="example" data-type="markdown"><pre translate="no">~~~figure $test-a\n> \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><ol class="references"></ol></section></aside>',
|
|
120
|
+
'<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>',
|
|
121
|
+
'<aside class="example" data-type="markdown"><pre translate="no">~~~figure $test-a\n> \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>',
|
|
122
122
|
'<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>',
|
|
123
123
|
'<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>',
|
|
124
124
|
]);
|
|
@@ -173,7 +173,7 @@ describe('Unit: parser/processor/figure', () => {
|
|
|
173
173
|
'<h2 id="index:0">0</h2>',
|
|
174
174
|
'<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>',
|
|
175
175
|
'<h2 id="index:0">0</h2>',
|
|
176
|
-
'<blockquote><section><h2>0</h2><ol class="references"></ol></section></blockquote>',
|
|
176
|
+
'<blockquote><section><h2>0</h2><h2>References</h2><ol class="references"></ol></section></blockquote>',
|
|
177
177
|
'<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>',
|
|
178
178
|
'<h2 id="index:0">0</h2>',
|
|
179
179
|
'<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>',
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { Infinity, Set, Map } from 'spica/global';
|
|
2
2
|
import { number as calculate, isFixed } from '../inline/extension/label';
|
|
3
|
-
import { define } from 'typed-dom/dom';
|
|
4
3
|
import { MultiMap } from 'spica/multimap';
|
|
5
4
|
import { push } from 'spica/array';
|
|
5
|
+
import { define } from 'typed-dom/dom';
|
|
6
|
+
import { querySelectorAll } from 'typed-dom/query';
|
|
6
7
|
|
|
7
8
|
export function* figure(
|
|
8
9
|
target: ParentNode & Node,
|
|
9
10
|
footnotes?: { readonly references: HTMLOListElement; },
|
|
10
11
|
opts: { readonly id?: string; } = {},
|
|
11
12
|
): Generator<HTMLAnchorElement | undefined, undefined, undefined> {
|
|
12
|
-
const refs = new MultiMap<string, HTMLAnchorElement>(push(
|
|
13
|
-
|
|
14
|
-
footnotes
|
|
13
|
+
const refs = new MultiMap<string, HTMLAnchorElement>(push(
|
|
14
|
+
querySelectorAll(target, 'a.label:not(.disabled)[data-label]'),
|
|
15
|
+
footnotes && querySelectorAll(footnotes.references, 'a.label:not(.disabled)') || [])
|
|
15
16
|
.map(el => [el.getAttribute('data-label')!, el]));
|
|
16
17
|
const labels = new Set<string>();
|
|
17
18
|
const numbers = new Map<string, string>();
|
|
@@ -19,10 +20,10 @@ export function* figure(
|
|
|
19
20
|
let bases: readonly string[] = base.split('.');
|
|
20
21
|
let index: readonly string[] = bases;
|
|
21
22
|
// Bug: Firefox
|
|
22
|
-
//for (let defs =
|
|
23
|
+
//for (let defs = querySelectorAll(target, ':scope > figure[data-label], :scope > h1, :scope > h2'), len = defs.length, i = 0; i < len; ++i) {
|
|
23
24
|
for (
|
|
24
|
-
let defs =
|
|
25
|
-
|
|
25
|
+
let defs = querySelectorAll(target, 'figure[data-label], h1, h2'),
|
|
26
|
+
len = defs.length, i = 0; i < len; ++i) {
|
|
26
27
|
yield;
|
|
27
28
|
const def = defs[i];
|
|
28
29
|
if (def.parentNode !== target) continue;
|
|
@@ -141,7 +142,8 @@ export function* figure(
|
|
|
141
142
|
}
|
|
142
143
|
labels.add(label);
|
|
143
144
|
opts.id !== '' && def.setAttribute('id', `label:${opts.id ? `${opts.id}:` : ''}${label}`);
|
|
144
|
-
for (
|
|
145
|
+
for (let rs = refs.take(label, Infinity), i = 0; i < rs.length; ++i) {
|
|
146
|
+
const ref = rs[i];
|
|
145
147
|
if (ref.getAttribute('data-invalid-message') === messages.reference) {
|
|
146
148
|
define(ref, {
|
|
147
149
|
class: void ref.classList.remove('invalid'),
|
|
@@ -151,8 +151,8 @@ describe('Unit: parser/processor/footnote', () => {
|
|
|
151
151
|
assert.deepStrictEqual(
|
|
152
152
|
[...target.children].map(el => el.outerHTML),
|
|
153
153
|
[
|
|
154
|
-
'<blockquote><blockquote><section><p><sup class="annotation disabled" title="a"><span hidden="">a</span><a>*1</a></sup></p><ol class="annotations"><li data-marker="*1">a<sup><a>^1</a></sup></li></ol><ol class="references"></ol></section></blockquote><section><p><sup class="annotation disabled" title="a"><span hidden="">a</span><a>*1</a></sup><br>~~~</p><ol class="annotations"><li data-marker="*1">a<sup><a>^1</a></sup></li></ol><ol class="references"></ol></section></blockquote>',
|
|
155
|
-
'<aside class="example" data-type="markdown"><pre translate="no">((a))</pre><hr><section><p><sup class="annotation disabled" title="a"><span hidden="">a</span><a>*1</a></sup></p><ol class="annotations"><li data-marker="*1">a<sup><a>^1</a></sup></li></ol><ol class="references"></ol></section></aside>',
|
|
154
|
+
'<blockquote><blockquote><section><p><sup class="annotation disabled" title="a"><span hidden="">a</span><a>*1</a></sup></p><ol class="annotations"><li data-marker="*1">a<sup><a>^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></blockquote><section><p><sup class="annotation disabled" title="a"><span hidden="">a</span><a>*1</a></sup><br>~~~</p><ol class="annotations"><li data-marker="*1">a<sup><a>^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></blockquote>',
|
|
155
|
+
'<aside class="example" data-type="markdown"><pre translate="no">((a))</pre><hr><section><p><sup class="annotation disabled" title="a"><span hidden="">a</span><a>*1</a></sup></p><ol class="annotations"><li data-marker="*1">a<sup><a>^1</a></sup></li></ol><h2>References</h2><ol class="references"></ol></section></aside>',
|
|
156
156
|
'<p><sup class="annotation" id="annotation:ref:1" title="a"><span hidden="">a</span><a href="#annotation:def:1">*1</a></sup></p>',
|
|
157
157
|
]);
|
|
158
158
|
assert.deepStrictEqual(
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { undefined, Infinity, Map, Node } from 'spica/global';
|
|
2
2
|
import { text } from '../inline/extension/indexee';
|
|
3
|
-
import { frag, html, define } from 'typed-dom/dom';
|
|
4
3
|
import { MultiMap } from 'spica/multimap';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { frag, html, define } from 'typed-dom/dom';
|
|
5
|
+
import { querySelectorAll } from 'typed-dom/query';
|
|
7
6
|
|
|
8
7
|
export function* footnote(
|
|
9
8
|
target: ParentNode & Node,
|
|
@@ -12,8 +11,11 @@ export function* footnote(
|
|
|
12
11
|
bottom: Node | null = null,
|
|
13
12
|
): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
|
|
14
13
|
// Bug: Firefox
|
|
15
|
-
//
|
|
16
|
-
|
|
14
|
+
//querySelectorAll(target, `:scope > .annotations`).forEach(el => el.remove());
|
|
15
|
+
for (let es = querySelectorAll(target, `.annotations`), i = 0; i < es.length; ++i) {
|
|
16
|
+
const el = es[i];
|
|
17
|
+
el.parentNode === target && el.remove();
|
|
18
|
+
}
|
|
17
19
|
yield* reference(target, footnotes?.references, opts, bottom);
|
|
18
20
|
yield* annotation(target, footnotes?.annotations, opts, bottom);
|
|
19
21
|
return;
|
|
@@ -40,16 +42,18 @@ function build(
|
|
|
40
42
|
const buffer = new MultiMap<string, HTMLElement>();
|
|
41
43
|
const titles = new Map<string, string>();
|
|
42
44
|
// Bug: Firefox
|
|
43
|
-
//const splitters = push([],
|
|
44
|
-
const splitters =
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
//const splitters = push([], querySelectorAll(target, `:scope > :is(${splitter ?? '_'})`));
|
|
46
|
+
const splitters: Element[] = [];
|
|
47
|
+
for (let es = querySelectorAll(target, splitter ?? '_'), i = 0; i < es.length; ++i) {
|
|
48
|
+
const el = es[i];
|
|
49
|
+
el.parentNode === target && splitters.push(el);
|
|
50
|
+
}
|
|
47
51
|
let count = 0;
|
|
48
52
|
let total = 0;
|
|
49
53
|
let style: 'count' | 'abbr';
|
|
50
54
|
for (
|
|
51
|
-
let refs =
|
|
52
|
-
|
|
55
|
+
let refs = querySelectorAll(target, `sup.${syntax}:not(.disabled)`),
|
|
56
|
+
len = refs.length, i = 0; i < len; ++i) {
|
|
53
57
|
yield;
|
|
54
58
|
const ref = refs[i];
|
|
55
59
|
while (+splitters[0]?.compareDocumentPosition(ref) & Node.DOCUMENT_POSITION_FOLLOWING) {
|
|
@@ -114,7 +118,8 @@ function build(
|
|
|
114
118
|
if (title && !blank && def.childNodes.length === 1) {
|
|
115
119
|
def.insertBefore(content.cloneNode(true), def.lastChild);
|
|
116
120
|
assert(def.childNodes.length > 1);
|
|
117
|
-
for (
|
|
121
|
+
for (let refs = buffer.take(identifier, Infinity), i = 0; i < refs.length; ++i) {
|
|
122
|
+
const ref = refs[i];
|
|
118
123
|
if (ref.getAttribute('data-invalid-type') !== 'content') continue;
|
|
119
124
|
define(ref, {
|
|
120
125
|
title,
|
package/src/renderer/render.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { RenderingOptions } from '../../';
|
|
|
3
3
|
import { code } from './render/code';
|
|
4
4
|
import { math } from './render/math';
|
|
5
5
|
import { media } from './render/media';
|
|
6
|
-
import { querySelectorAll } from 'typed-dom/query';
|
|
7
6
|
import { reduce } from 'spica/memoize';
|
|
7
|
+
import { querySelectorAllWith } from 'typed-dom/query';
|
|
8
8
|
|
|
9
9
|
const selector = 'img.media:not(.invalid):not([src])[data-src], a > :not(img).media:not(.invalid), pre.code:not(.invalid), .math:not(.invalid)';
|
|
10
10
|
|
|
@@ -14,8 +14,8 @@ const extend = reduce((opts: RenderingOptions): RenderingOptions =>
|
|
|
14
14
|
export function render(source: HTMLElement, opts: RenderingOptions = {}): void {
|
|
15
15
|
opts = extend(opts);
|
|
16
16
|
const base = location.href;
|
|
17
|
-
for (
|
|
18
|
-
render_(base,
|
|
17
|
+
for (let es = querySelectorAllWith<HTMLElement>(source, selector), i = 0; i < es.length; ++i) {
|
|
18
|
+
render_(base, es[i], opts);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
package/src/util/info.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Info } from '../..';
|
|
2
2
|
import { scope } from './scope';
|
|
3
|
-
import {
|
|
4
|
-
import { push } from 'spica/array';
|
|
3
|
+
import { querySelectorAll } from 'typed-dom/query';
|
|
5
4
|
|
|
6
5
|
export function info(source: DocumentFragment | HTMLElement | ShadowRoot): Info {
|
|
7
6
|
const match = scope(source, '.invalid');
|
|
@@ -19,8 +18,11 @@ export function info(source: DocumentFragment | HTMLElement | ShadowRoot): Info
|
|
|
19
18
|
};
|
|
20
19
|
|
|
21
20
|
function find<T extends HTMLElement>(selector: string): T[] {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const acc: T[] = [];
|
|
22
|
+
for (let es = querySelectorAll<T>(source, selector), i = 0; i < es.length; ++i) {
|
|
23
|
+
const el = es[i];
|
|
24
|
+
match(el) && acc.push(el);
|
|
25
|
+
}
|
|
26
|
+
return acc;
|
|
25
27
|
}
|
|
26
28
|
}
|
package/src/util/quote.ts
CHANGED
|
@@ -2,30 +2,31 @@ import { Element } from 'spica/global';
|
|
|
2
2
|
import { exec } from '../combinator/data/parser';
|
|
3
3
|
import { cite } from '../parser/block/reply/cite';
|
|
4
4
|
import { define } from 'typed-dom/dom';
|
|
5
|
-
import {
|
|
5
|
+
import { querySelectorAll } from 'typed-dom/query';
|
|
6
6
|
|
|
7
7
|
export function quote(anchor: string, range: Range): string {
|
|
8
8
|
if (exec(cite({ source: `>>${anchor}`, context: {} })) !== '') throw new Error(`Invalid anchor: ${anchor}`);
|
|
9
9
|
fit(range);
|
|
10
10
|
const node = trim(range.cloneContents());
|
|
11
11
|
if (!node.firstChild) return '';
|
|
12
|
-
|
|
12
|
+
for (let es = querySelectorAll(node, 'code[data-src], .math[data-src], .media[data-src], rt, rp'), i = 0; i < es.length; ++i) {
|
|
13
|
+
const el = es[i];
|
|
13
14
|
switch (true) {
|
|
14
15
|
case el.matches('code'):
|
|
15
16
|
case el.matches('.math'):
|
|
16
17
|
define(el, el.getAttribute('data-src')!);
|
|
17
|
-
|
|
18
|
+
continue;
|
|
18
19
|
case el.matches('.media'):
|
|
19
20
|
el.replaceWith(
|
|
20
21
|
/[\s{}]/.test(el.getAttribute('data-src')!)
|
|
21
22
|
? `!{ ${el.getAttribute('data-src')} }`
|
|
22
23
|
: `!{${el.getAttribute('data-src')}}`);
|
|
23
|
-
|
|
24
|
+
continue;
|
|
24
25
|
case el.matches('rt, rp'):
|
|
25
26
|
el.remove();
|
|
26
|
-
|
|
27
|
+
continue;
|
|
27
28
|
}
|
|
28
|
-
}
|
|
29
|
+
}
|
|
29
30
|
if (range.startOffset === 0 &&
|
|
30
31
|
range.startContainer.parentElement?.matches('.cite, .quote') &&
|
|
31
32
|
(!range.startContainer.previousSibling || range.startContainer.previousSibling.nodeName === 'BR')) {
|
|
@@ -35,25 +36,26 @@ export function quote(anchor: string, range: Range): string {
|
|
|
35
36
|
node.prepend(`>>${anchor}\n> `);
|
|
36
37
|
anchor = '';
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
+
for (let es = querySelectorAll(node, 'br'), i = 0; i < es.length; ++i) {
|
|
40
|
+
const el = es[i];
|
|
39
41
|
if (anchor && el.nextSibling instanceof Element && el.nextSibling.matches('.cite, .quote')) {
|
|
40
42
|
el.replaceWith(`\n>${el.nextSibling.matches('.quote.invalid') ? ' ' : ''}`);
|
|
41
|
-
|
|
43
|
+
continue;
|
|
42
44
|
}
|
|
43
45
|
if (anchor && el.parentElement?.closest('.cite, .quote')) {
|
|
44
46
|
el.replaceWith(`\n>${el.parentElement.closest('.quote.invalid') ? ' ' : ''}`);
|
|
45
|
-
|
|
47
|
+
continue;
|
|
46
48
|
}
|
|
47
49
|
if (anchor) {
|
|
48
50
|
el.replaceWith(`\n>>${anchor}\n> `);
|
|
49
51
|
anchor = '';
|
|
50
|
-
|
|
52
|
+
continue;
|
|
51
53
|
}
|
|
52
54
|
else {
|
|
53
55
|
el.replaceWith(`\n> `);
|
|
54
|
-
|
|
56
|
+
continue;
|
|
55
57
|
}
|
|
56
|
-
}
|
|
58
|
+
}
|
|
57
59
|
anchor && node.append(`\n>>${anchor}`);
|
|
58
60
|
return node.textContent!;
|
|
59
61
|
}
|
package/src/util/toc.ts
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
|
-
import { html } from 'typed-dom/dom';
|
|
3
|
-
import { duffEach, duffReduce } from 'spica/duff';
|
|
4
2
|
import { push } from 'spica/array';
|
|
3
|
+
import { html } from 'typed-dom/dom';
|
|
4
|
+
import { querySelectorAll } from 'typed-dom/query';
|
|
5
5
|
|
|
6
6
|
// Bug: Firefox
|
|
7
7
|
//const selector = 'h1 h2 h3 h4 h5 h6 aside.aside'.split(' ').map(s => `:scope > ${s}[id]`).join();
|
|
8
8
|
const selector = ':is(h1, h2, h3, h4, h5, h6, aside.aside)[id]';
|
|
9
9
|
|
|
10
10
|
export function toc(source: DocumentFragment | HTMLElement | ShadowRoot): HTMLUListElement {
|
|
11
|
-
const hs =
|
|
11
|
+
const hs: HTMLHeadingElement[] = [];
|
|
12
|
+
for (let es = querySelectorAll(source, selector), i = 0; i < es.length; ++i) {
|
|
13
|
+
const el = es[i];
|
|
12
14
|
assert(el.parentNode === source);
|
|
13
15
|
switch (el.tagName) {
|
|
14
16
|
case 'ASIDE':
|
|
15
|
-
|
|
17
|
+
hs.push(html(el.firstElementChild!.tagName.toLowerCase() as 'h1', { id: el.id, class: 'aside' }, el.firstElementChild!.cloneNode(true).childNodes));
|
|
18
|
+
continue;
|
|
16
19
|
default:
|
|
17
|
-
|
|
20
|
+
hs.push(el as HTMLHeadingElement);
|
|
21
|
+
continue;
|
|
18
22
|
}
|
|
19
|
-
}
|
|
23
|
+
}
|
|
20
24
|
return parse(cons(hs));
|
|
21
25
|
}
|
|
22
26
|
|
|
@@ -58,7 +62,9 @@ function level(h: HTMLHeadingElement): number {
|
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
function unlink(h: HTMLHeadingElement): Iterable<Node> {
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
for (let es = h.getElementsByTagName('a'), len = es.length, i = 0; i < len; ++i) {
|
|
66
|
+
const el = es[i];
|
|
67
|
+
el.replaceWith(...el.childNodes);
|
|
68
|
+
}
|
|
63
69
|
return h.childNodes;
|
|
64
70
|
}
|