securemark 0.283.7 → 0.285.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 +8 -0
- package/README.md +11 -11
- package/dist/index.js +182 -57
- package/markdown.d.ts +26 -17
- package/package.json +1 -1
- package/src/parser/context.ts +4 -4
- package/src/parser/inline/autolink/url.test.ts +1 -1
- package/src/parser/inline/bracket.test.ts +2 -2
- package/src/parser/inline/deletion.ts +15 -14
- package/src/parser/inline/emphasis.ts +2 -2
- package/src/parser/inline/emstrong.test.ts +115 -0
- package/src/parser/inline/emstrong.ts +71 -37
- package/src/parser/inline/extension/index.ts +2 -2
- package/src/parser/inline/extension/label.ts +1 -1
- package/src/parser/inline/extension/placeholder.ts +2 -2
- package/src/parser/inline/html.ts +2 -2
- package/src/parser/inline/insertion.ts +15 -14
- package/src/parser/inline/italic.test.ts +72 -0
- package/src/parser/inline/italic.ts +22 -0
- package/src/parser/inline/link.ts +1 -1
- package/src/parser/inline/mark.ts +22 -21
- package/src/parser/inline/math.ts +1 -1
- package/src/parser/inline/ruby.ts +6 -4
- package/src/parser/inline/strong.ts +2 -2
- package/src/parser/inline/template.ts +1 -1
- package/src/parser/inline.test.ts +12 -38
- package/src/parser/inline.ts +8 -4
- package/src/parser/source/text.ts +0 -3
- package/src/parser/util.ts +66 -1
- package/src/parser/visibility.ts +22 -19
package/markdown.d.ts
CHANGED
|
@@ -652,8 +652,8 @@ export namespace MarkdownParser {
|
|
|
652
652
|
InlineParser.TemplateParser,
|
|
653
653
|
InlineParser.RemarkParser,
|
|
654
654
|
InlineParser.ExtensionParser,
|
|
655
|
-
InlineParser.RubyParser,
|
|
656
655
|
InlineParser.LinkParser.TextLinkParser,
|
|
656
|
+
InlineParser.RubyParser,
|
|
657
657
|
InlineParser.HTMLParser,
|
|
658
658
|
InlineParser.InsertionParser,
|
|
659
659
|
InlineParser.DeletionParser,
|
|
@@ -661,6 +661,7 @@ export namespace MarkdownParser {
|
|
|
661
661
|
InlineParser.EmStrongParser,
|
|
662
662
|
InlineParser.StrongParser,
|
|
663
663
|
InlineParser.EmphasisParser,
|
|
664
|
+
InlineParser.ItalicParser,
|
|
664
665
|
InlineParser.MathParser,
|
|
665
666
|
InlineParser.CodeParser,
|
|
666
667
|
InlineParser.HTMLEntityParser,
|
|
@@ -815,20 +816,6 @@ export namespace MarkdownParser {
|
|
|
815
816
|
]> {
|
|
816
817
|
}
|
|
817
818
|
}
|
|
818
|
-
export interface RubyParser extends
|
|
819
|
-
// [AB](a b)
|
|
820
|
-
Inline<'ruby'>,
|
|
821
|
-
Parser<HTMLElement, Context, [
|
|
822
|
-
Parser<string[], Context, []>,
|
|
823
|
-
Parser<string[], Context, []>,
|
|
824
|
-
]> {
|
|
825
|
-
}
|
|
826
|
-
export namespace RubyParser {
|
|
827
|
-
export interface TextParser extends
|
|
828
|
-
Inline<'ruby/text'>,
|
|
829
|
-
Parser<string[], Context, []> {
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
819
|
export interface LinkParser extends
|
|
833
820
|
// { uri }
|
|
834
821
|
// [abc]{uri nofollow}
|
|
@@ -978,6 +965,20 @@ export namespace MarkdownParser {
|
|
|
978
965
|
}
|
|
979
966
|
}
|
|
980
967
|
}
|
|
968
|
+
export interface RubyParser extends
|
|
969
|
+
// [AB](a b)
|
|
970
|
+
Inline<'ruby'>,
|
|
971
|
+
Parser<HTMLElement, Context, [
|
|
972
|
+
Parser<string[], Context, []>,
|
|
973
|
+
Parser<string[], Context, []>,
|
|
974
|
+
]> {
|
|
975
|
+
}
|
|
976
|
+
export namespace RubyParser {
|
|
977
|
+
export interface TextParser extends
|
|
978
|
+
Inline<'ruby/text'>,
|
|
979
|
+
Parser<string[], Context, []> {
|
|
980
|
+
}
|
|
981
|
+
}
|
|
981
982
|
export interface HTMLParser extends
|
|
982
983
|
// Allow: wbr, bdo, bdi
|
|
983
984
|
// <bdi>abc</bdi>
|
|
@@ -1015,7 +1016,7 @@ export namespace MarkdownParser {
|
|
|
1015
1016
|
Inline<'insertion'>,
|
|
1016
1017
|
Parser<HTMLElement | string, Context, [
|
|
1017
1018
|
InlineParser,
|
|
1018
|
-
|
|
1019
|
+
InsertionParser,
|
|
1019
1020
|
]> {
|
|
1020
1021
|
}
|
|
1021
1022
|
export interface DeletionParser extends
|
|
@@ -1023,7 +1024,7 @@ export namespace MarkdownParser {
|
|
|
1023
1024
|
Inline<'deletion'>,
|
|
1024
1025
|
Parser<HTMLElement | string, Context, [
|
|
1025
1026
|
InlineParser,
|
|
1026
|
-
|
|
1027
|
+
DeletionParser,
|
|
1027
1028
|
]> {
|
|
1028
1029
|
}
|
|
1029
1030
|
export interface MarkParser extends
|
|
@@ -1066,6 +1067,14 @@ export namespace MarkdownParser {
|
|
|
1066
1067
|
]>,
|
|
1067
1068
|
]> {
|
|
1068
1069
|
}
|
|
1070
|
+
export interface ItalicParser extends
|
|
1071
|
+
// ///abc///
|
|
1072
|
+
Inline<'italic'>,
|
|
1073
|
+
Parser<HTMLElement | string, Context, [
|
|
1074
|
+
InlineParser,
|
|
1075
|
+
ItalicParser,
|
|
1076
|
+
]> {
|
|
1077
|
+
}
|
|
1069
1078
|
export interface MathParser extends
|
|
1070
1079
|
// $expr$
|
|
1071
1080
|
// ${expr}$
|
package/package.json
CHANGED
package/src/parser/context.ts
CHANGED
|
@@ -31,11 +31,11 @@ export const enum Recursion {
|
|
|
31
31
|
export const enum Backtrack {
|
|
32
32
|
template = 7 << 2,
|
|
33
33
|
index = 6 << 2,
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
link = 5 << 2,
|
|
35
|
+
ruby = 4 << 2,
|
|
36
36
|
media = 3 << 2,
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
bracket = 2 << 2,
|
|
38
|
+
url = 1 << 2,
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
export const enum Command {
|
|
@@ -16,7 +16,7 @@ describe('Unit: parser/inline/autolink/url', () => {
|
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('Http://host')), [['Http'], '://host']);
|
|
17
17
|
//assert.deepStrictEqual(inspect(parser('http://[::ffff:0:0%1]')), [['<a class="invalid">http://[::ffff:0:0%1]</a>'], '']);
|
|
18
18
|
//assert.deepStrictEqual(inspect(parser('http://[::ffff:0:0/96]')), [['<a class="invalid">http://[::ffff:0:0/96]</a>'], '']);
|
|
19
|
-
assert.deepStrictEqual(inspect(parser(' http://
|
|
19
|
+
assert.deepStrictEqual(inspect(parser(' http://host')), undefined);
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
it('basic', () => {
|
|
@@ -58,7 +58,7 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
58
58
|
assert.deepStrictEqual(inspect(parser('[]')), [['[', ']'], '']);
|
|
59
59
|
assert.deepStrictEqual(inspect(parser('[a')), [['[', 'a'], '']);
|
|
60
60
|
assert.deepStrictEqual(inspect(parser('[a]')), [['[', 'a', ']'], '']);
|
|
61
|
-
assert.deepStrictEqual(inspect(parser('[==]')), [['[', '
|
|
61
|
+
assert.deepStrictEqual(inspect(parser('[==]')), [['[', '=', '=', ']'], '']);
|
|
62
62
|
assert.deepStrictEqual(inspect(parser('[$]$')), [['[', '<span class="math" translate="no" data-src="$]$">$]$</span>'], '']);
|
|
63
63
|
assert.deepStrictEqual(inspect(parser(']')), undefined);
|
|
64
64
|
});
|
|
@@ -68,7 +68,7 @@ describe('Unit: parser/inline/bracket', () => {
|
|
|
68
68
|
assert.deepStrictEqual(inspect(parser('{}')), [['{', '}'], '']);
|
|
69
69
|
assert.deepStrictEqual(inspect(parser('{a')), [['{', 'a'], '']);
|
|
70
70
|
assert.deepStrictEqual(inspect(parser('{a}')), [['{', 'a', '}'], '']);
|
|
71
|
-
assert.deepStrictEqual(inspect(parser('{==}')), [['{', '
|
|
71
|
+
assert.deepStrictEqual(inspect(parser('{==}')), [['{', '=', '=', '}'], '']);
|
|
72
72
|
assert.deepStrictEqual(inspect(parser('}')), undefined);
|
|
73
73
|
});
|
|
74
74
|
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { DeletionParser } from '../inline';
|
|
2
|
-
import { Recursion } from '../context';
|
|
3
|
-
import { union, some, creation, precedence, surround, open, lazy } from '../../combinator';
|
|
2
|
+
import { Recursion, Command } from '../context';
|
|
3
|
+
import { union, some, creation, precedence, validate, surround, open, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
|
-
import { str } from '../source';
|
|
6
5
|
import { blankWith } from '../visibility';
|
|
7
|
-
import {
|
|
6
|
+
import { repeat } from '../util';
|
|
7
|
+
import { push } from 'spica/array';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
|
-
export const deletion: DeletionParser = lazy(() => creation(1, Recursion.inline,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
export const deletion: DeletionParser = lazy(() => creation(1, Recursion.inline, validate('~~',
|
|
11
|
+
precedence(0, repeat('~~', surround(
|
|
12
|
+
'',
|
|
13
|
+
some(union([
|
|
14
|
+
some(inline, blankWith('\n', '~~')),
|
|
15
|
+
open('\n', some(deletion, '~'), true),
|
|
16
|
+
])),
|
|
17
|
+
'~~', false,
|
|
18
|
+
([, bs], rest) => [bs, rest],
|
|
19
|
+
([, bs], rest) => [push(bs, [Command.Escape]), rest]),
|
|
20
|
+
nodes => [html('del', defrag(nodes))])))));
|
|
@@ -5,14 +5,14 @@ import { inline } from '../inline';
|
|
|
5
5
|
import { emstrong } from './emstrong';
|
|
6
6
|
import { strong } from './strong';
|
|
7
7
|
import { str } from '../source';
|
|
8
|
-
import {
|
|
8
|
+
import { tightStart, blankWith } from '../visibility';
|
|
9
9
|
import { unshift } from 'spica/array';
|
|
10
10
|
import { html, defrag } from 'typed-dom/dom';
|
|
11
11
|
|
|
12
12
|
export const emphasis: EmphasisParser = lazy(() => creation(1, Recursion.inline, surround(
|
|
13
13
|
str('*', '*'),
|
|
14
14
|
precedence(0,
|
|
15
|
-
|
|
15
|
+
tightStart(some(union([
|
|
16
16
|
strong,
|
|
17
17
|
some(inline, blankWith('*')),
|
|
18
18
|
open(some(inline, '*'), union([
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { emstrong } from './emstrong';
|
|
2
|
+
import { some } from '../../combinator';
|
|
3
|
+
import { inspect } from '../../debug.test';
|
|
4
|
+
|
|
5
|
+
describe('Unit: parser/inline/emstrong', () => {
|
|
6
|
+
describe('emstrong', () => {
|
|
7
|
+
const parser = (source: string) => some(emstrong)({ source, context: {} });
|
|
8
|
+
|
|
9
|
+
it('invalid', () => {
|
|
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', '<br>', '***'], '']);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('***a\\ ***')), [['***', 'a', ' ', '***'], '']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('***a\\\n***')), [['***', 'a', '<br>', '***'], '']);
|
|
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);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('basic', () => {
|
|
29
|
+
assert.deepStrictEqual(inspect(parser('***a***')), [['<em><strong>a</strong></em>'], '']);
|
|
30
|
+
assert.deepStrictEqual(inspect(parser('***ab***')), [['<em><strong>ab</strong></em>'], '']);
|
|
31
|
+
assert.deepStrictEqual(inspect(parser('***a****')), [['<em><strong>a</strong></em>'], '*']);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser('***a\nb***')), [['<em><strong>a<br>b</strong></em>'], '']);
|
|
33
|
+
assert.deepStrictEqual(inspect(parser('***a\\\nb***')), [['<em><strong>a<br>b</strong></em>'], '']);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('nest', () => {
|
|
37
|
+
assert.deepStrictEqual(inspect(parser('***`a`***')), [['<em><strong><code data-src="`a`">a</code></strong></em>'], '']);
|
|
38
|
+
assert.deepStrictEqual(inspect(parser('***(*a*)***')), [['<em><strong><span class="paren">(<em>a</em>)</span></strong></em>'], '']);
|
|
39
|
+
assert.deepStrictEqual(inspect(parser('***(**a**)***')), [['<em><strong><span class="paren">(<strong>a</strong>)</span></strong></em>'], '']);
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('***(***a***)***')), [['<em><strong><span class="paren">(<em><strong>a</strong></em>)</span></strong></em>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('***a*')), [['**', '<em>a</em>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('***a*b')), [['**', '<em>a</em>', 'b'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('***a*b*')), [['**', '<em>a</em>', 'b', '*'], '']);
|
|
44
|
+
assert.deepStrictEqual(inspect(parser('***a*b*c')), [['**', '<em>a</em>', 'b', '*', 'c'], '']);
|
|
45
|
+
assert.deepStrictEqual(inspect(parser('***a*b*c*')), [['**', '<em>a</em>', 'b', '<em>c</em>'], '']);
|
|
46
|
+
assert.deepStrictEqual(inspect(parser('***a*b*c**')), [['**', '<em>a</em>', 'b', '<em>c</em>', '*'], '']);
|
|
47
|
+
assert.deepStrictEqual(inspect(parser('***a*b*c***')), [['<strong><em>a</em>b<em>c</em></strong>'], '']);
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('***a*b**')), [['<strong><em>a</em>b</strong>'], '']);
|
|
49
|
+
assert.deepStrictEqual(inspect(parser('***a*b**c')), [['<strong><em>a</em>b</strong>'], 'c']);
|
|
50
|
+
assert.deepStrictEqual(inspect(parser('***a**')), [['*', '<strong>a</strong>'], '']);
|
|
51
|
+
assert.deepStrictEqual(inspect(parser('***a**b')), [['*', '<strong>a</strong>', 'b'], '']);
|
|
52
|
+
assert.deepStrictEqual(inspect(parser('***a**b*')), [['<em><strong>a</strong>b</em>'], '']);
|
|
53
|
+
assert.deepStrictEqual(inspect(parser('***a**b**')), [['<em><strong>a</strong>b</em>'], '*']);
|
|
54
|
+
assert.deepStrictEqual(inspect(parser('***a**b**c')), [['*', '<strong>a</strong>', 'b', '**', 'c'], '']);
|
|
55
|
+
assert.deepStrictEqual(inspect(parser('***a**b**c*')), [['*', '<strong>a</strong>', 'b', '**', 'c', '*'], '']);
|
|
56
|
+
assert.deepStrictEqual(inspect(parser('***a**b**c**')), [['*', '<strong>a</strong>', 'b', '<strong>c</strong>'], '']);
|
|
57
|
+
assert.deepStrictEqual(inspect(parser('***a**b**c***')), [['<em><strong>a</strong>b<strong>c</strong></em>'], '']);
|
|
58
|
+
assert.deepStrictEqual(inspect(parser('***a **b*')), [['***', 'a', ' ', '**', 'b', '*'], '']);
|
|
59
|
+
assert.deepStrictEqual(inspect(parser('***a\\ *b****')), [['<em><strong>a <em>b</em></strong></em>'], '']);
|
|
60
|
+
assert.deepStrictEqual(inspect(parser('***a\\ **b*')), [['***', 'a', ' ', '**', 'b', '*'], '']);
|
|
61
|
+
assert.deepStrictEqual(inspect(parser('***a	*b****')), [['<em><strong>a\t<em>b</em></strong></em>'], '']);
|
|
62
|
+
assert.deepStrictEqual(inspect(parser('***a<wbr>*b****')), [['<em><strong>a<wbr><em>b</em></strong></em>'], '']);
|
|
63
|
+
assert.deepStrictEqual(inspect(parser('***a *b****')), [['<em><strong>a <em>b</em></strong></em>'], '']);
|
|
64
|
+
assert.deepStrictEqual(inspect(parser('***a* **b****')), [['<strong><em>a</em> <strong>b</strong></strong>'], '']);
|
|
65
|
+
assert.deepStrictEqual(inspect(parser('***a*\\ **b****')), [['<strong><em>a</em> <strong>b</strong></strong>'], '']);
|
|
66
|
+
assert.deepStrictEqual(inspect(parser('***a*	**b****')), [['<strong><em>a</em>\t<strong>b</strong></strong>'], '']);
|
|
67
|
+
assert.deepStrictEqual(inspect(parser('***a*<wbr>**b****')), [['<strong><em>a</em><wbr><strong>b</strong></strong>'], '']);
|
|
68
|
+
assert.deepStrictEqual(inspect(parser('***a*b **')), [['**', '<em>a</em>', 'b'], ' **']);
|
|
69
|
+
assert.deepStrictEqual(inspect(parser('***a*b\\ **')), [['**', '<em>a</em>', 'b'], '\\ **']);
|
|
70
|
+
assert.deepStrictEqual(inspect(parser('***a**b*')), [['<em><strong>a</strong>b</em>'], '']);
|
|
71
|
+
assert.deepStrictEqual(inspect(parser('***a**b*c')), [['<em><strong>a</strong>b</em>'], 'c']);
|
|
72
|
+
assert.deepStrictEqual(inspect(parser('***a**b*c**')), [['<em><strong>a</strong>b</em>'], 'c**']);
|
|
73
|
+
assert.deepStrictEqual(inspect(parser('***a**b**c***')), [['<em><strong>a</strong>b<strong>c</strong></em>'], '']);
|
|
74
|
+
assert.deepStrictEqual(inspect(parser('***a**b**c***d')), [['<em><strong>a</strong>b<strong>c</strong></em>'], 'd']);
|
|
75
|
+
assert.deepStrictEqual(inspect(parser('***a** *b**')), [['<em><strong>a</strong> <em>b</em></em>'], '']);
|
|
76
|
+
assert.deepStrictEqual(inspect(parser('***a**\\ *b**')), [['<em><strong>a</strong> <em>b</em></em>'], '']);
|
|
77
|
+
assert.deepStrictEqual(inspect(parser('***a**	*b**')), [['<em><strong>a</strong>\t<em>b</em></em>'], '']);
|
|
78
|
+
assert.deepStrictEqual(inspect(parser('***a**<wbr>*b**')), [['<em><strong>a</strong><wbr><em>b</em></em>'], '']);
|
|
79
|
+
assert.deepStrictEqual(inspect(parser('***a**b *')), [['*', '<strong>a</strong>', 'b'], ' *']);
|
|
80
|
+
assert.deepStrictEqual(inspect(parser('***a**b\\ *')), [['*', '<strong>a</strong>', 'b'], '\\ *']);
|
|
81
|
+
assert.deepStrictEqual(inspect(parser('***a*')), [['**', '<em>a</em>'], '']);
|
|
82
|
+
assert.deepStrictEqual(inspect(parser('***a**')), [['*', '<strong>a</strong>'], '']);
|
|
83
|
+
assert.deepStrictEqual(inspect(parser('***a***')), [['<em><strong>a</strong></em>'], '']);
|
|
84
|
+
assert.deepStrictEqual(inspect(parser('***a***b')), [['<em><strong>a</strong></em>'], 'b']);
|
|
85
|
+
assert.deepStrictEqual(inspect(parser('***a****')), [['<em><strong>a</strong></em>'], '*']);
|
|
86
|
+
assert.deepStrictEqual(inspect(parser('***a*****')), [['<em><strong>a</strong></em>'], '**']);
|
|
87
|
+
assert.deepStrictEqual(inspect(parser('***a******')), [['<em><strong>a</strong></em>'], '***']);
|
|
88
|
+
assert.deepStrictEqual(inspect(parser('****a***')), [['*', '<em><strong>a</strong></em>'], '']);
|
|
89
|
+
assert.deepStrictEqual(inspect(parser('****a***b')), [['*', '<em><strong>a</strong></em>'], 'b']);
|
|
90
|
+
assert.deepStrictEqual(inspect(parser('****a****')), [['<em><em><strong>a</strong></em></em>'], '']);
|
|
91
|
+
assert.deepStrictEqual(inspect(parser('****a****b')), [['<em><em><strong>a</strong></em></em>'], 'b']);
|
|
92
|
+
assert.deepStrictEqual(inspect(parser('*****a***')), [['**', '<em><strong>a</strong></em>'], '']);
|
|
93
|
+
assert.deepStrictEqual(inspect(parser('*****a***b')), [['**', '<em><strong>a</strong></em>'], 'b']);
|
|
94
|
+
assert.deepStrictEqual(inspect(parser('*****a****')), [['*', '<em><em><strong>a</strong></em></em>'], '']);
|
|
95
|
+
assert.deepStrictEqual(inspect(parser('*****a****b')), [['*', '<em><em><strong>a</strong></em></em>'], 'b']);
|
|
96
|
+
assert.deepStrictEqual(inspect(parser('*****a*****')), [['<strong><em><strong>a</strong></em></strong>'], '']);
|
|
97
|
+
assert.deepStrictEqual(inspect(parser('******a***')), [['***', '<em><strong>a</strong></em>'], '']);
|
|
98
|
+
assert.deepStrictEqual(inspect(parser('******a***b')), [['***', '<em><strong>a</strong></em>', 'b'], '']);
|
|
99
|
+
assert.deepStrictEqual(inspect(parser('******a****')), [['**', '<em><em><strong>a</strong></em></em>'], '']);
|
|
100
|
+
assert.deepStrictEqual(inspect(parser('******a****b')), [['**', '<em><em><strong>a</strong></em></em>'], 'b']);
|
|
101
|
+
assert.deepStrictEqual(inspect(parser('******a*****')), [['*', '<strong><em><strong>a</strong></em></strong>'], '']);
|
|
102
|
+
assert.deepStrictEqual(inspect(parser('******a*****b')), [['*', '<strong><em><strong>a</strong></em></strong>'], 'b']);
|
|
103
|
+
assert.deepStrictEqual(inspect(parser('******a******')), [['<em><strong><em><strong>a</strong></em></strong></em>'], '']);
|
|
104
|
+
assert.deepStrictEqual(inspect(parser('******a******b')), [['<em><strong><em><strong>a</strong></em></strong></em>'], 'b']);
|
|
105
|
+
assert.deepStrictEqual(inspect(parser('******a*b')), [['***', '**', '<em>a</em>', 'b'], '']);
|
|
106
|
+
assert.deepStrictEqual(inspect(parser('******a*b *')), [['***', '**', '<em>a</em>', 'b', ' ', '*'], '']);
|
|
107
|
+
assert.deepStrictEqual(inspect(parser('******a*b **')), [['***', '**', '<em>a</em>', 'b'], ' **']);
|
|
108
|
+
assert.deepStrictEqual(inspect(parser('******a*b ***')), [['***', '**', '<em>a</em>', 'b'], ' ***']);
|
|
109
|
+
assert.deepStrictEqual(inspect(parser('******a*b ****')), [['***', '**', '<em>a</em>', 'b'], ' ****']);
|
|
110
|
+
assert.deepStrictEqual(inspect(parser('******a*b *****')), [['***', '**', '<em>a</em>', 'b'], ' *****']);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
});
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { EmStrongParser, EmphasisParser, StrongParser } from '../inline';
|
|
2
|
-
import { Recursion } from '../context';
|
|
2
|
+
import { Recursion, Command } from '../context';
|
|
3
3
|
import { Result, IntermediateParser } from '../../combinator/data/parser';
|
|
4
|
-
import { union, creation, precedence,
|
|
4
|
+
import { union, some, creation, precedence, validate, surround, open, lazy, bind } from '../../combinator';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { strong } from './strong';
|
|
7
7
|
import { emphasis } from './emphasis';
|
|
8
8
|
import { str } from '../source';
|
|
9
|
-
import {
|
|
9
|
+
import { tightStart, blankWith } from '../visibility';
|
|
10
|
+
import { repeat } from '../util';
|
|
10
11
|
import { html, defrag } from 'typed-dom/dom';
|
|
11
|
-
import { unshift } from 'spica/array';
|
|
12
|
+
import { unshift, push } from 'spica/array';
|
|
12
13
|
|
|
13
14
|
const substrong: IntermediateParser<StrongParser> = lazy(() => some(union([
|
|
14
15
|
some(inline, blankWith('**')),
|
|
@@ -27,36 +28,69 @@ const subemphasis: IntermediateParser<EmphasisParser> = lazy(() => some(union([
|
|
|
27
28
|
])),
|
|
28
29
|
])));
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
31
|
+
// 開閉が明示的でない構文は開閉の不明確な記号による再帰的適用を行わず早く閉じるよう解析しなければならない。
|
|
32
|
+
// このため終端記号の後ろを見て終端を中止し同じ構文を再帰的に適用してはならない。
|
|
33
|
+
export const emstrong: EmStrongParser = lazy(() => creation(1, Recursion.inline, validate('***',
|
|
34
|
+
precedence(0, repeat('***', surround(
|
|
35
|
+
'',
|
|
36
|
+
tightStart(some(union([
|
|
37
|
+
some(inline, blankWith('*')),
|
|
38
|
+
open(some(inline, '*'), inline),
|
|
39
|
+
]))),
|
|
40
|
+
str(/^\*{1,3}/), false,
|
|
41
|
+
([, bs, cs], rest, context): Result<HTMLElement | string, typeof context> => {
|
|
42
|
+
assert(cs.length === 1);
|
|
43
|
+
switch (cs[0]) {
|
|
44
|
+
case '***':
|
|
45
|
+
return [bs, rest];
|
|
46
|
+
case '**':
|
|
47
|
+
return bind<EmphasisParser>(
|
|
48
|
+
subemphasis,
|
|
49
|
+
(ds, rest) =>
|
|
50
|
+
rest.slice(0, 1) === '*'
|
|
51
|
+
? [[html('em', unshift([html('strong', defrag(bs))], defrag(ds))), Command.Separator], rest.slice(1)]
|
|
52
|
+
: [push(unshift(['*', html('strong', defrag(bs))], ds), [Command.Separator]), rest])
|
|
53
|
+
({ source: rest, context }) ?? [['*', html('strong', defrag(bs)), Command.Separator], rest];
|
|
54
|
+
case '*':
|
|
55
|
+
return bind<StrongParser>(
|
|
56
|
+
substrong,
|
|
57
|
+
(ds, rest) =>
|
|
58
|
+
rest.slice(0, 2) === '**'
|
|
59
|
+
? [[html('strong', unshift([html('em', defrag(bs))], defrag(ds))), Command.Separator], rest.slice(2)]
|
|
60
|
+
: [push(unshift(['**', html('em', defrag(bs))], ds), [Command.Separator]), rest])
|
|
61
|
+
({ source: rest, context }) ?? [['**', html('em', defrag(bs)), Command.Separator], rest];
|
|
62
|
+
}
|
|
63
|
+
assert(false);
|
|
64
|
+
},
|
|
65
|
+
([as, bs], rest) => [push(unshift(as, bs), [Command.Escape]), rest]),
|
|
66
|
+
// 3以上の`*`に対してemの適用を保証する
|
|
67
|
+
nodes => [html('em', [html('strong', defrag(nodes))])],
|
|
68
|
+
(acc, rest, prefix, postfix, state) => {
|
|
69
|
+
const nodes = [];
|
|
70
|
+
let i = postfix;
|
|
71
|
+
if (state) while (i > 0) {
|
|
72
|
+
switch (i) {
|
|
73
|
+
case 1:
|
|
74
|
+
acc = [[html('em', acc.flat())]];
|
|
75
|
+
i -= 1;
|
|
76
|
+
break;
|
|
77
|
+
case 2:
|
|
78
|
+
acc = [[html('strong', acc.flat())]];
|
|
79
|
+
i -= 2;
|
|
80
|
+
break;
|
|
81
|
+
default:
|
|
82
|
+
acc = [[html('em', [html('strong', acc.flat())])]];
|
|
83
|
+
i -= 3;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (prefix > postfix) {
|
|
87
|
+
nodes.push('*'.repeat(prefix - postfix));
|
|
88
|
+
}
|
|
89
|
+
for (let i = 0; i < acc.length; ++i) {
|
|
90
|
+
nodes.push(...acc[i]);
|
|
91
|
+
}
|
|
92
|
+
if (postfix > 0) {
|
|
93
|
+
rest = rest.slice(postfix);
|
|
94
|
+
}
|
|
95
|
+
return [nodes, rest];
|
|
96
|
+
})))));
|
|
@@ -4,7 +4,7 @@ import { union, inits, some, creation, precedence, state, constraint, validate,
|
|
|
4
4
|
import { inline } from '../../inline';
|
|
5
5
|
import { indexee, identity } from './indexee';
|
|
6
6
|
import { txt, str } from '../../source';
|
|
7
|
-
import {
|
|
7
|
+
import { tightStart, trimBlankNodeEnd } from '../../visibility';
|
|
8
8
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
import IndexParser = ExtensionParser.IndexParser;
|
|
@@ -12,7 +12,7 @@ import IndexParser = ExtensionParser.IndexParser;
|
|
|
12
12
|
export const index: IndexParser = lazy(() => constraint(State.index, false, creation(1, Recursion.ignore, fmap(indexee(surround(
|
|
13
13
|
'[#',
|
|
14
14
|
precedence(1, state(State.linkers | State.media,
|
|
15
|
-
|
|
15
|
+
tightStart(
|
|
16
16
|
some(inits([
|
|
17
17
|
inline,
|
|
18
18
|
signature,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
2
|
import { State, Recursion } from '../../context';
|
|
3
|
-
import { union,
|
|
3
|
+
import { union, creation, constraint, surround, clear, fmap } from '../../../combinator';
|
|
4
4
|
import { str } from '../../source';
|
|
5
5
|
import { html } from 'typed-dom/dom';
|
|
6
6
|
|
|
@@ -3,7 +3,7 @@ import { Recursion, Backtrack } from '../../context';
|
|
|
3
3
|
import { union, some, creation, precedence, surround, lazy } from '../../../combinator';
|
|
4
4
|
import { inline } from '../../inline';
|
|
5
5
|
import { str } from '../../source';
|
|
6
|
-
import {
|
|
6
|
+
import { tightStart } from '../../visibility';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
@@ -14,7 +14,7 @@ import { html, defrag } from 'typed-dom/dom';
|
|
|
14
14
|
export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => creation(1, Recursion.inline, surround(
|
|
15
15
|
str(/^\[[:^|]/),
|
|
16
16
|
precedence(1,
|
|
17
|
-
|
|
17
|
+
tightStart(some(union([inline]), ']', [[']', 1]]))),
|
|
18
18
|
str(']'), false,
|
|
19
19
|
([, bs], rest) => [[
|
|
20
20
|
html('span', {
|
|
@@ -3,7 +3,7 @@ import { Recursion } from '../context';
|
|
|
3
3
|
import { union, subsequence, some, creation, precedence, validate, focus, surround, open, match, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
-
import {
|
|
6
|
+
import { isLooseNodeStart, blankWith } from '../visibility';
|
|
7
7
|
import { memoize } from 'spica/memoize';
|
|
8
8
|
import { Clock } from 'spica/clock';
|
|
9
9
|
import { unshift, push, splice } from 'spica/array';
|
|
@@ -219,7 +219,7 @@ function elem(tag: string, as: string[], bs: (HTMLElement | string)[], cs: strin
|
|
|
219
219
|
if (!tags.includes(tag)) return invalid('tag', `Invalid HTML tag name "${tag}"`, as, bs, cs);
|
|
220
220
|
if (cs.length === 0) return invalid('tag', `Missing the closing HTML tag "</${tag}>"`, as, bs, cs);
|
|
221
221
|
if (bs.length === 0) return invalid('content', `Missing the content`, as, bs, cs);
|
|
222
|
-
if (!
|
|
222
|
+
if (!isLooseNodeStart(bs)) return invalid('content', `Missing the visible content in the same line`, as, bs, cs);
|
|
223
223
|
const attrs = attributes('html', [], attrspecs[tag], as.slice(1, -1));
|
|
224
224
|
return 'data-invalid-syntax' in attrs
|
|
225
225
|
? invalid('attribute', 'Invalid HTML attribute', as, bs, cs)
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { InsertionParser } from '../inline';
|
|
2
|
-
import { Recursion } from '../context';
|
|
3
|
-
import { union, some, creation, precedence, surround, open, lazy } from '../../combinator';
|
|
2
|
+
import { Recursion, Command } from '../context';
|
|
3
|
+
import { union, some, creation, precedence, validate, surround, open, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
|
-
import { str } from '../source';
|
|
6
5
|
import { blankWith } from '../visibility';
|
|
7
|
-
import {
|
|
6
|
+
import { repeat } from '../util';
|
|
7
|
+
import { push } from 'spica/array';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
|
-
export const insertion: InsertionParser = lazy(() => creation(1, Recursion.inline,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
export const insertion: InsertionParser = lazy(() => creation(1, Recursion.inline, validate('++',
|
|
11
|
+
precedence(0, repeat('++', surround(
|
|
12
|
+
'',
|
|
13
|
+
some(union([
|
|
14
|
+
some(inline, blankWith('\n', '++')),
|
|
15
|
+
open('\n', some(insertion, '+'), true),
|
|
16
|
+
])),
|
|
17
|
+
'++', false,
|
|
18
|
+
([, bs], rest) => [bs, rest],
|
|
19
|
+
([, bs], rest) => [push(bs, [Command.Escape]), rest]),
|
|
20
|
+
nodes => [html('ins', defrag(nodes))])))));
|