securemark 0.278.0 → 0.279.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/index.js +82 -54
- package/markdown.d.ts +31 -4
- package/package.json +6 -6
- package/src/combinator/control/manipulation/indent.ts +1 -1
- package/src/debug.test.ts +2 -2
- package/src/parser/api/parse.test.ts +3 -3
- package/src/parser/block/extension/figure.ts +3 -6
- package/src/parser/block/extension/message.ts +2 -0
- package/src/parser/block/extension/table.ts +14 -4
- package/src/parser/block/ilist.ts +4 -6
- package/src/parser/block/mediablock.ts +26 -0
- package/src/parser/block/olist.ts +3 -19
- package/src/parser/block/paragraph.test.ts +3 -3
- package/src/parser/block/table.ts +8 -3
- package/src/parser/block/ulist.ts +17 -5
- package/src/parser/block.ts +3 -0
- package/src/parser/inline/bracket.test.ts +8 -8
- package/src/parser/inline/bracket.ts +2 -2
- package/src/parser/inline/extension/indexer.ts +2 -4
- package/src/parser/inline/html.ts +1 -2
- package/src/parser/inline/remark.test.ts +3 -3
- package/src/parser/inline/remark.ts +1 -1
- package/src/parser/inline.test.ts +12 -12
- package/src/parser/inline.ts +2 -6
- package/src/parser/processor/figure.ts +0 -1
- package/src/parser/processor/note.ts +0 -3
- package/src/parser/visibility.ts +3 -5
- package/src/renderer/render/media/image.ts +1 -1
- package/src/renderer/render.test.ts +5 -5
- package/src/util/quote.test.ts +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../block';
|
|
2
|
-
import { union, inits, sequence, some,
|
|
2
|
+
import { union, inits, sequence, some, block, line, fence, rewrite, close, match, convert, fallback, fmap } from '../../../combinator';
|
|
3
3
|
import { str, contentline, emptyline } from '../../source';
|
|
4
4
|
import { label, segment as seg_label } from '../../inline/extension/label';
|
|
5
5
|
import { ulist } from '../ulist';
|
|
@@ -12,7 +12,6 @@ import { table, segment_ as seg_table } from './table';
|
|
|
12
12
|
import { blockquote, segment as seg_blockquote } from '../blockquote';
|
|
13
13
|
import { placeholder, segment_ as seg_placeholder } from './placeholder';
|
|
14
14
|
import { inline, media, shortmedia } from '../../inline';
|
|
15
|
-
import { State } from '../../context';
|
|
16
15
|
import { visualize, trimBlankStart, trimNodeEnd } from '../../visibility';
|
|
17
16
|
import { memoize } from 'spica/memoize';
|
|
18
17
|
import { html, defrag } from 'typed-dom/dom';
|
|
@@ -43,7 +42,7 @@ export const segment: FigureParser.SegmentParser = block(match(
|
|
|
43
42
|
]),
|
|
44
43
|
]),
|
|
45
44
|
closer),
|
|
46
|
-
([, fence]) => fence.length,
|
|
45
|
+
([, fence]) => fence.length, {})));
|
|
47
46
|
|
|
48
47
|
export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
|
|
49
48
|
convert(source => source.slice(source.match(/^~+(?:\w+\s+)?/)![0].length, source.trimEnd().lastIndexOf('\n')),
|
|
@@ -64,9 +63,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
|
|
|
64
63
|
line(shortmedia),
|
|
65
64
|
])),
|
|
66
65
|
emptyline,
|
|
67
|
-
block(
|
|
68
|
-
state(State.media,
|
|
69
|
-
visualize(trimBlankStart(some(inline))))),
|
|
66
|
+
block(visualize(trimBlankStart(some(inline)))),
|
|
70
67
|
]),
|
|
71
68
|
])),
|
|
72
69
|
([label, param, content, ...caption]: [HTMLAnchorElement, string, ...HTMLElement[]]) => [
|
|
@@ -11,6 +11,7 @@ import { codeblock } from '../codeblock';
|
|
|
11
11
|
import { mathblock } from '../mathblock';
|
|
12
12
|
import { sidefence } from '../sidefence';
|
|
13
13
|
import { blockquote } from '../blockquote';
|
|
14
|
+
import { mediablock } from '../mediablock';
|
|
14
15
|
import { paragraph } from '../paragraph';
|
|
15
16
|
import { unshift, push } from 'spica/array';
|
|
16
17
|
import { html } from 'typed-dom/dom';
|
|
@@ -74,5 +75,6 @@ const content: MessageParser.ContentParser = union([
|
|
|
74
75
|
mathblock,
|
|
75
76
|
sidefence,
|
|
76
77
|
blockquote,
|
|
78
|
+
mediablock,
|
|
77
79
|
paragraph,
|
|
78
80
|
]);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { max, min, isArray } from 'spica/alias';
|
|
2
2
|
import { ExtensionParser } from '../../block';
|
|
3
3
|
import { Tree, eval } from '../../../combinator/data/parser';
|
|
4
|
-
import { union, subsequence, inits, some, creation, block, line, validate, fence, rewrite, open, clear, convert, dup, lazy, fmap } from '../../../combinator';
|
|
5
|
-
import { inline } from '../../inline';
|
|
4
|
+
import { union, subsequence, inits, some, creation, block, line, validate, fence, rewrite, surround, open, clear, convert, dup, lazy, fmap } from '../../../combinator';
|
|
5
|
+
import { inline, medialink, media, shortmedia } from '../../inline';
|
|
6
6
|
import { str, anyline, emptyline, contentline } from '../../source';
|
|
7
7
|
import { visualize, trimBlankStart, trimNodeEnd } from '../../visibility';
|
|
8
8
|
import { unshift, splice } from 'spica/array';
|
|
@@ -84,7 +84,12 @@ const head: CellParser.HeadParser = creation(1, false, block(fmap(open(
|
|
|
84
84
|
anyline,
|
|
85
85
|
some(contentline, delimiter),
|
|
86
86
|
]),
|
|
87
|
-
|
|
87
|
+
union([
|
|
88
|
+
block(surround(/^[^\n]/, medialink, /^\s*$/)),
|
|
89
|
+
block(surround(/^[^\n]/, media, /^\s*$/)),
|
|
90
|
+
block(surround(/^[^\n]/, shortmedia, /^\s*$/)),
|
|
91
|
+
open(/^(?:\s*\n|\s)/, visualize(trimBlankStart(some(inline))), true),
|
|
92
|
+
])),
|
|
88
93
|
true),
|
|
89
94
|
ns => [html('th', attributes(ns.shift()! as string), trimNodeEnd(defrag(ns)))]),
|
|
90
95
|
false));
|
|
@@ -96,7 +101,12 @@ const data: CellParser.DataParser = creation(1, false, block(fmap(open(
|
|
|
96
101
|
anyline,
|
|
97
102
|
some(contentline, delimiter),
|
|
98
103
|
]),
|
|
99
|
-
|
|
104
|
+
union([
|
|
105
|
+
block(surround(/^[^\n]/, medialink, /^\s*$/)),
|
|
106
|
+
block(surround(/^[^\n]/, media, /^\s*$/)),
|
|
107
|
+
block(surround(/^[^\n]/, shortmedia, /^\s*$/)),
|
|
108
|
+
open(/^(?:\s*\n|\s)/, visualize(some(inline)), true),
|
|
109
|
+
])),
|
|
100
110
|
true),
|
|
101
111
|
ns => [html('td', attributes(ns.shift()! as string), trimNodeEnd(defrag(ns)))]),
|
|
102
112
|
false));
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { IListParser } from '../block';
|
|
2
|
-
import { union, inits, some, creation,
|
|
3
|
-
import { ulist_, fillFirstLine } from './ulist';
|
|
4
|
-
import { olist_
|
|
2
|
+
import { union, inits, some, creation, block, line, validate, indent, open, fallback, lazy, fmap } from '../../combinator';
|
|
3
|
+
import { ulist_, invalid, fillFirstLine } from './ulist';
|
|
4
|
+
import { olist_ } from './olist';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
|
-
import { State } from '../context';
|
|
7
6
|
import { html, defrag } from 'typed-dom/dom';
|
|
8
7
|
|
|
9
8
|
export const ilist: IListParser = lazy(() => block(validate(
|
|
10
9
|
/^[-+*](?=[^\S\n]|\n[^\S\n]*\S)/,
|
|
11
|
-
|
|
12
|
-
ilist_))));
|
|
10
|
+
ilist_)));
|
|
13
11
|
|
|
14
12
|
export const ilist_: IListParser = lazy(() => block(fmap(validate(
|
|
15
13
|
/^[-+*](?:$|\s)/,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MediaBlockParser } from '../block';
|
|
2
|
+
import { union, inits, some, block, line, validate, fallback, fmap } from '../../combinator';
|
|
3
|
+
import { medialink, media, shortmedia } from '../inline';
|
|
4
|
+
import { html } from 'typed-dom/dom';
|
|
5
|
+
|
|
6
|
+
export const mediablock: MediaBlockParser = block(validate(['[!', '!'], fmap(
|
|
7
|
+
inits([
|
|
8
|
+
line(union([
|
|
9
|
+
medialink,
|
|
10
|
+
media,
|
|
11
|
+
shortmedia,
|
|
12
|
+
])),
|
|
13
|
+
some(line(fallback(union([
|
|
14
|
+
medialink,
|
|
15
|
+
media,
|
|
16
|
+
shortmedia,
|
|
17
|
+
]), ({ source }) => [[html('div', [html('span', attrs, source.replace('\n', ''))])], '']))),
|
|
18
|
+
]),
|
|
19
|
+
ns => [html('div', ns)])));
|
|
20
|
+
|
|
21
|
+
const attrs = {
|
|
22
|
+
class: 'invalid',
|
|
23
|
+
'data-invalid-syntax': 'mediablock',
|
|
24
|
+
'data-invalid-type': 'syntax',
|
|
25
|
+
'data-invalid-message': 'Not media syntax',
|
|
26
|
+
} as const;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { OListParser } from '../block';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { checkbox, ulist_, fillFirstLine } from './ulist';
|
|
2
|
+
import { union, inits, subsequence, some, creation, block, line, validate, indent, focus, open, close, match, trim, fallback, lazy, fmap } from '../../combinator';
|
|
3
|
+
import { ulist_, checkbox, invalid, fillFirstLine } from './ulist';
|
|
5
4
|
import { ilist_ } from './ilist';
|
|
6
5
|
import { inline, indexee, indexer } from '../inline';
|
|
7
6
|
import { index } from '../inline/extension/index';
|
|
8
|
-
import { contentline } from '../source';
|
|
9
|
-
import { State } from '../context';
|
|
10
7
|
import { visualize, trimBlank } from '../visibility';
|
|
11
8
|
import { memoize } from 'spica/memoize';
|
|
12
9
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
@@ -21,8 +18,7 @@ export const olist: OListParser = lazy(() => block(validate(
|
|
|
21
18
|
/^([0-9]+|[a-z]+|[A-Z]+)(?:-[0-9]+)*\.(?=[^\S\n]|\n[^\S\n]*\S)/.source,
|
|
22
19
|
/^\(([0-9]+|[a-z]+)\)(?:-[0-9]+)*(?=[^\S\n]|\n[^\S\n]*\S)/.source,
|
|
23
20
|
].join('|')),
|
|
24
|
-
|
|
25
|
-
olist_))));
|
|
21
|
+
olist_)));
|
|
26
22
|
|
|
27
23
|
export const olist_: OListParser = lazy(() => block(union([
|
|
28
24
|
match(
|
|
@@ -59,18 +55,6 @@ const heads = {
|
|
|
59
55
|
({ source }) => [[source.trimEnd().replace(/^\($/, '(1)').replace(/^\((\w+)$/, '($1)')], '']),
|
|
60
56
|
} as const;
|
|
61
57
|
|
|
62
|
-
export const invalid = rewrite(
|
|
63
|
-
inits([contentline, indent<Parser<string>>(({ source }) => [[source], ''])]),
|
|
64
|
-
({ source }) => [[
|
|
65
|
-
'',
|
|
66
|
-
html('span', {
|
|
67
|
-
class: 'invalid',
|
|
68
|
-
'data-invalid-syntax': 'list',
|
|
69
|
-
'data-invalid-type': 'syntax',
|
|
70
|
-
'data-invalid-message': 'Fix the indent or the head of the list item',
|
|
71
|
-
}, source.replace('\n', ''))
|
|
72
|
-
], '']);
|
|
73
|
-
|
|
74
58
|
function idx(value: string): number {
|
|
75
59
|
switch (value) {
|
|
76
60
|
case 'i':
|
|
@@ -35,9 +35,9 @@ describe('Unit: parser/block/paragraph', () => {
|
|
|
35
35
|
assert.deepStrictEqual(inspect(parser('==a\n<wbr>==\nb')), [['<p>==a<br><wbr>==<br>b</p>'], '']);
|
|
36
36
|
assert.deepStrictEqual(inspect(parser('http://host#\\')), [['<p><a class="url" href="http://host#\\" target="_blank">http://host#\\</a></p>'], '']);
|
|
37
37
|
assert.deepStrictEqual(inspect(parser('a\nhttp://host#\\ \nb')), [['<p>a<br><a class="url" href="http://host#\\" target="_blank">http://host#\\</a><br>b</p>'], '']);
|
|
38
|
-
assert.deepStrictEqual(inspect(parser('!http://host#\\')), [['<p><a href="http://host#\\" target="_blank"><img class="media" data-src="http://host#\\" alt=""></a></p>'], '']);
|
|
39
|
-
assert.deepStrictEqual(inspect(parser('!http://host#\\ a')), [['<p>!<a class="url" href="http://host#" target="_blank">http://host#</a> a</p>'], '']);
|
|
40
|
-
assert.deepStrictEqual(inspect(parser(' !http://host#\\')), [['<p> !<a class="url" href="http://host#" target="_blank">http://host#</a></p>'], '']);
|
|
38
|
+
//assert.deepStrictEqual(inspect(parser('!http://host#\\')), [['<p><a href="http://host#\\" target="_blank"><img class="media" data-src="http://host#\\" alt=""></a></p>'], '']);
|
|
39
|
+
//assert.deepStrictEqual(inspect(parser('!http://host#\\ a')), [['<p>!<a class="url" href="http://host#" target="_blank">http://host#</a> a</p>'], '']);
|
|
40
|
+
//assert.deepStrictEqual(inspect(parser(' !http://host#\\')), [['<p> !<a class="url" href="http://host#" target="_blank">http://host#</a></p>'], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('\ta')), [['<p>\ta</p>'], '']);
|
|
42
42
|
});
|
|
43
43
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TableParser } from '../block';
|
|
2
|
-
import { union, sequence, some, creation, block, line, validate, focus, rewrite, surround, open, fallback, lazy, fmap } from '../../combinator';
|
|
3
|
-
import { inline } from '../inline';
|
|
2
|
+
import { union, sequence, some, creation, block, line, validate, focus, rewrite, surround, open, close, trimStart, fallback, lazy, fmap } from '../../combinator';
|
|
3
|
+
import { inline, media, medialink, shortmedia } from '../inline';
|
|
4
4
|
import { contentline } from '../source';
|
|
5
5
|
import { trimBlankStart, trimNodeEnd } from '../visibility';
|
|
6
6
|
import { duffReduce } from 'spica/duff';
|
|
@@ -49,7 +49,12 @@ const align: AlignParser = creation(1, false, fmap(open(
|
|
|
49
49
|
|
|
50
50
|
const cell: CellParser = surround(
|
|
51
51
|
/^\|\s*(?=\S)/,
|
|
52
|
-
|
|
52
|
+
trimStart(union([
|
|
53
|
+
close(medialink, /^\s*(?=\||$)/),
|
|
54
|
+
close(media, /^\s*(?=\||$)/),
|
|
55
|
+
close(shortmedia, /^\s*(?=\||$)/),
|
|
56
|
+
trimBlankStart(some(inline, /^\|/, [[/^[|\\]?\s*$/, 9]])),
|
|
57
|
+
])),
|
|
53
58
|
/^[^|]*/, true);
|
|
54
59
|
|
|
55
60
|
const head: CellParser.HeadParser = creation(1, false, fmap(
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { UListParser } from '../block';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { Parser } from '../../combinator/data/parser';
|
|
3
|
+
import { union, inits, subsequence, some, creation, block, line, validate, indent, focus, rewrite, open, close, trim, fallback, lazy, fmap } from '../../combinator';
|
|
4
|
+
import { olist_ } from './olist';
|
|
4
5
|
import { ilist_ } from './ilist';
|
|
5
6
|
import { inline, indexer, indexee } from '../inline';
|
|
6
7
|
import { index } from '../inline/extension/index';
|
|
7
|
-
import {
|
|
8
|
+
import { contentline } from '../source';
|
|
8
9
|
import { visualize, trimBlank } from '../visibility';
|
|
9
10
|
import { unshift } from 'spica/array';
|
|
10
11
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
11
12
|
|
|
12
13
|
export const ulist: UListParser = lazy(() => block(validate(
|
|
13
14
|
/^-(?=[^\S\n]|\n[^\S\n]*\S)/,
|
|
14
|
-
|
|
15
|
-
ulist_))));
|
|
15
|
+
ulist_)));
|
|
16
16
|
|
|
17
17
|
export const ulist_: UListParser = lazy(() => block(fmap(validate(
|
|
18
18
|
/^-(?=$|\s)/,
|
|
@@ -38,6 +38,18 @@ export const checkbox = creation(1, false, focus(
|
|
|
38
38
|
html('span', { class: 'checkbox' }, source[1].trimStart() ? '☑' : '☐'),
|
|
39
39
|
], '']));
|
|
40
40
|
|
|
41
|
+
export const invalid = rewrite(
|
|
42
|
+
inits([contentline, indent<Parser<string>>(({ source }) => [[source], ''])]),
|
|
43
|
+
({ source }) => [[
|
|
44
|
+
'',
|
|
45
|
+
html('span', {
|
|
46
|
+
class: 'invalid',
|
|
47
|
+
'data-invalid-syntax': 'list',
|
|
48
|
+
'data-invalid-type': 'syntax',
|
|
49
|
+
'data-invalid-message': 'Fix the indent or the head of the list item',
|
|
50
|
+
}, source.replace('\n', ''))
|
|
51
|
+
], '']);
|
|
52
|
+
|
|
41
53
|
export function fillFirstLine(ns: (HTMLElement | string)[]): (HTMLElement | string)[] {
|
|
42
54
|
return ns.length === 1
|
|
43
55
|
&& typeof ns[0] === 'object'
|
package/src/parser/block.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { mathblock } from './block/mathblock';
|
|
|
13
13
|
import { extension } from './block/extension';
|
|
14
14
|
import { sidefence } from './block/sidefence';
|
|
15
15
|
import { blockquote } from './block/blockquote';
|
|
16
|
+
import { mediablock } from './block/mediablock';
|
|
16
17
|
import { reply } from './block/reply';
|
|
17
18
|
import { paragraph } from './block/paragraph';
|
|
18
19
|
import { rnd0Z } from 'spica/random';
|
|
@@ -31,6 +32,7 @@ export import MathBlockParser = BlockParser.MathBlockParser;
|
|
|
31
32
|
export import ExtensionParser = BlockParser.ExtensionParser;
|
|
32
33
|
export import SidefenceParser = BlockParser.SidefenceParser;
|
|
33
34
|
export import BlockquoteParser = BlockParser.BlockquoteParser;
|
|
35
|
+
export import MediaBlockParser = BlockParser.MediaBlockParser;
|
|
34
36
|
export import ReplyParser = BlockParser.ReplyParser;
|
|
35
37
|
export import ParagraphParser = BlockParser.ParagraphParser;
|
|
36
38
|
|
|
@@ -50,6 +52,7 @@ export const block: BlockParser = creation(1, false, error(
|
|
|
50
52
|
extension,
|
|
51
53
|
sidefence,
|
|
52
54
|
blockquote,
|
|
55
|
+
mediablock,
|
|
53
56
|
reply,
|
|
54
57
|
paragraph
|
|
55
58
|
]))));
|
|
@@ -7,9 +7,9 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
7
7
|
const parser = (source: string) => some(bracket)({ source, context: {} });
|
|
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')), [['
|
|
12
|
+
assert.deepStrictEqual(inspect(parser('(a')), [['(', 'a'], '']);
|
|
13
13
|
assert.deepStrictEqual(inspect(parser('(0)')), [['(', '0', ')'], '']);
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('(1)')), [['(', '1', ')'], '']);
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('(10)')), [['(', '10', ')'], '']);
|
|
@@ -39,7 +39,7 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('(ABBR, ABBR)')), [['(', 'ABBR, ABBR', ')'], '']);
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('(\\a)')), [['<span class="paren">(a)</span>'], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('(==)')), [['<span class="paren">(==)</span>'], '']);
|
|
42
|
-
assert.deepStrictEqual(inspect(parser('($)$')), [['
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('($)$')), [['(', '<span class="math" translate="no" data-src="$)$">$)$</span>'], '']);
|
|
43
43
|
assert.deepStrictEqual(inspect(parser(')')), undefined);
|
|
44
44
|
assert.deepStrictEqual(inspect(parser('(1,2)')), [['(', '1,2', ')'], '']);
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('(0-1)')), [['(', '0-1', ')'], '']);
|
|
@@ -51,12 +51,12 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
it('[', () => {
|
|
54
|
-
assert.deepStrictEqual(inspect(parser('[')), [['
|
|
54
|
+
assert.deepStrictEqual(inspect(parser('[')), [['['], '']);
|
|
55
55
|
assert.deepStrictEqual(inspect(parser('[]')), [['[', ']'], '']);
|
|
56
|
-
assert.deepStrictEqual(inspect(parser('[a')), [['
|
|
56
|
+
assert.deepStrictEqual(inspect(parser('[a')), [['[', 'a'], '']);
|
|
57
57
|
assert.deepStrictEqual(inspect(parser('[a]')), [['[', 'a', ']'], '']);
|
|
58
58
|
assert.deepStrictEqual(inspect(parser('[==]')), [['[', '==', ']'], '']);
|
|
59
|
-
assert.deepStrictEqual(inspect(parser('[$]$')), [['
|
|
59
|
+
assert.deepStrictEqual(inspect(parser('[$]$')), [['[', '<span class="math" translate="no" data-src="$]$">$]$</span>'], '']);
|
|
60
60
|
assert.deepStrictEqual(inspect(parser(']')), undefined);
|
|
61
61
|
});
|
|
62
62
|
|
|
@@ -74,8 +74,8 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
74
74
|
assert.deepStrictEqual(inspect(parser('""')), [['"', '"'], '']);
|
|
75
75
|
assert.deepStrictEqual(inspect(parser('"a')), [['"', 'a'], '']);
|
|
76
76
|
assert.deepStrictEqual(inspect(parser('"a"')), [['"', 'a', '"'], '']);
|
|
77
|
-
assert.deepStrictEqual(inspect(parser('"(")"')), [['"', '
|
|
78
|
-
assert.deepStrictEqual(inspect(parser('"(("')), [['"', '
|
|
77
|
+
assert.deepStrictEqual(inspect(parser('"(")"')), [['"', '(', '"'], ')"']);
|
|
78
|
+
assert.deepStrictEqual(inspect(parser('"(("')), [['"', '(', '(', '"'], '']);
|
|
79
79
|
assert.deepStrictEqual(inspect(parser('"(\\")"')), [['"', '<span class="paren">(")</span>', '"'], '']);
|
|
80
80
|
assert.deepStrictEqual(inspect(parser('"(\n)"')), [['"', '<span class="paren">(<br>)</span>', '"'], '']);
|
|
81
81
|
assert.deepStrictEqual(inspect(parser('"(\\\n)"')), [['"', '<span class="paren">(<br>)</span>', '"'], '']);
|
|
@@ -12,14 +12,14 @@ export const bracket: BracketParser = lazy(() => union([
|
|
|
12
12
|
surround(str('('), syntax(Syntax.none, 2, 1, State.none, str(index)), str(')')),
|
|
13
13
|
surround(str('('), syntax(Syntax.bracket, 2, 1, State.none, some(inline, ')', [[')', 2]])), str(')'), true,
|
|
14
14
|
([as, bs = [], cs], rest) => [[html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))], rest],
|
|
15
|
-
([as, bs = []], rest) => [unshift(
|
|
15
|
+
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
16
16
|
surround(str('('), syntax(Syntax.none, 2, 1, State.none, str(new RegExp(index.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)/g, c => c.trimStart() && String.fromCharCode(c.charCodeAt(0) + 0xFEE0))))), str(')')),
|
|
17
17
|
surround(str('('), syntax(Syntax.bracket, 2, 1, State.none, some(inline, ')', [[')', 2]])), 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
20
|
surround(str('['), syntax(Syntax.bracket, 2, 1, State.none, some(inline, ']', [[']', 2]])), str(']'), true,
|
|
21
21
|
undefined,
|
|
22
|
-
([as, bs = []], rest) => [unshift(
|
|
22
|
+
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
23
23
|
surround(str('{'), syntax(Syntax.bracket, 2, 1, State.none, some(inline, '}', [['}', 2]])), str('}'), true,
|
|
24
24
|
undefined,
|
|
25
25
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
|
-
import { union, creation,
|
|
2
|
+
import { union, creation, focus, surround } from '../../../combinator';
|
|
3
3
|
import { signature } from './index';
|
|
4
|
-
import { State } from '../../context';
|
|
5
4
|
import { html } from 'typed-dom/dom';
|
|
6
5
|
|
|
7
6
|
export const indexer: ExtensionParser.IndexerParser = surround(
|
|
8
7
|
/^\s+\[(?=\|\S)/,
|
|
9
|
-
state(State.index, false,
|
|
10
8
|
union([
|
|
11
9
|
signature,
|
|
12
10
|
creation(focus(/^\|(?=\])/, () => [[html('span', { class: 'indexer', 'data-index': '' })], ''])),
|
|
13
|
-
])
|
|
11
|
+
]),
|
|
14
12
|
/^\]\s*$/);
|
|
@@ -41,8 +41,7 @@ export const html: HTMLParser = lazy(() => validate('<', validate(/^<[a-z]+(?=[^
|
|
|
41
41
|
([as, bs = [], cs], rest) =>
|
|
42
42
|
[[elem(tag, as, bs, cs)], rest],
|
|
43
43
|
([as, bs = []], rest) =>
|
|
44
|
-
[[elem(tag, as, bs, [])], rest]),
|
|
45
|
-
([, tag]) => TAGS.indexOf(tag), [])),
|
|
44
|
+
[[elem(tag, as, bs, [])], rest]))),
|
|
46
45
|
match(
|
|
47
46
|
/^<([a-z]+)(?=[^\S\n]|>)/i,
|
|
48
47
|
memoize(
|
|
@@ -16,12 +16,12 @@ describe('Unit: parser/inline/remark', () => {
|
|
|
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="remark"><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'], '']);
|
|
@@ -134,7 +134,7 @@ describe('Unit: parser/inline', () => {
|
|
|
134
134
|
assert.deepStrictEqual(inspect(parser('{a}')), [['<a class="url" href="a">a</a>'], '']);
|
|
135
135
|
assert.deepStrictEqual(inspect(parser('{{a}}')), [['<span class="template">{{a}}</span>'], '']);
|
|
136
136
|
assert.deepStrictEqual(inspect(parser('\r!{}')), [['!', '{', '}'], '']);
|
|
137
|
-
assert.deepStrictEqual(inspect(parser('\r!{a}')), [['<a
|
|
137
|
+
assert.deepStrictEqual(inspect(parser('\r!{a}')), [['!', '<a class="url" href="a">a</a>'], '']);
|
|
138
138
|
assert.deepStrictEqual(inspect(parser('\r!{{a}}')), [['!', '<span class="template">{{a}}</span>'], '']);
|
|
139
139
|
assert.deepStrictEqual(inspect(parser('\r!{{{a}}}')), [['!', '<span class="template">{{{a}}}</span>'], '']);
|
|
140
140
|
assert.deepStrictEqual(inspect(parser('\r!!{a}')), [['!', '!', '<a class="url" href="a">a</a>'], '']);
|
|
@@ -143,35 +143,35 @@ describe('Unit: parser/inline', () => {
|
|
|
143
143
|
assert.deepStrictEqual(inspect(parser('${{{a}}}')), [['$', '<span class="template">{{{a}}}</span>'], '']);
|
|
144
144
|
assert.deepStrictEqual(inspect(parser('Di$ney Micro$oft')), [['Di', '$', 'ney', ' ', 'Micro', '$', 'oft'], '']);
|
|
145
145
|
assert.deepStrictEqual(inspect(parser('Di$ney, Micro$oft')), [['Di', '$', 'ney', ',', ' ', 'Micro', '$', 'oft'], '']);
|
|
146
|
-
assert.deepStrictEqual(inspect(parser('(((a))')), [['
|
|
147
|
-
assert.deepStrictEqual(inspect(parser('((((a))')), [['
|
|
146
|
+
assert.deepStrictEqual(inspect(parser('(((a))')), [['(', '<sup class="annotation"><span>a</span></sup>'], '']);
|
|
147
|
+
assert.deepStrictEqual(inspect(parser('((((a))')), [['(', '(', '<sup class="annotation"><span>a</span></sup>'], '']);
|
|
148
148
|
assert.deepStrictEqual(inspect(parser('((((a))))')), [['<sup class="annotation"><span><span class="paren">((a))</span></span></sup>'], '']);
|
|
149
149
|
assert.deepStrictEqual(inspect(parser('((<bdi>))')), [['<sup class="annotation"><span><span class="invalid"><bdi></span></span></sup>'], '']);
|
|
150
|
-
assert.deepStrictEqual(inspect(parser('((${))}$')), [['
|
|
150
|
+
assert.deepStrictEqual(inspect(parser('((${))}$')), [['(', '(', '<span class="math" translate="no" data-src="${))}$">${))}$</span>'], '']);
|
|
151
151
|
assert.deepStrictEqual(inspect(parser('"((""))')), [['"', '<sup class="annotation"><span>""</span></sup>'], '']);
|
|
152
|
-
assert.deepStrictEqual(inspect(parser('[[[a]]')), [['
|
|
153
|
-
assert.deepStrictEqual(inspect(parser('[[[[a]]')), [['
|
|
152
|
+
assert.deepStrictEqual(inspect(parser('[[[a]]')), [['[', '<sup class="reference"><span>a</span></sup>'], '']);
|
|
153
|
+
assert.deepStrictEqual(inspect(parser('[[[[a]]')), [['[', '[', '<sup class="reference"><span>a</span></sup>'], '']);
|
|
154
154
|
assert.deepStrictEqual(inspect(parser('[[[[a]]]]')), [['<sup class="reference"><span>[[a]]</span></sup>'], '']);
|
|
155
155
|
assert.deepStrictEqual(inspect(parser('[[[$-1]]]')), [['<sup class="reference"><span><a class="label" data-label="$-1">$-1</a></span></sup>'], '']);
|
|
156
156
|
assert.deepStrictEqual(inspect(parser('[[[]{a}]]')), [['<sup class="reference"><span><a class="url" href="a">a</a></span></sup>'], '']);
|
|
157
157
|
assert.deepStrictEqual(inspect(parser('[[[a]{b}]]')), [['<sup class="reference"><span><a class="link" href="b">a</a></span></sup>'], '']);
|
|
158
158
|
assert.deepStrictEqual(inspect(parser('[(([a]{#}))]{#}')), [['<a class="link" href="#"><span class="paren">(<span class="paren">([a]{#})</span>)</span></a>'], '']);
|
|
159
159
|
assert.deepStrictEqual(inspect(parser('[[<bdi>]]')), [['<sup class="reference"><span><span class="invalid"><bdi></span></span></sup>'], '']);
|
|
160
|
-
assert.deepStrictEqual(inspect(parser('[[${]]}$')), [['
|
|
160
|
+
assert.deepStrictEqual(inspect(parser('[[${]]}$')), [['[', '[', '<span class="math" translate="no" data-src="${]]}$">${]]}$</span>'], '']);
|
|
161
161
|
assert.deepStrictEqual(inspect(parser('"[[""]]')), [['"', '<sup class="reference"><span>""</span></sup>'], '']);
|
|
162
162
|
assert.deepStrictEqual(inspect(parser('[==a==]{b}')), [['<a class="link" href="b">==a==</a>'], '']);
|
|
163
163
|
assert.deepStrictEqual(inspect(parser('[[a](b)]{c}')), [['<a class="link" href="c"><ruby>a<rp>(</rp><rt>b</rt><rp>)</rp></ruby></a>'], '']);
|
|
164
|
-
assert.deepStrictEqual(inspect(parser('[[[[[[[{a}')), [['
|
|
164
|
+
assert.deepStrictEqual(inspect(parser('[[[[[[[{a}')), [['[', '[', '[', '[', '[', '[', '[', '<a class="url" href="a">a</a>'], '']);
|
|
165
165
|
assert.deepStrictEqual(inspect(parser('<http://host>')), [['<', '<a class="url" href="http://host" target="_blank">http://host</a>', '>'], '']);
|
|
166
|
-
assert.deepStrictEqual(inspect(parser('[~http://host')), [['
|
|
167
|
-
assert.deepStrictEqual(inspect(parser('[~a@b')), [['
|
|
166
|
+
assert.deepStrictEqual(inspect(parser('[~http://host')), [['[', '~', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
|
|
167
|
+
assert.deepStrictEqual(inspect(parser('[~a@b')), [['[', '~', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
|
|
168
168
|
assert.deepStrictEqual(inspect(parser('[~~a~~]')), [['[', '<del>a</del>', ']'], '']);
|
|
169
169
|
assert.deepStrictEqual(inspect(parser('[^http://host')), [['[^', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
|
|
170
170
|
assert.deepStrictEqual(inspect(parser('[^a@b')), [['[^', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
|
|
171
171
|
assert.deepStrictEqual(inspect(parser('[#a++b\nc++]')), [['[', '<a class="hashtag" href="/hashtags/a">#a</a>', '<ins>b<br>c</ins>', ']'], '']);
|
|
172
172
|
assert.deepStrictEqual(inspect(parser('[++a\nb++]{/}')), [['[', '<ins>a<br>b</ins>', ']', '<a class="url" href="/">/</a>'], '']);
|
|
173
173
|
assert.deepStrictEqual(inspect(parser('[++a\nb]++')), [['[', '++', 'a', '<br>', 'b', ']', '++'], '']);
|
|
174
|
-
assert.deepStrictEqual(inspect(parser('[++[a\nb++]')), [['
|
|
174
|
+
assert.deepStrictEqual(inspect(parser('[++[a\nb++]')), [['[', '++', '[', 'a', '<br>', 'b', '++', ']'], '']);
|
|
175
175
|
assert.deepStrictEqual(inspect(parser('[[++a\nb++]]')), [['[', '[', '<ins>a<br>b</ins>', ']', ']'], '']);
|
|
176
176
|
assert.deepStrictEqual(inspect(parser('"[% *"*"*')), [['"', '[%', ' ', '*', '"', '*', '"', '*'], '']);
|
|
177
177
|
assert.deepStrictEqual(inspect(parser('"[% "*"* %]')), [['"', '<span class="remark"><input type="checkbox"><span>[% "*"* %]</span></span>'], '']);
|
|
@@ -242,7 +242,7 @@ describe('Unit: parser/inline', () => {
|
|
|
242
242
|
assert.deepStrictEqual(inspect(parser('*a*#b')), [['<em>a</em>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
|
|
243
243
|
assert.deepStrictEqual(inspect(parser('((a))#b')), [['<sup class="annotation"><span>a</span></sup>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
|
|
244
244
|
assert.deepStrictEqual(inspect(parser('[[a]]#b')), [['<sup class="reference"><span>a</span></sup>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
|
|
245
|
-
assert.deepStrictEqual(inspect(parser('[#a')), [['
|
|
245
|
+
assert.deepStrictEqual(inspect(parser('[#a')), [['[', '<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
|
|
246
246
|
assert.deepStrictEqual(inspect(parser('|#a')), [['|', '<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
|
|
247
247
|
assert.deepStrictEqual(inspect(parser(' #a')), [[' ', '<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
|
|
248
248
|
});
|
package/src/parser/inline.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { remark } from './inline/remark';
|
|
|
7
7
|
import { math } from './inline/math';
|
|
8
8
|
import { extension } from './inline/extension';
|
|
9
9
|
import { ruby } from './inline/ruby';
|
|
10
|
-
import { textlink
|
|
10
|
+
import { textlink } from './inline/link';
|
|
11
11
|
import { html } from './inline/html';
|
|
12
12
|
import { insertion } from './inline/insertion';
|
|
13
13
|
import { deletion } from './inline/deletion';
|
|
@@ -16,9 +16,7 @@ import { emstrong } from './inline/emstrong';
|
|
|
16
16
|
import { emphasis } from './inline/emphasis';
|
|
17
17
|
import { strong } from './inline/strong';
|
|
18
18
|
import { code } from './inline/code';
|
|
19
|
-
import { linemedia } from './inline/media';
|
|
20
19
|
import { htmlentity } from './inline/htmlentity';
|
|
21
|
-
import { lineshortmedia } from './inline/shortmedia';
|
|
22
20
|
import { autolink } from './inline/autolink';
|
|
23
21
|
import { bracket } from './inline/bracket';
|
|
24
22
|
import { text } from './source';
|
|
@@ -56,8 +54,6 @@ export const inline: InlineParser = lazy(() => union([
|
|
|
56
54
|
extension,
|
|
57
55
|
ruby,
|
|
58
56
|
textlink,
|
|
59
|
-
linemedialink,
|
|
60
|
-
linemedia,
|
|
61
57
|
html,
|
|
62
58
|
insertion,
|
|
63
59
|
deletion,
|
|
@@ -67,7 +63,6 @@ export const inline: InlineParser = lazy(() => union([
|
|
|
67
63
|
emphasis,
|
|
68
64
|
code,
|
|
69
65
|
htmlentity,
|
|
70
|
-
lineshortmedia,
|
|
71
66
|
autolink,
|
|
72
67
|
bracket,
|
|
73
68
|
text
|
|
@@ -75,5 +70,6 @@ export const inline: InlineParser = lazy(() => union([
|
|
|
75
70
|
|
|
76
71
|
export { indexee } from './inline/extension/indexee';
|
|
77
72
|
export { indexer } from './inline/extension/indexer';
|
|
73
|
+
export { medialink } from './inline/link';
|
|
78
74
|
export { media } from './inline/media';
|
|
79
75
|
export { shortmedia } from './inline/shortmedia';
|
|
@@ -14,7 +14,6 @@ export function* note(
|
|
|
14
14
|
): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
|
|
15
15
|
yield* annotation(target, notes?.annotations, opts, bottom);
|
|
16
16
|
yield* reference(target, notes?.references, opts, bottom);
|
|
17
|
-
return;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
export const annotation = build('annotation', n => `*${n}`, 'h1, h2, h3, h4, h5, h6, aside.aside, hr');
|
|
@@ -180,7 +179,6 @@ function build(
|
|
|
180
179
|
el.remove();
|
|
181
180
|
}
|
|
182
181
|
}
|
|
183
|
-
return;
|
|
184
182
|
}
|
|
185
183
|
|
|
186
184
|
function* proc(defs: Map<string, HTMLLIElement>, note: HTMLOListElement): Generator<HTMLLIElement | undefined, undefined, undefined> {
|
|
@@ -213,7 +211,6 @@ function build(
|
|
|
213
211
|
--length;
|
|
214
212
|
assert(children.length === length);
|
|
215
213
|
}
|
|
216
|
-
return;
|
|
217
214
|
}
|
|
218
215
|
}
|
|
219
216
|
|
package/src/parser/visibility.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { Parser, Input, eval } from '../combinator/data/parser';
|
|
|
3
3
|
import { union, some, verify, convert, fmap } from '../combinator';
|
|
4
4
|
import { unsafehtmlentity } from './inline/htmlentity';
|
|
5
5
|
import { linebreak, unescsource } from './source';
|
|
6
|
-
import { State } from './context';
|
|
7
6
|
import { invisibleHTMLEntityNames } from './api/normalize';
|
|
8
7
|
import { reduce } from 'spica/memoize';
|
|
9
8
|
import { push } from 'spica/array';
|
|
@@ -23,13 +22,12 @@ export function visualize<T extends HTMLElement | string>(parser: Parser<T>): Pa
|
|
|
23
22
|
return union([
|
|
24
23
|
convert(
|
|
25
24
|
source => source.replace(blank.line, line => line.replace(/[\\&<]/g, '\x1B$&')),
|
|
26
|
-
verify(parser, (ns, rest
|
|
25
|
+
verify(parser, (ns, rest) => !rest && hasVisible(ns))),
|
|
27
26
|
some(union([linebreak, unescsource])),
|
|
28
27
|
]);
|
|
29
28
|
}
|
|
30
29
|
function hasVisible(
|
|
31
30
|
nodes: readonly (HTMLElement | string)[],
|
|
32
|
-
{ state = 0 }: MarkdownParser.Context = {},
|
|
33
31
|
): boolean {
|
|
34
32
|
for (let i = 0; i < nodes.length; ++i) {
|
|
35
33
|
const node = nodes[i];
|
|
@@ -38,8 +36,8 @@ function hasVisible(
|
|
|
38
36
|
}
|
|
39
37
|
else {
|
|
40
38
|
if (node.innerText.trimStart()) return true;
|
|
41
|
-
if (state & State.media ^ State.media &&
|
|
42
|
-
|
|
39
|
+
//if (state & State.media ^ State.media &&
|
|
40
|
+
// (node.classList.contains('media') || node.getElementsByClassName('media')[0])) return true;
|
|
43
41
|
}
|
|
44
42
|
}
|
|
45
43
|
return false;
|
|
@@ -15,6 +15,6 @@ export function image(source: HTMLImageElement, url: URL, cache?: Dict<string, H
|
|
|
15
15
|
source.cloneNode(true),
|
|
16
16
|
Object.fromEntries([...source.attributes]
|
|
17
17
|
.filter(attr => !['class', 'data-type', 'data-src', 'src', 'loading'].includes(attr.name))
|
|
18
|
-
.map(attr => [attr.name, null]))));
|
|
18
|
+
.map(attr => [attr.name, attr.name === 'alt' ? '' : null]))));
|
|
19
19
|
return source;
|
|
20
20
|
}
|