securemark 0.255.0 → 0.257.0
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 +14 -0
- package/dist/index.js +209 -170
- package/markdown.d.ts +18 -11
- package/package.json +1 -1
- package/src/combinator/control/constraint/contract.ts +3 -13
- package/src/combinator/control/manipulation/context.ts +12 -7
- package/src/combinator/control/manipulation/resource.ts +37 -3
- package/src/combinator/control/manipulation/surround.ts +6 -6
- package/src/combinator/data/parser/inits.ts +1 -1
- package/src/combinator/data/parser/sequence.ts +1 -1
- package/src/combinator/data/parser/some.ts +16 -38
- package/src/combinator/data/parser.ts +34 -18
- package/src/debug.test.ts +2 -2
- package/src/parser/api/bind.ts +9 -11
- package/src/parser/api/parse.test.ts +51 -9
- package/src/parser/api/parse.ts +6 -5
- package/src/parser/block/extension/aside.ts +3 -3
- package/src/parser/block/extension/example.ts +3 -3
- package/src/parser/block.ts +1 -1
- package/src/parser/inline/annotation.test.ts +6 -5
- package/src/parser/inline/annotation.ts +9 -6
- package/src/parser/inline/autolink/url.ts +6 -6
- package/src/parser/inline/bracket.test.ts +11 -7
- package/src/parser/inline/bracket.ts +11 -11
- package/src/parser/inline/comment.test.ts +4 -3
- package/src/parser/inline/comment.ts +4 -4
- package/src/parser/inline/deletion.ts +3 -3
- package/src/parser/inline/emphasis.ts +3 -3
- package/src/parser/inline/emstrong.ts +4 -5
- package/src/parser/inline/extension/index.test.ts +1 -0
- package/src/parser/inline/extension/index.ts +8 -7
- package/src/parser/inline/extension/indexer.ts +3 -5
- package/src/parser/inline/extension/label.ts +1 -1
- package/src/parser/inline/extension/placeholder.test.ts +8 -7
- package/src/parser/inline/extension/placeholder.ts +4 -4
- package/src/parser/inline/html.test.ts +2 -0
- package/src/parser/inline/html.ts +5 -5
- package/src/parser/inline/insertion.ts +3 -3
- package/src/parser/inline/link.test.ts +1 -0
- package/src/parser/inline/link.ts +8 -7
- package/src/parser/inline/mark.ts +3 -3
- package/src/parser/inline/math.test.ts +21 -14
- package/src/parser/inline/math.ts +4 -15
- package/src/parser/inline/media.test.ts +0 -2
- package/src/parser/inline/media.ts +6 -6
- package/src/parser/inline/reference.test.ts +9 -9
- package/src/parser/inline/reference.ts +19 -7
- package/src/parser/inline/ruby.ts +29 -27
- package/src/parser/inline/strong.ts +3 -3
- package/src/parser/inline/template.ts +4 -4
- package/src/parser/inline.test.ts +13 -10
- package/src/parser/util.ts +18 -2
|
@@ -17,11 +17,11 @@ describe('Unit: parser/inline/annotation', () => {
|
|
|
17
17
|
assert.deepStrictEqual(inspect(parser('((\n))')), undefined);
|
|
18
18
|
assert.deepStrictEqual(inspect(parser('((\na))')), undefined);
|
|
19
19
|
assert.deepStrictEqual(inspect(parser('((\\\na))')), undefined);
|
|
20
|
-
assert.deepStrictEqual(inspect(parser('((a\n))')),
|
|
21
|
-
assert.deepStrictEqual(inspect(parser('((a\\\n))')),
|
|
22
|
-
assert.deepStrictEqual(inspect(parser('((a\nb))')),
|
|
23
|
-
assert.deepStrictEqual(inspect(parser('((a\\\nb))')),
|
|
24
|
-
assert.deepStrictEqual(inspect(parser('((*a\nb*))')),
|
|
20
|
+
assert.deepStrictEqual(inspect(parser('((a\n))')), [['(('], 'a\n))']);
|
|
21
|
+
assert.deepStrictEqual(inspect(parser('((a\\\n))')), [['(('], 'a\\\n))']);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser('((a\nb))')), [['(('], 'a\nb))']);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser('((a\\\nb))')), [['(('], 'a\\\nb))']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser('((*a\nb*))')), [['(('], '*a\nb*))']);
|
|
25
25
|
assert.deepStrictEqual(inspect(parser('((\\))')), undefined);
|
|
26
26
|
assert.deepStrictEqual(inspect(parser('((a)b))')), undefined);
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('(((a))')), undefined);
|
|
@@ -42,6 +42,7 @@ describe('Unit: parser/inline/annotation', () => {
|
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
it('nest', () => {
|
|
45
|
+
assert.deepStrictEqual(inspect(parser('((<bdi>))')), [['<sup class="annotation"><span><span class="invalid"><bdi></span></span></sup>'], '']);
|
|
45
46
|
assert.deepStrictEqual(inspect(parser('((`a`))')), [['<sup class="annotation"><span><code data-src="`a`">a</code></span></sup>'], '']);
|
|
46
47
|
assert.deepStrictEqual(inspect(parser('((@a))')), [['<sup class="annotation"><span><a href="/@a" class="account">@a</a></span></sup>'], '']);
|
|
47
48
|
assert.deepStrictEqual(inspect(parser('((http://host))')), [['<sup class="annotation"><span><a href="http://host" target="_blank">http://host</a></span></sup>'], '']);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { AnnotationParser } from '../inline';
|
|
3
|
-
import { union, some, validate, guard, context, creator, surround, lazy
|
|
3
|
+
import { union, some, validate, guard, context, precedence, creator, recursion, surround, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
|
-
import {
|
|
5
|
+
import { optimize } from './reference';
|
|
6
|
+
import { trimBlankStart, trimNodeEnd } from '../util';
|
|
6
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
8
|
|
|
8
|
-
export const annotation: AnnotationParser = lazy(() => creator(validate('((',
|
|
9
|
+
export const annotation: AnnotationParser = lazy(() => creator(recursion(precedence(6, validate('((', surround(
|
|
9
10
|
'((',
|
|
10
11
|
guard(context => context.syntax?.inline?.annotation ?? true,
|
|
11
12
|
context({ syntax: { inline: {
|
|
@@ -19,6 +20,8 @@ export const annotation: AnnotationParser = lazy(() => creator(validate('((', ')
|
|
|
19
20
|
//link: true,
|
|
20
21
|
//autolink: true,
|
|
21
22
|
}}, delimiters: undefined },
|
|
22
|
-
|
|
23
|
-
'))'
|
|
24
|
-
|
|
23
|
+
trimBlankStart(some(union([inline]), ')', [[/^\\?\n/, 9], [')', 3], ['))', 6]])))),
|
|
24
|
+
'))',
|
|
25
|
+
false,
|
|
26
|
+
([, ns], rest) => [[html('sup', { class: 'annotation' }, [html('span', trimNodeEnd(defrag(ns)))])], rest],
|
|
27
|
+
([, ns, rest], next) => next[0] === ')' ? undefined : optimize('((', ns, rest)))))));
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { AutolinkParser } from '../../inline';
|
|
2
|
-
import { union, some, validate, focus, rewrite,
|
|
2
|
+
import { union, some, validate, focus, rewrite, precedence, creator, convert, surround, open, lazy } from '../../../combinator';
|
|
3
3
|
import { link } from '../link';
|
|
4
4
|
import { unescsource } from '../../source';
|
|
5
|
+
import { clean } from '../../util';
|
|
5
6
|
|
|
6
7
|
const closer = /^[-+*=~^,.;:!?]*(?=["`|\[\](){}<>]|\\?$)/;
|
|
7
8
|
|
|
@@ -9,14 +10,13 @@ export const url: AutolinkParser.UrlParser = lazy(() => validate(['http://', 'ht
|
|
|
9
10
|
open(
|
|
10
11
|
/^https?:\/\/(?=[\x21-\x7E])/,
|
|
11
12
|
focus(/^[\x21-\x7E]+/, some(union([bracket, some(unescsource, closer)])))),
|
|
12
|
-
context({ syntax: { inline: { link: true } } },
|
|
13
13
|
convert(
|
|
14
14
|
url => `{ ${url} }`,
|
|
15
|
-
union([link]))))));
|
|
15
|
+
clean(union([link]))))));
|
|
16
16
|
|
|
17
|
-
const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => creator(union([
|
|
17
|
+
const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => creator(precedence(3, union([
|
|
18
18
|
surround('(', some(union([bracket, unescsource]), ')'), ')', true),
|
|
19
19
|
surround('[', some(union([bracket, unescsource]), ']'), ']', true),
|
|
20
20
|
surround('{', some(union([bracket, unescsource]), '}'), '}', true),
|
|
21
|
-
surround('"', some(unescsource, '"'), '"', true),
|
|
22
|
-
])));
|
|
21
|
+
surround('"', precedence(8, some(unescsource, '"')), '"', true),
|
|
22
|
+
]))));
|
|
@@ -7,11 +7,9 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
7
7
|
const parser = (source: string) => some(bracket)(source, {});
|
|
8
8
|
|
|
9
9
|
it('(', () => {
|
|
10
|
-
assert.deepStrictEqual(inspect(parser('(')), [['('], '']);
|
|
10
|
+
assert.deepStrictEqual(inspect(parser('(')), [['', '('], '']);
|
|
11
11
|
assert.deepStrictEqual(inspect(parser('()')), [['<span class="paren">()</span>'], '']);
|
|
12
|
-
assert.deepStrictEqual(inspect(parser('(a')), [['(', 'a'], '']);
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('(\\a)')), [['<span class="paren">(a)</span>'], '']);
|
|
14
|
-
assert.deepStrictEqual(inspect(parser(')')), undefined);
|
|
12
|
+
assert.deepStrictEqual(inspect(parser('(a')), [['', '(', 'a'], '']);
|
|
15
13
|
assert.deepStrictEqual(inspect(parser('(0)')), [['(', '0', ')'], '']);
|
|
16
14
|
assert.deepStrictEqual(inspect(parser('(1)')), [['(', '1', ')'], '']);
|
|
17
15
|
assert.deepStrictEqual(inspect(parser('(10)')), [['(', '10', ')'], '']);
|
|
@@ -39,6 +37,9 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
39
37
|
assert.deepStrictEqual(inspect(parser('(Name, Name)')), [['(', 'Name, Name', ')'], '']);
|
|
40
38
|
assert.deepStrictEqual(inspect(parser('(ABBR)')), [['(', 'ABBR', ')'], '']);
|
|
41
39
|
assert.deepStrictEqual(inspect(parser('(ABBR, ABBR)')), [['(', 'ABBR, ABBR', ')'], '']);
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('(\\a)')), [['<span class="paren">(a)</span>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('(==)')), [['<span class="paren">(==)</span>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser(')')), undefined);
|
|
42
43
|
assert.deepStrictEqual(inspect(parser('(1,2)')), [['(', '1,2', ')'], '']);
|
|
43
44
|
assert.deepStrictEqual(inspect(parser('(0-1)')), [['(', '0-1', ')'], '']);
|
|
44
45
|
assert.deepStrictEqual(inspect(parser('(0.1)')), [['(', '0.1', ')'], '']);
|
|
@@ -49,10 +50,11 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
49
50
|
});
|
|
50
51
|
|
|
51
52
|
it('[', () => {
|
|
52
|
-
assert.deepStrictEqual(inspect(parser('[')), [['['], '']);
|
|
53
|
+
assert.deepStrictEqual(inspect(parser('[')), [['', '['], '']);
|
|
53
54
|
assert.deepStrictEqual(inspect(parser('[]')), [['[', ']'], '']);
|
|
54
|
-
assert.deepStrictEqual(inspect(parser('[a')), [['[', 'a'], '']);
|
|
55
|
+
assert.deepStrictEqual(inspect(parser('[a')), [['', '[', 'a'], '']);
|
|
55
56
|
assert.deepStrictEqual(inspect(parser('[a]')), [['[', 'a', ']'], '']);
|
|
57
|
+
assert.deepStrictEqual(inspect(parser('[==]')), [['[', '==', ']'], '']);
|
|
56
58
|
assert.deepStrictEqual(inspect(parser(']')), undefined);
|
|
57
59
|
});
|
|
58
60
|
|
|
@@ -61,6 +63,7 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
61
63
|
assert.deepStrictEqual(inspect(parser('{}')), [['{', '}'], '']);
|
|
62
64
|
assert.deepStrictEqual(inspect(parser('{a')), [['{', 'a'], '']);
|
|
63
65
|
assert.deepStrictEqual(inspect(parser('{a}')), [['{', 'a', '}'], '']);
|
|
66
|
+
assert.deepStrictEqual(inspect(parser('{==}')), [['{', '==', '}'], '']);
|
|
64
67
|
assert.deepStrictEqual(inspect(parser('}')), undefined);
|
|
65
68
|
});
|
|
66
69
|
|
|
@@ -69,7 +72,8 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
69
72
|
assert.deepStrictEqual(inspect(parser('""')), [['"', '"'], '']);
|
|
70
73
|
assert.deepStrictEqual(inspect(parser('"a')), [['"', 'a'], '']);
|
|
71
74
|
assert.deepStrictEqual(inspect(parser('"a"')), [['"', 'a', '"'], '']);
|
|
72
|
-
assert.deepStrictEqual(inspect(parser('"(")"')), [['"', '(', '"'], ')"']);
|
|
75
|
+
assert.deepStrictEqual(inspect(parser('"(")"')), [['"', '', '(', '"'], ')"']);
|
|
76
|
+
assert.deepStrictEqual(inspect(parser('"(("')), [['"', '((', '"'], '']);
|
|
73
77
|
assert.deepStrictEqual(inspect(parser('"(\\")"')), [['"', '<span class="paren">(")</span>', '"'], '']);
|
|
74
78
|
assert.deepStrictEqual(inspect(parser('"(\n)"')), [['"', '<span class="paren">(<br>)</span>', '"'], '']);
|
|
75
79
|
assert.deepStrictEqual(inspect(parser('"(\\\n)"')), [['"', '<span class="paren">(<span class="linebreak"> </span>)</span>', '"'], '']);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { BracketParser } from '../inline';
|
|
3
|
-
import { union, some, creator, surround, lazy } from '../../combinator';
|
|
3
|
+
import { union, some, precedence, creator, surround, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
6
6
|
import { html, defrag } from 'typed-dom/dom';
|
|
@@ -8,23 +8,23 @@ import { unshift, push } from 'spica/array';
|
|
|
8
8
|
|
|
9
9
|
const index = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*/;
|
|
10
10
|
|
|
11
|
-
export const bracket: BracketParser = lazy(() => creator(union([
|
|
12
|
-
surround(str('('), str(index), str(')')),
|
|
13
|
-
surround(str('('), some(inline, ')'), str(')'), true,
|
|
11
|
+
export const bracket: BracketParser = lazy(() => creator(0, union([
|
|
12
|
+
surround(str('('), precedence(3, str(index)), str(')')),
|
|
13
|
+
surround(str('('), precedence(3, some(inline, ')', [[')', 3]])), str(')'), true,
|
|
14
14
|
([as, bs = [], cs], rest) => [[html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))], rest],
|
|
15
|
-
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
16
|
-
surround(str('('), str(new RegExp(index.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)/g, c => c.trimStart() && String.fromCharCode(c.charCodeAt(0) + 0xFEE0)))), str(')')),
|
|
17
|
-
surround(str('('), some(inline, ')'), str(')'), true,
|
|
15
|
+
([as, bs = []], rest) => [unshift([''], unshift(as, bs)), rest]),
|
|
16
|
+
surround(str('('), precedence(3, str(new RegExp(index.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)/g, c => c.trimStart() && String.fromCharCode(c.charCodeAt(0) + 0xFEE0))))), str(')')),
|
|
17
|
+
surround(str('('), precedence(3, some(inline, ')', [[')', 3]])), str(')'), true,
|
|
18
18
|
([as, bs = [], cs], rest) => [[html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))], rest],
|
|
19
19
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
20
|
-
surround(str('['), some(inline, ']'), str(']'), true,
|
|
20
|
+
surround(str('['), precedence(3, some(inline, ']', [[']', 3]])), str(']'), true,
|
|
21
21
|
undefined,
|
|
22
|
-
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
23
|
-
surround(str('{'), some(inline, '}'), str('}'), true,
|
|
22
|
+
([as, bs = []], rest) => [unshift([''], unshift(as, bs)), rest]),
|
|
23
|
+
surround(str('{'), precedence(3, some(inline, '}', [['}', 3]])), str('}'), true,
|
|
24
24
|
undefined,
|
|
25
25
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
26
26
|
// Control media blinking in editing rather than control confusion of pairs of quote marks.
|
|
27
|
-
surround(str('"'), some(inline, '"', '"'), str('"'), true,
|
|
27
|
+
surround(str('"'), precedence(8, some(inline, '"', [['"', 8]])), str('"'), true,
|
|
28
28
|
undefined,
|
|
29
29
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
30
30
|
])));
|
|
@@ -16,12 +16,12 @@ describe('Unit: parser/inline/comment', () => {
|
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('[% ')), [['[%'], '']);
|
|
17
17
|
assert.deepStrictEqual(inspect(parser('[% \n a')), [['[%', '<br>', ' ', 'a'], '']);
|
|
18
18
|
assert.deepStrictEqual(inspect(parser('[%%]')), undefined);
|
|
19
|
-
assert.deepStrictEqual(inspect(parser('[% [%')), [['[%', ' ', '[', '%'], '']);
|
|
19
|
+
assert.deepStrictEqual(inspect(parser('[% [%')), [['[%', ' ', '', '[', '%'], '']);
|
|
20
20
|
assert.deepStrictEqual(inspect(parser('[% [% ')), [['[%', ' ', '[%'], '']);
|
|
21
21
|
assert.deepStrictEqual(inspect(parser('[% [% a')), [['[%', ' ', '[%', ' ', 'a'], '']);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser('[% [% a %]')), [['[%', ' ', '<span class="comment"><input type="checkbox"><span>[% a %]</span></span>'], '']);
|
|
23
|
-
assert.deepStrictEqual(inspect(parser('[% a[%')), [['[%', ' ', 'a', '[', '%'], '']);
|
|
24
|
-
assert.deepStrictEqual(inspect(parser('[% a [%')), [['[%', ' ', 'a', ' ', '[', '%'], '']);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser('[% a[%')), [['[%', ' ', 'a', '', '[', '%'], '']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser('[% a [%')), [['[%', ' ', 'a', ' ', '', '[', '%'], '']);
|
|
25
25
|
assert.deepStrictEqual(inspect(parser('[% a [% ')), [['[%', ' ', 'a', ' ', '[%'], '']);
|
|
26
26
|
assert.deepStrictEqual(inspect(parser('[% a [% b')), [['[%', ' ', 'a', ' ', '[%', ' ', 'b'], '']);
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('[% a [%% b')), [['[%', ' ', 'a', ' ', '[%%', ' ', 'b'], '']);
|
|
@@ -55,6 +55,7 @@ describe('Unit: parser/inline/comment', () => {
|
|
|
55
55
|
assert.deepStrictEqual(inspect(parser('[% &a; %]')), [['<span class="comment"><input type="checkbox"><span>[% <span class="invalid">&a;</span> %]</span></span>'], '']);
|
|
56
56
|
assert.deepStrictEqual(inspect(parser('[% © %]')), [['<span class="comment"><input type="checkbox"><span>[% © %]</span></span>'], '']);
|
|
57
57
|
assert.deepStrictEqual(inspect(parser('[% &copy; %]')), [['<span class="comment"><input type="checkbox"><span>[% &copy; %]</span></span>'], '']);
|
|
58
|
+
assert.deepStrictEqual(inspect(parser('[% [ %]')), [['<span class="comment"><input type="checkbox"><span>[% [ %]</span></span>'], '']);
|
|
58
59
|
assert.deepStrictEqual(inspect(parser('[% \\ a %]')), [['<span class="comment"><input type="checkbox"><span>[% a %]</span></span>'], '']);
|
|
59
60
|
});
|
|
60
61
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { CommentParser } from '../inline';
|
|
2
|
-
import { union, some, validate, creator, surround, open, close, match, lazy } from '../../combinator';
|
|
2
|
+
import { union, some, validate, precedence, creator, surround, open, close, match, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { text, str } from '../source';
|
|
5
5
|
import { html, defrag } from 'typed-dom/dom';
|
|
6
6
|
import { memoize } from 'spica/memoize';
|
|
7
7
|
import { unshift, push } from 'spica/array';
|
|
8
8
|
|
|
9
|
-
export const comment: CommentParser = lazy(() =>
|
|
9
|
+
export const comment: CommentParser = lazy(() => validate('[%', creator(precedence(4, match(
|
|
10
10
|
/^\[(%+)\s/,
|
|
11
11
|
memoize(
|
|
12
12
|
([, fence]) =>
|
|
13
13
|
surround(
|
|
14
14
|
open(str(`[${fence}`), some(text, new RegExp(String.raw`^\s+${fence}\]|^\S`)), true),
|
|
15
|
-
some(union([inline]), new RegExp(String.raw`^\s+${fence}\]`)),
|
|
15
|
+
some(union([inline]), new RegExp(String.raw`^\s+${fence}\]`), [[new RegExp(String.raw`^\s+${fence}\]`), 4]]),
|
|
16
16
|
close(some(text, /^\S/), str(`${fence}]`)), true,
|
|
17
17
|
([as, bs = [], cs], rest) => [[
|
|
18
18
|
html('span', { class: 'comment' }, [
|
|
@@ -21,4 +21,4 @@ export const comment: CommentParser = lazy(() => creator(validate('[%', match(
|
|
|
21
21
|
]),
|
|
22
22
|
], rest],
|
|
23
23
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
24
|
-
([, fence]) => fence.length, [])))));
|
|
24
|
+
([, fence]) => fence.length, []))))));
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { DeletionParser } from '../inline';
|
|
2
|
-
import { union, some, creator, surround, open, lazy } from '../../combinator';
|
|
2
|
+
import { union, some, precedence, creator, surround, open, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
5
|
import { blankWith } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
9
|
-
export const deletion: DeletionParser = lazy(() => creator(surround(
|
|
9
|
+
export const deletion: DeletionParser = lazy(() => creator(precedence(2, surround(
|
|
10
10
|
str('~~'),
|
|
11
11
|
some(union([
|
|
12
12
|
some(inline, blankWith('\n', '~~')),
|
|
@@ -14,4 +14,4 @@ export const deletion: DeletionParser = lazy(() => creator(surround(
|
|
|
14
14
|
])),
|
|
15
15
|
str('~~'), false,
|
|
16
16
|
([, bs], rest) => [[html('del', defrag(bs))], rest],
|
|
17
|
-
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
17
|
+
([as, bs], rest) => [unshift(as, bs), rest]))));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EmphasisParser } from '../inline';
|
|
2
|
-
import { union, some, creator, surround, open, lazy } from '../../combinator';
|
|
2
|
+
import { union, some, precedence, creator, surround, open, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { emstrong } from './emstrong';
|
|
5
5
|
import { strong } from './strong';
|
|
@@ -8,7 +8,7 @@ import { startTight, blankWith } from '../util';
|
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
import { unshift } from 'spica/array';
|
|
10
10
|
|
|
11
|
-
export const emphasis: EmphasisParser = lazy(() => creator(surround(
|
|
11
|
+
export const emphasis: EmphasisParser = lazy(() => creator(precedence(1, surround(
|
|
12
12
|
str('*'),
|
|
13
13
|
startTight(some(union([
|
|
14
14
|
strong,
|
|
@@ -21,4 +21,4 @@ export const emphasis: EmphasisParser = lazy(() => creator(surround(
|
|
|
21
21
|
])), '*'),
|
|
22
22
|
str('*'), false,
|
|
23
23
|
([, bs], rest) => [[html('em', defrag(bs))], rest],
|
|
24
|
-
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
24
|
+
([as, bs], rest) => [unshift(as, bs), rest]))));
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { MarkdownParser } from '../../../markdown';
|
|
2
1
|
import { EmStrongParser, EmphasisParser, StrongParser } from '../inline';
|
|
3
2
|
import { Result, IntermediateParser } from '../../combinator/data/parser';
|
|
4
|
-
import { union, some, creator, surround, open, lazy, bind } from '../../combinator';
|
|
3
|
+
import { union, some, precedence, creator, surround, open, lazy, bind } from '../../combinator';
|
|
5
4
|
import { inline } from '../inline';
|
|
6
5
|
import { strong } from './strong';
|
|
7
6
|
import { emphasis } from './emphasis';
|
|
@@ -27,14 +26,14 @@ const subemphasis: IntermediateParser<EmphasisParser> = lazy(() => some(union([
|
|
|
27
26
|
])),
|
|
28
27
|
])));
|
|
29
28
|
|
|
30
|
-
export const emstrong: EmStrongParser = lazy(() => creator(surround(
|
|
29
|
+
export const emstrong: EmStrongParser = lazy(() => creator(precedence(1, surround(
|
|
31
30
|
str('***'),
|
|
32
31
|
startTight(some(union([
|
|
33
32
|
some(inline, blankWith('*')),
|
|
34
33
|
open(some(inline, '*'), inline),
|
|
35
34
|
]))),
|
|
36
35
|
str(/^\*{1,3}/), false,
|
|
37
|
-
([, bs, cs], rest, context): Result<HTMLElement | string,
|
|
36
|
+
([, bs, cs], rest, context): Result<HTMLElement | string, typeof context> => {
|
|
38
37
|
assert(cs.length === 1);
|
|
39
38
|
switch (cs[0]) {
|
|
40
39
|
case '***':
|
|
@@ -58,4 +57,4 @@ export const emstrong: EmStrongParser = lazy(() => creator(surround(
|
|
|
58
57
|
}
|
|
59
58
|
assert(false);
|
|
60
59
|
},
|
|
61
|
-
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
60
|
+
([as, bs], rest) => [unshift(as, bs), rest]))));
|
|
@@ -52,6 +52,7 @@ describe('Unit: parser/inline/extension/index', () => {
|
|
|
52
52
|
assert.deepStrictEqual(inspect(parser('[#\\]]')), [['<a class="index" href="#index:]">]</a>'], '']);
|
|
53
53
|
assert.deepStrictEqual(inspect(parser('[#\\\\]')), [['<a class="index" href="#index:\\">\\</a>'], '']);
|
|
54
54
|
assert.deepStrictEqual(inspect(parser('[#A]')), [['<a class="index" href="#index:A">A</a>'], '']);
|
|
55
|
+
assert.deepStrictEqual(inspect(parser('[#==]')), [['<a class="index" href="#index:==">==</a>'], '']);
|
|
55
56
|
assert.deepStrictEqual(inspect(parser('[#*A*]')), [['<a class="index" href="#index:A"><em>A</em></a>'], '']);
|
|
56
57
|
assert.deepStrictEqual(inspect(parser('[#`A`]')), [['<a class="index" href="#index:`A`"><code data-src="`A`">A</code></a>'], '']);
|
|
57
58
|
assert.deepStrictEqual(inspect(parser('[#${A}$]')), [['<a class="index" href="#index:${A}$"><span class="math" translate="no" data-src="${A}$">${A}$</span></a>'], '']);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { ExtensionParser } from '../../inline';
|
|
3
|
-
import { union, some, validate, guard, context, creator, surround, open, lazy, fmap } from '../../../combinator';
|
|
3
|
+
import { union, some, validate, guard, context, precedence, creator, surround, open, lazy, fmap } from '../../../combinator';
|
|
4
4
|
import { inline } from '../../inline';
|
|
5
5
|
import { indexee, identity } from './indexee';
|
|
6
6
|
import { txt, str, stropt } from '../../source';
|
|
@@ -9,7 +9,7 @@ import { html, define, defrag } from 'typed-dom/dom';
|
|
|
9
9
|
|
|
10
10
|
import IndexParser = ExtensionParser.IndexParser;
|
|
11
11
|
|
|
12
|
-
export const index: IndexParser = lazy(() =>
|
|
12
|
+
export const index: IndexParser = lazy(() => validate('[#', creator(precedence(3, fmap(indexee(surround(
|
|
13
13
|
'[#',
|
|
14
14
|
guard(context => context.syntax?.inline?.index ?? true,
|
|
15
15
|
startTight(
|
|
@@ -25,9 +25,10 @@ export const index: IndexParser = lazy(() => creator(validate('[#', ']', '\n', f
|
|
|
25
25
|
open(stropt(/^\|?/), trimBlankEnd(some(union([
|
|
26
26
|
signature,
|
|
27
27
|
inline,
|
|
28
|
-
]), ']', /^\\?\n
|
|
29
|
-
']'
|
|
30
|
-
|
|
28
|
+
]), ']', [[/^\\?\n/, 9], [']', 3]])), true)))),
|
|
29
|
+
']',
|
|
30
|
+
false,
|
|
31
|
+
([, ns], rest) => [[html('a', defrag(ns))], rest])),
|
|
31
32
|
([el]: [HTMLAnchorElement]) => [
|
|
32
33
|
define(el,
|
|
33
34
|
{
|
|
@@ -36,7 +37,7 @@ export const index: IndexParser = lazy(() => creator(validate('[#', ']', '\n', f
|
|
|
36
37
|
href: el.id ? `#${el.id}` : undefined,
|
|
37
38
|
},
|
|
38
39
|
el.childNodes),
|
|
39
|
-
]))));
|
|
40
|
+
])))));
|
|
40
41
|
|
|
41
42
|
const signature: IndexParser.SignatureParser = lazy(() => creator(fmap(open(
|
|
42
43
|
'|#',
|
|
@@ -49,5 +50,5 @@ const bracket: IndexParser.SignatureParser.BracketParser = lazy(() => creator(un
|
|
|
49
50
|
surround(str('('), some(union([bracket, txt]), ')'), str(')'), true),
|
|
50
51
|
surround(str('['), some(union([bracket, txt]), ']'), str(']'), true),
|
|
51
52
|
surround(str('{'), some(union([bracket, txt]), '}'), str('}'), true),
|
|
52
|
-
surround(str('"'), some(txt, '"'), str('"'), true),
|
|
53
|
+
surround(str('"'), precedence(8, some(txt, '"')), str('"'), true),
|
|
53
54
|
])));
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
|
-
import { union, verify, focus, creator,
|
|
2
|
+
import { union, verify, focus, creator, surround, fmap } from '../../../combinator';
|
|
3
3
|
import { index } from './index';
|
|
4
|
+
import { clean } from '../../util';
|
|
4
5
|
import { html } from 'typed-dom/dom';
|
|
5
6
|
|
|
6
7
|
export const indexer: ExtensionParser.IndexerParser = creator(fmap(verify(surround(
|
|
7
8
|
/^\s+(?=\[#\S)/,
|
|
8
|
-
|
|
9
|
-
index: true,
|
|
10
|
-
}}},
|
|
11
|
-
union([
|
|
9
|
+
clean(union([
|
|
12
10
|
focus('[#]', () => [[html('a', { href: '#' })], '']),
|
|
13
11
|
index,
|
|
14
12
|
])),
|
|
@@ -11,7 +11,7 @@ export const segment: ExtensionParser.LabelParser.SegmentParser = clear(validate
|
|
|
11
11
|
body,
|
|
12
12
|
])));
|
|
13
13
|
|
|
14
|
-
export const label: ExtensionParser.LabelParser =
|
|
14
|
+
export const label: ExtensionParser.LabelParser = validate(['[$', '$'], creator(fmap(
|
|
15
15
|
guard(context => context.syntax?.inline?.label ?? true,
|
|
16
16
|
union([
|
|
17
17
|
surround('[', body, ']'),
|
|
@@ -21,13 +21,13 @@ describe('Unit: parser/inline/extension/placeholder', () => {
|
|
|
21
21
|
assert.deepStrictEqual(inspect(parser('[^\na]')), undefined);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser('[^\\\na]')), undefined);
|
|
23
23
|
assert.deepStrictEqual(inspect(parser('[^ !http://host]')), undefined);
|
|
24
|
-
assert.deepStrictEqual(inspect(parser('[^a')),
|
|
25
|
-
assert.deepStrictEqual(inspect(parser('[^a\n]')),
|
|
26
|
-
assert.deepStrictEqual(inspect(parser('[^a\n\n]')),
|
|
27
|
-
assert.deepStrictEqual(inspect(parser('[^a\\\n]')),
|
|
28
|
-
assert.deepStrictEqual(inspect(parser('[^a\\\n\\\n]')),
|
|
29
|
-
assert.deepStrictEqual(inspect(parser('[^a\nb]')),
|
|
30
|
-
assert.deepStrictEqual(inspect(parser('[^a\\\nb]')),
|
|
24
|
+
assert.deepStrictEqual(inspect(parser('[^a')), [['[^', 'a'], '']);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser('[^a\n]')), [['[^', 'a'], '\n]']);
|
|
26
|
+
assert.deepStrictEqual(inspect(parser('[^a\n\n]')), [['[^', 'a'], '\n\n]']);
|
|
27
|
+
assert.deepStrictEqual(inspect(parser('[^a\\\n]')), [['[^', 'a'], '\\\n]']);
|
|
28
|
+
assert.deepStrictEqual(inspect(parser('[^a\\\n\\\n]')), [['[^', 'a'], '\\\n\\\n]']);
|
|
29
|
+
assert.deepStrictEqual(inspect(parser('[^a\nb]')), [['[^', 'a'], '\nb]']);
|
|
30
|
+
assert.deepStrictEqual(inspect(parser('[^a\\\nb]')), [['[^', 'a'], '\\\nb]']);
|
|
31
31
|
assert.deepStrictEqual(inspect(parser('[[]')), undefined);
|
|
32
32
|
assert.deepStrictEqual(inspect(parser('[]]')), undefined);
|
|
33
33
|
assert.deepStrictEqual(inspect(parser('[[]]')), undefined);
|
|
@@ -45,6 +45,7 @@ describe('Unit: parser/inline/extension/placeholder', () => {
|
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('[^a\\ \\ ]')), [['<span class="invalid">a </span>'], '']);
|
|
46
46
|
assert.deepStrictEqual(inspect(parser('[^a<wbr>]')), [['<span class="invalid">a<wbr></span>'], '']);
|
|
47
47
|
assert.deepStrictEqual(inspect(parser('[^a<wbr><wbr>]')), [['<span class="invalid">a<wbr><wbr></span>'], '']);
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('[^==]')), [['<span class="invalid">==</span>'], '']);
|
|
48
49
|
assert.deepStrictEqual(inspect(parser('[^a[% b %]]')), [['<span class="invalid">a<span class="comment"><input type="checkbox"><span>[% b %]</span></span></span>'], '']);
|
|
49
50
|
assert.deepStrictEqual(inspect(parser('[^a[% b %][% c %]]')), [['<span class="invalid">a<span class="comment"><input type="checkbox"><span>[% b %]</span></span><span class="comment"><input type="checkbox"><span>[% c %]</span></span></span>'], '']);
|
|
50
51
|
assert.deepStrictEqual(inspect(parser('[^\\]]')), [['<span class="invalid">]</span>'], '']);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
|
-
import { union, some, validate, creator, surround, lazy } from '../../../combinator';
|
|
2
|
+
import { union, some, validate, precedence, creator, surround, lazy } from '../../../combinator';
|
|
3
3
|
import { inline } from '../../inline';
|
|
4
4
|
import { str } from '../../source';
|
|
5
5
|
import { startTight } from '../../util';
|
|
@@ -10,9 +10,9 @@ import { unshift } from 'spica/array';
|
|
|
10
10
|
|
|
11
11
|
// All syntax surrounded by square brackets shouldn't contain line breaks.
|
|
12
12
|
|
|
13
|
-
export const placeholder: ExtensionParser.PlaceholderParser = lazy(() =>
|
|
13
|
+
export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => validate(['[:', '[^'], creator(precedence(3, surround(
|
|
14
14
|
str(/^\[[:^]/),
|
|
15
|
-
startTight(some(union([inline]), ']')),
|
|
15
|
+
startTight(some(union([inline]), ']', [[/^\\?\n/, 9], [']', 3]])),
|
|
16
16
|
str(']'), false,
|
|
17
17
|
([as, bs], rest) => [[
|
|
18
18
|
html('span', {
|
|
@@ -22,4 +22,4 @@ export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => creator
|
|
|
22
22
|
'data-invalid-message': `Reserved start symbol "${as[0][1]}" cannot be used in "[]"`,
|
|
23
23
|
}, defrag(bs)),
|
|
24
24
|
], rest],
|
|
25
|
-
([as, bs], rest) => [unshift(as, bs), rest]))));
|
|
25
|
+
([as, bs], rest) => [unshift(as, bs), rest])))));
|
|
@@ -25,6 +25,7 @@ describe('Unit: parser/inline/html', () => {
|
|
|
25
25
|
assert.deepStrictEqual(inspect(parser('<a,b>')), undefined);
|
|
26
26
|
assert.deepStrictEqual(inspect(parser('<a, b>')), undefined);
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('<T>')), undefined);
|
|
28
|
+
assert.deepStrictEqual(inspect(parser('<bdi>')), [['<span class="invalid"><bdi></span>'], '']);
|
|
28
29
|
assert.deepStrictEqual(inspect(parser('<bdi>z')), [['<span class="invalid"><bdi>z</span>'], '']);
|
|
29
30
|
assert.deepStrictEqual(inspect(parser('<bdi></bdi>')), [['<span class="invalid"><bdi></bdi></span>'], '']);
|
|
30
31
|
assert.deepStrictEqual(inspect(parser('<bdi> </bdi>')), [['<span class="invalid"><bdi> </bdi></span>'], '']);
|
|
@@ -76,6 +77,7 @@ describe('Unit: parser/inline/html', () => {
|
|
|
76
77
|
});
|
|
77
78
|
|
|
78
79
|
it('nest', () => {
|
|
80
|
+
assert.deepStrictEqual(inspect(parser('<bdi>[% </bdi>')), [['<bdi>[% </bdi>'], '']);
|
|
79
81
|
assert.deepStrictEqual(inspect(parser('<bdi><bdi>a</bdi></bdi>')), [['<bdi><bdi>a</bdi></bdi>'], '']);
|
|
80
82
|
assert.deepStrictEqual(inspect(parser('<bdi>a<bdi>b</bdi>c</bdi>')), [['<bdi>a<bdi>b</bdi>c</bdi>'], '']);
|
|
81
83
|
assert.deepStrictEqual(inspect(parser('<bdi>`a`</bdi>')), [['<bdi><code data-src="`a`">a</code></bdi>'], '']);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { undefined, Object } from 'spica/global';
|
|
2
2
|
import { HTMLParser } from '../inline';
|
|
3
|
-
import { union, subsequence, some, validate, focus, creator, surround, open, match, lazy } from '../../combinator';
|
|
3
|
+
import { union, subsequence, some, validate, focus, precedence, creator, surround, open, match, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
6
6
|
import { isStartLooseNodes, blankWith } from '../util';
|
|
@@ -18,7 +18,7 @@ const attrspecs = {
|
|
|
18
18
|
Object.setPrototypeOf(attrspecs, null);
|
|
19
19
|
Object.values(attrspecs).forEach(o => Object.setPrototypeOf(o, null));
|
|
20
20
|
|
|
21
|
-
export const html: HTMLParser = lazy(() =>
|
|
21
|
+
export const html: HTMLParser = lazy(() => validate('<', validate(/^<[a-z]+(?=[^\S\n]|>)/, creator(precedence(5, union([
|
|
22
22
|
focus(
|
|
23
23
|
'<wbr>',
|
|
24
24
|
() => [[h('wbr')], '']),
|
|
@@ -34,7 +34,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
|
|
|
34
34
|
str(`<${tag}`), some(attribute), str(/^[^\S\n]*>/), true),
|
|
35
35
|
subsequence([
|
|
36
36
|
focus(/^[^\S\n]*\n/, some(inline)),
|
|
37
|
-
some(open(/^\n?/, some(inline, blankWith('\n', `</${tag}>`)), true)),
|
|
37
|
+
some(open(/^\n?/, some(inline, blankWith('\n', `</${tag}>`), [[blankWith('\n', `</${tag}>`), 5]]), true)),
|
|
38
38
|
]),
|
|
39
39
|
str(`</${tag}>`), true,
|
|
40
40
|
([as, bs = [], cs], rest) =>
|
|
@@ -50,7 +50,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
|
|
|
50
50
|
str(`<${tag}`), some(attribute), str(/^[^\S\n]*>/), true),
|
|
51
51
|
subsequence([
|
|
52
52
|
focus(/^[^\S\n]*\n/, some(inline)),
|
|
53
|
-
some(inline, `</${tag}
|
|
53
|
+
some(inline, `</${tag}>`, [[`</${tag}>`, 5]]),
|
|
54
54
|
]),
|
|
55
55
|
str(`</${tag}>`), true,
|
|
56
56
|
([as, bs = [], cs], rest) =>
|
|
@@ -59,7 +59,7 @@ export const html: HTMLParser = lazy(() => creator(validate('<', validate(/^<[a-
|
|
|
59
59
|
[[elem(tag, as, bs, [])], rest]),
|
|
60
60
|
([, tag]) => tag,
|
|
61
61
|
new Cache(10000))),
|
|
62
|
-
])))));
|
|
62
|
+
]))))));
|
|
63
63
|
|
|
64
64
|
export const attribute: HTMLParser.TagParser.AttributeParser = union([
|
|
65
65
|
str(/^[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[^\S\n]|>)/),
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { InsertionParser } from '../inline';
|
|
2
|
-
import { union, some, creator, surround, open, lazy } from '../../combinator';
|
|
2
|
+
import { union, some, precedence, creator, surround, open, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
5
|
import { blankWith } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
9
|
-
export const insertion: InsertionParser = lazy(() => creator(surround(
|
|
9
|
+
export const insertion: InsertionParser = lazy(() => creator(precedence(2, surround(
|
|
10
10
|
str('++'),
|
|
11
11
|
some(union([
|
|
12
12
|
some(inline, blankWith('\n', '++')),
|
|
@@ -14,4 +14,4 @@ export const insertion: InsertionParser = lazy(() => creator(surround(
|
|
|
14
14
|
])),
|
|
15
15
|
str('++'), false,
|
|
16
16
|
([, bs], rest) => [[html('ins', defrag(bs))], rest],
|
|
17
|
-
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
17
|
+
([as, bs], rest) => [unshift(as, bs), rest]))));
|
|
@@ -151,6 +151,7 @@ describe('Unit: parser/inline/link', () => {
|
|
|
151
151
|
});
|
|
152
152
|
|
|
153
153
|
it('nest', () => {
|
|
154
|
+
assert.deepStrictEqual(inspect(parser('[*]{/}')), [['<a href="/">*</a>'], '']);
|
|
154
155
|
assert.deepStrictEqual(inspect(parser('[\\[]{/}')), [['<a href="/">[</a>'], '']);
|
|
155
156
|
assert.deepStrictEqual(inspect(parser('[\\]]{/}')), [['<a href="/">]</a>'], '']);
|
|
156
157
|
assert.deepStrictEqual(inspect(parser('[[]{a}]{a}')), [['<a href="a">[]{a}</a>'], '']);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { undefined, location, encodeURI, decodeURI, Location } from 'spica/global';
|
|
2
2
|
import { LinkParser } from '../inline';
|
|
3
3
|
import { eval } from '../../combinator/data/parser';
|
|
4
|
-
import { union, inits, tails, some, validate, guard, context, creator, surround, open, dup, reverse, lazy, fmap, bind } from '../../combinator';
|
|
4
|
+
import { union, inits, tails, some, validate, guard, context, precedence, creator, surround, open, dup, reverse, lazy, fmap, bind } from '../../combinator';
|
|
5
5
|
import { inline, media, shortmedia } from '../inline';
|
|
6
6
|
import { attributes } from './html';
|
|
7
7
|
import { autolink } from '../autolink';
|
|
8
8
|
import { str } from '../source';
|
|
9
|
-
import {
|
|
9
|
+
import { trimBlankStart, trimNodeEnd, stringify } from '../util';
|
|
10
10
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
11
11
|
import { ReadonlyURL } from 'spica/url';
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ const optspec = {
|
|
|
15
15
|
} as const;
|
|
16
16
|
Object.setPrototypeOf(optspec, null);
|
|
17
17
|
|
|
18
|
-
export const link: LinkParser = lazy(() =>
|
|
18
|
+
export const link: LinkParser = lazy(() => validate(['[', '{'], creator(10, precedence(3, bind(
|
|
19
19
|
guard(context => context.syntax?.inline?.link ?? true,
|
|
20
20
|
reverse(tails([
|
|
21
21
|
context({ syntax: { inline: {
|
|
@@ -36,7 +36,7 @@ export const link: LinkParser = lazy(() => creator(10, validate(['[', '{'], '}',
|
|
|
36
36
|
media: false,
|
|
37
37
|
autolink: false,
|
|
38
38
|
}}},
|
|
39
|
-
|
|
39
|
+
trimBlankStart(some(inline, ']', [[/^\\?\n/, 9], [']', 3]]))),
|
|
40
40
|
']',
|
|
41
41
|
true),
|
|
42
42
|
]))),
|
|
@@ -44,6 +44,7 @@ export const link: LinkParser = lazy(() => creator(10, validate(['[', '{'], '}',
|
|
|
44
44
|
]))),
|
|
45
45
|
([params, content = []]: [string[], (HTMLElement | string)[]], rest, context) => {
|
|
46
46
|
assert(params.every(p => typeof p === 'string'));
|
|
47
|
+
content = trimNodeEnd(content);
|
|
47
48
|
if (eval(some(autolink)(stringify(content), context))?.some(node => typeof node === 'object')) return;
|
|
48
49
|
assert(!html('div', content).querySelector('a, .media, .annotation, .reference') || (content[0] as HTMLElement).matches('.media'));
|
|
49
50
|
const INSECURE_URI = params.shift()!;
|
|
@@ -59,7 +60,7 @@ export const link: LinkParser = lazy(() => creator(10, validate(['[', '{'], '}',
|
|
|
59
60
|
if (el.classList.contains('invalid')) return [[el], rest];
|
|
60
61
|
assert(el.classList.length === 0);
|
|
61
62
|
return [[define(el, attributes('link', [], optspec, params))], rest];
|
|
62
|
-
}))));
|
|
63
|
+
})))));
|
|
63
64
|
|
|
64
65
|
export const uri: LinkParser.ParameterParser.UriParser = union([
|
|
65
66
|
open(/^[^\S\n]+/, str(/^\S+/)),
|
|
@@ -89,8 +90,8 @@ export function resolve(uri: string, host: URL | Location, source: URL | Locatio
|
|
|
89
90
|
default:
|
|
90
91
|
const target = new ReadonlyURL(uri, source.href);
|
|
91
92
|
return target.origin === host.origin
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
? target.href.slice(target.origin.length)
|
|
94
|
+
: target.href;
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
|