securemark 0.217.0 → 0.218.3
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 +17 -0
- package/dist/securemark.js +166 -143
- package/markdown.d.ts +7 -6
- package/package-lock.json +7 -7
- package/package.json +1 -1
- package/src/parser/api/bind.test.ts +5 -5
- package/src/parser/api/bind.ts +2 -2
- package/src/parser/api/parse.test.ts +18 -0
- package/src/parser/api/parse.ts +2 -2
- package/src/parser/block/blockquote.test.ts +1 -1
- package/src/parser/block/extension/example.test.ts +1 -1
- package/src/parser/block/extension/fig.ts +1 -1
- package/src/parser/block/extension/table.ts +2 -2
- package/src/parser/block/heading.test.ts +10 -12
- package/src/parser/block/ilist.ts +8 -1
- package/src/parser/block/paragraph.test.ts +7 -0
- package/src/parser/function/footnote.test.ts +16 -16
- package/src/parser/function/footnote.ts +1 -1
- package/src/parser/inline/annotation.test.ts +5 -2
- package/src/parser/inline/annotation.ts +4 -5
- package/src/parser/inline/comment.ts +1 -1
- package/src/parser/inline/deletion.test.ts +1 -0
- package/src/parser/inline/deletion.ts +2 -1
- package/src/parser/inline/emphasis.ts +5 -5
- package/src/parser/inline/emstrong.ts +4 -4
- package/src/parser/inline/extension/index.test.ts +25 -7
- package/src/parser/inline/extension/index.ts +17 -14
- package/src/parser/inline/extension/indexee.ts +1 -1
- package/src/parser/inline/extension/indexer.test.ts +2 -0
- package/src/parser/inline/extension/indexer.ts +5 -3
- package/src/parser/inline/extension/placeholder.test.ts +10 -10
- package/src/parser/inline/extension/placeholder.ts +13 -9
- package/src/parser/inline/html.test.ts +2 -1
- package/src/parser/inline/html.ts +16 -22
- package/src/parser/inline/insertion.test.ts +1 -0
- package/src/parser/inline/insertion.ts +2 -1
- package/src/parser/inline/link.test.ts +3 -7
- package/src/parser/inline/link.ts +9 -9
- package/src/parser/inline/mark.test.ts +1 -0
- package/src/parser/inline/mark.ts +2 -2
- package/src/parser/inline/math.ts +2 -2
- package/src/parser/inline/media.test.ts +3 -7
- package/src/parser/inline/media.ts +5 -5
- package/src/parser/inline/reference.test.ts +24 -9
- package/src/parser/inline/reference.ts +9 -9
- package/src/parser/inline/ruby.test.ts +2 -1
- package/src/parser/inline/ruby.ts +12 -10
- package/src/parser/inline/strong.ts +5 -5
- package/src/parser/segment.ts +11 -17
- package/src/parser/source/escapable.ts +1 -0
- package/src/parser/source/str.ts +3 -5
- package/src/parser/source/text.ts +8 -6
- package/src/parser/source/unescapable.ts +1 -0
- package/src/parser/util.ts +85 -60
package/markdown.d.ts
CHANGED
|
@@ -707,21 +707,21 @@ export namespace MarkdownParser {
|
|
|
707
707
|
// [#index]
|
|
708
708
|
Inline<'extension/index'>,
|
|
709
709
|
Parser<HTMLAnchorElement, Context, [
|
|
710
|
+
IndexParser.SignatureParser,
|
|
710
711
|
InlineParser,
|
|
711
|
-
IndexParser.IndexerParser,
|
|
712
712
|
]> {
|
|
713
713
|
}
|
|
714
714
|
export namespace IndexParser {
|
|
715
|
-
export interface
|
|
716
|
-
Inline<'extension/index/
|
|
715
|
+
export interface SignatureParser extends
|
|
716
|
+
Inline<'extension/index/signature'>,
|
|
717
717
|
Parser<HTMLElement, Context, [
|
|
718
|
-
|
|
718
|
+
SignatureParser.BracketParser,
|
|
719
719
|
SourceParser.TxtParser,
|
|
720
720
|
]> {
|
|
721
721
|
}
|
|
722
|
-
export namespace
|
|
722
|
+
export namespace SignatureParser {
|
|
723
723
|
export interface BracketParser extends
|
|
724
|
-
Inline<'extension/index/
|
|
724
|
+
Inline<'extension/index/signature/bracket'>,
|
|
725
725
|
Parser<string, Context, [
|
|
726
726
|
Parser<string, Context, [
|
|
727
727
|
BracketParser,
|
|
@@ -826,6 +826,7 @@ export namespace MarkdownParser {
|
|
|
826
826
|
SourceParser.StrParser,
|
|
827
827
|
SourceParser.StrParser,
|
|
828
828
|
SourceParser.StrParser,
|
|
829
|
+
SourceParser.StrParser,
|
|
829
830
|
]> {
|
|
830
831
|
}
|
|
831
832
|
}
|
package/package-lock.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "securemark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.218.3",
|
|
4
4
|
"lockfileVersion": 1,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"dependencies": {
|
|
@@ -2968,9 +2968,9 @@
|
|
|
2968
2968
|
"dev": true
|
|
2969
2969
|
},
|
|
2970
2970
|
"electron-to-chromium": {
|
|
2971
|
-
"version": "1.3.
|
|
2972
|
-
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.
|
|
2973
|
-
"integrity": "sha512-
|
|
2971
|
+
"version": "1.3.864",
|
|
2972
|
+
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.864.tgz",
|
|
2973
|
+
"integrity": "sha512-v4rbad8GO6/yVI92WOeU9Wgxc4NA0n4f6P1FvZTY+jyY7JHEhw3bduYu60v3Q1h81Cg6eo4ApZrFPuycwd5hGw==",
|
|
2974
2974
|
"dev": true
|
|
2975
2975
|
},
|
|
2976
2976
|
"elliptic": {
|
|
@@ -8649,9 +8649,9 @@
|
|
|
8649
8649
|
}
|
|
8650
8650
|
},
|
|
8651
8651
|
"prompts": {
|
|
8652
|
-
"version": "2.4.
|
|
8653
|
-
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.
|
|
8654
|
-
"integrity": "sha512-
|
|
8652
|
+
"version": "2.4.2",
|
|
8653
|
+
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
|
|
8654
|
+
"integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
|
|
8655
8655
|
"dev": true,
|
|
8656
8656
|
"requires": {
|
|
8657
8657
|
"kleur": "^3.0.3",
|
package/package.json
CHANGED
|
@@ -46,9 +46,9 @@ describe('Unit: parser/api/bind', () => {
|
|
|
46
46
|
assert.deepStrictEqual(
|
|
47
47
|
inspect(iter, 3),
|
|
48
48
|
[
|
|
49
|
-
'<h1 class="error" translate="no">Error: Too large segment over 100,000
|
|
49
|
+
'<h1 class="error" translate="no">Error: Too large segment over 100,000 bytes.</h1>',
|
|
50
50
|
`<pre class="error" translate="no">${'\n'.repeat(997)}...</pre>`,
|
|
51
|
-
'<h1 class="error" translate="no">Error: Too large segment over 100,000
|
|
51
|
+
'<h1 class="error" translate="no">Error: Too large segment over 100,000 bytes.</h1>',
|
|
52
52
|
]);
|
|
53
53
|
});
|
|
54
54
|
|
|
@@ -212,15 +212,15 @@ describe('Unit: parser/api/bind', () => {
|
|
|
212
212
|
html('ol', [
|
|
213
213
|
html('li', { id: 'annotation:def:1' }, [
|
|
214
214
|
'1',
|
|
215
|
-
html('sup', [html('a', { href: '#annotation:ref:1' }, '
|
|
215
|
+
html('sup', [html('a', { href: '#annotation:ref:1' }, '^1')])
|
|
216
216
|
]),
|
|
217
217
|
html('li', { id: 'annotation:def:2' }, [
|
|
218
218
|
'2',
|
|
219
|
-
html('sup', [html('a', { href: '#annotation:ref:2' }, '
|
|
219
|
+
html('sup', [html('a', { href: '#annotation:ref:2' }, '^2')])
|
|
220
220
|
]),
|
|
221
221
|
html('li', { id: 'annotation:def:3' }, [
|
|
222
222
|
'3',
|
|
223
|
-
html('sup', [html('a', { href: '#annotation:ref:3' }, '
|
|
223
|
+
html('sup', [html('a', { href: '#annotation:ref:3' }, '^3')])
|
|
224
224
|
]),
|
|
225
225
|
]).outerHTML);
|
|
226
226
|
assert.throws(() => update('').next());
|
package/src/parser/api/bind.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { MarkdownParser } from '../../../markdown';
|
|
|
5
5
|
import { eval } from '../../combinator/data/parser';
|
|
6
6
|
import { header } from '../header';
|
|
7
7
|
import { block } from '../block';
|
|
8
|
-
import { segment,
|
|
8
|
+
import { segment, validate, MAX_INPUT_SIZE } from '../segment';
|
|
9
9
|
import { normalize } from './normalize';
|
|
10
10
|
import { headers } from './header';
|
|
11
11
|
import { figure } from '../function/figure';
|
|
@@ -43,7 +43,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
|
|
|
43
43
|
function* parse(source: string): Generator<Progress, undefined, undefined> {
|
|
44
44
|
if (settings.chunk && revision) throw new Error('Chunks cannot be updated.');
|
|
45
45
|
const url = headers(source).find(field => field.toLowerCase().startsWith('url:'))?.slice(4).trim() ?? '';
|
|
46
|
-
source = normalize(
|
|
46
|
+
source = normalize(validate(source, MAX_INPUT_SIZE) ? source : source.slice(0, MAX_INPUT_SIZE + 1));
|
|
47
47
|
context = ObjectAssign(context, { url: url ? new ReadonlyURL(url) : undefined });
|
|
48
48
|
const rev = revision = Symbol();
|
|
49
49
|
const sourceSegments: string[] = [];
|
|
@@ -35,9 +35,27 @@ describe('Unit: parser/api/parse', () => {
|
|
|
35
35
|
assert.deepStrictEqual(
|
|
36
36
|
[...parse('\\').children].map(el => el.outerHTML),
|
|
37
37
|
['<p>\\</p>']);
|
|
38
|
+
assert.deepStrictEqual(
|
|
39
|
+
[...parse('\\\na').children].map(el => el.outerHTML),
|
|
40
|
+
['<p>\\<br>a</p>']);
|
|
38
41
|
assert.deepStrictEqual(
|
|
39
42
|
[...parse('	').children].map(el => el.outerHTML),
|
|
40
43
|
['<p>&Tab;</p>']);
|
|
44
|
+
assert.deepStrictEqual(
|
|
45
|
+
[...parse('	\na').children].map(el => el.outerHTML),
|
|
46
|
+
['<p>&Tab;<br>a</p>']);
|
|
47
|
+
assert.deepStrictEqual(
|
|
48
|
+
[...parse('<wbr>').children].map(el => el.outerHTML),
|
|
49
|
+
['<p><wbr></p>']);
|
|
50
|
+
assert.deepStrictEqual(
|
|
51
|
+
[...parse('<wbr>\na').children].map(el => el.outerHTML),
|
|
52
|
+
['<p><wbr><br>a</p>']);
|
|
53
|
+
assert.deepStrictEqual(
|
|
54
|
+
[...parse('[#\n<wbr>\n#]').children].map(el => el.outerHTML),
|
|
55
|
+
['<p>[#<br><wbr><br>#]</p>']);
|
|
56
|
+
assert.deepStrictEqual(
|
|
57
|
+
[...parse('[#\n<wbr>\n#]a').children].map(el => el.outerHTML),
|
|
58
|
+
['<p><sup class="comment" title="<wbr>"></sup>a</p>']);
|
|
41
59
|
});
|
|
42
60
|
|
|
43
61
|
it('linebreak', () => {
|
package/src/parser/api/parse.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { MarkdownParser } from '../../../markdown';
|
|
|
5
5
|
import { eval } from '../../combinator/data/parser';
|
|
6
6
|
import { header } from '../header';
|
|
7
7
|
import { block } from '../block';
|
|
8
|
-
import { segment,
|
|
8
|
+
import { segment, validate, MAX_SEGMENT_SIZE } from '../segment';
|
|
9
9
|
import { normalize } from './normalize';
|
|
10
10
|
import { headers } from './header';
|
|
11
11
|
import { figure } from '../function/figure';
|
|
@@ -22,7 +22,7 @@ const inherit = memoize<MarkdownParser.Context, MarkdownParser.Context>(context
|
|
|
22
22
|
const inherit2 = memoize<MarkdownParser.Context, (url: string) => MarkdownParser.Context>(context => memoize((_: string) => ObjectCreate(context)), new WeakMap());
|
|
23
23
|
|
|
24
24
|
export function parse(source: string, opts: Options = {}, context?: MarkdownParser.Context): DocumentFragment {
|
|
25
|
-
if (source
|
|
25
|
+
if (!validate(source, MAX_SEGMENT_SIZE)) throw new Error(`Too large input over ${MAX_SEGMENT_SIZE.toLocaleString('en')} bytes.`);
|
|
26
26
|
const url = headers(source).find(field => field.toLowerCase().startsWith('url:'))?.slice(4).trim() ?? '';
|
|
27
27
|
source = !context ? normalize(source) : source;
|
|
28
28
|
assert(!context?.delimiters);
|
|
@@ -96,7 +96,7 @@ describe('Unit: parser/block/blockquote', () => {
|
|
|
96
96
|
assert.deepStrictEqual(inspect(parser('!>> ## a\n> ## a')), [['<blockquote><blockquote><section><h2>a</h2><ol class="annotations"></ol><ol class="references"></ol></section></blockquote><section><h2>a</h2><ol class="annotations"></ol><ol class="references"></ol></section></blockquote>'], '']);
|
|
97
97
|
assert.deepStrictEqual(inspect(parser('!>> ~ a\n> ~ a')), [['<blockquote><blockquote><section><dl><dt>a</dt><dd></dd></dl><ol class="annotations"></ol><ol class="references"></ol></section></blockquote><section><dl><dt>a</dt><dd></dd></dl><ol class="annotations"></ol><ol class="references"></ol></section></blockquote>'], '']);
|
|
98
98
|
assert.deepStrictEqual(inspect(parser('!>> ~~~figure $fig-a\n>> > \n>>\n~~~\n> ~~~figure $fig-a\n> > \n>\n[#a]\n~~~')), [['<blockquote><blockquote><section><figure data-label="fig-a" data-group="fig" data-number="1"><div class="figcontent"><blockquote></blockquote></div><span class="figindex">Fig. 1: </span><figcaption></figcaption></figure><ol class="annotations"></ol><ol class="references"></ol></section></blockquote><section><figure data-label="fig-a" data-group="fig" data-number="1"><div class="figcontent"><blockquote></blockquote></div><span class="figindex">Fig. 1: </span><figcaption><a class="index">a</a></figcaption></figure><ol class="annotations"></ol><ol class="references"></ol></section></blockquote>'], '']);
|
|
99
|
-
assert.deepStrictEqual(inspect(parser('!>> ((a))\n> ((a))')), [['<blockquote><blockquote><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup></p><ol class="annotations"><li>a<sup><a
|
|
99
|
+
assert.deepStrictEqual(inspect(parser('!>> ((a))\n> ((a))')), [['<blockquote><blockquote><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup></p><ol class="annotations"><li>a<sup><a>^1</a></sup></li></ol><ol class="references"></ol></section></blockquote><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup></p><ol class="annotations"><li>a<sup><a>^1</a></sup></li></ol><ol class="references"></ol></section></blockquote>'], '']);
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
});
|
|
@@ -23,7 +23,7 @@ describe('Unit: parser/block/extension/example', () => {
|
|
|
23
23
|
assert.deepStrictEqual(inspect(parser('~~~example/markdown\n[$fig-a]\n!https://host\n~~~')), [['<aside class="example" data-type="markdown"><pre translate="no">[$fig-a]\n!https://host</pre><hr><section><figure data-label="fig-a" data-group="fig" data-number="1"><div class="figcontent"><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div><span class="figindex">Fig. 1: </span><figcaption></figcaption></figure><ol class="annotations"></ol><ol class="references"></ol></section></aside>'], '']);
|
|
24
24
|
assert.deepStrictEqual(inspect(parser('~~~example/markdown\n## a\n~~~')), [['<aside class="example" data-type="markdown"><pre translate="no">## a</pre><hr><section><h2>a</h2><ol class="annotations"></ol><ol class="references"></ol></section></aside>'], '']);
|
|
25
25
|
assert.deepStrictEqual(inspect(parser('~~~example/markdown\n~ a\n~~~')), [['<aside class="example" data-type="markdown"><pre translate="no">~ a</pre><hr><section><dl><dt>a</dt><dd></dd></dl><ol class="annotations"></ol><ol class="references"></ol></section></aside>'], '']);
|
|
26
|
-
assert.deepStrictEqual(inspect(parser('~~~example/markdown\n((a))[[b]]\n~~~')), [['<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>a<sup><a
|
|
26
|
+
assert.deepStrictEqual(inspect(parser('~~~example/markdown\n((a))[[b]]\n~~~')), [['<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>a<sup><a>^1</a></sup></li></ol><ol class="references"><li>b<sup><a>^1</a></sup></li></ol></section></aside>'], '']);
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('~~~~example/markdown\na\n~~~~')), [['<aside class="example" data-type="markdown"><pre translate="no">a</pre><hr><section><p>a</p><ol class="annotations"></ol><ol class="references"></ol></section></aside>'], '']);
|
|
28
28
|
assert.deepStrictEqual(inspect(parser('~~~example/math\na\n~~~')), [['<aside class="example" data-type="math"><pre translate="no">a</pre><hr><div class="math" translate="no">$$\na\n$$</div></aside>'], '']);
|
|
29
29
|
assert.deepStrictEqual(inspect(parser(`~~~example/math\n0${'\n'.repeat(100)}~~~`), '>'), [['<aside class="example" data-type="math">'], '']);
|
|
@@ -26,7 +26,7 @@ export const segment: FigParser.SegmentParser = block(validate(['[$', '$'],
|
|
|
26
26
|
|
|
27
27
|
export const fig: FigParser = block(rewrite(segment, convert(
|
|
28
28
|
source => {
|
|
29
|
-
const fence = (/^[^\n]*\n!?>+\s/.test(source) && source.match(/^~{3,}(?=\s*$)/
|
|
29
|
+
const fence = (/^[^\n]*\n!?>+\s/.test(source) && source.match(/^~{3,}(?=\s*$)/mg) || [])
|
|
30
30
|
.reduce((max, fence) => fence > max ? fence : max, '~~') + '~';
|
|
31
31
|
return `${fence}figure ${source}\n\n${fence}`;
|
|
32
32
|
},
|
|
@@ -82,7 +82,7 @@ const head: CellParser.HeadParser = creator(block(fmap(open(
|
|
|
82
82
|
anyline,
|
|
83
83
|
some(contentline, delimiter),
|
|
84
84
|
]),
|
|
85
|
-
visualize(trim(some(union([inline])))
|
|
85
|
+
visualize(trim(some(union([inline]))))),
|
|
86
86
|
true),
|
|
87
87
|
ns => [html('th', attributes(ns.shift()! as string), defrag(ns))]),
|
|
88
88
|
false));
|
|
@@ -94,7 +94,7 @@ const data: CellParser.DataParser = creator(block(fmap(open(
|
|
|
94
94
|
anyline,
|
|
95
95
|
some(contentline, delimiter),
|
|
96
96
|
]),
|
|
97
|
-
visualize(trim(some(union([inline])))
|
|
97
|
+
visualize(trim(some(union([inline]))))),
|
|
98
98
|
true),
|
|
99
99
|
ns => [html('td', attributes(ns.shift()! as string), defrag(ns))]),
|
|
100
100
|
false));
|
|
@@ -64,24 +64,22 @@ describe('Unit: parser/block/heading', () => {
|
|
|
64
64
|
assert.deepStrictEqual(inspect(parser('# a [#b]')), [['<h1 id="index:b">a<span class="indexer" data-index="b"></span></h1>'], '']);
|
|
65
65
|
assert.deepStrictEqual(inspect(parser('# a [#b] ')), [['<h1 id="index:b">a<span class="indexer" data-index="b"></span></h1>'], '']);
|
|
66
66
|
assert.deepStrictEqual(inspect(parser('# a [#b]\\')), [['<h1 id="index:a_[#b]">a [#b]</h1>'], '']);
|
|
67
|
+
assert.deepStrictEqual(inspect(parser('# a [#B]')), [['<h1 id="index:B">a<span class="indexer" data-index="B"></span></h1>'], '']);
|
|
68
|
+
assert.deepStrictEqual(inspect(parser('# a [#b ]')), [['<h1 id="index:b">a<span class="indexer" data-index="b"></span></h1>'], '']);
|
|
69
|
+
assert.deepStrictEqual(inspect(parser('# a [#b ]')), [['<h1 id="index:b">a<span class="indexer" data-index="b"></span></h1>'], '']);
|
|
67
70
|
assert.deepStrictEqual(inspect(parser('# a [#b c]')), [['<h1 id="index:b_c">a<span class="indexer" data-index="b_c"></span></h1>'], '']);
|
|
68
71
|
assert.deepStrictEqual(inspect(parser('# a [#*b*`c`${d}$]')), [['<h1 id="index:b`c`${d}$">a<span class="indexer" data-index="b`c`${d}$"></span></h1>'], '']);
|
|
72
|
+
assert.deepStrictEqual(inspect(parser('# a [#@a]')), [['<h1 id="index:@a">a<span class="indexer" data-index="@a"></span></h1>'], '']);
|
|
73
|
+
assert.deepStrictEqual(inspect(parser('# a [#http://host]')), [['<h1 id="index:http://host">a<span class="indexer" data-index="http://host"></span></h1>'], '']);
|
|
74
|
+
assert.deepStrictEqual(inspect(parser('# a [#!http://host]')), [['<h1 id="index:!http://host">a<span class="indexer" data-index="!http://host"></span></h1>'], '']);
|
|
75
|
+
assert.deepStrictEqual(inspect(parser('# a [#a((b))]')), [['<h1 id="index:a((b))">a<span class="indexer" data-index="a((b))"></span></h1>'], '']);
|
|
76
|
+
assert.deepStrictEqual(inspect(parser('# a [#a[[b]]]')), [['<h1 id="index:a[[b]]">a<span class="indexer" data-index="a[[b]]"></span></h1>'], '']);
|
|
77
|
+
assert.deepStrictEqual(inspect(parser('# a [#b|#c]')), [['<h1 id="index:c">a<span class="indexer" data-index="c"></span></h1>'], '']);
|
|
69
78
|
assert.deepStrictEqual(inspect(parser('# a [#b] [#c]')), [['<h1 id="index:c">a [#b]<span class="indexer" data-index="c"></span></h1>'], '']);
|
|
70
79
|
assert.deepStrictEqual(inspect(parser('# a [#b] \n')), [['<h1 id="index:b">a<span class="indexer" data-index="b"></span></h1>'], '']);
|
|
71
80
|
assert.deepStrictEqual(inspect(parser('# a \\[#b]')), [['<h1 id="index:a_[#b]">a [#b]</h1>'], '']);
|
|
72
|
-
assert.deepStrictEqual(inspect(parser('# A')), [['<h1 id="index:A">A</h1>'], '']);
|
|
73
|
-
assert.deepStrictEqual(inspect(parser('# *A*')), [['<h1 id="index:A"><em>A</em></h1>'], '']);
|
|
74
|
-
assert.deepStrictEqual(inspect(parser('# `A`')), [['<h1 id="index:`A`"><code data-src="`A`">A</code></h1>'], '']);
|
|
75
|
-
assert.deepStrictEqual(inspect(parser('# ${A}$')), [['<h1 id="index:${A}$"><span class="math" translate="no" data-src="${A}$">${A}$</span></h1>'], '']);
|
|
76
|
-
assert.deepStrictEqual(inspect(parser('# A [#B]')), [['<h1 id="index:B">A<span class="indexer" data-index="B"></span></h1>'], '']);
|
|
77
|
-
assert.deepStrictEqual(inspect(parser('# A [#`B`]')), [['<h1 id="index:`B`">A<span class="indexer" data-index="`B`"></span></h1>'], '']);
|
|
78
|
-
assert.deepStrictEqual(inspect(parser('# A [#@a]')), [['<h1 id="index:@a">A<span class="indexer" data-index="@a"></span></h1>'], '']);
|
|
79
|
-
assert.deepStrictEqual(inspect(parser('# A [#http://host]')), [['<h1 id="index:http://host">A<span class="indexer" data-index="http://host"></span></h1>'], '']);
|
|
80
|
-
assert.deepStrictEqual(inspect(parser('# A [#!http://host]')), [['<h1 id="index:!http://host">A<span class="indexer" data-index="!http://host"></span></h1>'], '']);
|
|
81
|
-
assert.deepStrictEqual(inspect(parser('# A [#a((b))]')), [['<h1 id="index:a((b))">A<span class="indexer" data-index="a((b))"></span></h1>'], '']);
|
|
82
|
-
assert.deepStrictEqual(inspect(parser('# A [#a[[b]]]')), [['<h1 id="index:a[[b]]">A<span class="indexer" data-index="a[[b]]"></span></h1>'], '']);
|
|
83
|
-
assert.deepStrictEqual(inspect(parser('# A [#b|#c]')), [['<h1 id="index:c">A<span class="indexer" data-index="c"></span></h1>'], '']);
|
|
84
81
|
assert.deepStrictEqual(inspect(parser('## a [#b] [#c]')), [['<h2 id="index:c">a [<a href="/hashtags/b" class="hashtag">#b</a>]<span class="indexer" data-index="c"></span></h2>'], '']);
|
|
82
|
+
assert.deepStrictEqual(inspect(parser('## a [#b ] [#c ]')), [['<h2 id="index:c">a [<a href="/hashtags/b" class="hashtag">#b</a> ]<span class="indexer" data-index="c"></span></h2>'], '']);
|
|
85
83
|
});
|
|
86
84
|
|
|
87
85
|
});
|
|
@@ -16,7 +16,14 @@ export const ilist: IListParser = lazy(() => block(fmap(validate(
|
|
|
16
16
|
]),
|
|
17
17
|
ns => [html('li', defrag(fillFirstLine(ns)))]),
|
|
18
18
|
]))))),
|
|
19
|
-
es => [
|
|
19
|
+
es => [
|
|
20
|
+
html('ul', {
|
|
21
|
+
class: 'invalid',
|
|
22
|
+
'data-invalid-syntax': 'list',
|
|
23
|
+
'data-invalid-type': 'syntax',
|
|
24
|
+
'data-invalid-description': 'Use "-" instead of "+" or "*".',
|
|
25
|
+
}, es),
|
|
26
|
+
])));
|
|
20
27
|
|
|
21
28
|
export const ilist_: IListParser = convert(
|
|
22
29
|
source => source.replace(/^[-+*](?=$|\n)/, `$& `),
|
|
@@ -20,6 +20,11 @@ describe('Unit: parser/block/paragraph', () => {
|
|
|
20
20
|
assert.deepStrictEqual(inspect(parser('a\\ \n')), [['<p>a</p>'], '']);
|
|
21
21
|
assert.deepStrictEqual(inspect(parser('a\\\n')), [['<p>a</p>'], '']);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser('a\\\nb')), [['<p>a<span class="linebreak"> </span>b</p>'], '']);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser('<wbr>')), [['<p><wbr></p>'], '']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser('<wbr>\n')), [['<p><wbr></p>'], '']);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser('<wbr>\na')), [['<p><wbr><br>a</p>'], '']);
|
|
26
|
+
assert.deepStrictEqual(inspect(parser('a\n<wbr>\n')), [['<p>a<br><wbr></p>'], '']);
|
|
27
|
+
assert.deepStrictEqual(inspect(parser('a\n<wbr>\nb')), [['<p>a<br><wbr><br>b</p>'], '']);
|
|
23
28
|
assert.deepStrictEqual(inspect(parser(' a')), [['<p>a</p>'], '']);
|
|
24
29
|
});
|
|
25
30
|
|
|
@@ -52,6 +57,8 @@ describe('Unit: parser/block/paragraph', () => {
|
|
|
52
57
|
it('comment', () => {
|
|
53
58
|
assert.deepStrictEqual(inspect(parser('[# a #]')), [['<p>[# a #]</p>'], '']);
|
|
54
59
|
assert.deepStrictEqual(inspect(parser('[# a #]b')), [['<p><sup class="comment" title="a"></sup>b</p>'], '']);
|
|
60
|
+
assert.deepStrictEqual(inspect(parser('[#\n<wbr>\n#]')), [['<p>[#<br><wbr><br>#]</p>'], '']);
|
|
61
|
+
assert.deepStrictEqual(inspect(parser('[#\n<wbr>\n#]a')), [['<p><sup class="comment" title="<wbr>"></sup>a</p>'], '']);
|
|
55
62
|
});
|
|
56
63
|
|
|
57
64
|
});
|
|
@@ -37,7 +37,7 @@ describe('Unit: parser/footnote', () => {
|
|
|
37
37
|
html('ol', [
|
|
38
38
|
html('li', { id: 'annotation:def:1' }, [
|
|
39
39
|
'a b',
|
|
40
|
-
html('sup', [html('a', { href: '#annotation:ref:1' }, '
|
|
40
|
+
html('sup', [html('a', { href: '#annotation:ref:1' }, '^1')])
|
|
41
41
|
]),
|
|
42
42
|
]).outerHTML);
|
|
43
43
|
}
|
|
@@ -65,11 +65,11 @@ describe('Unit: parser/footnote', () => {
|
|
|
65
65
|
html('ol', [
|
|
66
66
|
html('li', { id: 'annotation:def:1' }, [
|
|
67
67
|
'1',
|
|
68
|
-
html('sup', [html('a', { href: '#annotation:ref:1' }, '
|
|
68
|
+
html('sup', [html('a', { href: '#annotation:ref:1' }, '^1')])
|
|
69
69
|
]),
|
|
70
70
|
html('li', { id: 'annotation:def:2' }, [
|
|
71
71
|
'12345678901234567890',
|
|
72
|
-
html('sup', [html('a', { href: '#annotation:ref:2' }, '
|
|
72
|
+
html('sup', [html('a', { href: '#annotation:ref:2' }, '^2')])
|
|
73
73
|
]),
|
|
74
74
|
]).outerHTML);
|
|
75
75
|
}
|
|
@@ -106,22 +106,22 @@ describe('Unit: parser/footnote', () => {
|
|
|
106
106
|
html('ol', [
|
|
107
107
|
html('li', { id: 'annotation:def:1' }, [
|
|
108
108
|
'1',
|
|
109
|
-
html('sup', [html('a', { href: '#annotation:ref:1' }, '
|
|
109
|
+
html('sup', [html('a', { href: '#annotation:ref:1' }, '^1')])
|
|
110
110
|
]),
|
|
111
111
|
html('li', { id: 'annotation:def:2' }, [
|
|
112
112
|
'2',
|
|
113
113
|
html('sup', [
|
|
114
|
-
html('a', { href: '#annotation:ref:2' }, '
|
|
115
|
-
html('a', { href: '#annotation:ref:4' }, '
|
|
114
|
+
html('a', { href: '#annotation:ref:2' }, '^2'),
|
|
115
|
+
html('a', { href: '#annotation:ref:4' }, '^4'),
|
|
116
116
|
]),
|
|
117
117
|
]),
|
|
118
118
|
html('li', { id: 'annotation:def:3' }, [
|
|
119
119
|
'3',
|
|
120
|
-
html('sup', [html('a', { href: '#annotation:ref:3' }, '
|
|
120
|
+
html('sup', [html('a', { href: '#annotation:ref:3' }, '^3')])
|
|
121
121
|
]),
|
|
122
122
|
html('li', { id: 'annotation:def:4' }, [
|
|
123
123
|
'4',
|
|
124
|
-
html('sup', [html('a', { href: '#annotation:ref:5' }, '
|
|
124
|
+
html('sup', [html('a', { href: '#annotation:ref:5' }, '^5')])
|
|
125
125
|
]),
|
|
126
126
|
]).outerHTML);
|
|
127
127
|
}
|
|
@@ -143,13 +143,13 @@ describe('Unit: parser/footnote', () => {
|
|
|
143
143
|
assert.deepStrictEqual(
|
|
144
144
|
[...target.children].map(el => el.outerHTML),
|
|
145
145
|
[
|
|
146
|
-
'<blockquote><blockquote><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup></p><ol class="annotations"><li>a<sup><a
|
|
147
|
-
'<aside class="example" data-type="markdown"><pre translate="no">((a))</pre><hr><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup></p><ol class="annotations"><li>a<sup><a
|
|
146
|
+
'<blockquote><blockquote><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup></p><ol class="annotations"><li>a<sup><a>^1</a></sup></li></ol><ol class="references"></ol></section></blockquote><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup><br>~~~</p><ol class="annotations"><li>a<sup><a>^1</a></sup></li></ol><ol class="references"></ol></section></blockquote>',
|
|
147
|
+
'<aside class="example" data-type="markdown"><pre translate="no">((a))</pre><hr><section><p><sup class="annotation disabled" title="a"><a>*1</a></sup></p><ol class="annotations"><li>a<sup><a>^1</a></sup></li></ol><ol class="references"></ol></section></aside>',
|
|
148
148
|
'<p><sup class="annotation" id="annotation:ref:1" title="a"><a href="#annotation:def:1">*1</a></sup></p>',
|
|
149
149
|
]);
|
|
150
150
|
assert.deepStrictEqual(
|
|
151
151
|
footnote.outerHTML,
|
|
152
|
-
'<ol><li id="annotation:def:1">a<sup><a href="#annotation:ref:1"
|
|
152
|
+
'<ol><li id="annotation:def:1">a<sup><a href="#annotation:ref:1">^1</a></sup></li></ol>');
|
|
153
153
|
}
|
|
154
154
|
});
|
|
155
155
|
|
|
@@ -172,7 +172,7 @@ describe('Unit: parser/footnote', () => {
|
|
|
172
172
|
html('ol', [
|
|
173
173
|
html('li', { id: 'annotation:0:def:1' }, [
|
|
174
174
|
'a b',
|
|
175
|
-
html('sup', [html('a', { href: '#annotation:0:ref:1' }, '
|
|
175
|
+
html('sup', [html('a', { href: '#annotation:0:ref:1' }, '^1')])
|
|
176
176
|
]),
|
|
177
177
|
]).outerHTML);
|
|
178
178
|
}
|
|
@@ -200,7 +200,7 @@ describe('Unit: parser/footnote', () => {
|
|
|
200
200
|
html('ol', [
|
|
201
201
|
html('li', { id: 'reference:def:1' }, [
|
|
202
202
|
'a b',
|
|
203
|
-
html('sup', [html('a', { href: '#reference:ref:1' }, '
|
|
203
|
+
html('sup', [html('a', { href: '#reference:ref:1' }, '^1')])
|
|
204
204
|
]),
|
|
205
205
|
]).outerHTML);
|
|
206
206
|
}
|
|
@@ -232,9 +232,9 @@ describe('Unit: parser/footnote', () => {
|
|
|
232
232
|
html('li', { id: 'reference:def:1' }, [
|
|
233
233
|
'b',
|
|
234
234
|
html('sup', [
|
|
235
|
-
html('a', { href: '#reference:ref:1' }, '
|
|
236
|
-
html('a', { href: '#reference:ref:2', title: 'b' }, '
|
|
237
|
-
html('a', { href: '#reference:ref:3' }, '
|
|
235
|
+
html('a', { href: '#reference:ref:1' }, '^1'),
|
|
236
|
+
html('a', { href: '#reference:ref:2', title: 'b' }, '^2'),
|
|
237
|
+
html('a', { href: '#reference:ref:3' }, '^3'),
|
|
238
238
|
])
|
|
239
239
|
]),
|
|
240
240
|
]).outerHTML);
|
|
@@ -20,7 +20,6 @@ describe('Unit: parser/inline/annotation', () => {
|
|
|
20
20
|
assert.deepStrictEqual(inspect(parser('((\na))')), undefined);
|
|
21
21
|
assert.deepStrictEqual(inspect(parser('((\\ a))')), undefined);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser('((\\\na))')), undefined);
|
|
23
|
-
assert.deepStrictEqual(inspect(parser('((a ))')), undefined);
|
|
24
23
|
assert.deepStrictEqual(inspect(parser('((a\n))')), undefined);
|
|
25
24
|
assert.deepStrictEqual(inspect(parser('((a\\\n))')), undefined);
|
|
26
25
|
assert.deepStrictEqual(inspect(parser('((a\nb))')), undefined);
|
|
@@ -36,7 +35,11 @@ describe('Unit: parser/inline/annotation', () => {
|
|
|
36
35
|
|
|
37
36
|
it('basic', () => {
|
|
38
37
|
assert.deepStrictEqual(inspect(parser('((a))')), [['<sup class="annotation">a</sup>'], '']);
|
|
39
|
-
assert.deepStrictEqual(inspect(parser('((a ))')), [['<sup class="annotation">a
|
|
38
|
+
assert.deepStrictEqual(inspect(parser('((a ))')), [['<sup class="annotation">a</sup>'], '']);
|
|
39
|
+
assert.deepStrictEqual(inspect(parser('((a ))')), [['<sup class="annotation">a</sup>'], '']);
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('((a ))')), [['<sup class="annotation">a</sup>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('((a <wbr>))')), [['<sup class="annotation">a</sup>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('((a [# b #]))')), [['<sup class="annotation">a <sup class="comment" title="b"></sup></sup>'], '']);
|
|
40
43
|
assert.deepStrictEqual(inspect(parser('((ab))')), [['<sup class="annotation">ab</sup>'], '']);
|
|
41
44
|
});
|
|
42
45
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { AnnotationParser } from '../inline';
|
|
3
|
-
import { union, some, validate,
|
|
3
|
+
import { union, some, validate, guard, context, creator, surround, lazy, fmap } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
|
-
import { startTight,
|
|
5
|
+
import { startTight, trimEnd } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
|
|
8
|
-
export const annotation: AnnotationParser = lazy(() => creator(validate('((', '))', '\n', fmap(
|
|
8
|
+
export const annotation: AnnotationParser = lazy(() => creator(validate('((', '))', '\n', fmap(surround(
|
|
9
9
|
'((',
|
|
10
10
|
guard(context => context.syntax?.inline?.annotation ?? true,
|
|
11
11
|
startTight(
|
|
@@ -21,5 +21,4 @@ export const annotation: AnnotationParser = lazy(() => creator(validate('((', ')
|
|
|
21
21
|
}}, state: undefined },
|
|
22
22
|
union([some(inline, ')', /^\\?\n/)])))),
|
|
23
23
|
'))'),
|
|
24
|
-
|
|
25
|
-
ns => [html('sup', { class: 'annotation' }, defrag(ns))]))));
|
|
24
|
+
ns => [html('sup', { class: 'annotation' }, trimEnd(defrag(ns)))]))));
|
|
@@ -6,5 +6,5 @@ export const comment: CommentParser = creator(validate('[#', '#]', match(
|
|
|
6
6
|
/^\[(#+)\s+((?:\S+\s+)+?)(\1\]|$)/,
|
|
7
7
|
([, , title, closer]) => (rest, { resources }) =>
|
|
8
8
|
closer
|
|
9
|
-
? [[html('sup', { class: 'comment', title: title.trim() })], rest]
|
|
9
|
+
? [[html('sup', { class: 'comment', title: title.trim().replace(/\x7F.?/gs, '') })], rest]
|
|
10
10
|
: resources && void (resources.budget -= title.match(/\s+/g)!.length))));
|
|
@@ -27,6 +27,7 @@ describe('Unit: parser/inline/deletion', () => {
|
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('~~\\\na~~')), [['<del><span class="linebreak"> </span>a</del>'], '']);
|
|
28
28
|
assert.deepStrictEqual(inspect(parser('~~<wbr>a~~')), [['<del><wbr>a</del>'], '']);
|
|
29
29
|
assert.deepStrictEqual(inspect(parser('~~[# a #]b~~')), [['<del><sup class="comment" title="a"></sup>b</del>'], '']);
|
|
30
|
+
assert.deepStrictEqual(inspect(parser('~~a\n~~')), [['<del>a</del>'], '']);
|
|
30
31
|
assert.deepStrictEqual(inspect(parser('~~a\nb~~')), [['<del>a<br>b</del>'], '']);
|
|
31
32
|
assert.deepStrictEqual(inspect(parser('~~a\\\nb~~')), [['<del>a<span class="linebreak"> </span>b</del>'], '']);
|
|
32
33
|
assert.deepStrictEqual(inspect(parser('~~\\~~~')), [['<del>~</del>'], '']);
|
|
@@ -2,6 +2,7 @@ import { DeletionParser } from '../inline';
|
|
|
2
2
|
import { union, some, creator, surround, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
+
import { trimEndBR } from '../util';
|
|
5
6
|
import { html, defrag } from 'typed-dom';
|
|
6
7
|
import { unshift } from 'spica/array';
|
|
7
8
|
|
|
@@ -9,5 +10,5 @@ export const deletion: DeletionParser = lazy(() => creator(surround(
|
|
|
9
10
|
str('~~'),
|
|
10
11
|
union([some(inline, '~~')]),
|
|
11
12
|
str('~~'), false,
|
|
12
|
-
([, bs], rest) => [[html('del', defrag(bs))], rest],
|
|
13
|
+
([, bs], rest) => [[html('del', defrag(trimEndBR(bs)))], rest],
|
|
13
14
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { EmphasisParser } from '../inline';
|
|
2
|
-
import { union, some, creator, surround, lazy } from '../../combinator';
|
|
2
|
+
import { union, some, creator, surround, close, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { strong } from './strong';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
-
import { startTight,
|
|
6
|
+
import { startTight, verifyEndTight, trimEndBR } from '../util';
|
|
7
7
|
import { html, defrag } from 'typed-dom';
|
|
8
8
|
import { unshift } from 'spica/array';
|
|
9
9
|
|
|
10
|
-
export const emphasis: EmphasisParser = lazy(() => creator(surround(
|
|
11
|
-
str('*',
|
|
10
|
+
export const emphasis: EmphasisParser = lazy(() => creator(surround(close(
|
|
11
|
+
str('*'), /^(?!\*)/),
|
|
12
12
|
startTight(some(union([strong, some(inline, '*')]))),
|
|
13
13
|
str('*'), false,
|
|
14
14
|
([as, bs, cs], rest) =>
|
|
15
|
-
|
|
15
|
+
verifyEndTight(bs)
|
|
16
16
|
? [[html('em', defrag(trimEndBR(bs)))], rest]
|
|
17
17
|
: [unshift(as, bs), cs[0] + rest],
|
|
18
18
|
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
@@ -2,7 +2,7 @@ import { EmStrongParser } from '../inline';
|
|
|
2
2
|
import { union, some, creator, surround, lazy, bind } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
-
import { startTight,
|
|
5
|
+
import { startTight, verifyEndTight, trimEndBR } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
@@ -11,13 +11,13 @@ export const emstrong: EmStrongParser = lazy(() => creator(surround(
|
|
|
11
11
|
startTight(union([some(inline, '*')])),
|
|
12
12
|
str(/^\*{1,3}/), false,
|
|
13
13
|
([as, bs, cs], rest, context) => {
|
|
14
|
-
if (!
|
|
14
|
+
if (!verifyEndTight(bs)) return [unshift(as, bs), cs[0] + rest];
|
|
15
15
|
switch (cs[0]) {
|
|
16
16
|
case '*':
|
|
17
17
|
return bind<EmStrongParser>(
|
|
18
18
|
union([some(inline, '**')]),
|
|
19
19
|
(ds, rest) =>
|
|
20
|
-
rest.slice(0, 2) === '**' &&
|
|
20
|
+
rest.slice(0, 2) === '**' && verifyEndTight(ds)
|
|
21
21
|
? [[html('strong', unshift([html('em', defrag(trimEndBR(bs)))], defrag(trimEndBR(ds))))], rest.slice(2)]
|
|
22
22
|
: [unshift(['**', html('em', defrag(trimEndBR(bs)))], ds), rest])
|
|
23
23
|
(rest, context) ?? [['**', html('em', defrag(trimEndBR(bs)))], rest];
|
|
@@ -25,7 +25,7 @@ export const emstrong: EmStrongParser = lazy(() => creator(surround(
|
|
|
25
25
|
return bind<EmStrongParser>(
|
|
26
26
|
union([some(inline, '*')]),
|
|
27
27
|
(ds, rest) =>
|
|
28
|
-
rest.slice(0, 1) === '*' &&
|
|
28
|
+
rest.slice(0, 1) === '*' && verifyEndTight(ds)
|
|
29
29
|
? [[html('em', unshift([html('strong', defrag(trimEndBR(bs)))], defrag(trimEndBR(ds))))], rest.slice(1)]
|
|
30
30
|
: [unshift(['*', html('strong', defrag(trimEndBR(bs)))], ds), rest])
|
|
31
31
|
(rest, context) ?? [['*', html('strong', defrag(trimEndBR(bs)))], rest];
|