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,13 @@
|
|
|
1
1
|
import { EmStrongParser, EmphasisParser, StrongParser } from '../inline';
|
|
2
2
|
import { Recursion, Command } from '../context';
|
|
3
|
-
import { Result, Node, Context, IntermediateParser } from '../../combinator/data/parser';
|
|
3
|
+
import { Result, List, Data, Node, Context, IntermediateParser, eval } from '../../combinator/data/parser';
|
|
4
4
|
import { union, some, recursion, 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
9
|
import { tightStart, blankWith } from '../visibility';
|
|
10
|
-
import { repeat } from '../util';
|
|
11
|
-
import { unshift, push } from 'spica/array';
|
|
10
|
+
import { unwrap, repeat } from '../util';
|
|
12
11
|
import { html, defrag } from 'typed-dom/dom';
|
|
13
12
|
|
|
14
13
|
const substrong: IntermediateParser<StrongParser> = lazy(() => some(union([
|
|
@@ -36,10 +35,10 @@ export const emstrong: EmStrongParser = lazy(() => validate('***',
|
|
|
36
35
|
str(/\*{1,3}/y), false,
|
|
37
36
|
([, bs, cs], context): Result<Node<EmStrongParser>, Context<EmStrongParser>> => {
|
|
38
37
|
assert(cs.length === 1);
|
|
39
|
-
const { buffer } = context;
|
|
40
|
-
switch (cs
|
|
38
|
+
const { buffer = new List() } = context;
|
|
39
|
+
switch (cs.head!.value) {
|
|
41
40
|
case '***':
|
|
42
|
-
return
|
|
41
|
+
return bs;
|
|
43
42
|
case '**':
|
|
44
43
|
return bind<EmphasisParser>(
|
|
45
44
|
subemphasis,
|
|
@@ -47,13 +46,18 @@ export const emstrong: EmStrongParser = lazy(() => validate('***',
|
|
|
47
46
|
const { source } = context;
|
|
48
47
|
if (source.startsWith('*', context.position)) {
|
|
49
48
|
context.position += 1;
|
|
50
|
-
|
|
49
|
+
buffer.push(new Data(html('strong', defrag(unwrap(bs)))));
|
|
50
|
+
buffer.import(ds);
|
|
51
|
+
return new List([new Data(html('em', defrag(unwrap(buffer)))), new Data(Command.Separator)]);
|
|
51
52
|
}
|
|
52
53
|
else {
|
|
53
|
-
|
|
54
|
+
buffer.push(new Data(html('strong', defrag(unwrap(bs)))));
|
|
55
|
+
buffer.import(ds);
|
|
56
|
+
buffer.push(new Data(Command.Separator));
|
|
57
|
+
return prepend('*', buffer);
|
|
54
58
|
}
|
|
55
59
|
})
|
|
56
|
-
({ context }) ??
|
|
60
|
+
({ context }) ?? prepend('*', buffer.import(new List([new Data(html('strong', defrag(unwrap(bs)))), new Data(Command.Separator)])));
|
|
57
61
|
case '*':
|
|
58
62
|
return bind<StrongParser>(
|
|
59
63
|
substrong,
|
|
@@ -61,19 +65,24 @@ export const emstrong: EmStrongParser = lazy(() => validate('***',
|
|
|
61
65
|
const { source } = context;
|
|
62
66
|
if (source.startsWith('**', context.position)) {
|
|
63
67
|
context.position += 2;
|
|
64
|
-
|
|
68
|
+
buffer.push(new Data(html('em', defrag(unwrap(bs)))));
|
|
69
|
+
buffer.import(ds);
|
|
70
|
+
return new List([new Data(html('strong', defrag(unwrap(buffer)))), new Data(Command.Separator)]);
|
|
65
71
|
}
|
|
66
72
|
else {
|
|
67
|
-
|
|
73
|
+
buffer.push(new Data(html('em', defrag(unwrap(bs)))));
|
|
74
|
+
buffer.import(ds);
|
|
75
|
+
buffer.push(new Data(Command.Separator));
|
|
76
|
+
return prepend('**', buffer);
|
|
68
77
|
}
|
|
69
78
|
})
|
|
70
|
-
({ context }) ??
|
|
79
|
+
({ context }) ?? prepend('**', buffer.import(new List([new Data(html('em', defrag(unwrap(bs)))), new Data(Command.Separator)])));
|
|
71
80
|
}
|
|
72
81
|
assert(false);
|
|
73
82
|
},
|
|
74
|
-
([, bs], { buffer }) => bs &&
|
|
83
|
+
([, bs], { buffer }) => bs && buffer!.import(bs) && buffer!.push(new Data(Command.Cancel)) && buffer!),
|
|
75
84
|
// 3以上の`*`に対してemの適用を保証する
|
|
76
|
-
nodes => [html('em', [html('strong', defrag(nodes))])],
|
|
85
|
+
nodes => new List([new Data(html('em', [html('strong', defrag(unwrap(nodes)))]))]),
|
|
77
86
|
(nodes, context, prefix, postfix, state) => {
|
|
78
87
|
context.position += postfix;
|
|
79
88
|
assert(postfix < 3);
|
|
@@ -82,10 +91,10 @@ export const emstrong: EmStrongParser = lazy(() => validate('***',
|
|
|
82
91
|
case 0:
|
|
83
92
|
break;
|
|
84
93
|
case 1:
|
|
85
|
-
nodes = [html('em', defrag(nodes))];
|
|
94
|
+
nodes = new List([new Data(html('em', defrag(unwrap(nodes))))]);
|
|
86
95
|
break;
|
|
87
96
|
case 2:
|
|
88
|
-
nodes = [html('strong', defrag(nodes))];
|
|
97
|
+
nodes = new List([new Data(html('strong', defrag(unwrap(nodes))))]);
|
|
89
98
|
break;
|
|
90
99
|
default:
|
|
91
100
|
assert(false);
|
|
@@ -96,51 +105,51 @@ export const emstrong: EmStrongParser = lazy(() => validate('***',
|
|
|
96
105
|
case 0:
|
|
97
106
|
break;
|
|
98
107
|
case 1:
|
|
99
|
-
nodes = bind<EmphasisParser>(
|
|
108
|
+
nodes = eval(bind<EmphasisParser>(
|
|
100
109
|
subemphasis,
|
|
101
110
|
ds => {
|
|
102
111
|
const { source } = context;
|
|
103
112
|
if (source.startsWith('*', context.position)) {
|
|
104
113
|
context.position += 1;
|
|
105
|
-
return [
|
|
114
|
+
return new List([new Data(html('em', defrag(unwrap(nodes.import(ds)))))]);
|
|
106
115
|
}
|
|
107
116
|
else {
|
|
108
|
-
return
|
|
117
|
+
return prepend('*', nodes.import(ds));
|
|
109
118
|
}
|
|
110
119
|
})
|
|
111
|
-
({ context })
|
|
120
|
+
({ context })) ?? prepend('*', nodes);
|
|
112
121
|
prefix -= 1;
|
|
113
122
|
break;
|
|
114
123
|
case 2:
|
|
115
|
-
nodes = bind<StrongParser>(
|
|
124
|
+
nodes = eval(bind<StrongParser>(
|
|
116
125
|
substrong,
|
|
117
126
|
ds => {
|
|
118
127
|
const { source } = context;
|
|
119
128
|
if (source.startsWith('**', context.position)) {
|
|
120
129
|
context.position += 2;
|
|
121
|
-
return [
|
|
130
|
+
return new List([new Data(html('strong', defrag(unwrap(nodes.import(ds)))))]);
|
|
122
131
|
}
|
|
123
132
|
else {
|
|
124
|
-
return
|
|
133
|
+
return prepend('**', nodes.import(ds));
|
|
125
134
|
}
|
|
126
135
|
})
|
|
127
|
-
({ context })
|
|
136
|
+
({ context })) ?? prepend('**', nodes);
|
|
128
137
|
prefix -= 2;
|
|
129
138
|
break;
|
|
130
139
|
}
|
|
131
140
|
}
|
|
132
141
|
if (prefix > postfix) {
|
|
133
|
-
nodes =
|
|
142
|
+
nodes = prepend('*'.repeat(prefix - postfix), nodes);
|
|
134
143
|
}
|
|
135
|
-
return
|
|
144
|
+
return nodes;
|
|
136
145
|
}))));
|
|
137
146
|
|
|
138
|
-
function prepend<N>(prefix: string, nodes: N
|
|
139
|
-
if (typeof nodes
|
|
140
|
-
nodes
|
|
147
|
+
function prepend<N>(prefix: string, nodes: List<Data<N>>): List<Data<N>> {
|
|
148
|
+
if (typeof nodes.head?.value === 'string') {
|
|
149
|
+
nodes.head.value = prefix + nodes.head.value as N;
|
|
141
150
|
}
|
|
142
151
|
else {
|
|
143
|
-
unshift(
|
|
152
|
+
nodes.unshift(new Data(prefix as N));
|
|
144
153
|
}
|
|
145
154
|
return nodes;
|
|
146
155
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
2
|
import { State, Backtrack } from '../../context';
|
|
3
|
+
import { List, Data } from '../../../combinator/data/parser';
|
|
3
4
|
import { union, inits, some, precedence, state, constraint, validate, surround, lazy, fmap } from '../../../combinator';
|
|
4
5
|
import { inline } from '../../inline';
|
|
5
6
|
import { indexee, identity } from './indexee';
|
|
6
7
|
import { unsafehtmlentity } from '../htmlentity';
|
|
7
8
|
import { txt, str } from '../../source';
|
|
8
9
|
import { tightStart, trimBlankNodeEnd } from '../../visibility';
|
|
9
|
-
import {
|
|
10
|
+
import { unwrap } from '../../util';
|
|
10
11
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
11
12
|
|
|
12
13
|
import IndexParser = ExtensionParser.IndexParser;
|
|
@@ -23,23 +24,23 @@ export const index: IndexParser = lazy(() => constraint(State.index, fmap(indexe
|
|
|
23
24
|
false,
|
|
24
25
|
([, bs], context) =>
|
|
25
26
|
context.linebreak === 0 && trimBlankNodeEnd(bs).length > 0
|
|
26
|
-
? [
|
|
27
|
+
? new List([new Data(html('a', { 'data-index': dataindex(bs) }, defrag(unwrap(bs))))])
|
|
27
28
|
: undefined,
|
|
28
29
|
undefined,
|
|
29
30
|
[3 | Backtrack.bracket])),
|
|
30
31
|
ns => {
|
|
31
32
|
if (ns.length === 1) {
|
|
32
|
-
const el = ns
|
|
33
|
-
return [
|
|
34
|
-
define(el, {
|
|
33
|
+
const el = ns.head!.value as HTMLElement;
|
|
34
|
+
return new List([
|
|
35
|
+
new Data(define(el, {
|
|
35
36
|
id: el.id ? null : undefined,
|
|
36
37
|
class: 'index',
|
|
37
38
|
href: el.id ? `#${el.id}` : undefined,
|
|
38
|
-
})
|
|
39
|
-
];
|
|
39
|
+
}))
|
|
40
|
+
]);
|
|
40
41
|
}
|
|
41
42
|
else {
|
|
42
|
-
assert(ns.
|
|
43
|
+
assert(ns.last?.value === '');
|
|
43
44
|
ns.pop();
|
|
44
45
|
return ns;
|
|
45
46
|
}
|
|
@@ -54,21 +55,23 @@ export const signature: IndexParser.SignatureParser = lazy(() => validate('|', s
|
|
|
54
55
|
/(?=])/y,
|
|
55
56
|
false,
|
|
56
57
|
([, ns], context) => {
|
|
57
|
-
const index = identity('index', undefined, ns.
|
|
58
|
+
const index = identity('index', undefined, ns.foldl((acc, { value }) => acc + value, ''))?.slice(7);
|
|
58
59
|
return index && context.linebreak === 0
|
|
59
|
-
? [
|
|
60
|
+
? new List([new Data(html('span', { class: 'indexer', 'data-index': index }))])
|
|
60
61
|
: undefined;
|
|
61
62
|
},
|
|
62
|
-
([as, bs]) => bs &&
|
|
63
|
+
([as, bs]) => bs && as.import(bs),
|
|
63
64
|
[3 | Backtrack.bracket])));
|
|
64
65
|
|
|
65
|
-
export function dataindex(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
export function dataindex(nodes: List<Data<string | HTMLElement>>): string | undefined {
|
|
67
|
+
let node = nodes.last;
|
|
68
|
+
if (typeof node?.value !== 'object') return;
|
|
69
|
+
switch (node.value.tagName) {
|
|
70
|
+
case 'UL':
|
|
71
|
+
case 'OL':
|
|
72
|
+
node = node.prev;
|
|
73
|
+
if (typeof node?.value !== 'object') return;
|
|
73
74
|
}
|
|
75
|
+
if (!node.value.classList.contains('indexer')) return;
|
|
76
|
+
return node.value.getAttribute('data-index') ?? undefined;
|
|
74
77
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../../../markdown';
|
|
2
|
-
import { Parser } from '../../../combinator/data/parser';
|
|
2
|
+
import { Parser, List, Data } from '../../../combinator/data/parser';
|
|
3
3
|
import { fmap } from '../../../combinator';
|
|
4
4
|
import { define } from 'typed-dom/dom';
|
|
5
5
|
|
|
@@ -7,7 +7,7 @@ export function indexee<P extends Parser<unknown, MarkdownParser.Context>>(parse
|
|
|
7
7
|
export function indexee(parser: Parser<HTMLElement, MarkdownParser.Context>): Parser<HTMLElement> {
|
|
8
8
|
return fmap(parser, (ns, { id }) =>
|
|
9
9
|
ns.length === 1
|
|
10
|
-
? [define(ns
|
|
10
|
+
? new List([new Data(define(ns.head!.value, { id: identity('index', id, ns.head!.value), 'data-index': null }))])
|
|
11
11
|
: ns);
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
|
+
import { List, Data } from '../../../combinator/data/parser';
|
|
2
3
|
import { union, focus, surround } from '../../../combinator';
|
|
3
4
|
import { signature } from './index';
|
|
4
5
|
import { html } from 'typed-dom/dom';
|
|
@@ -13,6 +14,6 @@ export const indexer: ExtensionParser.IndexerParser = surround(
|
|
|
13
14
|
/\s\[(?=\|\S)/y,
|
|
14
15
|
union([
|
|
15
16
|
signature,
|
|
16
|
-
focus(/\|(?=\])/y, () => [
|
|
17
|
+
focus(/\|(?=\])/y, () => new List([new Data(html('span', { class: 'indexer', 'data-index': '' }))])),
|
|
17
18
|
]),
|
|
18
19
|
/\]\s*$/y);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
2
|
import { State, Backtrack } from '../../context';
|
|
3
|
+
import { List, Data } from '../../../combinator/data/parser';
|
|
3
4
|
import { union, constraint, clear, surround, fmap } from '../../../combinator';
|
|
4
5
|
import { str } from '../../source';
|
|
5
6
|
import { html } from 'typed-dom/dom';
|
|
@@ -16,9 +17,12 @@ export const label: ExtensionParser.LabelParser = constraint(State.label, fmap(
|
|
|
16
17
|
surround('[', body, ']', false, undefined, undefined, [1 | Backtrack.bracket, 1]),
|
|
17
18
|
body,
|
|
18
19
|
]),
|
|
19
|
-
([
|
|
20
|
-
html('a', {
|
|
21
|
-
|
|
20
|
+
([{ value }]) => new List([
|
|
21
|
+
new Data(html('a', {
|
|
22
|
+
class: 'label',
|
|
23
|
+
'data-label': value.slice(value[1] === '-' ? 0 : 1).toLowerCase(),
|
|
24
|
+
}, value)),
|
|
25
|
+
])));
|
|
22
26
|
|
|
23
27
|
export function number(label: string, base: string): string {
|
|
24
28
|
return isFixed(label)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../inline';
|
|
2
2
|
import { Recursion, Backtrack } from '../../context';
|
|
3
|
+
import { List, Data } from '../../../combinator/data/parser';
|
|
3
4
|
import { union, some, recursion, precedence, surround, lazy } from '../../../combinator';
|
|
4
5
|
import { inline } from '../../inline';
|
|
5
6
|
import { str } from '../../source';
|
|
6
7
|
import { tightStart } from '../../visibility';
|
|
7
8
|
import { invalid } from '../../util';
|
|
8
|
-
import { unshift } from 'spica/array';
|
|
9
9
|
import { html } from 'typed-dom/dom';
|
|
10
10
|
|
|
11
11
|
// Don't use the symbols already used: !#$%@&*+~=|
|
|
@@ -18,13 +18,13 @@ export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => surroun
|
|
|
18
18
|
precedence(1, recursion(Recursion.inline,
|
|
19
19
|
tightStart(some(union([inline]), ']', [[']', 1]])))),
|
|
20
20
|
str(']'), false,
|
|
21
|
-
(_, context) => [
|
|
22
|
-
html('span',
|
|
21
|
+
(_, context) => new List([
|
|
22
|
+
new Data(html('span',
|
|
23
23
|
{
|
|
24
24
|
class: 'invalid',
|
|
25
25
|
...invalid('extension', 'syntax', `Invalid start symbol or linebreak`),
|
|
26
26
|
},
|
|
27
|
-
context.source.slice(context.position - context.range!, context.position))
|
|
28
|
-
]
|
|
29
|
-
([as, bs]) => bs &&
|
|
27
|
+
context.source.slice(context.position - context.range!, context.position)))
|
|
28
|
+
]),
|
|
29
|
+
([as, bs]) => bs && as.import(bs as List<Data<string>>),
|
|
30
30
|
[3 | Backtrack.bracket]));
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { HTMLParser } from '../inline';
|
|
2
2
|
import { Recursion } from '../context';
|
|
3
|
-
import { Ctx } from '../../combinator/data/parser';
|
|
3
|
+
import { List, Data, Ctx } from '../../combinator/data/parser';
|
|
4
4
|
import { union, some, recursion, precedence, validate, surround, open, match, lazy } from '../../combinator';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { str } from '../source';
|
|
7
7
|
import { isLooseNodeStart, blankWith } from '../visibility';
|
|
8
|
-
import { invalid } from '../util';
|
|
8
|
+
import { invalid, unwrap } from '../util';
|
|
9
9
|
import { memoize } from 'spica/memoize';
|
|
10
|
-
import { unshift, push } from 'spica/array';
|
|
11
10
|
import { html as h, defrag } from 'typed-dom/dom';
|
|
12
11
|
|
|
13
12
|
const tags: readonly string[] = ['wbr', 'bdo', 'bdi'];
|
|
@@ -28,10 +27,10 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
28
27
|
some(union([attribute])),
|
|
29
28
|
open(str(/ ?/y), str('>'), true),
|
|
30
29
|
true,
|
|
31
|
-
([as, bs =
|
|
32
|
-
[
|
|
33
|
-
([as, bs =
|
|
34
|
-
[
|
|
30
|
+
([as, bs = new List(), cs], context) =>
|
|
31
|
+
new List([new Data(elem(as.head!.value.slice(1), false, [...unwrap(as.import(bs).import(cs))], new List(), new List(), context))]),
|
|
32
|
+
([as, bs = new List()], context) =>
|
|
33
|
+
new List([new Data(elem(as.head!.value.slice(1), false, [...unwrap(as.import(bs))], new List(), new List(), context))])),
|
|
35
34
|
match(
|
|
36
35
|
new RegExp(String.raw`<(${TAGS.join('|')})(?=[^\S\n]|>)`, 'y'),
|
|
37
36
|
memoize(
|
|
@@ -40,8 +39,8 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
40
39
|
surround(
|
|
41
40
|
str(`<${tag}`), some(attribute), open(str(/ ?/y), str('>'), true),
|
|
42
41
|
true,
|
|
43
|
-
([as, bs =
|
|
44
|
-
([as, bs =
|
|
42
|
+
([as, bs = new List(), cs]) => as.import(bs).import(cs),
|
|
43
|
+
([as, bs = new List()]) => as.import(bs)),
|
|
45
44
|
// 不可視のHTML構造が可視構造を変化させるべきでない。
|
|
46
45
|
// 可視のHTMLは優先度変更を検討する。
|
|
47
46
|
// このため<>は将来的に共通構造を変化させる可能性があり
|
|
@@ -53,10 +52,10 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
53
52
|
])))),
|
|
54
53
|
str(`</${tag}>`),
|
|
55
54
|
true,
|
|
56
|
-
([as, bs =
|
|
57
|
-
[
|
|
58
|
-
([as, bs =
|
|
59
|
-
[
|
|
55
|
+
([as, bs = new List(), cs], context) =>
|
|
56
|
+
new List([new Data(elem(tag, true, [...unwrap(as)], bs, cs, context))]),
|
|
57
|
+
([as, bs = new List()], context) =>
|
|
58
|
+
new List([new Data(elem(tag, true, [...unwrap(as)], bs, new List(), context))])),
|
|
60
59
|
([, tag]) => tag,
|
|
61
60
|
new Map())),
|
|
62
61
|
surround(
|
|
@@ -65,10 +64,10 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
65
64
|
some(union([attribute])),
|
|
66
65
|
open(str(/ ?/y), str('>'), true),
|
|
67
66
|
true,
|
|
68
|
-
([as, bs =
|
|
69
|
-
[
|
|
70
|
-
([as, bs =
|
|
71
|
-
[
|
|
67
|
+
([as, bs = new List(), cs], context) =>
|
|
68
|
+
new List([new Data(elem(as.head!.value.slice(1), false, [...unwrap(as.import(bs).import(cs))], new List(), new List(), context))]),
|
|
69
|
+
([as, bs = new List()], context) =>
|
|
70
|
+
new List([new Data(elem(as.head!.value.slice(1), false, [...unwrap(as.import(bs))], new List(), new List(), context))])),
|
|
72
71
|
])));
|
|
73
72
|
|
|
74
73
|
export const attribute: HTMLParser.AttributeParser = union([
|
|
@@ -76,7 +75,7 @@ export const attribute: HTMLParser.AttributeParser = union([
|
|
|
76
75
|
str(/ [^\s<>]+/y),
|
|
77
76
|
]);
|
|
78
77
|
|
|
79
|
-
function elem(tag: string, content: boolean, as: string[], bs:
|
|
78
|
+
function elem(tag: string, content: boolean, as: readonly string[], bs: List<Data<HTMLElement | string>>, cs: List<Data<string>>, context: Ctx): HTMLElement {
|
|
80
79
|
assert(as.length > 0);
|
|
81
80
|
assert(as[0][0] === '<');
|
|
82
81
|
if (!tags.includes(tag)) return ielem('tag', `Invalid HTML tag name "${tag}"`, context);
|
|
@@ -88,7 +87,7 @@ function elem(tag: string, content: boolean, as: string[], bs: (HTMLElement | st
|
|
|
88
87
|
const [attrs] = attributes('html', attrspecs[tag], as.slice(1, as.at(-1) === '>' ? -1 : as.length));
|
|
89
88
|
if (/(?<!\S)invalid(?!\S)/.test(attrs['class'] ?? '')) return ielem('attribute', 'Invalid HTML attribute', context)
|
|
90
89
|
if (as.at(-1) !== '>') return ielem('tag', `Missing the closing symbol ">"`, context);
|
|
91
|
-
return h(tag as 'span', attrs, defrag(bs));
|
|
90
|
+
return h(tag as 'span', attrs, defrag(unwrap(bs)));
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
function ielem(type: string, message: string, context: Ctx): HTMLElement {
|
|
@@ -105,7 +104,7 @@ const requiredAttributes = memoize(
|
|
|
105
104
|
export function attributes(
|
|
106
105
|
syntax: string,
|
|
107
106
|
spec: Readonly<Record<string, readonly (string | undefined)[] | undefined>> | undefined,
|
|
108
|
-
params:
|
|
107
|
+
params: Iterable<string>,
|
|
109
108
|
): [Record<string, string | undefined>, string[]] {
|
|
110
109
|
assert(spec instanceof Object === false);
|
|
111
110
|
assert(!spec?.['__proto__']);
|
|
@@ -113,17 +112,17 @@ export function attributes(
|
|
|
113
112
|
const remains = [];
|
|
114
113
|
let invalidation = false;
|
|
115
114
|
const attrs: Record<string, string | undefined> = {};
|
|
116
|
-
for (
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
119
|
-
const name =
|
|
120
|
-
const value =
|
|
121
|
-
?
|
|
115
|
+
for (const param of params) {
|
|
116
|
+
const attr = param.trimStart();
|
|
117
|
+
if (attr === '') continue;
|
|
118
|
+
const name = attr.split('=', 1)[0];
|
|
119
|
+
const value = attr !== name
|
|
120
|
+
? attr.slice(name.length + 2, -1).replace(/\\(.?)/g, '$1')
|
|
122
121
|
: undefined;
|
|
123
122
|
invalidation ||= name === '' || !spec || name in attrs;
|
|
124
|
-
if (name === '')continue;
|
|
123
|
+
if (name === '') continue;
|
|
125
124
|
if (spec && name in spec && !spec[name]) {
|
|
126
|
-
remains.push(
|
|
125
|
+
remains.push(param);
|
|
127
126
|
continue;
|
|
128
127
|
}
|
|
129
128
|
if (spec?.[name]?.includes(value) || spec?.[name]?.length === 0 && value !== undefined) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HTMLEntityParser, UnsafeHTMLEntityParser } from '../inline';
|
|
2
|
+
import { List, Data } from '../../combinator/data/parser';
|
|
2
3
|
import { union, focus, fmap } from '../../combinator';
|
|
3
4
|
import { invalid } from '../util';
|
|
4
5
|
import { html } from 'typed-dom/dom';
|
|
@@ -10,20 +11,20 @@ export const unsafehtmlentity: UnsafeHTMLEntityParser = focus(
|
|
|
10
11
|
const { source } = context;
|
|
11
12
|
context.position += source.length;
|
|
12
13
|
return source.length > 1 && source.at(-1) === ';'
|
|
13
|
-
? [
|
|
14
|
-
: [
|
|
14
|
+
? new List([new Data(parser(source) ?? source)])
|
|
15
|
+
: new List([new Data(source)]);
|
|
15
16
|
});
|
|
16
17
|
|
|
17
18
|
export const htmlentity: HTMLEntityParser = fmap(
|
|
18
19
|
union([unsafehtmlentity]),
|
|
19
|
-
([
|
|
20
|
-
length === 1 ||
|
|
21
|
-
?
|
|
22
|
-
: html('span', {
|
|
20
|
+
([{ value }]) => new List([
|
|
21
|
+
length === 1 || value.at(-1) !== ';'
|
|
22
|
+
? new Data(value)
|
|
23
|
+
: new Data(html('span', {
|
|
23
24
|
class: 'invalid',
|
|
24
25
|
...invalid('htmlentity', 'syntax', 'Invalid HTML entity'),
|
|
25
|
-
},
|
|
26
|
-
]);
|
|
26
|
+
}, value))
|
|
27
|
+
]));
|
|
27
28
|
|
|
28
29
|
const parser = (el => (entity: string): string | undefined => {
|
|
29
30
|
if (entity === '
') return ' ';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { InsertionParser } from '../inline';
|
|
2
2
|
import { Recursion, Command } from '../context';
|
|
3
|
+
import { List, Data } from '../../combinator/data/parser';
|
|
3
4
|
import { union, some, recursion, precedence, validate, surround, open, lazy } from '../../combinator';
|
|
4
5
|
import { inline } from '../inline';
|
|
5
6
|
import { blankWith } from '../visibility';
|
|
6
|
-
import { repeat } from '../util';
|
|
7
|
-
import { push } from 'spica/array';
|
|
7
|
+
import { unwrap, repeat } from '../util';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const insertion: InsertionParser = lazy(() => validate('++',
|
|
@@ -16,6 +16,6 @@ export const insertion: InsertionParser = lazy(() => validate('++',
|
|
|
16
16
|
open('\n', some(inline, '+'), true),
|
|
17
17
|
]))),
|
|
18
18
|
'++', false,
|
|
19
|
-
([, bs], { buffer }) =>
|
|
20
|
-
([, bs], { buffer }) => bs &&
|
|
21
|
-
nodes => [html('ins', defrag(nodes))]))));
|
|
19
|
+
([, bs], { buffer }) => buffer!.import(bs),
|
|
20
|
+
([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
|
|
21
|
+
nodes => new List([new Data(html('ins', defrag(unwrap(nodes))))])))));
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ItalicParser } from '../inline';
|
|
2
2
|
import { Recursion, Command } from '../context';
|
|
3
|
+
import { List, Data } from '../../combinator/data/parser';
|
|
3
4
|
import { union, some, recursion, precedence, validate, surround, open, lazy } from '../../combinator';
|
|
4
5
|
import { inline } from '../inline';
|
|
5
6
|
import { tightStart, blankWith } from '../visibility';
|
|
6
|
-
import { repeat } from '../util';
|
|
7
|
-
import { push } from 'spica/array';
|
|
7
|
+
import { unwrap, repeat } from '../util';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
// 可読性のため実際にはオブリーク体を指定する。
|
|
@@ -19,6 +19,6 @@ export const italic: ItalicParser = lazy(() => validate('///',
|
|
|
19
19
|
open(some(inline, '/'), inline),
|
|
20
20
|
])))),
|
|
21
21
|
'///', false,
|
|
22
|
-
([, bs], { buffer }) =>
|
|
23
|
-
([, bs], { buffer }) => bs &&
|
|
24
|
-
nodes => [html('i', defrag(nodes))]))));
|
|
22
|
+
([, bs], { buffer }) => buffer!.import(bs),
|
|
23
|
+
([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
|
|
24
|
+
nodes => new List([new Data(html('i', defrag(unwrap(nodes))))])))));
|