securemark 0.293.4 → 0.294.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/dist/index.js +868 -564
- package/markdown.d.ts +13 -13
- package/package.json +3 -3
- package/src/combinator/control/constraint/block.test.ts +6 -6
- package/src/combinator/control/constraint/contract.ts +3 -3
- package/src/combinator/control/constraint/line.test.ts +7 -7
- package/src/combinator/control/constraint/line.ts +1 -1
- package/src/combinator/control/manipulation/clear.ts +2 -3
- package/src/combinator/control/manipulation/convert.ts +2 -2
- package/src/combinator/control/manipulation/duplicate.ts +4 -5
- package/src/combinator/control/manipulation/fence.ts +2 -2
- package/src/combinator/control/manipulation/indent.test.ts +2 -2
- package/src/combinator/control/manipulation/indent.ts +4 -4
- package/src/combinator/control/manipulation/reverse.ts +2 -2
- package/src/combinator/control/manipulation/scope.ts +3 -4
- package/src/combinator/control/manipulation/surround.ts +14 -15
- package/src/combinator/control/monad/bind.ts +6 -6
- package/src/combinator/control/monad/fmap.ts +7 -7
- package/src/combinator/data/data.ts +135 -0
- package/src/combinator/data/parser/context.test.ts +16 -15
- package/src/combinator/data/parser/context.ts +5 -4
- package/src/combinator/data/parser/inits.ts +6 -7
- package/src/combinator/data/parser/sequence.test.ts +3 -3
- package/src/combinator/data/parser/sequence.ts +6 -7
- package/src/combinator/data/parser/some.test.ts +3 -3
- package/src/combinator/data/parser/some.ts +4 -4
- package/src/combinator/data/parser/subsequence.test.ts +4 -4
- package/src/combinator/data/parser/subsequence.ts +3 -3
- package/src/combinator/data/parser/tails.ts +3 -3
- package/src/combinator/data/parser/union.test.ts +3 -3
- package/src/combinator/data/parser.ts +16 -7
- package/src/debug.test.ts +6 -5
- package/src/parser/api/bind.ts +6 -8
- package/src/parser/api/header.ts +1 -1
- package/src/parser/api/normalize.ts +2 -4
- package/src/parser/api/parse.ts +3 -1
- package/src/parser/block/blockquote.ts +6 -4
- package/src/parser/block/codeblock.ts +8 -7
- package/src/parser/block/dlist.ts +9 -8
- package/src/parser/block/extension/aside.ts +27 -21
- package/src/parser/block/extension/example.ts +29 -26
- package/src/parser/block/extension/fig.ts +1 -1
- package/src/parser/block/extension/figbase.ts +6 -5
- package/src/parser/block/extension/figure.ts +23 -19
- package/src/parser/block/extension/message.ts +35 -24
- package/src/parser/block/extension/placeholder.ts +17 -13
- package/src/parser/block/extension/table.ts +47 -40
- package/src/parser/block/heading.test.ts +3 -12
- package/src/parser/block/heading.ts +12 -8
- package/src/parser/block/ilist.ts +13 -12
- package/src/parser/block/mathblock.ts +21 -17
- package/src/parser/block/mediablock.ts +7 -5
- package/src/parser/block/olist.ts +15 -5
- package/src/parser/block/pagebreak.ts +2 -1
- package/src/parser/block/paragraph.ts +3 -1
- package/src/parser/block/reply/cite.ts +20 -15
- package/src/parser/block/reply/quote.ts +9 -7
- package/src/parser/block/reply.ts +7 -3
- package/src/parser/block/sidefence.ts +8 -7
- package/src/parser/block/table.ts +23 -22
- package/src/parser/block/ulist.ts +16 -12
- package/src/parser/block.ts +7 -6
- package/src/parser/header.test.ts +3 -1
- package/src/parser/header.ts +20 -20
- package/src/parser/inline/annotation.ts +3 -1
- package/src/parser/inline/autolink/account.ts +3 -2
- package/src/parser/inline/autolink/anchor.ts +3 -2
- package/src/parser/inline/autolink/channel.ts +5 -4
- package/src/parser/inline/autolink/email.ts +4 -3
- package/src/parser/inline/autolink/hashnum.ts +3 -2
- package/src/parser/inline/autolink/hashtag.ts +4 -3
- package/src/parser/inline/autolink/url.ts +7 -6
- package/src/parser/inline/bracket.ts +16 -15
- package/src/parser/inline/code.ts +5 -4
- package/src/parser/inline/deletion.ts +5 -5
- package/src/parser/inline/emphasis.ts +4 -3
- package/src/parser/inline/emstrong.test.ts +18 -18
- package/src/parser/inline/emstrong.ts +39 -30
- package/src/parser/inline/extension/index.ts +22 -19
- package/src/parser/inline/extension/indexee.ts +2 -2
- package/src/parser/inline/extension/indexer.ts +2 -1
- package/src/parser/inline/extension/label.ts +7 -3
- package/src/parser/inline/extension/placeholder.ts +6 -6
- package/src/parser/inline/html.ts +27 -28
- package/src/parser/inline/htmlentity.ts +9 -8
- package/src/parser/inline/insertion.ts +5 -5
- package/src/parser/inline/italic.ts +5 -5
- package/src/parser/inline/link.ts +36 -38
- package/src/parser/inline/mark.ts +7 -7
- package/src/parser/inline/math.ts +5 -4
- package/src/parser/inline/media.ts +33 -32
- package/src/parser/inline/reference.ts +19 -20
- package/src/parser/inline/remark.ts +11 -11
- package/src/parser/inline/ruby.ts +50 -53
- package/src/parser/inline/strong.ts +4 -3
- package/src/parser/inline/template.ts +16 -15
- package/src/parser/inline.test.ts +3 -3
- package/src/parser/segment.ts +3 -1
- package/src/parser/source/escapable.ts +9 -8
- package/src/parser/source/line.ts +4 -3
- package/src/parser/source/str.ts +2 -2
- package/src/parser/source/text.ts +19 -26
- package/src/parser/source/unescapable.ts +6 -5
- package/src/parser/util.ts +16 -30
- package/src/parser/visibility.ts +19 -20
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../../markdown';
|
|
2
2
|
import { LinkParser } from '../inline';
|
|
3
3
|
import { State, Backtrack, Command } from '../context';
|
|
4
|
+
import { List, Data } from '../../combinator/data/parser';
|
|
4
5
|
import { union, inits, tails, sequence, subsequence, some, creation, precedence, state, constraint, validate, surround, open, setBacktrack, dup, reverse, lazy, fmap, bind } from '../../combinator';
|
|
5
6
|
import { inline, media, shortmedia } from '../inline';
|
|
6
7
|
import { attributes } from './html';
|
|
7
8
|
import { unescsource, str } from '../source';
|
|
8
9
|
import { trimBlankStart, trimBlankNodeEnd } from '../visibility';
|
|
9
|
-
import { invalid, stringify } from '../util';
|
|
10
|
+
import { unwrap, invalid, stringify } from '../util';
|
|
10
11
|
import { ReadonlyURL } from 'spica/url';
|
|
11
|
-
import { unshift, push } from 'spica/array';
|
|
12
12
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
13
13
|
|
|
14
14
|
const optspec = {
|
|
@@ -24,9 +24,9 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
24
24
|
trimBlankStart(some(union([inline]), ']', [[']', 1]])),
|
|
25
25
|
']',
|
|
26
26
|
true,
|
|
27
|
-
([, ns =
|
|
27
|
+
([, ns = new List()], context) =>
|
|
28
28
|
context.linebreak === 0
|
|
29
|
-
?
|
|
29
|
+
? ns.push(new Data(Command.Separator)) && ns
|
|
30
30
|
: undefined,
|
|
31
31
|
undefined,
|
|
32
32
|
[3 | Backtrack.bracket, 3 | Backtrack.link, 2 | Backtrack.ruby])),
|
|
@@ -42,12 +42,12 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
42
42
|
if (!bs) return;
|
|
43
43
|
const head = context.position - context.range!;
|
|
44
44
|
setBacktrack(context, [2 | Backtrack.link], head);
|
|
45
|
-
return
|
|
45
|
+
return as.import(bs).push(new Data(Command.Cancel)) && as;
|
|
46
46
|
},
|
|
47
47
|
[3 | Backtrack.link])),
|
|
48
48
|
]),
|
|
49
|
-
([content,
|
|
50
|
-
if (content.
|
|
49
|
+
([{ value: content }, { value: params = undefined } = {}], context) => {
|
|
50
|
+
if (content.last!.value === Command.Separator) {
|
|
51
51
|
content.pop();
|
|
52
52
|
if (params === undefined) {
|
|
53
53
|
const head = context.position - context.range!;
|
|
@@ -55,37 +55,37 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
|
-
params = content as string
|
|
59
|
-
content =
|
|
58
|
+
params = content as List<Data<string>>;
|
|
59
|
+
content = new List();
|
|
60
60
|
}
|
|
61
|
-
if (params.
|
|
61
|
+
if (params.last!.value === Command.Cancel) {
|
|
62
62
|
params.pop();
|
|
63
|
-
return [
|
|
64
|
-
html('span',
|
|
63
|
+
return new List([
|
|
64
|
+
new Data(html('span',
|
|
65
65
|
{
|
|
66
66
|
class: 'invalid',
|
|
67
67
|
...invalid('link', 'syntax', 'Missing the closing symbol "}"')
|
|
68
68
|
},
|
|
69
|
-
context.source.slice(context.position - context.range!, context.position))
|
|
70
|
-
]
|
|
69
|
+
context.source.slice(context.position - context.range!, context.position)))
|
|
70
|
+
]);
|
|
71
71
|
}
|
|
72
|
-
assert(!html('div', content).querySelector('a, .media, .annotation, .reference'));
|
|
73
|
-
assert(content
|
|
72
|
+
assert(!html('div', unwrap(content)).querySelector('a, .media, .annotation, .reference'));
|
|
73
|
+
assert(content.head?.value !== '');
|
|
74
74
|
if (content.length !== 0 && trimBlankNodeEnd(content).length === 0) return;
|
|
75
|
-
return [
|
|
75
|
+
return new List([new Data(parse(content, params as List<Data<string>>, context))]);
|
|
76
76
|
}))))));
|
|
77
77
|
|
|
78
78
|
export const medialink: LinkParser.MediaLinkParser = lazy(() => constraint(State.link | State.media, validate(/[[{]/y, creation(10,
|
|
79
79
|
state(State.linkers,
|
|
80
|
-
bind(
|
|
80
|
+
bind(sequence([
|
|
81
81
|
dup(surround(
|
|
82
82
|
'[',
|
|
83
83
|
union([media, shortmedia]),
|
|
84
84
|
']')),
|
|
85
85
|
dup(surround(/{(?![{}])/y, inits([uri, some(option)]), / ?}/y)),
|
|
86
|
-
])
|
|
87
|
-
([
|
|
88
|
-
[
|
|
86
|
+
]),
|
|
87
|
+
([{ value: content }, { value: params }], context) =>
|
|
88
|
+
new List([new Data(parse(content, params as List<Data<string>>, context))])))))));
|
|
89
89
|
|
|
90
90
|
export const unsafelink: LinkParser.UnsafeLinkParser = lazy(() =>
|
|
91
91
|
creation(10,
|
|
@@ -96,8 +96,8 @@ export const unsafelink: LinkParser.UnsafeLinkParser = lazy(() =>
|
|
|
96
96
|
']')),
|
|
97
97
|
dup(surround(/{(?![{}])/y, inits([uri, some(option)]), / ?}/y)),
|
|
98
98
|
])),
|
|
99
|
-
([params, content =
|
|
100
|
-
[
|
|
99
|
+
([{ value: params }, { value: content } = new Data(new List<Data<string>>())], context) =>
|
|
100
|
+
new List([new Data(parse(content, params, context))]))));
|
|
101
101
|
|
|
102
102
|
export const uri: LinkParser.ParameterParser.UriParser = union([
|
|
103
103
|
open(/ /y, str(/\S+/y)),
|
|
@@ -105,19 +105,18 @@ export const uri: LinkParser.ParameterParser.UriParser = union([
|
|
|
105
105
|
]);
|
|
106
106
|
|
|
107
107
|
export const option: LinkParser.ParameterParser.OptionParser = union([
|
|
108
|
-
fmap(str(/ nofollow(?=[ }])/y), () => [
|
|
108
|
+
fmap(str(/ nofollow(?=[ }])/y), () => new List([new Data(' rel="nofollow"')])),
|
|
109
109
|
str(/ [a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[ }])/yi),
|
|
110
110
|
str(/ [^\s{}]+/y),
|
|
111
111
|
]);
|
|
112
112
|
|
|
113
113
|
function parse(
|
|
114
|
-
content:
|
|
115
|
-
params: string
|
|
114
|
+
content: List<Data<string | HTMLElement>>,
|
|
115
|
+
params: List<Data<string>>,
|
|
116
116
|
context: MarkdownParser.Context,
|
|
117
117
|
): HTMLAnchorElement {
|
|
118
118
|
assert(params.length > 0);
|
|
119
|
-
|
|
120
|
-
const INSECURE_URI = params.shift()!;
|
|
119
|
+
const INSECURE_URI = params.shift()!.value;
|
|
121
120
|
assert(INSECURE_URI === INSECURE_URI.trim());
|
|
122
121
|
assert(!INSECURE_URI.match(/\s/));
|
|
123
122
|
let uri: ReadonlyURL | undefined;
|
|
@@ -135,12 +134,12 @@ function parse(
|
|
|
135
134
|
context.host?.origin || location.origin);
|
|
136
135
|
return el.classList.contains('invalid')
|
|
137
136
|
? el
|
|
138
|
-
: define(el, attributes('link', optspec, params)[0]);
|
|
137
|
+
: define(el, attributes('link', optspec, unwrap(params))[0]);
|
|
139
138
|
}
|
|
140
139
|
|
|
141
140
|
function elem(
|
|
142
141
|
INSECURE_URI: string,
|
|
143
|
-
content:
|
|
142
|
+
content: List<Data<string | HTMLElement>>,
|
|
144
143
|
uri: ReadonlyURL | undefined,
|
|
145
144
|
origin: string,
|
|
146
145
|
): HTMLAnchorElement {
|
|
@@ -155,7 +154,7 @@ function elem(
|
|
|
155
154
|
case 'https:':
|
|
156
155
|
assert(uri.host);
|
|
157
156
|
switch (true) {
|
|
158
|
-
case /[0-9a-z]:\S/i.test(stringify(content)):
|
|
157
|
+
case /[0-9a-z]:\S/i.test(stringify(unwrap(content))):
|
|
159
158
|
type = 'content';
|
|
160
159
|
message = 'URI must not be contained';
|
|
161
160
|
break;
|
|
@@ -171,20 +170,19 @@ function elem(
|
|
|
171
170
|
href: uri.source,
|
|
172
171
|
target: undefined
|
|
173
172
|
|| uri.origin !== origin
|
|
174
|
-
|| typeof content
|
|
173
|
+
|| typeof content.head?.value === 'object' && content.head!.value.classList.contains('media')
|
|
175
174
|
? '_blank'
|
|
176
175
|
: undefined,
|
|
177
176
|
},
|
|
178
177
|
content.length === 0
|
|
179
178
|
? decode(INSECURE_URI)
|
|
180
|
-
: content);
|
|
179
|
+
: defrag(unwrap(content)));
|
|
181
180
|
}
|
|
182
181
|
break;
|
|
183
182
|
case 'tel:':
|
|
184
|
-
assert(content.length <= 1);
|
|
185
183
|
const tel = content.length === 0
|
|
186
184
|
? INSECURE_URI
|
|
187
|
-
: content
|
|
185
|
+
: stringify(unwrap(content));
|
|
188
186
|
const pattern = /^(?:tel:)?(?:\+(?!0))?\d+(?:-\d+)*$/i;
|
|
189
187
|
switch (true) {
|
|
190
188
|
case content.length <= 1
|
|
@@ -198,8 +196,8 @@ function elem(
|
|
|
198
196
|
href: uri.source,
|
|
199
197
|
},
|
|
200
198
|
content.length === 0
|
|
201
|
-
?
|
|
202
|
-
: content);
|
|
199
|
+
? INSECURE_URI
|
|
200
|
+
: defrag(unwrap(content)));
|
|
203
201
|
default:
|
|
204
202
|
type = 'content';
|
|
205
203
|
message = 'Invalid content';
|
|
@@ -216,7 +214,7 @@ function elem(
|
|
|
216
214
|
},
|
|
217
215
|
content.length === 0
|
|
218
216
|
? INSECURE_URI
|
|
219
|
-
: content);
|
|
217
|
+
: defrag(unwrap(content)));
|
|
220
218
|
}
|
|
221
219
|
|
|
222
220
|
export function resolve(uri: string, host: URL | Location, source: URL | Location): string {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { MarkParser } from '../inline';
|
|
2
2
|
import { State, Recursion, Command } from '../context';
|
|
3
|
+
import { List, Data } from '../../combinator/data/parser';
|
|
3
4
|
import { union, some, recursion, precedence, state, constraint, validate, surround, open, lazy } from '../../combinator';
|
|
4
5
|
import { inline } from '../inline';
|
|
5
6
|
import { identity, signature } from './extension/indexee';
|
|
6
7
|
import { tightStart, blankWith } from '../visibility';
|
|
7
|
-
import { repeat } from '../util';
|
|
8
|
-
import { push } from 'spica/array';
|
|
8
|
+
import { unwrap, repeat } from '../util';
|
|
9
9
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
10
10
|
|
|
11
11
|
export const mark: MarkParser = lazy(() => constraint(State.linkers & ~State.mark, validate('==',
|
|
@@ -17,12 +17,12 @@ export const mark: MarkParser = lazy(() => constraint(State.linkers & ~State.mar
|
|
|
17
17
|
open(some(inline, '='), inline),
|
|
18
18
|
])))),
|
|
19
19
|
'==', false,
|
|
20
|
-
([, bs], { buffer }) =>
|
|
21
|
-
([, bs], { buffer }) => bs &&
|
|
20
|
+
([, bs], { buffer }) => buffer!.import(bs),
|
|
21
|
+
([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
|
|
22
22
|
(nodes, { id }) => {
|
|
23
|
-
const el = html('mark', defrag(nodes));
|
|
23
|
+
const el = html('mark', defrag(unwrap(nodes)));
|
|
24
24
|
define(el, { id: identity('mark', id, signature(el)) });
|
|
25
25
|
return el.id
|
|
26
|
-
? [el, html('a', { href: `#${el.id}` })]
|
|
27
|
-
: [el];
|
|
26
|
+
? new List([new Data(el), new Data(html('a', { href: `#${el.id}` }))])
|
|
27
|
+
: new List([new Data(el)]);
|
|
28
28
|
}))))));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MathParser } from '../inline';
|
|
2
2
|
import { Backtrack, Recursion } from '../context';
|
|
3
|
+
import { List, Data } from '../../combinator/data/parser';
|
|
3
4
|
import { union, some, recursion, precedence, rewrite, surround, lazy } from '../../combinator';
|
|
4
5
|
import { escsource, str } from '../source';
|
|
5
6
|
import { invalid } from '../util';
|
|
@@ -23,8 +24,8 @@ export const math: MathParser = lazy(() => rewrite(
|
|
|
23
24
|
/\$(?![-0-9A-Za-z])/y,
|
|
24
25
|
false, undefined, undefined, [3 | Backtrack.bracket]),
|
|
25
26
|
]),
|
|
26
|
-
({ context: { source, caches: { math: cache } = {} } }) => [
|
|
27
|
-
cache?.get(source)?.cloneNode(true) ||
|
|
27
|
+
({ context: { source, caches: { math: cache } = {} } }) => new List([
|
|
28
|
+
new Data(cache?.get(source)?.cloneNode(true) ||
|
|
28
29
|
html('span',
|
|
29
30
|
!forbiddenCommand.test(source)
|
|
30
31
|
? { class: 'math', translate: 'no', 'data-src': source }
|
|
@@ -34,8 +35,8 @@ export const math: MathParser = lazy(() => rewrite(
|
|
|
34
35
|
...invalid('math', 'content',
|
|
35
36
|
`"${source.match(forbiddenCommand)![0]}" command is forbidden`),
|
|
36
37
|
},
|
|
37
|
-
source)
|
|
38
|
-
]
|
|
38
|
+
source))
|
|
39
|
+
])));
|
|
39
40
|
|
|
40
41
|
const bracket: MathParser.BracketParser = lazy(() => surround(
|
|
41
42
|
str('{'),
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { MediaParser } from '../inline';
|
|
2
2
|
import { State, Recursion, Backtrack, Command } from '../context';
|
|
3
|
-
import { subinput } from '../../combinator/data/parser';
|
|
4
|
-
import { union, inits, tails, some, creation, recursion, precedence, constraint,
|
|
3
|
+
import { List, Data, subinput } from '../../combinator/data/parser';
|
|
4
|
+
import { union, inits, tails, some, creation, recursion, precedence, constraint, surround, open, setBacktrack, dup, lazy, fmap, bind } from '../../combinator';
|
|
5
5
|
import { unsafelink, uri, option as linkoption, resolve, decode } from './link';
|
|
6
6
|
import { attributes } from './html';
|
|
7
7
|
import { unsafehtmlentity } from './htmlentity';
|
|
8
8
|
import { txt, str } from '../source';
|
|
9
|
-
import { invalid } from '../util';
|
|
9
|
+
import { unwrap, invalid } from '../util';
|
|
10
10
|
import { ReadonlyURL } from 'spica/url';
|
|
11
|
-
import { unshift, push } from 'spica/array';
|
|
12
11
|
import { html, define } from 'typed-dom/dom';
|
|
13
12
|
|
|
14
13
|
const optspec = {
|
|
@@ -21,7 +20,7 @@ Object.setPrototypeOf(optspec, null);
|
|
|
21
20
|
|
|
22
21
|
export const media: MediaParser = lazy(() => constraint(State.media, creation(10, open(
|
|
23
22
|
'!',
|
|
24
|
-
bind(
|
|
23
|
+
bind(fmap(tails([
|
|
25
24
|
dup(surround(
|
|
26
25
|
'[',
|
|
27
26
|
precedence(1, some(union([
|
|
@@ -31,9 +30,9 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
|
|
|
31
30
|
]), ']')),
|
|
32
31
|
']',
|
|
33
32
|
true,
|
|
34
|
-
([, ns =
|
|
33
|
+
([, ns = new List()], context) =>
|
|
35
34
|
context.linebreak === 0
|
|
36
|
-
?
|
|
35
|
+
? ns
|
|
37
36
|
: undefined,
|
|
38
37
|
undefined,
|
|
39
38
|
[3 | Backtrack.escbracket])),
|
|
@@ -47,26 +46,29 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
|
|
|
47
46
|
if (!bs) return;
|
|
48
47
|
const head = context.position - context.range!;
|
|
49
48
|
setBacktrack(context, [2 | Backtrack.link], head);
|
|
50
|
-
return
|
|
49
|
+
return as.import(bs).push(new Data(Command.Cancel)) && as;
|
|
51
50
|
},
|
|
52
51
|
[3 | Backtrack.link])),
|
|
53
52
|
]),
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
nodes =>
|
|
54
|
+
nodes.length === 1
|
|
55
|
+
? new List<Data<List<Data<string>>>>([new Data(new List([new Data('')])), nodes.delete(nodes.head!)])
|
|
56
|
+
: new List<Data<List<Data<string>>>>([new Data(new List([new Data(nodes.head!.value.foldl((acc, { value }) => acc + value, ''))])), nodes.delete(nodes.last!)])),
|
|
57
|
+
([{ value: [{ value: text }] }, { value: params }], context) => {
|
|
58
|
+
if (text && text.trimStart() === '') return;
|
|
59
|
+
text = text.trim();
|
|
60
|
+
if (params.last!.value === Command.Cancel) {
|
|
58
61
|
params.pop();
|
|
59
|
-
return [
|
|
60
|
-
html('span',
|
|
62
|
+
return new List([
|
|
63
|
+
new Data(html('span',
|
|
61
64
|
{
|
|
62
65
|
class: 'invalid',
|
|
63
66
|
...invalid('media', 'syntax', 'Missing the closing symbol "}"')
|
|
64
67
|
},
|
|
65
|
-
'!' + context.source.slice(context.position - context.range!, context.position))
|
|
66
|
-
]
|
|
68
|
+
'!' + context.source.slice(context.position - context.range!, context.position)))
|
|
69
|
+
]);
|
|
67
70
|
}
|
|
68
|
-
|
|
69
|
-
const INSECURE_URI = params.shift()!;
|
|
71
|
+
const INSECURE_URI = params.shift()!.value;
|
|
70
72
|
assert(INSECURE_URI === INSECURE_URI.trim());
|
|
71
73
|
assert(!INSECURE_URI.match(/\s/));
|
|
72
74
|
// altが空だとエラーが見えないため埋める。
|
|
@@ -85,37 +87,37 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
|
|
|
85
87
|
|| html('img', { class: 'media', 'data-src': uri?.source });
|
|
86
88
|
assert(!el.matches('.invalid'));
|
|
87
89
|
el.setAttribute('alt', text);
|
|
88
|
-
if (!sanitize(el, uri)) return [
|
|
90
|
+
if (!sanitize(el, uri)) return new List([new Data(el)]);
|
|
89
91
|
assert(!el.matches('.invalid'));
|
|
90
|
-
const [attrs, linkparams] = attributes('media', optspec, params);
|
|
92
|
+
const [attrs, linkparams] = attributes('media', optspec, unwrap(params));
|
|
91
93
|
define(el, attrs);
|
|
92
94
|
assert(el.matches('img') || !el.matches('.invalid'));
|
|
93
95
|
// Awaiting the generic support for attr().
|
|
94
96
|
if (el.hasAttribute('aspect-ratio')) {
|
|
95
97
|
el.style.aspectRatio = el.getAttribute('aspect-ratio')!;
|
|
96
98
|
}
|
|
97
|
-
if (context.state! & State.link) return [
|
|
98
|
-
if (cache && cache.tagName !== 'IMG') return [
|
|
99
|
+
if (context.state! & State.link) return new List([new Data(el)]);
|
|
100
|
+
if (cache && cache.tagName !== 'IMG') return new List([new Data(el)]);
|
|
99
101
|
const { source, position } = context;
|
|
100
102
|
return fmap(
|
|
101
103
|
unsafelink as MediaParser,
|
|
102
|
-
([
|
|
104
|
+
([{ value }]) => {
|
|
103
105
|
context.source = source;
|
|
104
106
|
context.position = position;
|
|
105
|
-
return [define(
|
|
107
|
+
return new List([new Data(define(value, { class: null, target: '_blank' }, [el]))]);
|
|
106
108
|
})
|
|
107
109
|
(subinput(`{ ${INSECURE_URI}${linkparams.join('')} }`, context));
|
|
108
110
|
})))));
|
|
109
111
|
|
|
110
112
|
const bracket: MediaParser.TextParser.BracketParser = lazy(() => recursion(Recursion.terminal, union([
|
|
111
113
|
surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'), true,
|
|
112
|
-
undefined, () =>
|
|
114
|
+
undefined, () => new List(), [3 | Backtrack.escbracket]),
|
|
113
115
|
surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'), true,
|
|
114
|
-
undefined, () =>
|
|
116
|
+
undefined, () => new List(), [3 | Backtrack.escbracket]),
|
|
115
117
|
surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'), true,
|
|
116
|
-
undefined, () =>
|
|
118
|
+
undefined, () => new List(), [3 | Backtrack.escbracket]),
|
|
117
119
|
surround(str('"'), precedence(2, some(union([unsafehtmlentity, txt]), '"')), str('"'), true,
|
|
118
|
-
undefined, () =>
|
|
120
|
+
undefined, () => new List(), [3 | Backtrack.escbracket]),
|
|
119
121
|
])));
|
|
120
122
|
|
|
121
123
|
const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
|
|
@@ -124,11 +126,10 @@ const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
|
|
|
124
126
|
str(/[x:]/y),
|
|
125
127
|
str(/[1-9][0-9]*(?=[ }])/y),
|
|
126
128
|
false,
|
|
127
|
-
([[a], [b], [c]]) =>
|
|
129
|
+
([[{ value: a }], [{ value: b }], [{ value: c }]]) =>
|
|
128
130
|
b === 'x'
|
|
129
|
-
? [`width="${a}"
|
|
130
|
-
: [`aspect-ratio="${a}/${c}"`],
|
|
131
|
-
]),
|
|
131
|
+
? new List([new Data(`width="${a}"`), new Data(`height="${c}"`)])
|
|
132
|
+
: new List([new Data(`aspect-ratio="${a}/${c}"`)])),
|
|
132
133
|
linkoption,
|
|
133
134
|
]));
|
|
134
135
|
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { ReferenceParser } from '../inline';
|
|
2
2
|
import { State, Backtrack, Command } from '../context';
|
|
3
|
-
import { eval } from '../../combinator/data/parser';
|
|
3
|
+
import { List, Data, eval } from '../../combinator/data/parser';
|
|
4
4
|
import { union, subsequence, some, precedence, state, constraint, surround, isBacktrack, setBacktrack, lazy } from '../../combinator';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { textlink } from './link';
|
|
7
7
|
import { str } from '../source';
|
|
8
8
|
import { trimBlankStart, trimBlankNodeEnd } from '../visibility';
|
|
9
|
+
import { unwrap, invalid } from '../util';
|
|
9
10
|
import { html, defrag } from 'typed-dom/dom';
|
|
10
|
-
import { unshift, push } from 'spica/array';
|
|
11
|
-
import { invalid } from '../util';
|
|
12
11
|
|
|
13
12
|
export const reference: ReferenceParser = lazy(() => constraint(State.reference, surround(
|
|
14
13
|
str('[['),
|
|
@@ -22,7 +21,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
22
21
|
([, ns], context) => {
|
|
23
22
|
const { position, range = 0, linebreak = 0 } = context;
|
|
24
23
|
if (linebreak === 0) {
|
|
25
|
-
return [
|
|
24
|
+
return new List([new Data(html('sup', attributes(ns), [html('span', defrag(unwrap(trimBlankNodeEnd(ns))))]))]);
|
|
26
25
|
}
|
|
27
26
|
else {
|
|
28
27
|
const head = position - range;
|
|
@@ -42,13 +41,13 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
42
41
|
else {
|
|
43
42
|
assert(source[position] === ']');
|
|
44
43
|
if (state & State.annotation) {
|
|
45
|
-
push(
|
|
44
|
+
bs.push(new Data(source[position]));
|
|
46
45
|
}
|
|
47
46
|
context.position += 1;
|
|
48
47
|
let result: ReturnType<typeof textlink>;
|
|
49
48
|
if (source[context.position] !== '{') {
|
|
50
49
|
setBacktrack(context, [2 | Backtrack.link], head + 1);
|
|
51
|
-
result =
|
|
50
|
+
result = new List();
|
|
52
51
|
}
|
|
53
52
|
else {
|
|
54
53
|
result = !isBacktrack(context, [1 | Backtrack.link])
|
|
@@ -57,7 +56,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
57
56
|
context.range = range;
|
|
58
57
|
if (!result) {
|
|
59
58
|
setBacktrack(context, [2 | Backtrack.link], head + 1);
|
|
60
|
-
result =
|
|
59
|
+
result = new List();
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
assert(result);
|
|
@@ -71,21 +70,21 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
71
70
|
some(inline, ']', [[']', 1]]),
|
|
72
71
|
str(']'),
|
|
73
72
|
true,
|
|
74
|
-
([, cs =
|
|
75
|
-
|
|
76
|
-
([, cs =
|
|
73
|
+
([, cs = new List(), ds]) =>
|
|
74
|
+
cs.import(ds),
|
|
75
|
+
([, cs = new List()]) => {
|
|
77
76
|
setBacktrack(context, [2 | Backtrack.link], head);
|
|
78
|
-
return
|
|
77
|
+
return cs;
|
|
79
78
|
})
|
|
80
79
|
({ context });
|
|
81
80
|
if (state & State.annotation && next) {
|
|
82
|
-
return
|
|
81
|
+
return (as as List<Data<string | HTMLElement>>).import(bs).import(eval(result!)).import(eval(next));
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
84
|
context.position = position;
|
|
86
85
|
}
|
|
87
86
|
return state & State.annotation
|
|
88
|
-
?
|
|
87
|
+
? as.import(bs as List<Data<string>>)
|
|
89
88
|
: undefined;
|
|
90
89
|
},
|
|
91
90
|
[1 | Backtrack.bracket, 3 | Backtrack.doublebracket])));
|
|
@@ -98,22 +97,22 @@ const abbr: ReferenceParser.AbbrParser = surround(
|
|
|
98
97
|
true,
|
|
99
98
|
([, ns], context) => {
|
|
100
99
|
const { source, position, range = 0 } = context;
|
|
101
|
-
if (!ns) return [
|
|
100
|
+
if (!ns) return new List([new Data(''), new Data(source.slice(position - range, source[position - 1] === '|' ? position - 1 : position))]);
|
|
102
101
|
context.position += source[position] === ' ' ? 1 : 0;
|
|
103
|
-
return [
|
|
102
|
+
return new List([new Data(Command.Separator), new Data(ns.head!.value.trimEnd())]);
|
|
104
103
|
},
|
|
105
104
|
(_, context) => {
|
|
106
105
|
context.position -= context.range!;
|
|
107
|
-
return [
|
|
106
|
+
return new List([new Data('')]);
|
|
108
107
|
});
|
|
109
108
|
|
|
110
|
-
function attributes(ns:
|
|
111
|
-
switch (ns
|
|
109
|
+
function attributes(ns: List<Data<string | HTMLElement>>): Record<string, string | undefined> {
|
|
110
|
+
switch (ns.head!.value) {
|
|
112
111
|
case '':
|
|
113
112
|
return { class: 'invalid', ...invalid('reference', 'syntax', 'Invalid abbreviation') };
|
|
114
113
|
case Command.Separator:
|
|
115
|
-
const abbr = ns
|
|
116
|
-
ns
|
|
114
|
+
const abbr = ns.head!.next!.value as string;
|
|
115
|
+
ns.head!.value = ns.head!.next!.value = '';
|
|
117
116
|
return { class: 'reference', 'data-abbr': abbr };
|
|
118
117
|
default:
|
|
119
118
|
return { class: 'reference' };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { RemarkParser } from '../inline';
|
|
2
2
|
import { Recursion } from '../context';
|
|
3
|
+
import { List, Data } from '../../combinator/data/parser';
|
|
3
4
|
import { union, some, recursion, precedence, focus, surround, close, fallback, lazy } from '../../combinator';
|
|
4
5
|
import { inline } from '../inline';
|
|
5
6
|
import { text, str } from '../source';
|
|
6
|
-
import { invalid } from '../util';
|
|
7
|
-
import { unshift, push } from 'spica/array';
|
|
7
|
+
import { unwrap, invalid } from '../util';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const remark: RemarkParser = lazy(() => fallback(surround(
|
|
@@ -12,13 +12,13 @@ export const remark: RemarkParser = lazy(() => fallback(surround(
|
|
|
12
12
|
precedence(3, recursion(Recursion.inline,
|
|
13
13
|
some(union([inline]), /\s%\]/y, [[/\s%\]/y, 3]]))),
|
|
14
14
|
close(text, str(`%]`)), true,
|
|
15
|
-
([as, bs =
|
|
16
|
-
html('span', { class: 'remark' }, [
|
|
15
|
+
([as, bs = new List(), cs]) => new List([
|
|
16
|
+
new Data(html('span', { class: 'remark' }, [
|
|
17
17
|
html('input', { type: 'checkbox' }),
|
|
18
|
-
html('span', defrag(
|
|
19
|
-
]),
|
|
20
|
-
]
|
|
21
|
-
([as, bs]) => bs &&
|
|
22
|
-
focus(/\[%+(?=\s)/y, ({ context: { source } }) => [
|
|
23
|
-
html('span', { class: 'invalid', ...invalid('remark', 'syntax', 'Invalid start symbol') }, source)
|
|
24
|
-
]
|
|
18
|
+
html('span', defrag(unwrap(as.import(bs as List<Data<string>>).import(cs)))),
|
|
19
|
+
])),
|
|
20
|
+
]),
|
|
21
|
+
([as, bs]) => bs && as.import(bs as List<Data<string>>)),
|
|
22
|
+
focus(/\[%+(?=\s)/y, ({ context: { source } }) => new List([
|
|
23
|
+
new Data(html('span', { class: 'invalid', ...invalid('remark', 'syntax', 'Invalid start symbol') }, source))
|
|
24
|
+
]))));
|