securemark 0.292.0 → 0.293.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 +4 -0
- package/dist/index.js +395 -287
- package/markdown.d.ts +22 -39
- package/package.json +1 -1
- package/src/combinator/control/constraint/contract.ts +6 -15
- package/src/combinator/control/manipulation/clear.ts +3 -4
- package/src/combinator/control/manipulation/fence.ts +3 -1
- package/src/combinator/control/manipulation/indent.ts +5 -11
- package/src/combinator/control/manipulation/match.ts +3 -2
- package/src/combinator/control/manipulation/recovery.ts +1 -1
- package/src/combinator/control/manipulation/scope.ts +3 -10
- package/src/combinator/control/manipulation/surround.ts +4 -24
- package/src/combinator/data/parser/context/delimiter.ts +10 -9
- package/src/combinator/data/parser/context.ts +31 -0
- package/src/combinator/data/parser/inits.ts +1 -1
- package/src/combinator/data/parser/sequence.ts +1 -1
- package/src/combinator/data/parser/some.test.ts +1 -1
- package/src/combinator/data/parser/some.ts +4 -5
- package/src/combinator/data/parser.ts +0 -1
- package/src/parser/api/parse.test.ts +16 -8
- package/src/parser/api/parse.ts +1 -2
- package/src/parser/autolink.test.ts +7 -7
- package/src/parser/autolink.ts +2 -4
- package/src/parser/block/blockquote.test.ts +1 -1
- package/src/parser/block/blockquote.ts +6 -6
- package/src/parser/block/codeblock.ts +1 -1
- package/src/parser/block/dlist.test.ts +1 -1
- package/src/parser/block/dlist.ts +6 -6
- package/src/parser/block/extension/aside.ts +1 -1
- package/src/parser/block/extension/example.ts +1 -1
- package/src/parser/block/extension/fig.ts +3 -3
- package/src/parser/block/extension/figbase.ts +1 -1
- package/src/parser/block/extension/figure.ts +4 -4
- package/src/parser/block/extension/message.ts +1 -1
- package/src/parser/block/extension/placeholder.ts +1 -1
- package/src/parser/block/extension/table.test.ts +1 -1
- package/src/parser/block/extension/table.ts +15 -15
- package/src/parser/block/extension.ts +2 -2
- package/src/parser/block/heading.test.ts +1 -1
- package/src/parser/block/heading.ts +2 -2
- package/src/parser/block/ilist.test.ts +3 -3
- package/src/parser/block/ilist.ts +4 -4
- package/src/parser/block/mathblock.ts +1 -1
- package/src/parser/block/mediablock.ts +1 -1
- package/src/parser/block/olist.test.ts +16 -14
- package/src/parser/block/olist.ts +12 -12
- package/src/parser/block/pagebreak.ts +1 -1
- package/src/parser/block/paragraph.test.ts +2 -2
- package/src/parser/block/paragraph.ts +2 -2
- package/src/parser/block/reply/cite.ts +4 -4
- package/src/parser/block/reply/quote.ts +5 -4
- package/src/parser/block/reply.ts +3 -3
- package/src/parser/block/sidefence.ts +3 -3
- package/src/parser/block/table.ts +10 -10
- package/src/parser/block/ulist.test.ts +8 -7
- package/src/parser/block/ulist.ts +6 -6
- package/src/parser/block.ts +48 -15
- package/src/parser/header.ts +3 -3
- package/src/parser/inline/autolink/account.test.ts +8 -7
- package/src/parser/inline/autolink/account.ts +11 -8
- package/src/parser/inline/autolink/anchor.test.ts +1 -1
- package/src/parser/inline/autolink/anchor.ts +21 -17
- package/src/parser/inline/autolink/channel.test.ts +8 -8
- package/src/parser/inline/autolink/channel.ts +40 -15
- package/src/parser/inline/autolink/email.test.ts +15 -15
- package/src/parser/inline/autolink/email.ts +5 -7
- package/src/parser/inline/autolink/hashnum.test.ts +4 -9
- package/src/parser/inline/autolink/hashnum.ts +8 -4
- package/src/parser/inline/autolink/hashtag.test.ts +9 -10
- package/src/parser/inline/autolink/hashtag.ts +9 -6
- package/src/parser/inline/autolink/url.test.ts +72 -74
- package/src/parser/inline/autolink/url.ts +19 -23
- package/src/parser/inline/autolink.ts +21 -24
- package/src/parser/inline/bracket.ts +3 -3
- package/src/parser/inline/code.ts +2 -2
- package/src/parser/inline/deletion.test.ts +2 -2
- package/src/parser/inline/deletion.ts +1 -1
- package/src/parser/inline/emphasis.test.ts +5 -5
- package/src/parser/inline/emphasis.ts +2 -7
- package/src/parser/inline/emstrong.test.ts +14 -14
- package/src/parser/inline/emstrong.ts +4 -16
- package/src/parser/inline/extension/index.test.ts +5 -3
- package/src/parser/inline/extension/index.ts +4 -7
- package/src/parser/inline/extension/indexer.test.ts +1 -1
- package/src/parser/inline/extension/indexer.ts +3 -3
- package/src/parser/inline/extension/label.ts +1 -1
- package/src/parser/inline/extension/placeholder.ts +1 -1
- package/src/parser/inline/html.test.ts +2 -2
- package/src/parser/inline/html.ts +14 -14
- package/src/parser/inline/htmlentity.ts +1 -1
- package/src/parser/inline/insertion.test.ts +2 -2
- package/src/parser/inline/insertion.ts +1 -1
- package/src/parser/inline/italic.test.ts +5 -5
- package/src/parser/inline/italic.ts +1 -1
- package/src/parser/inline/link.ts +15 -15
- package/src/parser/inline/mark.test.ts +5 -5
- package/src/parser/inline/mark.ts +1 -1
- package/src/parser/inline/math.test.ts +6 -6
- package/src/parser/inline/math.ts +7 -11
- package/src/parser/inline/media.ts +9 -9
- package/src/parser/inline/reference.test.ts +4 -4
- package/src/parser/inline/reference.ts +4 -4
- package/src/parser/inline/remark.test.ts +7 -7
- package/src/parser/inline/remark.ts +2 -2
- package/src/parser/inline/ruby.ts +3 -1
- package/src/parser/inline/shortmedia.ts +6 -9
- package/src/parser/inline/strong.test.ts +5 -5
- package/src/parser/inline/strong.ts +2 -7
- package/src/parser/inline.test.ts +13 -11
- package/src/parser/source/escapable.test.ts +6 -6
- package/src/parser/source/escapable.ts +29 -5
- package/src/parser/source/line.ts +28 -4
- package/src/parser/source/str.ts +5 -27
- package/src/parser/source/text.test.ts +27 -27
- package/src/parser/source/text.ts +58 -6
- package/src/parser/source/unescapable.test.ts +6 -6
- package/src/parser/source/unescapable.ts +27 -3
- package/src/parser/util.ts +3 -3
- package/src/parser/visibility.ts +14 -9
|
@@ -3,16 +3,17 @@ import { union, some, block, validate, rewrite, convert, lazy, fmap } from '../.
|
|
|
3
3
|
import { math } from '../../inline/math';
|
|
4
4
|
import { autolink } from '../../inline/autolink';
|
|
5
5
|
import { linebreak, unescsource, anyline } from '../../source';
|
|
6
|
+
import { linearize } from '../../util';
|
|
6
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
8
|
|
|
8
|
-
export const syntax =
|
|
9
|
+
export const syntax = />+[^\S\n]/y;
|
|
9
10
|
|
|
10
11
|
export const quote: ReplyParser.QuoteParser = lazy(() => block(fmap(validate(
|
|
11
12
|
'>',
|
|
12
13
|
rewrite(
|
|
13
14
|
some(validate(syntax, anyline)),
|
|
14
|
-
convert(
|
|
15
|
-
source => source.replace(/(?<=^>+[^\S\n])/mg, '\r')
|
|
15
|
+
linearize(convert(
|
|
16
|
+
source => source.replace(/(?<=^>+[^\S\n])/mg, '\r'),
|
|
16
17
|
some(union([
|
|
17
18
|
// quote補助関数が残した数式をパースする。
|
|
18
19
|
math,
|
|
@@ -20,7 +21,7 @@ export const quote: ReplyParser.QuoteParser = lazy(() => block(fmap(validate(
|
|
|
20
21
|
linebreak,
|
|
21
22
|
unescsource,
|
|
22
23
|
])),
|
|
23
|
-
false))),
|
|
24
|
+
false), -1))),
|
|
24
25
|
(ns: [string, ...(string | HTMLElement)[]]) => [
|
|
25
26
|
html('span', { class: 'quote' }, defrag(ns)),
|
|
26
27
|
html('br'),
|
|
@@ -4,11 +4,11 @@ import { cite, syntax as csyntax } from './reply/cite';
|
|
|
4
4
|
import { quote, syntax as qsyntax } from './reply/quote';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { anyline } from '../source';
|
|
7
|
-
import {
|
|
7
|
+
import { linearize } from '../util';
|
|
8
8
|
import { visualize, trimBlankNodeEnd } from '../visibility';
|
|
9
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
10
10
|
|
|
11
|
-
const delimiter = new RegExp(`${csyntax.source}|${qsyntax.source}
|
|
11
|
+
const delimiter = new RegExp(`${csyntax.source}|${qsyntax.source}`, 'y');
|
|
12
12
|
|
|
13
13
|
export const reply: ReplyParser = block(validate(csyntax, fmap(
|
|
14
14
|
some(union([
|
|
@@ -16,6 +16,6 @@ export const reply: ReplyParser = block(validate(csyntax, fmap(
|
|
|
16
16
|
quote,
|
|
17
17
|
rewrite(
|
|
18
18
|
some(anyline, delimiter),
|
|
19
|
-
visualize(
|
|
19
|
+
visualize(linearize(some(inline), 1))),
|
|
20
20
|
])),
|
|
21
21
|
ns => [html('p', trimBlankNodeEnd(defrag(ns)))])));
|
|
@@ -7,7 +7,7 @@ import { invalid } from '../util';
|
|
|
7
7
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
8
8
|
|
|
9
9
|
export const sidefence: SidefenceParser = lazy(() => block(fmap(focus(
|
|
10
|
-
|
|
10
|
+
/(?=\|+(?:[^\S\n]|\n\|))(?:\|+(?:[^\S\n][^\n]*)?(?:$|\n))+$/y,
|
|
11
11
|
union([source]), false),
|
|
12
12
|
([el]) => [
|
|
13
13
|
define(el, {
|
|
@@ -16,13 +16,13 @@ export const sidefence: SidefenceParser = lazy(() => block(fmap(focus(
|
|
|
16
16
|
}),
|
|
17
17
|
])));
|
|
18
18
|
|
|
19
|
-
const opener =
|
|
19
|
+
const opener = /(?=\|\|+(?:$|\s))/y;
|
|
20
20
|
const unindent = (source: string) => source.replace(/(?<=^|\n)\|(?:[^\S\n]|(?=\|*(?:$|\s)))|\n$/g, '');
|
|
21
21
|
|
|
22
22
|
const source: SidefenceParser.SourceParser = lazy(() => fmap(
|
|
23
23
|
some(recursion(Recursion.block, union([
|
|
24
24
|
focus(
|
|
25
|
-
|
|
25
|
+
/(?:\|\|+(?:[^\S\n][^\n]*)?(?:$|\n))+/y,
|
|
26
26
|
convert(unindent, source, false, true), false),
|
|
27
27
|
rewrite(
|
|
28
28
|
some(contentline, opener),
|
|
@@ -13,7 +13,7 @@ import AlignParser = TableParser.AlignParser;
|
|
|
13
13
|
import CellParser = TableParser.CellParser;
|
|
14
14
|
|
|
15
15
|
export const table: TableParser = lazy(() => block(fmap(validate(
|
|
16
|
-
|
|
16
|
+
/\|[^\n]*(?:\n\|[^\n]*){2}/y,
|
|
17
17
|
sequence([
|
|
18
18
|
row(some(head), true),
|
|
19
19
|
row(some(align), false),
|
|
@@ -27,7 +27,7 @@ export const table: TableParser = lazy(() => block(fmap(validate(
|
|
|
27
27
|
])));
|
|
28
28
|
|
|
29
29
|
const row = <P extends CellParser | AlignParser>(parser: P, optional: boolean): RowParser<P> => fallback(fmap(
|
|
30
|
-
line(surround(
|
|
30
|
+
line(surround(/(?=\|)/y, some(union([parser])), /[|\\]?\s*$/y, optional)),
|
|
31
31
|
es => [html('tr', es)]),
|
|
32
32
|
rewrite(contentline, ({ context: { source } }) => [[
|
|
33
33
|
html('tr', {
|
|
@@ -39,22 +39,22 @@ const row = <P extends CellParser | AlignParser>(parser: P, optional: boolean):
|
|
|
39
39
|
const align: AlignParser = fmap(open(
|
|
40
40
|
'|',
|
|
41
41
|
union([
|
|
42
|
-
focus(
|
|
42
|
+
focus(/:-+:?/y, ({ context: { source } }) =>
|
|
43
43
|
[[source.at(-1) === ':' ? 'center' : 'start']], false),
|
|
44
|
-
focus(
|
|
44
|
+
focus(/-+:?/y, ({ context: { source } }) =>
|
|
45
45
|
[[source.at(-1) === ':' ? 'end' : '']], false),
|
|
46
46
|
])),
|
|
47
47
|
ns => [html('td', defrag(ns))]);
|
|
48
48
|
|
|
49
49
|
const cell: CellParser = surround(
|
|
50
|
-
|
|
50
|
+
/\|\s*(?=\S)/y,
|
|
51
51
|
trimStart(union([
|
|
52
|
-
close(medialink,
|
|
53
|
-
close(media,
|
|
54
|
-
close(shortmedia,
|
|
55
|
-
trimBlank(some(inline,
|
|
52
|
+
close(medialink, /\s*(?=\||$)/y),
|
|
53
|
+
close(media, /\s*(?=\||$)/y),
|
|
54
|
+
close(shortmedia, /\s*(?=\||$)/y),
|
|
55
|
+
trimBlank(some(inline, /\|/y, [[/[|\\]?\s*$/y, 9]])),
|
|
56
56
|
])),
|
|
57
|
-
|
|
57
|
+
/[^|]*/y, true);
|
|
58
58
|
|
|
59
59
|
const head: CellParser.HeadParser = fmap(
|
|
60
60
|
cell,
|
|
@@ -19,6 +19,7 @@ describe('Unit: parser/block/ulist', () => {
|
|
|
19
19
|
assert.deepStrictEqual(inspect(parser('-[ ]'), ctx), undefined);
|
|
20
20
|
assert.deepStrictEqual(inspect(parser('-[x]'), ctx), undefined);
|
|
21
21
|
assert.deepStrictEqual(inspect(parser('-\n'), ctx), undefined);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser('-\n- a'), ctx), undefined);
|
|
22
23
|
assert.deepStrictEqual(inspect(parser(' - '), ctx), undefined);
|
|
23
24
|
assert.deepStrictEqual(inspect(parser('+'), ctx), undefined);
|
|
24
25
|
assert.deepStrictEqual(inspect(parser('*'), ctx), undefined);
|
|
@@ -36,23 +37,23 @@ describe('Unit: parser/block/ulist', () => {
|
|
|
36
37
|
|
|
37
38
|
it('multiple', () => {
|
|
38
39
|
// pending
|
|
39
|
-
assert.deepStrictEqual(inspect(parser('
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('- \n-'), ctx), [['<ul><li></li><li></li></ul>'], '']);
|
|
40
41
|
// filled
|
|
41
42
|
assert.deepStrictEqual(inspect(parser('- 1\n- 2'), ctx), [['<ul><li id="index::1">1</li><li id="index::2">2</li></ul>'], '']);
|
|
42
43
|
assert.deepStrictEqual(inspect(parser('- 1\n- 2\n- 3'), ctx), [['<ul><li id="index::1">1</li><li id="index::2">2</li><li id="index::3">3</li></ul>'], '']);
|
|
43
44
|
// invalid
|
|
44
|
-
assert.deepStrictEqual(inspect(parser('
|
|
45
|
-
assert.deepStrictEqual(inspect(parser('
|
|
45
|
+
assert.deepStrictEqual(inspect(parser('- \n+'), ctx), [['<ul><li></li><li id="index::+"><span class="invalid">+</span></li></ul>'], '']);
|
|
46
|
+
assert.deepStrictEqual(inspect(parser('- \n0'), ctx), [['<ul><li></li><li id="index::0"><span class="invalid">0</span></li></ul>'], '']);
|
|
46
47
|
});
|
|
47
48
|
|
|
48
49
|
it('nest', () => {
|
|
49
|
-
assert.deepStrictEqual(inspect(parser('
|
|
50
|
+
assert.deepStrictEqual(inspect(parser('- \n -'), ctx), [['<ul><li><br><ul><li></li></ul></li></ul>'], '']);
|
|
50
51
|
assert.deepStrictEqual(inspect(parser('- 1\n - 2'), ctx), [['<ul><li id="index::1">1<ul><li id="index::2">2</li></ul></li></ul>'], '']);
|
|
51
52
|
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n- 3'), ctx), [['<ul><li id="index::1">1<ul><li id="index::2">2</li></ul></li><li id="index::3">3</li></ul>'], '']);
|
|
52
53
|
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n - 3'), ctx), [['<ul><li id="index::1">1<ul><li id="index::2">2</li><li id="index::3">3</li></ul></li></ul>'], '']);
|
|
53
54
|
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n - 3'), ctx), [['<ul><li id="index::1">1<ul><li id="index::2">2<ul><li id="index::3">3</li></ul></li></ul></li></ul>'], '']);
|
|
54
55
|
assert.deepStrictEqual(inspect(parser('- 1\n - 2\n - 3'), ctx), [['<ul><li id="index::1">1<ul><li id="index::2">2</li></ul></li><li id="index::-_3"><span class="invalid"> - 3</span></li></ul>'], '']);
|
|
55
|
-
assert.deepStrictEqual(inspect(parser('
|
|
56
|
+
assert.deepStrictEqual(inspect(parser('- \n -\n +\n -\n +\n+'), ctx), [['<ul><li><br><ul><li></li><li id="index::+"><span class="invalid">+</span></li><li></li><li id="index::+"><span class="invalid">+</span></li></ul></li><li id="index::+"><span class="invalid">+</span></li></ul>'], '']);
|
|
56
57
|
assert.deepStrictEqual(inspect(parser('- 1\n + 2'), ctx), [['<ul><li id="index::1">1<ul class="invalid"><li>2</li></ul></li></ul>'], '']);
|
|
57
58
|
assert.deepStrictEqual(inspect(parser('- 1\n 0'), ctx), [['<ul><li id="index::1">1<ol><li></li></ol></li></ul>'], '']);
|
|
58
59
|
assert.deepStrictEqual(inspect(parser('- 1\n 0.'), ctx), [['<ul><li id="index::1">1<ol><li></li></ol></li></ul>'], '']);
|
|
@@ -71,10 +72,10 @@ describe('Unit: parser/block/ulist', () => {
|
|
|
71
72
|
});
|
|
72
73
|
|
|
73
74
|
it('indexer', () => {
|
|
74
|
-
assert.deepStrictEqual(inspect(parser('- [|a]'), ctx), [['<ul><li id="index::[|a]">[|a]</li></ul>'], '']);
|
|
75
|
+
assert.deepStrictEqual(inspect(parser('- [|a]'), ctx), [['<ul><li id="index::[|a]"><span class="invalid">[|a]</span></li></ul>'], '']);
|
|
75
76
|
assert.deepStrictEqual(inspect(parser('- a [|]'), ctx), [['<ul><li>a<span class="indexer" data-index=""></span></li></ul>'], '']);
|
|
76
77
|
assert.deepStrictEqual(inspect(parser('- a [|b]'), ctx), [['<ul><li id="index::b">a<span class="indexer" data-index="b"></span></li></ul>'], '']);
|
|
77
|
-
assert.deepStrictEqual(inspect(parser('- [ ] [|a]'), ctx), [['<ul class="checklist"><li id="index::[|a]"><span class="checkbox">☐</span>[|a]</li></ul>'], '']);
|
|
78
|
+
assert.deepStrictEqual(inspect(parser('- [ ] [|a]'), ctx), [['<ul class="checklist"><li id="index::[|a]"><span class="checkbox">☐</span><span class="invalid">[|a]</span></li></ul>'], '']);
|
|
78
79
|
assert.deepStrictEqual(inspect(parser('- [ ] a [|b]'), ctx), [['<ul class="checklist"><li id="index::b"><span class="checkbox">☐</span>a<span class="indexer" data-index="b"></span></li></ul>'], '']);
|
|
79
80
|
assert.deepStrictEqual(inspect(parser('- a [|]\n - c [|d]'), ctx), [['<ul><li>a<span class="indexer" data-index=""></span><ul><li id="index::d">c<span class="indexer" data-index="d"></span></li></ul></li></ul>'], '']);
|
|
80
81
|
assert.deepStrictEqual(inspect(parser('- a [|b]\n - c [|d]'), ctx), [['<ul><li id="index::b">a<span class="indexer" data-index="b"></span><ul><li id="index::d">c<span class="indexer" data-index="d"></span></li></ul></li></ul>'], '']);
|
|
@@ -4,23 +4,23 @@ import { union, inits, subsequence, some, recursion, block, line, validate, inde
|
|
|
4
4
|
import { olist_ } from './olist';
|
|
5
5
|
import { ilist_, ilistitem } from './ilist';
|
|
6
6
|
import { inline, indexer, indexee, dataindex } from '../inline';
|
|
7
|
-
import {
|
|
7
|
+
import { linearize } from '../util';
|
|
8
8
|
import { visualize, trimBlank } from '../visibility';
|
|
9
9
|
import { unshift } from 'spica/array';
|
|
10
10
|
import { html, defrag } from 'typed-dom/dom';
|
|
11
11
|
|
|
12
12
|
export const ulist: UListParser = lazy(() => block(validate(
|
|
13
|
-
|
|
13
|
+
/- /y,
|
|
14
14
|
ulist_)));
|
|
15
15
|
|
|
16
16
|
export const ulist_: UListParser = lazy(() => block(fmap(validate(
|
|
17
|
-
|
|
17
|
+
/-(?=$|[ \n])/y,
|
|
18
18
|
some(recursion(Recursion.listitem, union([
|
|
19
19
|
indexee(fmap(fallback(
|
|
20
20
|
inits([
|
|
21
|
-
line(open(
|
|
21
|
+
line(open(/-(?:$|[ \n])/y, subsequence([
|
|
22
22
|
checkbox,
|
|
23
|
-
trim(visualize(
|
|
23
|
+
trim(visualize(linearize(trimBlank(some(union([indexer, inline]))), - 1))),
|
|
24
24
|
]), true)),
|
|
25
25
|
indent(union([ulist_, olist_, ilist_])),
|
|
26
26
|
]),
|
|
@@ -30,7 +30,7 @@ export const ulist_: UListParser = lazy(() => block(fmap(validate(
|
|
|
30
30
|
es => [format(html('ul', es))])));
|
|
31
31
|
|
|
32
32
|
export const checkbox = focus(
|
|
33
|
-
|
|
33
|
+
/\[[xX ]\](?=$|[ \n])/y,
|
|
34
34
|
({ context: { source } }) => [[
|
|
35
35
|
html('span', { class: 'checkbox' }, source[1].trimStart() ? '☑' : '☐'),
|
|
36
36
|
]]);
|
package/src/parser/block.ts
CHANGED
|
@@ -42,7 +42,7 @@ export const block: BlockParser = reset(
|
|
|
42
42
|
{
|
|
43
43
|
resources: {
|
|
44
44
|
// バックトラックのせいで文字数制限を受けないようにする。
|
|
45
|
-
clock: MAX_SEGMENT_SIZE * 1,
|
|
45
|
+
clock: MAX_SEGMENT_SIZE * 5 + 1,
|
|
46
46
|
recursions: [
|
|
47
47
|
10 || Recursion.block,
|
|
48
48
|
20 || Recursion.blockquote,
|
|
@@ -55,23 +55,56 @@ export const block: BlockParser = reset(
|
|
|
55
55
|
backtracks: {},
|
|
56
56
|
},
|
|
57
57
|
error(union([
|
|
58
|
+
input => {
|
|
59
|
+
const { context: { source, position } } = input;
|
|
60
|
+
if (position === source.length) return;
|
|
61
|
+
switch (source.slice(position, position + 3)) {
|
|
62
|
+
case '===':
|
|
63
|
+
return pagebreak(input);
|
|
64
|
+
case '~~~':
|
|
65
|
+
return extension(input);
|
|
66
|
+
}
|
|
67
|
+
switch (source.slice(position, position + 2)) {
|
|
68
|
+
case '$$':
|
|
69
|
+
return mathblock(input);
|
|
70
|
+
case '[$':
|
|
71
|
+
return extension(input);
|
|
72
|
+
case '[!':
|
|
73
|
+
return mediablock(input);
|
|
74
|
+
case '!>':
|
|
75
|
+
return blockquote(input);
|
|
76
|
+
case '>>':
|
|
77
|
+
return blockquote(input)
|
|
78
|
+
|| reply(input);
|
|
79
|
+
case '- ':
|
|
80
|
+
return ulist(input)
|
|
81
|
+
|| ilist(input);
|
|
82
|
+
case '+ ':
|
|
83
|
+
case '* ':
|
|
84
|
+
return ilist(input);
|
|
85
|
+
case '~ ':
|
|
86
|
+
return dlist(input);
|
|
87
|
+
}
|
|
88
|
+
switch (source[position]) {
|
|
89
|
+
case '#':
|
|
90
|
+
return heading(input);
|
|
91
|
+
case '|':
|
|
92
|
+
return table(input)
|
|
93
|
+
|| sidefence(input);
|
|
94
|
+
case '`':
|
|
95
|
+
return codeblock(input);
|
|
96
|
+
case '$':
|
|
97
|
+
return extension(input);
|
|
98
|
+
case '>':
|
|
99
|
+
return blockquote(input);
|
|
100
|
+
case '!':
|
|
101
|
+
return mediablock(input);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
58
104
|
emptyline,
|
|
59
|
-
pagebreak,
|
|
60
|
-
heading,
|
|
61
|
-
ulist,
|
|
62
105
|
olist,
|
|
63
|
-
ilist,
|
|
64
|
-
dlist,
|
|
65
|
-
table,
|
|
66
|
-
codeblock,
|
|
67
|
-
mathblock,
|
|
68
|
-
extension,
|
|
69
|
-
sidefence,
|
|
70
|
-
blockquote,
|
|
71
|
-
mediablock,
|
|
72
|
-
reply,
|
|
73
106
|
paragraph
|
|
74
|
-
])));
|
|
107
|
+
]) as any));
|
|
75
108
|
|
|
76
109
|
function error(parser: BlockParser): BlockParser {
|
|
77
110
|
const reg = new RegExp(String.raw`^${Command.Error}.*\n`)
|
package/src/parser/header.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { normalize } from './api/normalize';
|
|
|
7
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
8
8
|
|
|
9
9
|
export const header: MarkdownParser.HeaderParser = lazy(() => validate(
|
|
10
|
-
|
|
10
|
+
/---+[^\S\v\f\r\n]*\r?\n[^\S\n]*(?=\S)/y,
|
|
11
11
|
inits([
|
|
12
12
|
rewrite(
|
|
13
13
|
({ context }) => {
|
|
@@ -23,7 +23,7 @@ export const header: MarkdownParser.HeaderParser = lazy(() => validate(
|
|
|
23
23
|
block(
|
|
24
24
|
union([
|
|
25
25
|
validate(({ context }) => context.header ?? true,
|
|
26
|
-
focus(
|
|
26
|
+
focus(/---[^\S\v\f\r\n]*\r?\n(?:[A-Za-z][0-9A-Za-z]*(?:-[A-Za-z][0-9A-Za-z]*)*:[ \t]+\S[^\v\f\r\n]*\r?\n){1,100}---[^\S\v\f\r\n]*(?:$|\r?\n)/y,
|
|
27
27
|
convert(source =>
|
|
28
28
|
normalize(source.slice(source.indexOf('\n') + 1, source.trimEnd().lastIndexOf('\n'))).replace(/(\S)\s+$/mg, '$1'),
|
|
29
29
|
fmap(
|
|
@@ -48,7 +48,7 @@ export const header: MarkdownParser.HeaderParser = lazy(() => validate(
|
|
|
48
48
|
]];
|
|
49
49
|
},
|
|
50
50
|
]))),
|
|
51
|
-
clear(str(
|
|
51
|
+
clear(str(/[^\S\v\f\r\n]*\r?\n/y)),
|
|
52
52
|
])));
|
|
53
53
|
|
|
54
54
|
const field: MarkdownParser.HeaderParser.FieldParser = line(({ context: { source, position } }) => {
|
|
@@ -16,14 +16,15 @@ describe('Unit: parser/inline/autolink/account', () => {
|
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('@-'), ctx), [['@'], '-']);
|
|
17
17
|
assert.deepStrictEqual(inspect(parser('@.'), ctx), [['@'], '.']);
|
|
18
18
|
assert.deepStrictEqual(inspect(parser('@0'), ctx), [['@0'], '']);
|
|
19
|
-
assert.deepStrictEqual(inspect(parser('@a@'), ctx), [['@a
|
|
20
|
-
assert.deepStrictEqual(inspect(parser('@a@b'), ctx), [['@a
|
|
21
|
-
assert.deepStrictEqual(inspect(parser('@a@b@c'), ctx), [['@a
|
|
22
|
-
assert.deepStrictEqual(inspect(parser('@ab@'), ctx), [['@ab
|
|
23
|
-
assert.deepStrictEqual(inspect(parser('@a@b'), ctx), [['@a@b'], '']);
|
|
19
|
+
assert.deepStrictEqual(inspect(parser('@a@'), ctx), [['@a'], '@']);
|
|
20
|
+
assert.deepStrictEqual(inspect(parser('@a@b'), ctx), [['@a'], '@b']);
|
|
21
|
+
assert.deepStrictEqual(inspect(parser('@a@b@c'), ctx), [['@a'], '@b@c']);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser('@ab@'), ctx), [['@ab'], '@']);
|
|
24
23
|
assert.deepStrictEqual(inspect(parser('@@'), ctx), [['@@'], '']);
|
|
25
24
|
assert.deepStrictEqual(inspect(parser('@@a'), ctx), [['@@a'], '']);
|
|
26
25
|
assert.deepStrictEqual(inspect(parser('@@@a'), ctx), [['@@@a'], '']);
|
|
26
|
+
assert.deepStrictEqual(inspect(parser('@#'), ctx), [['@', '#'], '']);
|
|
27
|
+
assert.deepStrictEqual(inspect(parser('@#a'), ctx), [['@', '<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
|
|
27
28
|
assert.deepStrictEqual(inspect(parser(' @a'), ctx), undefined);
|
|
28
29
|
});
|
|
29
30
|
|
|
@@ -37,8 +38,8 @@ describe('Unit: parser/inline/autolink/account', () => {
|
|
|
37
38
|
assert.deepStrictEqual(inspect(parser('@a--b'), ctx), [['<a class="account" href="/@a">@a</a>'], '--b']);
|
|
38
39
|
assert.deepStrictEqual(inspect(parser('@a.'), ctx), [['<a class="account" href="/@a">@a</a>'], '.']);
|
|
39
40
|
assert.deepStrictEqual(inspect(parser('@a.domain.com'), ctx), [['<a class="account" href="/@a.domain.com">@a.domain.com</a>'], '']);
|
|
40
|
-
assert.deepStrictEqual(inspect(parser('@http://host'), ctx), [['
|
|
41
|
-
assert.deepStrictEqual(inspect(parser('@ttp://host'), ctx), [['
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('@http://host'), ctx), [['@http'], '://host']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('@ttp://host'), ctx), [ [ '@ttp' ], '://host' ]);
|
|
42
43
|
assert.deepStrictEqual(inspect(parser('@domain/a'), ctx), [['<a class="account" href="https://domain/@a" target="_blank">@domain/a</a>'], '']);
|
|
43
44
|
assert.deepStrictEqual(inspect(parser('@domain.com/a'), ctx), [['<a class="account" href="https://domain.com/@a" target="_blank">@domain.com/a</a>'], '']);
|
|
44
45
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AutolinkParser } from '../../inline';
|
|
2
|
-
import { State } from '../../context';
|
|
2
|
+
import { State, Backtrack } from '../../context';
|
|
3
3
|
import { union, tails, state, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
|
|
4
4
|
import { unsafelink } from '../link';
|
|
5
5
|
import { str } from '../../source';
|
|
@@ -9,17 +9,20 @@ import { define } from 'typed-dom/dom';
|
|
|
9
9
|
|
|
10
10
|
export const account: AutolinkParser.AccountParser = lazy(() => rewrite(
|
|
11
11
|
open(
|
|
12
|
-
|
|
12
|
+
/(?<![0-9a-z])@/yi,
|
|
13
13
|
tails([
|
|
14
|
-
str(
|
|
15
|
-
str(
|
|
16
|
-
])
|
|
14
|
+
str(/[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*\//yi),
|
|
15
|
+
str(/[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*(?![0-9a-z@#]|>>|:\S)/yi),
|
|
16
|
+
]),
|
|
17
|
+
false,
|
|
18
|
+
[3 | Backtrack.autolink]),
|
|
17
19
|
union([
|
|
18
20
|
constraint(State.autolink, state(State.autolink, fmap(convert(
|
|
19
21
|
source =>
|
|
20
|
-
`[${source}]{ ${
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
`[${source}]{ ${
|
|
23
|
+
source.includes('/')
|
|
24
|
+
? `https://${source.slice(1).replace('/', '/@')}`
|
|
25
|
+
: `/${source}`
|
|
23
26
|
} }`,
|
|
24
27
|
unsafelink,
|
|
25
28
|
false),
|
|
@@ -18,7 +18,7 @@ describe('Unit: parser/inline/autolink/anchor', () => {
|
|
|
18
18
|
assert.deepStrictEqual(inspect(parser('>>https://host'), ctx), undefined);
|
|
19
19
|
assert.deepStrictEqual(inspect(parser('>>tel:1234567890'), ctx), undefined);
|
|
20
20
|
assert.deepStrictEqual(inspect(parser('>>>'), ctx), undefined);
|
|
21
|
-
assert.deepStrictEqual(inspect(parser('a>>0'), ctx), [['a
|
|
21
|
+
assert.deepStrictEqual(inspect(parser('a>>0'), ctx), [['a'], '>>0']);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser(' >>0'), ctx), undefined);
|
|
23
23
|
});
|
|
24
24
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { AutolinkParser } from '../../inline';
|
|
2
|
-
import { State } from '../../context';
|
|
3
|
-
import { union, state, constraint,
|
|
2
|
+
import { State, Backtrack } from '../../context';
|
|
3
|
+
import { union, state, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
|
|
4
4
|
import { unsafelink } from '../link';
|
|
5
|
+
import { str } from '../../source';
|
|
5
6
|
import { define } from 'typed-dom/dom';
|
|
6
7
|
|
|
7
8
|
// Timeline(pseudonym): user/tid
|
|
@@ -14,18 +15,21 @@ import { define } from 'typed-dom/dom';
|
|
|
14
15
|
// 内部表現はUnixTimeに統一する(時系列順)
|
|
15
16
|
// 外部表現は投稿ごとに投稿者の投稿時のタイムゾーンに統一する(非時系列順)
|
|
16
17
|
|
|
17
|
-
export const anchor: AutolinkParser.AnchorParser = lazy(() =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
export const anchor: AutolinkParser.AnchorParser = lazy(() => rewrite(
|
|
19
|
+
open(
|
|
20
|
+
/(?<![0-9a-z])>>/yi,
|
|
21
|
+
str(/(?:[a-z][0-9a-z]*(?:-[0-9a-z]+)*\/)?[0-9a-z]+(?:-[0-9a-z]+)*(?![0-9a-z@#]|>>|:\S)/yi),
|
|
22
|
+
false,
|
|
23
|
+
[3 | Backtrack.autolink]),
|
|
24
|
+
union([
|
|
25
|
+
constraint(State.autolink, state(State.autolink, fmap(convert(
|
|
26
|
+
source =>
|
|
27
|
+
`[${source}]{ ${source.includes('/')
|
|
28
|
+
? `/@${source.slice(2).replace('/', '/timeline?at=')}`
|
|
29
|
+
: `?at=${source.slice(2)}`
|
|
30
|
+
} }`,
|
|
31
|
+
unsafelink,
|
|
32
|
+
false),
|
|
33
|
+
([el]) => [define(el, { class: 'anchor' })]))),
|
|
34
|
+
({ context: { source } }) => [[source]],
|
|
35
|
+
])));
|
|
@@ -10,19 +10,19 @@ describe('Unit: parser/inline/autolink/channel', () => {
|
|
|
10
10
|
|
|
11
11
|
it('invalid', () => {
|
|
12
12
|
assert.deepStrictEqual(inspect(parser(''), ctx), undefined);
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('@a@'), ctx), [['@a
|
|
14
|
-
assert.deepStrictEqual(inspect(parser('@a@b'), ctx), [['@a
|
|
15
|
-
assert.deepStrictEqual(inspect(parser('@a#'), ctx), [['@a
|
|
16
|
-
assert.deepStrictEqual(inspect(parser('@a#1'), ctx), [['@a
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('@a#b@'), ctx), [['@a
|
|
18
|
-
assert.deepStrictEqual(inspect(parser('@a#1@b'), ctx), [['@a
|
|
19
|
-
assert.deepStrictEqual(inspect(parser('@a#b#'), ctx), [['@a#b#'], '']);
|
|
20
|
-
assert.deepStrictEqual(inspect(parser('@a#b#1'), ctx), [['@a#b#1'], '']);
|
|
13
|
+
assert.deepStrictEqual(inspect(parser('@a@'), ctx), [['@a'], '@']);
|
|
14
|
+
assert.deepStrictEqual(inspect(parser('@a@b'), ctx), [['@a'], '@b']);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('@a#'), ctx), [['@a'], '#']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('@a#1'), ctx), [['@a'], '#1']);
|
|
17
|
+
assert.deepStrictEqual(inspect(parser('@a#b@'), ctx), [['@a'], '#b@']);
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('@a#1@b'), ctx), [['@a'], '#1@b']);
|
|
21
19
|
assert.deepStrictEqual(inspect(parser(' @a#b'), ctx), undefined);
|
|
22
20
|
});
|
|
23
21
|
|
|
24
22
|
it('valid', () => {
|
|
25
23
|
assert.deepStrictEqual(inspect(parser('@a#b'), ctx), [['<a class="channel" href="/@a?ch=b">@a#b</a>'], '']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser('@a#b#'), ctx), [['<a class="channel" href="/@a?ch=b">@a#b</a>'], '#']);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser('@a#b#1'), ctx), [['<a class="channel" href="/@a?ch=b">@a#b</a>'], '#1']);
|
|
26
26
|
assert.deepStrictEqual(inspect(parser('@a#b#c'), ctx), [['<a class="channel" href="/@a?ch=b+c">@a#b#c</a>'], '']);
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('@domain/a#b'), ctx), [['<a class="channel" href="https://domain/@a?ch=b" target="_blank">@domain/a#b</a>'], '']);
|
|
28
28
|
});
|
|
@@ -1,22 +1,47 @@
|
|
|
1
1
|
import { AutolinkParser } from '../../inline';
|
|
2
|
-
import { State } from '../../context';
|
|
3
|
-
import { sequence, some, constraint,
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { State, Backtrack } from '../../context';
|
|
3
|
+
import { union, tails, sequence, some, state, constraint, verify, rewrite, open, convert, fmap, lazy } from '../../../combinator';
|
|
4
|
+
import { unsafelink } from '../link';
|
|
5
|
+
import { emoji } from './hashtag';
|
|
6
|
+
import { str } from '../../source';
|
|
7
7
|
import { define } from 'typed-dom/dom';
|
|
8
8
|
|
|
9
9
|
// https://example/@user?ch=a+b must be a user channel page or a redirect page going there.
|
|
10
10
|
|
|
11
|
-
export const channel: AutolinkParser.ChannelParser =
|
|
12
|
-
constraint(State.autolink, bind(
|
|
11
|
+
export const channel: AutolinkParser.ChannelParser = lazy(() => rewrite(
|
|
13
12
|
sequence([
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
open(
|
|
14
|
+
/(?<![0-9a-z])@/yi,
|
|
15
|
+
tails([
|
|
16
|
+
str(/[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*\//yi),
|
|
17
|
+
str(/[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*(?![0-9a-z@]|>>|:\S)/yi),
|
|
18
|
+
]),
|
|
19
|
+
false,
|
|
20
|
+
[3 | Backtrack.autolink]),
|
|
21
|
+
some(open(
|
|
22
|
+
'#',
|
|
23
|
+
verify(
|
|
24
|
+
str(new RegExp([
|
|
25
|
+
/(?!['_])(?:[^\p{C}\p{S}\p{P}\s]|emoji|'(?=[0-9A-Za-z])|_(?=[^'\p{C}\p{S}\p{P}\s]|emoji))+(?![0-9a-z@]|>>|:\S|[^\p{C}\p{S}\p{P}\s]|emoji)/yu.source,
|
|
26
|
+
].join('').replace(/emoji/g, emoji), 'yu')),
|
|
27
|
+
([source]) => !/^[0-9]{1,4}$|^[0-9]{5}/.test(source)),
|
|
28
|
+
false,
|
|
29
|
+
[3 | Backtrack.autolink])),
|
|
16
30
|
]),
|
|
17
|
-
(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
31
|
+
union([
|
|
32
|
+
constraint(State.autolink, state(State.autolink, fmap(convert(
|
|
33
|
+
source =>
|
|
34
|
+
`[${source}]{ ${
|
|
35
|
+
source.includes('/')
|
|
36
|
+
? `https://${source.slice(1, source.indexOf('#')).replace('/', '/@')}`
|
|
37
|
+
: `/${source.slice(0, source.indexOf('#'))}`
|
|
38
|
+
} }`,
|
|
39
|
+
unsafelink,
|
|
40
|
+
false),
|
|
41
|
+
([el], { source, position, range = 0 }) => {
|
|
42
|
+
const src = source.slice(position - range, position);
|
|
43
|
+
const url = `${el.getAttribute('href')}?ch=${src.slice(src.indexOf('#') + 1).replace(/#/g, '+')}`;
|
|
44
|
+
return [define(el, { class: 'channel', href: url }, src)];
|
|
45
|
+
}))),
|
|
46
|
+
({ context: { source } }) => [[source]],
|
|
47
|
+
])));
|
|
@@ -10,23 +10,25 @@ describe('Unit: parser/inline/autolink/email', () => {
|
|
|
10
10
|
|
|
11
11
|
it('invalid', () => {
|
|
12
12
|
assert.deepStrictEqual(inspect(parser(''), ctx), undefined);
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('a@'), ctx), [['a
|
|
14
|
-
assert.deepStrictEqual(inspect(parser('a@+'), ctx), [['a
|
|
15
|
-
assert.deepStrictEqual(inspect(parser('a@_'), ctx), [['a
|
|
16
|
-
assert.deepStrictEqual(inspect(parser('a@-'), ctx), [['a
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('a@.'), ctx), [['a
|
|
18
|
-
assert.deepStrictEqual(inspect(parser('a@b@'), ctx), [['a
|
|
19
|
-
assert.deepStrictEqual(inspect(parser('a@bc@'), ctx), [['a
|
|
20
|
-
assert.deepStrictEqual(inspect(parser('a@b@c'), ctx), [['a
|
|
21
|
-
assert.deepStrictEqual(inspect(parser('a@b#'), ctx), [['a
|
|
22
|
-
assert.deepStrictEqual(inspect(parser('a@b#1'), ctx), [['a
|
|
23
|
-
assert.deepStrictEqual(inspect(parser('a@@'), ctx), [['a
|
|
24
|
-
assert.deepStrictEqual(inspect(parser('a@@b'), ctx), [['a
|
|
13
|
+
assert.deepStrictEqual(inspect(parser('a@'), ctx), [['a'], '@']);
|
|
14
|
+
assert.deepStrictEqual(inspect(parser('a@+'), ctx), [['a'], '@+']);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('a@_'), ctx), [['a'], '@_']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('a@-'), ctx), [['a'], '@-']);
|
|
17
|
+
assert.deepStrictEqual(inspect(parser('a@.'), ctx), [['a'], '@.']);
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('a@b@'), ctx), [['a'], '@b@']);
|
|
19
|
+
assert.deepStrictEqual(inspect(parser('a@bc@'), ctx), [['a'], '@bc@']);
|
|
20
|
+
assert.deepStrictEqual(inspect(parser('a@b@c'), ctx), [['a'], '@b@c']);
|
|
21
|
+
assert.deepStrictEqual(inspect(parser('a@b#'), ctx), [['a'], '@b#']);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser('a@b#1'), ctx), [['a'], '@b#1']);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser('a@@'), ctx), [['a@', '@'], '']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser('a@@b'), ctx), [['a@', '<a class="account" href="/@b">@b</a>'], '']);
|
|
25
25
|
assert.deepStrictEqual(inspect(parser('a+@b'), ctx), [['a'], '+@b']);
|
|
26
26
|
assert.deepStrictEqual(inspect(parser('a__b@c'), ctx), [['a'], '__b@c']);
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('a..b@c'), ctx), [['a'], '..b@c']);
|
|
28
28
|
assert.deepStrictEqual(inspect(parser('a++b@c'), ctx), [['a'], '++b@c']);
|
|
29
|
-
assert.deepStrictEqual(inspect(parser(
|
|
29
|
+
assert.deepStrictEqual(inspect(parser('a@http://host'), ctx), [['a'], '@http://host']);
|
|
30
|
+
assert.deepStrictEqual(inspect(parser('a@ttp://host'), ctx), [['a'], '@ttp://host']);
|
|
31
|
+
assert.deepStrictEqual(inspect(parser(`a@${'b'.repeat(64)}`), ctx), [['a'], `@${'b'.repeat(64)}`]);
|
|
30
32
|
assert.deepStrictEqual(inspect(parser(' a@b'), ctx), undefined);
|
|
31
33
|
});
|
|
32
34
|
|
|
@@ -44,8 +46,6 @@ describe('Unit: parser/inline/autolink/email', () => {
|
|
|
44
46
|
assert.deepStrictEqual(inspect(parser('a@b.'), ctx), [['<a class="email" href="mailto:a@b">a@b</a>'], '.']);
|
|
45
47
|
assert.deepStrictEqual(inspect(parser('a@b.c'), ctx), [['<a class="email" href="mailto:a@b.c">a@b.c</a>'], '']);
|
|
46
48
|
assert.deepStrictEqual(inspect(parser('a@b..c'), ctx), [['<a class="email" href="mailto:a@b">a@b</a>'], '..c']);
|
|
47
|
-
assert.deepStrictEqual(inspect(parser('a@http://host'), ctx), [['<a class="email" href="mailto:a@http">a@http</a>'], '://host']);
|
|
48
|
-
assert.deepStrictEqual(inspect(parser('a@ttp://host'), ctx), [['<a class="email" href="mailto:a@ttp">a@ttp</a>'], '://host']);
|
|
49
49
|
assert.deepStrictEqual(inspect(parser('ab+cd@0'), ctx), [['<a class="email" href="mailto:ab+cd@0">ab+cd@0</a>'], '']);
|
|
50
50
|
});
|
|
51
51
|
|