securemark 0.294.6 → 0.294.8
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 +226 -216
- package/markdown.d.ts +13 -36
- package/package.json +1 -1
- package/src/combinator/control/constraint/block.ts +2 -2
- package/src/combinator/control/constraint/line.ts +7 -5
- package/src/combinator/control/manipulation/convert.ts +2 -1
- package/src/combinator/control/manipulation/fence.ts +4 -4
- package/src/combinator/control/manipulation/indent.ts +3 -5
- package/src/combinator/control/manipulation/surround.ts +47 -18
- package/src/combinator/data/parser/some.ts +1 -1
- package/src/combinator/data/parser/union.ts +6 -2
- package/src/parser/api/bind.test.ts +0 -1
- package/src/parser/api/normalize.test.ts +5 -8
- package/src/parser/api/normalize.ts +11 -11
- package/src/parser/api/parse.test.ts +3 -3
- package/src/parser/autolink.ts +1 -2
- package/src/parser/block/extension/fig.ts +4 -1
- package/src/parser/block/heading.ts +12 -2
- package/src/parser/block/reply/quote.ts +1 -2
- package/src/parser/block/ulist.ts +1 -1
- package/src/parser/block.ts +0 -4
- package/src/parser/header.ts +28 -40
- package/src/parser/inline/annotation.ts +2 -3
- package/src/parser/inline/autolink/account.ts +47 -17
- package/src/parser/inline/autolink/anchor.test.ts +0 -1
- package/src/parser/inline/autolink/anchor.ts +15 -15
- package/src/parser/inline/autolink/email.test.ts +1 -1
- package/src/parser/inline/autolink/email.ts +10 -11
- package/src/parser/inline/autolink/hashnum.ts +17 -14
- package/src/parser/inline/autolink/hashtag.ts +23 -19
- package/src/parser/inline/autolink/url.ts +24 -19
- package/src/parser/inline/autolink.ts +36 -25
- package/src/parser/inline/bracket.ts +14 -14
- package/src/parser/inline/deletion.ts +2 -1
- package/src/parser/inline/emphasis.ts +2 -1
- package/src/parser/inline/emstrong.ts +2 -1
- package/src/parser/inline/extension/index.ts +4 -4
- package/src/parser/inline/extension/indexer.ts +1 -1
- package/src/parser/inline/extension/label.ts +1 -1
- package/src/parser/inline/extension/placeholder.ts +4 -3
- package/src/parser/inline/html.ts +5 -5
- package/src/parser/inline/htmlentity.ts +3 -3
- package/src/parser/inline/insertion.ts +2 -1
- package/src/parser/inline/italic.ts +2 -1
- package/src/parser/inline/link.ts +7 -20
- package/src/parser/inline/mark.ts +2 -1
- package/src/parser/inline/math.ts +4 -2
- package/src/parser/inline/media.ts +24 -25
- package/src/parser/inline/reference.ts +4 -4
- package/src/parser/inline/remark.ts +2 -1
- package/src/parser/inline/ruby.ts +3 -4
- package/src/parser/inline/strong.ts +2 -1
- package/src/parser/inline/template.ts +10 -10
- package/src/parser/inline.ts +2 -1
- package/src/parser/segment.ts +2 -2
- package/src/parser/source/escapable.ts +3 -4
- package/src/parser/source/line.ts +3 -1
- package/src/parser/source/text.ts +8 -13
- package/src/parser/source/unescapable.ts +2 -4
- package/src/parser/source.ts +1 -2
- package/src/parser/inline/autolink/channel.ts +0 -44
|
@@ -22,12 +22,12 @@ export const index: IndexParser = lazy(() => constraint(State.index, fmap(indexe
|
|
|
22
22
|
]), ']', [[']', 1]])))),
|
|
23
23
|
str(']'),
|
|
24
24
|
false,
|
|
25
|
+
[3 | Backtrack.bracket],
|
|
25
26
|
([, bs], context) =>
|
|
26
27
|
context.linebreak === 0 && trimBlankNodeEnd(bs).length > 0
|
|
27
28
|
? new List([new Data(html('a', { 'data-index': dataindex(bs) }, defrag(unwrap(bs))))])
|
|
28
29
|
: undefined,
|
|
29
|
-
undefined,
|
|
30
|
-
[3 | Backtrack.bracket])),
|
|
30
|
+
undefined)),
|
|
31
31
|
ns => {
|
|
32
32
|
if (ns.length === 1) {
|
|
33
33
|
const el = ns.head!.value as HTMLElement;
|
|
@@ -54,14 +54,14 @@ export const signature: IndexParser.SignatureParser = lazy(() => validate('|', s
|
|
|
54
54
|
]), ']'),
|
|
55
55
|
/(?=])/y,
|
|
56
56
|
false,
|
|
57
|
+
[3 | Backtrack.bracket],
|
|
57
58
|
([, ns], context) => {
|
|
58
59
|
const index = identity('index', undefined, ns.foldl((acc, { value }) => acc + value, ''))?.slice(7);
|
|
59
60
|
return index && context.linebreak === 0
|
|
60
61
|
? new List([new Data(html('span', { class: 'indexer', 'data-index': index }))])
|
|
61
62
|
: undefined;
|
|
62
63
|
},
|
|
63
|
-
([as, bs]) => bs && as.import(bs)
|
|
64
|
-
[3 | Backtrack.bracket])));
|
|
64
|
+
([as, bs]) => bs && as.import(bs))));
|
|
65
65
|
|
|
66
66
|
export function dataindex(nodes: List<Data<string | HTMLElement>>): string | undefined {
|
|
67
67
|
let node = nodes.last;
|
|
@@ -14,7 +14,7 @@ export const segment: ExtensionParser.LabelParser.SegmentParser = clear(union([
|
|
|
14
14
|
|
|
15
15
|
export const label: ExtensionParser.LabelParser = constraint(State.label, fmap(
|
|
16
16
|
union([
|
|
17
|
-
surround('[', body, ']', false,
|
|
17
|
+
surround('[', body, ']', false, [1 | Backtrack.bracket, 1]),
|
|
18
18
|
body,
|
|
19
19
|
]),
|
|
20
20
|
([{ value }]) => new List([
|
|
@@ -17,7 +17,9 @@ export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => surroun
|
|
|
17
17
|
str(/\[[:^|]/y),
|
|
18
18
|
precedence(1, recursion(Recursion.inline,
|
|
19
19
|
tightStart(some(union([inline]), ']', [[']', 1]])))),
|
|
20
|
-
str(']'),
|
|
20
|
+
str(']'),
|
|
21
|
+
false,
|
|
22
|
+
[3 | Backtrack.bracket],
|
|
21
23
|
(_, context) => new List([
|
|
22
24
|
new Data(html('span',
|
|
23
25
|
{
|
|
@@ -26,5 +28,4 @@ export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => surroun
|
|
|
26
28
|
},
|
|
27
29
|
context.source.slice(context.position - context.range!, context.position)))
|
|
28
30
|
]),
|
|
29
|
-
([as, bs]) => bs && as.import(bs as List<Data<string>>)
|
|
30
|
-
[3 | Backtrack.bracket]));
|
|
31
|
+
([as, bs]) => bs && as.import(bs as List<Data<string>>)));
|
|
@@ -23,10 +23,10 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
23
23
|
union([
|
|
24
24
|
surround(
|
|
25
25
|
// https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
26
|
-
str(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[ >])/
|
|
26
|
+
str(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[ >])/y),
|
|
27
27
|
some(union([attribute])),
|
|
28
28
|
open(str(/ ?/y), str('>'), true),
|
|
29
|
-
true,
|
|
29
|
+
true, [],
|
|
30
30
|
([as, bs = new List(), cs], context) =>
|
|
31
31
|
new List([new Data(elem(as.head!.value.slice(1), false, [...unwrap(as.import(bs).import(cs))], new List(), new List(), context))]),
|
|
32
32
|
([as, bs = new List()], context) =>
|
|
@@ -38,7 +38,7 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
38
38
|
surround<HTMLParser.TagParser, string>(
|
|
39
39
|
surround(
|
|
40
40
|
str(`<${tag}`), some(attribute), open(str(/ ?/y), str('>'), true),
|
|
41
|
-
true,
|
|
41
|
+
true, [],
|
|
42
42
|
([as, bs = new List(), cs]) => as.import(bs).import(cs),
|
|
43
43
|
([as, bs = new List()]) => as.import(bs)),
|
|
44
44
|
// 不可視のHTML構造が可視構造を変化させるべきでない。
|
|
@@ -51,7 +51,7 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
51
51
|
open('\n', some(inline, `</${tag}>`), true),
|
|
52
52
|
])))),
|
|
53
53
|
str(`</${tag}>`),
|
|
54
|
-
true,
|
|
54
|
+
true, [],
|
|
55
55
|
([as, bs = new List(), cs], context) =>
|
|
56
56
|
new List([new Data(elem(tag, true, [...unwrap(as)], bs, cs, context))]),
|
|
57
57
|
([as, bs = new List()], context) =>
|
|
@@ -63,7 +63,7 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
63
63
|
str(/<[a-z]+(?=[ >])/yi),
|
|
64
64
|
some(union([attribute])),
|
|
65
65
|
open(str(/ ?/y), str('>'), true),
|
|
66
|
-
true,
|
|
66
|
+
true, [],
|
|
67
67
|
([as, bs = new List(), cs], context) =>
|
|
68
68
|
new List([new Data(elem(as.head!.value.slice(1), false, [...unwrap(as.import(bs).import(cs))], new List(), new List(), context))]),
|
|
69
69
|
([as, bs = new List()], context) =>
|
|
@@ -9,11 +9,11 @@ import { html } from 'typed-dom/dom';
|
|
|
9
9
|
export const unsafehtmlentity: UnsafeHTMLEntityParser = surround(
|
|
10
10
|
str('&'), str(/[0-9A-Za-z]+/y), str(';'),
|
|
11
11
|
false,
|
|
12
|
+
[3 | Backtrack.bracket],
|
|
12
13
|
([as, bs, cs]) =>
|
|
13
14
|
new List([new Data(parser(as.head!.value + bs.head!.value + cs.head!.value))]),
|
|
14
15
|
([as, bs]) =>
|
|
15
|
-
new List([new Data(as.head!.value + (bs?.head?.value ?? ''))])
|
|
16
|
-
[3 | Backtrack.bracket]);
|
|
16
|
+
new List([new Data(as.head!.value + (bs?.head?.value ?? ''))]));
|
|
17
17
|
|
|
18
18
|
export const htmlentity: HTMLEntityParser = fmap(
|
|
19
19
|
union([unsafehtmlentity]),
|
|
@@ -23,7 +23,7 @@ export const htmlentity: HTMLEntityParser = fmap(
|
|
|
23
23
|
: new Data(html('span', {
|
|
24
24
|
class: 'invalid',
|
|
25
25
|
...invalid('htmlentity', 'syntax', 'Invalid HTML entity'),
|
|
26
|
-
|
|
26
|
+
}, value))
|
|
27
27
|
]));
|
|
28
28
|
|
|
29
29
|
const parser = (el => (entity: string): string => {
|
|
@@ -15,7 +15,8 @@ export const insertion: InsertionParser = lazy(() =>
|
|
|
15
15
|
some(inline, blankWith('\n', '++')),
|
|
16
16
|
open('\n', some(inline, '+'), true),
|
|
17
17
|
]))),
|
|
18
|
-
'++',
|
|
18
|
+
'++',
|
|
19
|
+
false, [],
|
|
19
20
|
([, bs], { buffer }) => buffer!.import(bs),
|
|
20
21
|
([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
|
|
21
22
|
nodes => new List([new Data(html('ins', defrag(unwrap(nodes))))]))));
|
|
@@ -18,7 +18,8 @@ export const italic: ItalicParser = lazy(() =>
|
|
|
18
18
|
some(inline, blankWith('///')),
|
|
19
19
|
open(some(inline, '/'), inline),
|
|
20
20
|
])))),
|
|
21
|
-
'///',
|
|
21
|
+
'///',
|
|
22
|
+
false, [],
|
|
22
23
|
([, bs], { buffer }) => buffer!.import(bs),
|
|
23
24
|
([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
|
|
24
25
|
nodes => new List([new Data(html('i', defrag(unwrap(nodes))))]))));
|
|
@@ -2,10 +2,10 @@ import { MarkdownParser } from '../../../markdown';
|
|
|
2
2
|
import { LinkParser } from '../inline';
|
|
3
3
|
import { State, Backtrack, Command } from '../context';
|
|
4
4
|
import { List, Data } from '../../combinator/data/parser';
|
|
5
|
-
import { union, inits,
|
|
5
|
+
import { union, inits, sequence, subsequence, some, creation, precedence, state, constraint, surround, open, setBacktrack, dup, lazy, fmap, bind } from '../../combinator';
|
|
6
6
|
import { inline, media, shortmedia } from '../inline';
|
|
7
7
|
import { attributes } from './html';
|
|
8
|
-
import {
|
|
8
|
+
import { str } from '../source';
|
|
9
9
|
import { trimBlankStart, trimBlankNodeEnd } from '../visibility';
|
|
10
10
|
import { unwrap, invalid, stringify } from '../util';
|
|
11
11
|
import { ReadonlyURL } from 'spica/url';
|
|
@@ -24,12 +24,11 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
24
24
|
trimBlankStart(some(union([inline]), ']', [[']', 1]])),
|
|
25
25
|
']',
|
|
26
26
|
true,
|
|
27
|
+
[3 | Backtrack.bracket, 3 | Backtrack.link, 2 | Backtrack.ruby],
|
|
27
28
|
([, ns = new List()], context) =>
|
|
28
29
|
context.linebreak === 0
|
|
29
30
|
? ns.push(new Data(Command.Separator)) && ns
|
|
30
|
-
: undefined,
|
|
31
|
-
undefined,
|
|
32
|
-
[3 | Backtrack.bracket, 3 | Backtrack.link, 2 | Backtrack.ruby])),
|
|
31
|
+
: undefined)),
|
|
33
32
|
// `{ `と`{`で個別にバックトラックが発生し+1nされる。
|
|
34
33
|
// 自己再帰的にパースしてもオプションの不要なパースによる計算量の増加により相殺される。
|
|
35
34
|
dup(surround(
|
|
@@ -37,14 +36,14 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
37
36
|
inits([uri, some(option)]),
|
|
38
37
|
/ ?}/y,
|
|
39
38
|
false,
|
|
39
|
+
[3 | Backtrack.link],
|
|
40
40
|
undefined,
|
|
41
41
|
([as, bs], context) => {
|
|
42
42
|
if (!bs) return;
|
|
43
43
|
const head = context.position - context.range!;
|
|
44
44
|
setBacktrack(context, [2 | Backtrack.link], head);
|
|
45
45
|
return as.import(bs).push(new Data(Command.Cancel)) && as;
|
|
46
|
-
},
|
|
47
|
-
[3 | Backtrack.link])),
|
|
46
|
+
})),
|
|
48
47
|
]),
|
|
49
48
|
([{ value: content }, { value: params = undefined } = {}], context) => {
|
|
50
49
|
if (content.last!.value === Command.Separator) {
|
|
@@ -87,18 +86,6 @@ export const medialink: LinkParser.MediaLinkParser = lazy(() => constraint(State
|
|
|
87
86
|
([{ value: content }, { value: params }], context) =>
|
|
88
87
|
new List([new Data(parse(content, params as List<Data<string>>, context))]))))));
|
|
89
88
|
|
|
90
|
-
export const unsafelink: LinkParser.UnsafeLinkParser = lazy(() =>
|
|
91
|
-
creation(10,
|
|
92
|
-
bind(reverse(tails([
|
|
93
|
-
dup(surround(
|
|
94
|
-
'[',
|
|
95
|
-
some(union([unescsource]), ']'),
|
|
96
|
-
']')),
|
|
97
|
-
dup(surround(/{(?![{}])/y, inits([uri, some(option)]), / ?}/y)),
|
|
98
|
-
])),
|
|
99
|
-
([{ value: params }, { value: content } = new Data(new List<Data<string>>())], context) =>
|
|
100
|
-
new List([new Data(parse(content, params, context))]))));
|
|
101
|
-
|
|
102
89
|
export const uri: LinkParser.ParameterParser.UriParser = union([
|
|
103
90
|
open(/ /y, str(/\S+/y)),
|
|
104
91
|
str(/[^\s{}]+/y),
|
|
@@ -110,7 +97,7 @@ export const option: LinkParser.ParameterParser.OptionParser = union([
|
|
|
110
97
|
str(/ [^\s{}]+/y),
|
|
111
98
|
]);
|
|
112
99
|
|
|
113
|
-
function parse(
|
|
100
|
+
export function parse(
|
|
114
101
|
content: List<Data<string | HTMLElement>>,
|
|
115
102
|
params: List<Data<string>>,
|
|
116
103
|
context: MarkdownParser.Context,
|
|
@@ -16,7 +16,8 @@ export const mark: MarkParser = lazy(() => constraint(State.linkers & ~State.mar
|
|
|
16
16
|
some(inline, blankWith('==')),
|
|
17
17
|
open(some(inline, '='), inline),
|
|
18
18
|
])))),
|
|
19
|
-
'==',
|
|
19
|
+
'==',
|
|
20
|
+
false, [],
|
|
20
21
|
([, bs], { buffer }) => buffer!.import(bs),
|
|
21
22
|
([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
|
|
22
23
|
(nodes, { id }) => {
|
|
@@ -14,7 +14,8 @@ export const math: MathParser = lazy(() => rewrite(
|
|
|
14
14
|
/\$(?={)/y,
|
|
15
15
|
precedence(4, bracket),
|
|
16
16
|
'$',
|
|
17
|
-
false,
|
|
17
|
+
false,
|
|
18
|
+
[3 | Backtrack.bracket]),
|
|
18
19
|
surround(
|
|
19
20
|
/\$(?![\s{}])/y,
|
|
20
21
|
precedence(2, some(union([
|
|
@@ -22,7 +23,8 @@ export const math: MathParser = lazy(() => rewrite(
|
|
|
22
23
|
precedence(4, bracket),
|
|
23
24
|
]))),
|
|
24
25
|
/\$(?![-0-9A-Za-z])/y,
|
|
25
|
-
false,
|
|
26
|
+
false,
|
|
27
|
+
[3 | Backtrack.bracket]),
|
|
26
28
|
]),
|
|
27
29
|
({ context: { source, caches: { math: cache } = {} } }) => new List([
|
|
28
30
|
new Data(cache?.get(source)?.cloneNode(true) ||
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { MediaParser } from '../inline';
|
|
2
2
|
import { State, Recursion, Backtrack, Command } from '../context';
|
|
3
|
-
import { List, Data
|
|
3
|
+
import { List, Data } from '../../combinator/data/parser';
|
|
4
4
|
import { union, inits, tails, some, creation, recursion, precedence, constraint, surround, open, setBacktrack, dup, lazy, fmap, bind } from '../../combinator';
|
|
5
|
-
import {
|
|
5
|
+
import { uri, option as linkoption, resolve, decode, parse } from './link';
|
|
6
6
|
import { attributes } from './html';
|
|
7
7
|
import { unsafehtmlentity } from './htmlentity';
|
|
8
8
|
import { txt, str } from '../source';
|
|
@@ -30,25 +30,24 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
|
|
|
30
30
|
]), ']')),
|
|
31
31
|
']',
|
|
32
32
|
true,
|
|
33
|
+
[3 | Backtrack.escbracket],
|
|
33
34
|
([, ns = new List()], context) =>
|
|
34
35
|
context.linebreak === 0
|
|
35
36
|
? ns
|
|
36
|
-
: undefined,
|
|
37
|
-
undefined,
|
|
38
|
-
[3 | Backtrack.escbracket])),
|
|
37
|
+
: undefined)),
|
|
39
38
|
dup(surround(
|
|
40
39
|
/{(?![{}])/y,
|
|
41
40
|
inits([uri, some(option)]),
|
|
42
41
|
/ ?}/y,
|
|
43
42
|
false,
|
|
43
|
+
[3 | Backtrack.link],
|
|
44
44
|
undefined,
|
|
45
45
|
([as, bs], context) => {
|
|
46
46
|
if (!bs) return;
|
|
47
47
|
const head = context.position - context.range!;
|
|
48
48
|
setBacktrack(context, [2 | Backtrack.link], head);
|
|
49
49
|
return as.import(bs).push(new Data(Command.Cancel)) && as;
|
|
50
|
-
},
|
|
51
|
-
[3 | Backtrack.link])),
|
|
50
|
+
})),
|
|
52
51
|
]),
|
|
53
52
|
nodes =>
|
|
54
53
|
nodes.length === 1
|
|
@@ -98,26 +97,26 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
|
|
|
98
97
|
}
|
|
99
98
|
if (context.state! & State.link) return new List([new Data(el)]);
|
|
100
99
|
if (cache && cache.tagName !== 'IMG') return new List([new Data(el)]);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
})
|
|
109
|
-
|
|
100
|
+
return new List([new Data(define(
|
|
101
|
+
parse(
|
|
102
|
+
new List(),
|
|
103
|
+
linkparams.reduce(
|
|
104
|
+
(acc, p) => acc.push(new Data(p)) && acc,
|
|
105
|
+
new List([new Data(INSECURE_URI)])),
|
|
106
|
+
context),
|
|
107
|
+
{ class: null, target: '_blank' }, [el]))
|
|
108
|
+
]);
|
|
110
109
|
})))));
|
|
111
110
|
|
|
112
111
|
const bracket: MediaParser.TextParser.BracketParser = lazy(() => recursion(Recursion.terminal, union([
|
|
113
|
-
surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'),
|
|
114
|
-
undefined, () => new List()
|
|
115
|
-
surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'),
|
|
116
|
-
undefined, () => new List()
|
|
117
|
-
surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'),
|
|
118
|
-
undefined, () => new List()
|
|
119
|
-
surround(str('"'), precedence(2, some(union([unsafehtmlentity, txt]), '"')), str('"'),
|
|
120
|
-
undefined, () => new List()
|
|
112
|
+
surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'),
|
|
113
|
+
true, [3 | Backtrack.escbracket], undefined, () => new List()),
|
|
114
|
+
surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'),
|
|
115
|
+
true, [3 | Backtrack.escbracket], undefined, () => new List()),
|
|
116
|
+
surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'),
|
|
117
|
+
true, [3 | Backtrack.escbracket], undefined, () => new List()),
|
|
118
|
+
surround(str('"'), precedence(2, some(union([unsafehtmlentity, txt]), '"')), str('"'),
|
|
119
|
+
true, [3 | Backtrack.escbracket], undefined, () => new List()),
|
|
121
120
|
])));
|
|
122
121
|
|
|
123
122
|
const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
|
|
@@ -125,7 +124,7 @@ const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
|
|
|
125
124
|
open(/ /y, str(/[1-9][0-9]*/y)),
|
|
126
125
|
str(/[x:]/y),
|
|
127
126
|
str(/[1-9][0-9]*(?=[ }])/y),
|
|
128
|
-
false,
|
|
127
|
+
false, [],
|
|
129
128
|
([[{ value: a }], [{ value: b }], [{ value: c }]]) =>
|
|
130
129
|
b === 'x'
|
|
131
130
|
? new List([new Data(`width="${a}"`), new Data(`height="${c}"`)])
|
|
@@ -18,6 +18,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
18
18
|
]))),
|
|
19
19
|
']]',
|
|
20
20
|
false,
|
|
21
|
+
[1 | Backtrack.bracket, 3 | Backtrack.doublebracket],
|
|
21
22
|
([, ns], context) => {
|
|
22
23
|
const { position, range = 0, linebreak = 0 } = context;
|
|
23
24
|
if (linebreak === 0) {
|
|
@@ -69,7 +70,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
69
70
|
'',
|
|
70
71
|
some(inline, ']', [[']', 1]]),
|
|
71
72
|
str(']'),
|
|
72
|
-
true,
|
|
73
|
+
true, [],
|
|
73
74
|
([, cs = new List(), ds]) =>
|
|
74
75
|
cs.import(ds),
|
|
75
76
|
([, cs = new List()]) => {
|
|
@@ -86,15 +87,14 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
86
87
|
return state & State.annotation
|
|
87
88
|
? as.import(bs as List<Data<string>>)
|
|
88
89
|
: undefined;
|
|
89
|
-
}
|
|
90
|
-
[1 | Backtrack.bracket, 3 | Backtrack.doublebracket])));
|
|
90
|
+
})));
|
|
91
91
|
|
|
92
92
|
// Chicago-Style
|
|
93
93
|
const abbr: ReferenceParser.AbbrParser = surround(
|
|
94
94
|
str('^'),
|
|
95
95
|
union([str(/(?=[A-Z])(?:[0-9A-Za-z]'?|(?:[-.:]|\.?\??,? ?)(?!['\-.:?, ]))+/y)]),
|
|
96
96
|
/\|?(?=]])|\|/y,
|
|
97
|
-
true,
|
|
97
|
+
true, [],
|
|
98
98
|
([, ns], context) => {
|
|
99
99
|
const { source, position, range = 0 } = context;
|
|
100
100
|
if (!ns) return new List([new Data(''), new Data(source.slice(position - range, source[position - 1] === '|' ? position - 1 : position))]);
|
|
@@ -11,7 +11,8 @@ export const remark: RemarkParser = lazy(() => fallback(surround(
|
|
|
11
11
|
str(/\[%(?=[ \n])/y),
|
|
12
12
|
precedence(3, recursion(Recursion.inline,
|
|
13
13
|
some(union([inline]), /[ \n]%\]/y, [[/[ \n]%\]/y, 3]]))),
|
|
14
|
-
close(text, str(`%]`)),
|
|
14
|
+
close(text, str(`%]`)),
|
|
15
|
+
true, [],
|
|
15
16
|
([as, bs = new List(), cs]) => new List([
|
|
16
17
|
new Data(html('span', { class: 'remark' }, [
|
|
17
18
|
html('input', { type: 'checkbox' }),
|
|
@@ -13,15 +13,14 @@ export const ruby: RubyParser = lazy(() => bind(
|
|
|
13
13
|
dup(surround(
|
|
14
14
|
'[', text, ']',
|
|
15
15
|
false,
|
|
16
|
+
[1 | Backtrack.bracket, 3 | Backtrack.ruby],
|
|
16
17
|
([, ns]) => {
|
|
17
18
|
ns && ns.last?.value === '' && ns.pop();
|
|
18
19
|
return isTightNodeStart(ns) ? ns : undefined;
|
|
19
|
-
},
|
|
20
|
-
undefined,
|
|
21
|
-
[1 | Backtrack.bracket, 3 | Backtrack.ruby])),
|
|
20
|
+
})),
|
|
22
21
|
dup(surround(
|
|
23
22
|
'(', text, ')',
|
|
24
|
-
false,
|
|
23
|
+
false,
|
|
25
24
|
[1 | Backtrack.bracket, 3 | Backtrack.ruby])),
|
|
26
25
|
]),
|
|
27
26
|
([{ value: texts }, { value: rubies = undefined } = {}], context) => {
|
|
@@ -17,6 +17,7 @@ export const strong: StrongParser = lazy(() => surround(
|
|
|
17
17
|
some(inline, blankWith('*')),
|
|
18
18
|
open(some(inline, '*'), inline),
|
|
19
19
|
]))))),
|
|
20
|
-
str('**'),
|
|
20
|
+
str('**'),
|
|
21
|
+
false, [],
|
|
21
22
|
([, bs]) => new List([new Data(html('strong', defrag(unwrap(bs))))]),
|
|
22
23
|
([as, bs]) => bs && as.import(bs as List<Data<string>>)));
|
|
@@ -12,6 +12,7 @@ export const template: TemplateParser = lazy(() => surround(
|
|
|
12
12
|
some(union([bracket, escsource]), '}')),
|
|
13
13
|
str('}}'),
|
|
14
14
|
true,
|
|
15
|
+
[3 | Backtrack.doublebracket, 3 | Backtrack.escbracket],
|
|
15
16
|
([as, bs = new List(), cs]) => new List([
|
|
16
17
|
new Data(html('span', { class: 'template' }, defrag(unwrap(as.import(bs as List<Data<string>>).import(cs)))))
|
|
17
18
|
]),
|
|
@@ -23,25 +24,24 @@ export const template: TemplateParser = lazy(() => surround(
|
|
|
23
24
|
...invalid('template', 'syntax', `Missing the closing symbol "}}"`),
|
|
24
25
|
},
|
|
25
26
|
context.source.slice(context.position - context.range!, context.position)))
|
|
26
|
-
])
|
|
27
|
-
[3 | Backtrack.doublebracket, 3 | Backtrack.escbracket]));
|
|
27
|
+
])));
|
|
28
28
|
|
|
29
29
|
const bracket: TemplateParser.BracketParser = lazy(() => union([
|
|
30
|
-
surround(str('('), recursion(Recursion.terminal, some(union([bracket, escsource]), ')')), str(')'),
|
|
31
|
-
undefined, () => new List()
|
|
32
|
-
surround(str('['), recursion(Recursion.terminal, some(union([bracket, escsource]), ']')), str(']'),
|
|
33
|
-
undefined, () => new List()
|
|
34
|
-
surround(str('{'), recursion(Recursion.terminal, some(union([bracket, escsource]), '}')), str('}'),
|
|
35
|
-
undefined, () => new List()
|
|
30
|
+
surround(str('('), recursion(Recursion.terminal, some(union([bracket, escsource]), ')')), str(')'),
|
|
31
|
+
true, [3 | Backtrack.escbracket], undefined, () => new List()),
|
|
32
|
+
surround(str('['), recursion(Recursion.terminal, some(union([bracket, escsource]), ']')), str(']'),
|
|
33
|
+
true, [3 | Backtrack.escbracket], undefined, () => new List()),
|
|
34
|
+
surround(str('{'), recursion(Recursion.terminal, some(union([bracket, escsource]), '}')), str('}'),
|
|
35
|
+
true, [3 | Backtrack.escbracket], undefined, () => new List()),
|
|
36
36
|
surround(
|
|
37
37
|
str('"'),
|
|
38
38
|
precedence(2, recursion(Recursion.terminal, some(escsource, /["\n]/y, [['"', 2], ['\n', 3]]))),
|
|
39
39
|
str('"'),
|
|
40
40
|
true,
|
|
41
|
+
[3 | Backtrack.escbracket],
|
|
41
42
|
([as, bs = new List(), cs], context) =>
|
|
42
43
|
context.linebreak === 0
|
|
43
44
|
? as.import(bs as List<Data<string>>).import(cs)
|
|
44
45
|
: (context.position -= 1, as.import(bs as List<Data<string>>)),
|
|
45
|
-
([as, bs]) => bs && as.import(bs as List<Data<string>>),
|
|
46
|
-
[3 | Backtrack.escbracket]),
|
|
46
|
+
([as, bs]) => bs && as.import(bs as List<Data<string>>)),
|
|
47
47
|
]));
|
package/src/parser/inline.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { reference } from './inline/reference';
|
|
|
5
5
|
import { template } from './inline/template';
|
|
6
6
|
import { remark } from './inline/remark';
|
|
7
7
|
import { extension } from './inline/extension';
|
|
8
|
+
import { label } from './inline/extension/label';
|
|
8
9
|
import { textlink } from './inline/link';
|
|
9
10
|
import { ruby } from './inline/ruby';
|
|
10
11
|
import { html } from './inline/html';
|
|
@@ -94,7 +95,7 @@ export const inline: InlineParser = lazy(() => union([
|
|
|
94
95
|
return html(input);
|
|
95
96
|
case '$':
|
|
96
97
|
if (source[position + 1] === '{') return math(input);
|
|
97
|
-
return
|
|
98
|
+
return label(input)
|
|
98
99
|
|| math(input);
|
|
99
100
|
case '+':
|
|
100
101
|
if (source[position + 1] === '+') return insertion(input);
|
package/src/parser/segment.ts
CHANGED
|
@@ -13,6 +13,7 @@ export const MAX_SEGMENT_SIZE = 100_000; // 100,000 bytes (Max value size of FDB
|
|
|
13
13
|
export const MAX_INPUT_SIZE = MAX_SEGMENT_SIZE * 10;
|
|
14
14
|
|
|
15
15
|
const parser: SegmentParser = union([
|
|
16
|
+
some(emptyline),
|
|
16
17
|
input => {
|
|
17
18
|
const { context: { source, position } } = input;
|
|
18
19
|
if (position === source.length) return;
|
|
@@ -35,8 +36,7 @@ const parser: SegmentParser = union([
|
|
|
35
36
|
return extension(input);
|
|
36
37
|
}
|
|
37
38
|
},
|
|
38
|
-
some(contentline
|
|
39
|
-
some(emptyline, MAX_SEGMENT_SIZE + 1),
|
|
39
|
+
some(contentline),
|
|
40
40
|
]) as any;
|
|
41
41
|
|
|
42
42
|
export function* segment(source: string): Generator<string, undefined, undefined> {
|
|
@@ -14,10 +14,6 @@ export const escsource: EscapableSourceParser = ({ context }) => {
|
|
|
14
14
|
consume(1, context);
|
|
15
15
|
context.position += 1;
|
|
16
16
|
switch (char) {
|
|
17
|
-
case '\r':
|
|
18
|
-
assert(!source.includes('\r', position + 1));
|
|
19
|
-
consume(-1, context);
|
|
20
|
-
return new List();
|
|
21
17
|
case Command.Escape:
|
|
22
18
|
consume(1, context);
|
|
23
19
|
context.position += 1;
|
|
@@ -33,6 +29,9 @@ export const escsource: EscapableSourceParser = ({ context }) => {
|
|
|
33
29
|
context.position += 1;
|
|
34
30
|
return new List([new Data(source.slice(position, position + 2))]);
|
|
35
31
|
}
|
|
32
|
+
case '\r':
|
|
33
|
+
consume(-1, context);
|
|
34
|
+
return new List();
|
|
36
35
|
case '\n':
|
|
37
36
|
context.linebreak ||= source.length - position;
|
|
38
37
|
return new List([new Data(html('br'))]);
|
|
@@ -8,6 +8,7 @@ export const anyline: AnyLineParser = input => {
|
|
|
8
8
|
context.position = source.indexOf('\n', position) + 1 || source.length;
|
|
9
9
|
return new List();
|
|
10
10
|
};
|
|
11
|
+
|
|
11
12
|
const regEmptyline = /[^\S\n]*(?:$|\n)/y;
|
|
12
13
|
export const emptyline: EmptyLineParser = input => {
|
|
13
14
|
const { context } = input;
|
|
@@ -21,6 +22,7 @@ export const emptyline: EmptyLineParser = input => {
|
|
|
21
22
|
context.position = i;
|
|
22
23
|
return new List();
|
|
23
24
|
};
|
|
25
|
+
|
|
24
26
|
const regContentline = /[^\S\n]*\S[^\n]*(?:$|\n)/y;
|
|
25
27
|
export const contentline: ContentLineParser = input => {
|
|
26
28
|
const { context } = input;
|
|
@@ -33,4 +35,4 @@ export const contentline: ContentLineParser = input => {
|
|
|
33
35
|
if (i === 0) return;
|
|
34
36
|
context.position = i;
|
|
35
37
|
return new List();
|
|
36
|
-
}
|
|
38
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { TextParser, TxtParser
|
|
1
|
+
import { TextParser, TxtParser } from '../source';
|
|
2
2
|
import { Command } from '../context';
|
|
3
3
|
import { List, Data } from '../../combinator/data/parser';
|
|
4
|
-
import { union, consume
|
|
4
|
+
import { union, consume } from '../../combinator';
|
|
5
5
|
import { html } from 'typed-dom/dom';
|
|
6
6
|
|
|
7
7
|
//const delimiter = /(?=[\\!@#$&"`\[\](){}<>()[]{}*%|\r\n]|([+~=])\1|\/{3}|\s(?:\\?(?:$|\s)|[$%])|:\/\/)/g;
|
|
@@ -15,10 +15,6 @@ export const text: TextParser = input => {
|
|
|
15
15
|
consume(1, context);
|
|
16
16
|
context.position += 1;
|
|
17
17
|
switch (char) {
|
|
18
|
-
case '\r':
|
|
19
|
-
assert(!source.includes('\r', position + 1));
|
|
20
|
-
consume(-1, context);
|
|
21
|
-
return new List();
|
|
22
18
|
case Command.Escape:
|
|
23
19
|
case '\\':
|
|
24
20
|
switch (source[position + 1]) {
|
|
@@ -32,6 +28,9 @@ export const text: TextParser = input => {
|
|
|
32
28
|
context.position += 1;
|
|
33
29
|
return new List([new Data(source.slice(position + 1, context.position))]);
|
|
34
30
|
}
|
|
31
|
+
case '\r':
|
|
32
|
+
consume(-1, context);
|
|
33
|
+
return new List();
|
|
35
34
|
case '\n':
|
|
36
35
|
context.linebreak ||= source.length - position;
|
|
37
36
|
return new List([new Data(html('br'))]);
|
|
@@ -64,10 +63,6 @@ export const txt: TxtParser = union([
|
|
|
64
63
|
text,
|
|
65
64
|
]) as TxtParser;
|
|
66
65
|
|
|
67
|
-
export const linebreak: LinebreakParser = focus(/[\r\n]/y, union([
|
|
68
|
-
text,
|
|
69
|
-
])) as LinebreakParser;
|
|
70
|
-
|
|
71
66
|
export function canSkip(source: string, position: number): boolean {
|
|
72
67
|
assert(position < source.length);
|
|
73
68
|
if (!isWhitespace(source[position], false)) return false;
|
|
@@ -185,12 +180,12 @@ export function backToEmailHead(source: string, position: number, index: number)
|
|
|
185
180
|
? delim
|
|
186
181
|
: index;
|
|
187
182
|
}
|
|
188
|
-
function isAlphanumeric(char: string): boolean {
|
|
183
|
+
export function isAlphanumeric(char: string): boolean {
|
|
189
184
|
assert(char.length === 1);
|
|
190
185
|
if (char < '0' || '\x7F' < char) return false;
|
|
191
186
|
return '0' <= char && char <= '9'
|
|
192
|
-
|| '
|
|
193
|
-
|| '
|
|
187
|
+
|| 'A' <= char && char <= 'Z'
|
|
188
|
+
|| 'a' <= char && char <= 'z';
|
|
194
189
|
}
|
|
195
190
|
|
|
196
191
|
//const dict = new class {
|
|
@@ -14,14 +14,12 @@ export const unescsource: UnescapableSourceParser = ({ context }) => {
|
|
|
14
14
|
consume(1, context);
|
|
15
15
|
context.position += 1;
|
|
16
16
|
switch (char) {
|
|
17
|
-
case '\r':
|
|
18
|
-
assert(!source.includes('\r', position + 1));
|
|
19
|
-
consume(-1, context);
|
|
20
|
-
return new List();
|
|
21
17
|
case Command.Escape:
|
|
22
18
|
consume(1, context);
|
|
23
19
|
context.position += 1;
|
|
24
20
|
return new List([new Data(source.slice(position + 1, position + 2))]);
|
|
21
|
+
case '\r':
|
|
22
|
+
return new List();
|
|
25
23
|
case '\n':
|
|
26
24
|
context.linebreak ||= source.length - position;
|
|
27
25
|
return new List([new Data(html('br'))]);
|
package/src/parser/source.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { MarkdownParser } from '../../markdown';
|
|
|
3
3
|
import SourceParser = MarkdownParser.SourceParser;
|
|
4
4
|
export import TextParser = SourceParser.TextParser;
|
|
5
5
|
export import TxtParser = SourceParser.TxtParser;
|
|
6
|
-
export import LinebreakParser = SourceParser.LinebreakParser;
|
|
7
6
|
export import EscapableSourceParser = SourceParser.EscapableSourceParser;
|
|
8
7
|
export import UnescapableSourceParser = SourceParser.UnescapableSourceParser;
|
|
9
8
|
export import StrParser = SourceParser.StrParser;
|
|
@@ -11,7 +10,7 @@ export import ContentLineParser = SourceParser.ContentLineParser;
|
|
|
11
10
|
export import EmptyLineParser = SourceParser.EmptyLineParser;
|
|
12
11
|
export import AnyLineParser = SourceParser.AnyLineParser;
|
|
13
12
|
|
|
14
|
-
export { text, txt
|
|
13
|
+
export { text, txt } from './source/text';
|
|
15
14
|
export { escsource } from './source/escapable';
|
|
16
15
|
export { unescsource } from './source/unescapable';
|
|
17
16
|
export { str, strs } from './source/str';
|