securemark 0.260.4 → 0.261.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 +12 -0
- package/README.md +12 -12
- package/design.md +0 -4
- package/dist/index.js +268 -243
- package/markdown.d.ts +7 -23
- package/package.json +6 -6
- package/src/combinator/data/parser/context/memo.ts +4 -0
- package/src/combinator/data/parser/context.ts +25 -16
- package/src/combinator/data/parser.ts +0 -1
- package/src/parser/api/bind.ts +2 -1
- package/src/parser/api/parse.test.ts +1 -1
- package/src/parser/api/parse.ts +2 -1
- package/src/parser/block/blockquote.test.ts +2 -2
- package/src/parser/block/dlist.test.ts +1 -1
- package/src/parser/block/extension/example.test.ts +1 -1
- package/src/parser/block/extension/fig.test.ts +1 -1
- package/src/parser/block/heading.test.ts +2 -2
- package/src/parser/block/paragraph.test.ts +1 -4
- package/src/parser/block/reply/cite.test.ts +5 -0
- package/src/parser/block/reply/cite.ts +5 -4
- package/src/parser/context.ts +8 -7
- package/src/parser/inline/autolink/anchor.test.ts +1 -0
- package/src/parser/inline/autolink/email.test.ts +3 -0
- package/src/parser/inline/autolink/email.ts +1 -1
- package/src/parser/inline/autolink/hashnum.test.ts +1 -2
- package/src/parser/inline/autolink/hashnum.ts +1 -1
- package/src/parser/inline/autolink/hashtag.test.ts +15 -12
- package/src/parser/inline/autolink/hashtag.ts +3 -3
- package/src/parser/inline/autolink/url.test.ts +1 -1
- package/src/parser/inline/autolink/url.ts +1 -1
- package/src/parser/inline/autolink.ts +14 -5
- package/src/parser/inline/deletion.test.ts +2 -2
- package/src/parser/inline/emphasis.test.ts +26 -35
- package/src/parser/inline/emphasis.ts +5 -12
- package/src/parser/inline/escape.ts +1 -10
- package/src/parser/inline/extension/index.test.ts +2 -2
- package/src/parser/inline/extension/index.ts +1 -1
- package/src/parser/inline/insertion.test.ts +2 -2
- package/src/parser/inline/link.test.ts +1 -1
- package/src/parser/inline/link.ts +2 -2
- package/src/parser/inline/mark.test.ts +1 -1
- package/src/parser/inline/media.ts +2 -2
- package/src/parser/inline/ruby.ts +10 -6
- package/src/parser/inline/strong.test.ts +25 -32
- package/src/parser/inline/strong.ts +4 -8
- package/src/parser/inline/template.ts +1 -1
- package/src/parser/inline.test.ts +18 -91
- package/src/parser/inline.ts +0 -3
- package/src/parser/locale/ja.ts +1 -9
- package/src/parser/locale.test.ts +1 -1
- package/src/parser/source/text.test.ts +9 -4
- package/src/parser/source/text.ts +9 -16
- package/src/parser/inline/emstrong.ts +0 -62
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AutolinkParser } from '../inline';
|
|
2
|
-
import { union, some, syntax, constraint, validate, fmap } from '../../combinator';
|
|
2
|
+
import { union, some, syntax, constraint, validate, focus, fmap } from '../../combinator';
|
|
3
3
|
import { url } from './autolink/url';
|
|
4
4
|
import { email } from './autolink/email';
|
|
5
5
|
import { channel } from './autolink/channel';
|
|
@@ -14,22 +14,31 @@ import { stringify } from '../util';
|
|
|
14
14
|
export const autolink: AutolinkParser = fmap(
|
|
15
15
|
validate(/^(?:[@#>0-9a-z]|\S[#>])/i,
|
|
16
16
|
constraint(State.autolink, false,
|
|
17
|
-
syntax(Syntax.autolink, 1, 1, State.
|
|
17
|
+
syntax(Syntax.autolink, 1, 1, ~State.shortcut,
|
|
18
18
|
some(union([
|
|
19
19
|
url,
|
|
20
20
|
email,
|
|
21
21
|
// Escape unmatched email-like strings.
|
|
22
|
-
|
|
22
|
+
focus(
|
|
23
|
+
/^[0-9a-z](?:[_.+-](?=[0-9a-z])|[0-9a-z])*(?:@(?:[0-9a-z]+(?:[.-][0-9a-z]+)*)?)*/i,
|
|
24
|
+
({ source }) => {
|
|
25
|
+
if (source.length > 255 || source.includes('@')) return [[source], ''];
|
|
26
|
+
const i = source.indexOf('_');
|
|
27
|
+
if (i === -1) return [[source], ''];
|
|
28
|
+
return [[source.slice(0, i)], source.slice(i)];
|
|
29
|
+
}),
|
|
23
30
|
channel,
|
|
24
31
|
account,
|
|
25
32
|
// Escape unmatched account-like strings.
|
|
26
33
|
str(/^@+[0-9a-z]*(?:-[0-9a-z]+)*/i),
|
|
27
34
|
// Escape invalid leading characters.
|
|
28
|
-
str(new RegExp(/^(?:[^\p{C}\p{S}\p{P}\s]|emoji
|
|
35
|
+
str(new RegExp(/^(?:[^\p{C}\p{S}\p{P}\s]|emoji)(?=#)/u.source.replace('emoji', emoji), 'u')),
|
|
29
36
|
hashtag,
|
|
30
37
|
hashnum,
|
|
31
38
|
// Escape unmatched hashtag-like strings.
|
|
32
|
-
str(new RegExp(/^#+(?:[^\p{C}\p{S}\p{P}\s]|emoji|
|
|
39
|
+
str(new RegExp(/^#+(?:[^\p{C}\p{S}\p{P}\s]|emoji|')*/u.source.replace('emoji', emoji), 'u')),
|
|
40
|
+
// Escape invalid leading characters.
|
|
41
|
+
str(/^[0-9\p{Sc}](?=>)/u),
|
|
33
42
|
anchor,
|
|
34
43
|
]))))),
|
|
35
44
|
ns => ns.length === 1 ? ns : [stringify(ns)]);
|
|
@@ -37,8 +37,8 @@ describe('Unit: parser/inline/deletion', () => {
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
it('nest', () => {
|
|
40
|
-
assert.deepStrictEqual(inspect(parser('
|
|
41
|
-
assert.deepStrictEqual(inspect(parser('
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('~~_~~a~~_~~')), [['<del><em><del>a</del></em></del>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('~~_++a++_~~')), [['<del><em><ins>a</ins></em></del>'], '']);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
});
|
|
@@ -7,47 +7,38 @@ describe('Unit: parser/inline/emphasis', () => {
|
|
|
7
7
|
const parser = (source: string) => some(emphasis)({ source, context: {} });
|
|
8
8
|
|
|
9
9
|
it('invalid', () => {
|
|
10
|
-
assert.deepStrictEqual(inspect(parser('
|
|
11
|
-
assert.deepStrictEqual(inspect(parser('
|
|
12
|
-
assert.deepStrictEqual(inspect(parser('
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('
|
|
14
|
-
assert.deepStrictEqual(inspect(parser('
|
|
15
|
-
assert.deepStrictEqual(inspect(parser('
|
|
16
|
-
assert.deepStrictEqual(inspect(parser('
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('
|
|
18
|
-
assert.deepStrictEqual(inspect(parser('
|
|
19
|
-
assert.deepStrictEqual(inspect(parser('
|
|
20
|
-
assert.deepStrictEqual(inspect(parser('
|
|
21
|
-
assert.deepStrictEqual(inspect(parser('
|
|
22
|
-
assert.deepStrictEqual(inspect(parser('
|
|
23
|
-
assert.deepStrictEqual(inspect(parser('
|
|
24
|
-
assert.deepStrictEqual(inspect(parser('
|
|
25
|
-
assert.deepStrictEqual(inspect(parser('
|
|
26
|
-
assert.deepStrictEqual(inspect(parser('*<wbr>a*')), undefined);
|
|
27
|
-
assert.deepStrictEqual(inspect(parser('**a**')), undefined);
|
|
28
|
-
assert.deepStrictEqual(inspect(parser('***a***')), undefined);
|
|
29
|
-
assert.deepStrictEqual(inspect(parser(' *a*')), undefined);
|
|
10
|
+
assert.deepStrictEqual(inspect(parser('_')), undefined);
|
|
11
|
+
assert.deepStrictEqual(inspect(parser('_a')), [['_', 'a'], '']);
|
|
12
|
+
assert.deepStrictEqual(inspect(parser('_a _')), [['_', 'a'], ' _']);
|
|
13
|
+
assert.deepStrictEqual(inspect(parser('_a _')), [['_', 'a', ' '], ' _']);
|
|
14
|
+
assert.deepStrictEqual(inspect(parser('_a\n_')), [['_', 'a'], '\n_']);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('_a\\ _')), [['_', 'a'], '\\ _']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('_a\\\n_')), [['_', 'a'], '\\\n_']);
|
|
17
|
+
assert.deepStrictEqual(inspect(parser('_ _')), undefined);
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('_ a_')), undefined);
|
|
19
|
+
assert.deepStrictEqual(inspect(parser('_ a _')), undefined);
|
|
20
|
+
assert.deepStrictEqual(inspect(parser('_\n_')), undefined);
|
|
21
|
+
assert.deepStrictEqual(inspect(parser('_\na_')), undefined);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser('_\\ a_')), undefined);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser('_\\\na_')), undefined);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser('_<wbr>a_')), undefined);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser(' _a_')), undefined);
|
|
30
26
|
});
|
|
31
27
|
|
|
32
28
|
it('basic', () => {
|
|
33
|
-
assert.deepStrictEqual(inspect(parser('
|
|
34
|
-
assert.deepStrictEqual(inspect(parser('
|
|
35
|
-
assert.deepStrictEqual(inspect(parser('
|
|
36
|
-
assert.deepStrictEqual(inspect(parser('
|
|
37
|
-
assert.deepStrictEqual(inspect(parser('*a**')), [['<em>a</em>'], '*']);
|
|
29
|
+
assert.deepStrictEqual(inspect(parser('_a_')), [['<em>a</em>'], '']);
|
|
30
|
+
assert.deepStrictEqual(inspect(parser('_ab_')), [['<em>ab</em>'], '']);
|
|
31
|
+
assert.deepStrictEqual(inspect(parser('_a\nb_')), [['<em>a<br>b</em>'], '']);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser('_a\\\nb_')), [['<em>a<span class="linebreak"> </span>b</em>'], '']);
|
|
38
33
|
});
|
|
39
34
|
|
|
40
35
|
it('nest', () => {
|
|
41
|
-
assert.deepStrictEqual(inspect(parser('
|
|
42
|
-
assert.deepStrictEqual(inspect(parser('*
|
|
43
|
-
assert.deepStrictEqual(inspect(parser('
|
|
44
|
-
assert.deepStrictEqual(inspect(parser('
|
|
45
|
-
assert.deepStrictEqual(inspect(parser('
|
|
46
|
-
assert.deepStrictEqual(inspect(parser('
|
|
47
|
-
assert.deepStrictEqual(inspect(parser('*a**b**c*d')), [['<em>a<strong>b</strong>c</em>'], 'd']);
|
|
48
|
-
assert.deepStrictEqual(inspect(parser('*`a`*')), [['<em><code data-src="`a`">a</code></em>'], '']);
|
|
49
|
-
assert.deepStrictEqual(inspect(parser('*(*a*)*')), [['<em><span class="paren">(<em>a</em>)</span></em>'], '']);
|
|
50
|
-
assert.deepStrictEqual(inspect(parser('*(**a**)*')), [['<em><span class="paren">(<strong>a</strong>)</span></em>'], '']);
|
|
36
|
+
assert.deepStrictEqual(inspect(parser('_a _b__')), [['<em>a <em>b</em></em>'], '']);
|
|
37
|
+
assert.deepStrictEqual(inspect(parser('_a *b*_')), [['<em>a <strong>b</strong></em>'], '']);
|
|
38
|
+
assert.deepStrictEqual(inspect(parser('_a\\ _b__')), [['<em>a <em>b</em></em>'], '']);
|
|
39
|
+
assert.deepStrictEqual(inspect(parser('_a	_b__')), [['<em>a\t<em>b</em></em>'], '']);
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('_a<wbr>_b__')), [['<em>a<wbr><em>b</em></em>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('_(_a_)_')), [['<em><span class="paren">(<em>a</em>)</span></em>'], '']);
|
|
51
42
|
});
|
|
52
43
|
|
|
53
44
|
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { EmphasisParser } from '../inline';
|
|
2
2
|
import { union, some, syntax, surround, open, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
|
-
import { emstrong } from './emstrong';
|
|
5
|
-
import { strong } from './strong';
|
|
6
4
|
import { str } from '../source';
|
|
7
5
|
import { Syntax, State } from '../context';
|
|
8
6
|
import { startTight, blankWith } from '../visibility';
|
|
@@ -10,17 +8,12 @@ import { html, defrag } from 'typed-dom/dom';
|
|
|
10
8
|
import { unshift } from 'spica/array';
|
|
11
9
|
|
|
12
10
|
export const emphasis: EmphasisParser = lazy(() => surround(
|
|
13
|
-
str('
|
|
11
|
+
str('_'),
|
|
14
12
|
syntax(Syntax.none, 1, 1, State.none,
|
|
15
13
|
startTight(some(union([
|
|
16
|
-
|
|
17
|
-
some(inline,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
strong,
|
|
21
|
-
emphasis,
|
|
22
|
-
])),
|
|
23
|
-
])), '*')),
|
|
24
|
-
str('*'), false,
|
|
14
|
+
some(inline, blankWith('_')),
|
|
15
|
+
open(some(inline, '_'), emphasis),
|
|
16
|
+
])), '_')),
|
|
17
|
+
str('_'), false,
|
|
25
18
|
([, bs], rest) => [[html('em', defrag(bs))], rest],
|
|
26
19
|
([as, bs], rest) => [unshift(as, bs), rest]));
|
|
@@ -6,20 +6,11 @@ import { str } from '../source';
|
|
|
6
6
|
const repeat = str(/^(.)\1*/);
|
|
7
7
|
|
|
8
8
|
export const escape: EscapeParser = union([({ source, context }) => {
|
|
9
|
-
if (source.length < 3) return;
|
|
10
9
|
switch (source[0]) {
|
|
11
|
-
case '*':
|
|
12
|
-
if (source.length < 4) return;
|
|
13
|
-
assert(source[3]);
|
|
14
|
-
return source[3] === source[0]
|
|
15
|
-
&& source[2] === source[0]
|
|
16
|
-
&& source[1] === source[0]
|
|
17
|
-
? repeat({ source, context })
|
|
18
|
-
: undefined;
|
|
19
10
|
case '+':
|
|
20
11
|
case '~':
|
|
21
12
|
case '=':
|
|
22
|
-
|
|
13
|
+
if (!source[2]) return;
|
|
23
14
|
return source[2] === source[0]
|
|
24
15
|
&& source[1] === source[0]
|
|
25
16
|
? repeat({ source, context })
|
|
@@ -53,7 +53,7 @@ describe('Unit: parser/inline/extension/index', () => {
|
|
|
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
55
|
assert.deepStrictEqual(inspect(parser('[#==]')), [['<a class="index" href="#index:==">==</a>'], '']);
|
|
56
|
-
assert.deepStrictEqual(inspect(parser('[
|
|
56
|
+
assert.deepStrictEqual(inspect(parser('[#_A_]')), [['<a class="index" href="#index:A"><em>A</em></a>'], '']);
|
|
57
57
|
assert.deepStrictEqual(inspect(parser('[#`A`]')), [['<a class="index" href="#index:`A`"><code data-src="`A`">A</code></a>'], '']);
|
|
58
58
|
assert.deepStrictEqual(inspect(parser('[#${A}$]')), [['<a class="index" href="#index:${A}$"><span class="math" translate="no" data-src="${A}$">${A}$</span></a>'], '']);
|
|
59
59
|
assert.deepStrictEqual(inspect(parser('[#[A](a)]')), [['<a class="index" href="#index:A"><ruby>A<rp>(</rp><rt>a</rt><rp>)</rp></ruby></a>'], '']);
|
|
@@ -80,7 +80,7 @@ describe('Unit: parser/inline/extension/index', () => {
|
|
|
80
80
|
assert.deepStrictEqual(inspect(parser('[#a|#b ]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
|
|
81
81
|
assert.deepStrictEqual(inspect(parser('[#a|#b ]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
|
|
82
82
|
assert.deepStrictEqual(inspect(parser('[#a|#\\b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
|
|
83
|
-
assert.deepStrictEqual(inspect(parser('[#a
|
|
83
|
+
assert.deepStrictEqual(inspect(parser('[#a|#_b_]')), [['<a class="index" href="#index:_b_">a<span class="indexer" data-index="_b_"></span></a>'], '']);
|
|
84
84
|
assert.deepStrictEqual(inspect(parser('[#a|#b c]')), [['<a class="index" href="#index:b_c">a<span class="indexer" data-index="b_c"></span></a>'], '']);
|
|
85
85
|
assert.deepStrictEqual(inspect(parser('[#a|#b c]')), [['<a class="index" href="#index:b_c">a<span class="indexer" data-index="b_c"></span></a>'], '']);
|
|
86
86
|
assert.deepStrictEqual(inspect(parser('[#a|#[]]')), [['<a class="index" href="#index:[]">a<span class="indexer" data-index="[]"></span></a>'], '']);
|
|
@@ -13,7 +13,7 @@ import IndexParser = ExtensionParser.IndexParser;
|
|
|
13
13
|
export const index: IndexParser = lazy(() => validate('[#', fmap(indexee(surround(
|
|
14
14
|
'[#',
|
|
15
15
|
constraint(State.index, false,
|
|
16
|
-
syntax(Syntax.index, 2, 1, State.
|
|
16
|
+
syntax(Syntax.index, 2, 1, State.linkers | State.media,
|
|
17
17
|
startTight(
|
|
18
18
|
open(stropt(/^\|?/), trimBlankEnd(some(union([
|
|
19
19
|
signature,
|
|
@@ -37,8 +37,8 @@ describe('Unit: parser/inline/insertion', () => {
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
it('nest', () => {
|
|
40
|
-
assert.deepStrictEqual(inspect(parser('
|
|
41
|
-
assert.deepStrictEqual(inspect(parser('
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('++_++a++_++')), [['<ins><em><ins>a</ins></em></ins>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('++_~~a~~_++')), [['<ins><em><del>a</del></em></ins>'], '']);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
});
|
|
@@ -170,7 +170,7 @@ describe('Unit: parser/inline/link', () => {
|
|
|
170
170
|
assert.deepStrictEqual(inspect(parser('[((a))]{b}')), [['<a class="link" href="b"><span class="paren">((a))</span></a>'], '']);
|
|
171
171
|
assert.deepStrictEqual(inspect(parser('[[[a]]]{b}')), [['<a class="link" href="b">[[a]]</a>'], '']);
|
|
172
172
|
assert.deepStrictEqual(inspect(parser('[!http://host]{/}')), [['<a class="link" href="/" target="_blank"><img class="media" data-src="http://host" alt=""></a>'], '']);
|
|
173
|
-
assert.deepStrictEqual(inspect(parser('[
|
|
173
|
+
assert.deepStrictEqual(inspect(parser('[_a_]{b}')), [['<a class="link" href="b"><em>a</em></a>'], '']);
|
|
174
174
|
});
|
|
175
175
|
|
|
176
176
|
it('external', () => {
|
|
@@ -25,7 +25,7 @@ export const link: LinkParser = lazy(() => validate(['[', '{'], union([
|
|
|
25
25
|
|
|
26
26
|
const textlink: LinkParser.TextLinkParser = lazy(() =>
|
|
27
27
|
constraint(State.link, false,
|
|
28
|
-
syntax(Syntax.link, 2, 10, State.
|
|
28
|
+
syntax(Syntax.link, 2, 10, State.linkers | State.media,
|
|
29
29
|
bind(reverse(tails([
|
|
30
30
|
dup(surround(
|
|
31
31
|
'[',
|
|
@@ -41,7 +41,7 @@ const textlink: LinkParser.TextLinkParser = lazy(() =>
|
|
|
41
41
|
|
|
42
42
|
const medialink: LinkParser.MediaLinkParser = lazy(() =>
|
|
43
43
|
constraint(State.link | State.media, false,
|
|
44
|
-
syntax(Syntax.link, 2, 10, State.
|
|
44
|
+
syntax(Syntax.link, 2, 10, State.linkers,
|
|
45
45
|
bind(reverse(sequence([
|
|
46
46
|
dup(surround(
|
|
47
47
|
'[',
|
|
@@ -40,7 +40,7 @@ describe('Unit: parser/inline/mark', () => {
|
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('==a\\ ==b====')), [['<mark>a <mark>b</mark></mark>'], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('==a	==b====')), [['<mark>a\t<mark>b</mark></mark>'], '']);
|
|
42
42
|
assert.deepStrictEqual(inspect(parser('==a<wbr>==b====')), [['<mark>a<wbr><mark>b</mark></mark>'], '']);
|
|
43
|
-
assert.deepStrictEqual(inspect(parser('
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('==_==a==_==')), [['<mark><em><mark>a</mark></em></mark>'], '']);
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
});
|
|
@@ -21,7 +21,7 @@ Object.setPrototypeOf(optspec, null);
|
|
|
21
21
|
export const media: MediaParser = lazy(() => validate(['![', '!{'], open(
|
|
22
22
|
'!',
|
|
23
23
|
constraint(State.media, false,
|
|
24
|
-
syntax(Syntax.media, 2, 10, State.
|
|
24
|
+
syntax(Syntax.media, 2, 10, ~State.link,
|
|
25
25
|
bind(verify(fmap(tails([
|
|
26
26
|
dup(surround(
|
|
27
27
|
'[',
|
|
@@ -55,7 +55,7 @@ export const media: MediaParser = lazy(() => validate(['![', '!{'], open(
|
|
|
55
55
|
el.style.aspectRatio = el.getAttribute('aspect-ratio')!;
|
|
56
56
|
}
|
|
57
57
|
if (context.state! & State.link) return [[el], rest];
|
|
58
|
-
if (cache && cache.tagName !== 'IMG') return creation(10,
|
|
58
|
+
if (cache && cache.tagName !== 'IMG') return creation(10, _ => [[el!], rest])({ source: '!', context });
|
|
59
59
|
return fmap(
|
|
60
60
|
unsafelink as MediaParser,
|
|
61
61
|
([link]) => [define(link, { class: null, target: '_blank' }, [el])])
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { RubyParser } from '../inline';
|
|
3
3
|
import { eval, exec } from '../../combinator/data/parser';
|
|
4
|
-
import { sequence, syntax, creation, validate, verify,
|
|
4
|
+
import { sequence, syntax, creation, validate, verify, surround, lazy, fmap } from '../../combinator';
|
|
5
5
|
import { unsafehtmlentity } from './htmlentity';
|
|
6
|
-
import { text as txt } from '../source';
|
|
6
|
+
import { text as txt, str } from '../source';
|
|
7
7
|
import { Syntax, State } from '../context';
|
|
8
8
|
import { isStartTightNodes } from '../visibility';
|
|
9
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
10
10
|
import { unshift, push } from 'spica/array';
|
|
11
11
|
|
|
12
|
-
export const ruby: RubyParser = lazy(() => validate('[', syntax(Syntax.
|
|
12
|
+
export const ruby: RubyParser = lazy(() => validate('[', syntax(Syntax.ruby, 2, 1, State.all, fmap(verify(fmap(
|
|
13
13
|
sequence([
|
|
14
|
-
surround('[',
|
|
15
|
-
surround('(',
|
|
14
|
+
surround('[', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']'),
|
|
15
|
+
surround('(', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ')'),
|
|
16
16
|
]),
|
|
17
|
-
([texts]) =>
|
|
17
|
+
([texts, rubies], _, context) => [
|
|
18
|
+
eval(text({ source: texts, context }), [])[0] ?? '',
|
|
19
|
+
eval(text({ source: rubies, context }), [])[0] ?? '',
|
|
20
|
+
]),
|
|
21
|
+
([texts, rubies]) => texts && rubies && isStartTightNodes(texts)),
|
|
18
22
|
([texts, rubies]) => {
|
|
19
23
|
texts[texts.length - 1] === '' && texts.pop();
|
|
20
24
|
switch (true) {
|
|
@@ -7,44 +7,37 @@ describe('Unit: parser/inline/strong', () => {
|
|
|
7
7
|
const parser = (source: string) => some(strong)({ source, context: {} });
|
|
8
8
|
|
|
9
9
|
it('invalid', () => {
|
|
10
|
-
assert.deepStrictEqual(inspect(parser('
|
|
11
|
-
assert.deepStrictEqual(inspect(parser('
|
|
12
|
-
assert.deepStrictEqual(inspect(parser('
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('
|
|
14
|
-
assert.deepStrictEqual(inspect(parser('
|
|
15
|
-
assert.deepStrictEqual(inspect(parser('
|
|
16
|
-
assert.deepStrictEqual(inspect(parser('
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('
|
|
18
|
-
assert.deepStrictEqual(inspect(parser('
|
|
19
|
-
assert.deepStrictEqual(inspect(parser('
|
|
20
|
-
assert.deepStrictEqual(inspect(parser('
|
|
21
|
-
assert.deepStrictEqual(inspect(parser('
|
|
22
|
-
assert.deepStrictEqual(inspect(parser('
|
|
23
|
-
assert.deepStrictEqual(inspect(parser('
|
|
24
|
-
assert.deepStrictEqual(inspect(parser('
|
|
25
|
-
assert.deepStrictEqual(inspect(parser('
|
|
26
|
-
assert.deepStrictEqual(inspect(parser('**<wbr>a**')), undefined);
|
|
27
|
-
assert.deepStrictEqual(inspect(parser('***a***')), undefined);
|
|
28
|
-
assert.deepStrictEqual(inspect(parser(' **a**')), undefined);
|
|
10
|
+
assert.deepStrictEqual(inspect(parser('*')), undefined);
|
|
11
|
+
assert.deepStrictEqual(inspect(parser('*a')), [['*', 'a'], '']);
|
|
12
|
+
assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a'], ' *']);
|
|
13
|
+
assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a', ' '], ' *']);
|
|
14
|
+
assert.deepStrictEqual(inspect(parser('*a\n*')), [['*', 'a'], '\n*']);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('*a\\ *')), [['*', 'a'], '\\ *']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['*', 'a'], '\\\n*']);
|
|
17
|
+
assert.deepStrictEqual(inspect(parser('* *')), undefined);
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('* a*')), undefined);
|
|
19
|
+
assert.deepStrictEqual(inspect(parser('* a *')), undefined);
|
|
20
|
+
assert.deepStrictEqual(inspect(parser('*\n*')), undefined);
|
|
21
|
+
assert.deepStrictEqual(inspect(parser('*\na*')), undefined);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser('*\\ a*')), undefined);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser('*\\\na*')), undefined);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser('*<wbr>a*')), undefined);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser(' *a*')), undefined);
|
|
29
26
|
});
|
|
30
27
|
|
|
31
28
|
it('basic', () => {
|
|
32
|
-
assert.deepStrictEqual(inspect(parser('
|
|
33
|
-
assert.deepStrictEqual(inspect(parser('
|
|
34
|
-
assert.deepStrictEqual(inspect(parser('
|
|
35
|
-
assert.deepStrictEqual(inspect(parser('
|
|
29
|
+
assert.deepStrictEqual(inspect(parser('*a*')), [['<strong>a</strong>'], '']);
|
|
30
|
+
assert.deepStrictEqual(inspect(parser('*ab*')), [['<strong>ab</strong>'], '']);
|
|
31
|
+
assert.deepStrictEqual(inspect(parser('*a\nb*')), [['<strong>a<br>b</strong>'], '']);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser('*a\\\nb*')), [['<strong>a<span class="linebreak"> </span>b</strong>'], '']);
|
|
36
33
|
});
|
|
37
34
|
|
|
38
35
|
it('nest', () => {
|
|
39
|
-
assert.deepStrictEqual(inspect(parser('
|
|
40
|
-
assert.deepStrictEqual(inspect(parser('
|
|
41
|
-
assert.deepStrictEqual(inspect(parser('
|
|
42
|
-
assert.deepStrictEqual(inspect(parser('
|
|
43
|
-
assert.deepStrictEqual(inspect(parser('
|
|
44
|
-
assert.deepStrictEqual(inspect(parser('**a*b*c**d')), [['<strong>a<em>b</em>c</strong>'], 'd']);
|
|
45
|
-
assert.deepStrictEqual(inspect(parser('**`a`**')), [['<strong><code data-src="`a`">a</code></strong>'], '']);
|
|
46
|
-
assert.deepStrictEqual(inspect(parser('**(*a*)**')), [['<strong><span class="paren">(<em>a</em>)</span></strong>'], '']);
|
|
47
|
-
assert.deepStrictEqual(inspect(parser('**(**a**)**')), [['<strong><span class="paren">(<strong>a</strong>)</span></strong>'], '']);
|
|
36
|
+
assert.deepStrictEqual(inspect(parser('*a _b_*')), [['<strong>a <em>b</em></strong>'], '']);
|
|
37
|
+
assert.deepStrictEqual(inspect(parser('*a *b**')), [['<strong>a <strong>b</strong></strong>'], '']);
|
|
38
|
+
assert.deepStrictEqual(inspect(parser('*a	*b**')), [['<strong>a\t<strong>b</strong></strong>'], '']);
|
|
39
|
+
assert.deepStrictEqual(inspect(parser('*a<wbr>*b**')), [['<strong>a<wbr><strong>b</strong></strong>'], '']);
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('*(*a*)*')), [['<strong><span class="paren">(<strong>a</strong>)</span></strong>'], '']);
|
|
48
41
|
});
|
|
49
42
|
|
|
50
43
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { StrongParser } from '../inline';
|
|
2
2
|
import { union, some, syntax, surround, open, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
|
-
import { emstrong } from './emstrong';
|
|
5
4
|
import { str } from '../source';
|
|
6
5
|
import { Syntax, State } from '../context';
|
|
7
6
|
import { startTight, blankWith } from '../visibility';
|
|
@@ -9,15 +8,12 @@ import { html, defrag } from 'typed-dom/dom';
|
|
|
9
8
|
import { unshift } from 'spica/array';
|
|
10
9
|
|
|
11
10
|
export const strong: StrongParser = lazy(() => surround(
|
|
12
|
-
str('
|
|
11
|
+
str('*'),
|
|
13
12
|
syntax(Syntax.none, 1, 1, State.none,
|
|
14
13
|
startTight(some(union([
|
|
15
|
-
some(inline, blankWith('
|
|
16
|
-
open(some(inline, '*'),
|
|
17
|
-
emstrong,
|
|
18
|
-
strong,
|
|
19
|
-
])),
|
|
14
|
+
some(inline, blankWith('*')),
|
|
15
|
+
open(some(inline, '*'), strong),
|
|
20
16
|
])), '*')),
|
|
21
|
-
str('
|
|
17
|
+
str('*'), false,
|
|
22
18
|
([, bs], rest) => [[html('strong', defrag(bs))], rest],
|
|
23
19
|
([as, bs], rest) => [unshift(as, bs), rest]));
|
|
@@ -7,7 +7,7 @@ import { html } from 'typed-dom/dom';
|
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
9
9
|
export const template: TemplateParser = lazy(() => surround(
|
|
10
|
-
'{{', syntax(Syntax.none, 2, 1, State.
|
|
10
|
+
'{{', syntax(Syntax.none, 2, 1, State.all, some(union([bracket, escsource]), '}')), '}}', true,
|
|
11
11
|
([, ns = []], rest) => [[html('span', { class: 'template' }, `{{${ns.join('').replace(/\x1B/g, '')}}}`)], rest]));
|
|
12
12
|
|
|
13
13
|
const bracket: TemplateParser.BracketParser = lazy(() => creation(union([
|