securemark 0.288.0 → 0.288.2
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 +7261 -7317
- package/markdown.d.ts +1 -7
- package/package.json +1 -1
- package/src/combinator/control/manipulation/surround.ts +5 -0
- package/src/combinator/data/parser/context/delimiter.ts +2 -2
- package/src/combinator/data/parser.ts +1 -0
- package/src/parser/api/parse.test.ts +2 -2
- package/src/parser/block/codeblock.ts +9 -6
- package/src/parser/block/extension/aside.ts +7 -8
- package/src/parser/block/extension/example.ts +7 -8
- package/src/parser/block/extension/figure.ts +77 -74
- package/src/parser/block/extension/message.ts +7 -8
- package/src/parser/block/extension/placeholder.ts +6 -3
- package/src/parser/block/extension/table.ts +13 -24
- package/src/parser/block/heading.test.ts +1 -1
- package/src/parser/block/heading.ts +2 -3
- package/src/parser/block/ilist.ts +17 -7
- package/src/parser/block/mathblock.ts +8 -6
- package/src/parser/block/mediablock.ts +5 -8
- package/src/parser/block/olist.ts +5 -7
- package/src/parser/block/reply/cite.ts +2 -6
- package/src/parser/block/reply/quote.ts +3 -2
- package/src/parser/block/reply.ts +1 -1
- package/src/parser/block/sidefence.ts +2 -3
- package/src/parser/block/table.ts +2 -3
- package/src/parser/block/ulist.ts +3 -17
- package/src/parser/context.ts +1 -2
- package/src/parser/header.ts +2 -3
- package/src/parser/inline/annotation.test.ts +1 -0
- package/src/parser/inline/bracket.ts +18 -24
- package/src/parser/inline/extension/index.test.ts +1 -1
- package/src/parser/inline/extension/index.ts +17 -7
- package/src/parser/inline/extension/indexee.ts +2 -3
- package/src/parser/inline/extension/indexer.test.ts +2 -1
- package/src/parser/inline/extension/placeholder.ts +2 -3
- package/src/parser/inline/html.ts +21 -23
- package/src/parser/inline/htmlentity.ts +6 -8
- package/src/parser/inline/link.test.ts +4 -0
- package/src/parser/inline/link.ts +3 -5
- package/src/parser/inline/math.ts +3 -3
- package/src/parser/inline/media.test.ts +17 -13
- package/src/parser/inline/media.ts +15 -9
- package/src/parser/inline/reference.ts +3 -7
- package/src/parser/inline/ruby.ts +4 -5
- package/src/parser/inline.test.ts +5 -3
- package/src/parser/source/escapable.test.ts +5 -5
- package/src/parser/source/escapable.ts +7 -1
- package/src/parser/source/str.ts +4 -6
- package/src/parser/source/text.ts +1 -0
- package/src/parser/source/unescapable.test.ts +5 -5
- package/src/parser/source/unescapable.ts +13 -8
- package/src/parser/util.ts +12 -0
- package/src/parser/visibility.ts +2 -3
package/markdown.d.ts
CHANGED
|
@@ -1112,12 +1112,6 @@ export namespace MarkdownParser {
|
|
|
1112
1112
|
// ""
|
|
1113
1113
|
Inline<'bracket'>,
|
|
1114
1114
|
Parser<HTMLElement | string, Context, [
|
|
1115
|
-
SourceParser.StrParser,
|
|
1116
|
-
InlineParser,
|
|
1117
|
-
SourceParser.StrParser,
|
|
1118
|
-
InlineParser,
|
|
1119
|
-
InlineParser,
|
|
1120
|
-
InlineParser,
|
|
1121
1115
|
InlineParser,
|
|
1122
1116
|
InlineParser,
|
|
1123
1117
|
InlineParser,
|
|
@@ -1251,7 +1245,7 @@ export namespace MarkdownParser {
|
|
|
1251
1245
|
export interface TextParser extends
|
|
1252
1246
|
// abc
|
|
1253
1247
|
Source<'text'>,
|
|
1254
|
-
Parser<string | HTMLBRElement
|
|
1248
|
+
Parser<string | HTMLBRElement, Context, []> {
|
|
1255
1249
|
}
|
|
1256
1250
|
export interface TxtParser extends
|
|
1257
1251
|
// abc
|
package/package.json
CHANGED
|
@@ -94,6 +94,11 @@ export function surround<T>(
|
|
|
94
94
|
backtracks[source.length + offset - 1] |= 1 << (backtrack >>> 2) + shift;
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
+
context.recent = [
|
|
98
|
+
lmr_.slice(0, lmr_.length - mr_.length),
|
|
99
|
+
mr_.slice(0, mr_.length - r_.length),
|
|
100
|
+
r_.slice(0, r_.length - rest.length),
|
|
101
|
+
];
|
|
97
102
|
return rr
|
|
98
103
|
? f
|
|
99
104
|
? f([rl, rm!, rr], rest, context)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { memoize
|
|
1
|
+
import { memoize } from 'spica/memoize';
|
|
2
2
|
|
|
3
3
|
interface Delimiter {
|
|
4
4
|
readonly index: number;
|
|
@@ -27,7 +27,7 @@ export class Delimiters {
|
|
|
27
27
|
case 'string':
|
|
28
28
|
return source => source.slice(0, pattern.length) === pattern || undefined;
|
|
29
29
|
case 'object':
|
|
30
|
-
return
|
|
30
|
+
return source => pattern.test(source) || undefined;
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
this.signature);
|
|
@@ -21,6 +21,7 @@ export interface Ctx {
|
|
|
21
21
|
state?: number;
|
|
22
22
|
backtracks?: Record<number, number>;
|
|
23
23
|
backtrack?: number;
|
|
24
|
+
recent?: string[];
|
|
24
25
|
}
|
|
25
26
|
export type Tree<P extends Parser<unknown>> = P extends Parser<infer T> ? T : never;
|
|
26
27
|
export type SubParsers<P extends Parser<unknown>> = P extends Parser<unknown, Ctx, infer D> ? D : never;
|
|
@@ -350,7 +350,7 @@ describe('Unit: parser/api/parse', () => {
|
|
|
350
350
|
|
|
351
351
|
it('backtrack', function () {
|
|
352
352
|
this.timeout(5000);
|
|
353
|
-
const str = `${'.'.repeat(
|
|
353
|
+
const str = `${'.'.repeat(7 + 0)}((${'['.repeat(13)}{{http://[[[${'.'.repeat(8328)}`;
|
|
354
354
|
assert.deepStrictEqual(
|
|
355
355
|
[...parse(str).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
356
356
|
[`<p>${str}</p>`]);
|
|
@@ -358,7 +358,7 @@ describe('Unit: parser/api/parse', () => {
|
|
|
358
358
|
|
|
359
359
|
it('backtrack error', function () {
|
|
360
360
|
this.timeout(5000);
|
|
361
|
-
const str = `${'.'.repeat(
|
|
361
|
+
const str = `${'.'.repeat(7 + 1)}((${'['.repeat(13)}{{http://[[[${'.'.repeat(8328)}`;
|
|
362
362
|
assert.deepStrictEqual(
|
|
363
363
|
[...parse(str).children].map(el => el.outerHTML.replace(/:\w+/, ':rnd')),
|
|
364
364
|
[
|
|
@@ -2,6 +2,7 @@ import { CodeBlockParser } from '../block';
|
|
|
2
2
|
import { eval } from '../../combinator/data/parser';
|
|
3
3
|
import { block, validate, fence, clear, fmap } from '../../combinator';
|
|
4
4
|
import { autolink } from '../autolink';
|
|
5
|
+
import { invalid } from '../util';
|
|
5
6
|
import { html, defrag } from 'typed-dom/dom';
|
|
6
7
|
|
|
7
8
|
const opener = /^(`{3,})(?!`)([^\n]*)(?:$|\n)/;
|
|
@@ -51,12 +52,14 @@ export const codeblock: CodeBlockParser = block(validate('```', fmap(
|
|
|
51
52
|
if (!closer || overflow || params.invalid) return [html('pre', {
|
|
52
53
|
class: 'invalid',
|
|
53
54
|
translate: 'no',
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
!closer
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
...invalid(
|
|
56
|
+
'codeblock',
|
|
57
|
+
!closer || overflow ? 'fence' : 'argument',
|
|
58
|
+
!closer
|
|
59
|
+
? `Missing the closing delimiter "${delim}"`
|
|
60
|
+
: overflow
|
|
61
|
+
? `Invalid trailing line after the closing delimiter "${delim}"`
|
|
62
|
+
: params.invalid!),
|
|
60
63
|
}, `${opener}${body}${overflow || closer}`)];
|
|
61
64
|
const el = html('pre',
|
|
62
65
|
{
|
|
@@ -2,6 +2,7 @@ import { ExtensionParser } from '../../block';
|
|
|
2
2
|
import { Recursion } from '../../context';
|
|
3
3
|
import { recursion, block, validate, fence, fmap } from '../../../combinator';
|
|
4
4
|
import { identity } from '../../inline/extension/indexee';
|
|
5
|
+
import { invalid } from '../../util';
|
|
5
6
|
import { parse } from '../../api/parse';
|
|
6
7
|
import { html } from 'typed-dom/dom';
|
|
7
8
|
|
|
@@ -12,12 +13,12 @@ export const aside: ExtensionParser.AsideParser = recursion(Recursion.block, blo
|
|
|
12
13
|
if (!closer || overflow || param.trimStart()) return [html('pre', {
|
|
13
14
|
class: 'invalid',
|
|
14
15
|
translate: 'no',
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
...invalid(
|
|
17
|
+
'aside',
|
|
18
|
+
!closer || overflow ? 'fence' : 'argument',
|
|
18
19
|
!closer ? `Missing the closing delimiter "${delim}"` :
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
|
|
21
|
+
'Invalid argument'),
|
|
21
22
|
}, `${opener}${body}${overflow || closer}`)];
|
|
22
23
|
const references = html('ol', { class: 'references' });
|
|
23
24
|
const document = parse(body.slice(0, -1), {
|
|
@@ -31,9 +32,7 @@ export const aside: ExtensionParser.AsideParser = recursion(Recursion.block, blo
|
|
|
31
32
|
if (!heading) return [html('pre', {
|
|
32
33
|
class: 'invalid',
|
|
33
34
|
translate: 'no',
|
|
34
|
-
|
|
35
|
-
'data-invalid-type': 'content',
|
|
36
|
-
'data-invalid-message': 'Missing the title at the first line',
|
|
35
|
+
...invalid('aside', 'content', 'Missing the title at the first line'),
|
|
37
36
|
}, `${opener}${body}${closer}`)];
|
|
38
37
|
assert(identity('index', context.id, heading));
|
|
39
38
|
return [
|
|
@@ -3,6 +3,7 @@ import { Recursion } from '../../context';
|
|
|
3
3
|
import { eval } from '../../../combinator/data/parser';
|
|
4
4
|
import { recursion, block, validate, fence, fmap } from '../../../combinator';
|
|
5
5
|
import { mathblock } from '../mathblock';
|
|
6
|
+
import { invalid } from '../../util';
|
|
6
7
|
import { parse } from '../../api/parse';
|
|
7
8
|
import { html } from 'typed-dom/dom';
|
|
8
9
|
|
|
@@ -15,12 +16,12 @@ export const example: ExtensionParser.ExampleParser = recursion(Recursion.block,
|
|
|
15
16
|
if (!closer || overflow || param.trimStart()) return [html('pre', {
|
|
16
17
|
class: 'invalid',
|
|
17
18
|
translate: 'no',
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
...invalid(
|
|
20
|
+
'example',
|
|
21
|
+
!closer || overflow ? 'fence' : 'argument',
|
|
21
22
|
!closer ? `Missing the closing delimiter "${delim}"` :
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
|
|
24
|
+
'Invalid argument'),
|
|
24
25
|
}, `${opener}${body}${overflow || closer}`)];
|
|
25
26
|
switch (type) {
|
|
26
27
|
case 'markdown': {
|
|
@@ -53,9 +54,7 @@ export const example: ExtensionParser.ExampleParser = recursion(Recursion.block,
|
|
|
53
54
|
html('pre', {
|
|
54
55
|
class: 'invalid',
|
|
55
56
|
translate: 'no',
|
|
56
|
-
|
|
57
|
-
'data-invalid-type': 'type',
|
|
58
|
-
'data-invalid-message': 'Invalid example type',
|
|
57
|
+
...invalid('example', 'type', 'Invalid example type'),
|
|
59
58
|
}, `${opener}${body}${closer}`),
|
|
60
59
|
];
|
|
61
60
|
}
|
|
@@ -13,6 +13,7 @@ import { blockquote, segment as seg_blockquote } from '../blockquote';
|
|
|
13
13
|
import { placeholder, segment_ as seg_placeholder } from './placeholder';
|
|
14
14
|
import { inline, media, shortmedia } from '../../inline';
|
|
15
15
|
import { visualize, trimBlank } from '../../visibility';
|
|
16
|
+
import { invalid } from '../../util';
|
|
16
17
|
import { memoize } from 'spica/memoize';
|
|
17
18
|
import { html, defrag } from 'typed-dom/dom';
|
|
18
19
|
|
|
@@ -79,38 +80,40 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
|
|
|
79
80
|
])),
|
|
80
81
|
fmap(
|
|
81
82
|
fence(/^(~{3,})(?:figure|\[?\$\S*)(?!\S)[^\n]*(?:$|\n)/, 300),
|
|
82
|
-
([body, overflow, closer, opener, delim]: string[], _, context) =>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
'
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
'
|
|
94
|
-
'
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
'
|
|
98
|
-
'
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
'
|
|
102
|
-
'
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
83
|
+
([body, overflow, closer, opener, delim]: string[], _, context) => {
|
|
84
|
+
const violation =
|
|
85
|
+
!closer && [
|
|
86
|
+
'fence',
|
|
87
|
+
`Missing the closing delimiter "${delim}"`,
|
|
88
|
+
] ||
|
|
89
|
+
overflow && [
|
|
90
|
+
'fence',
|
|
91
|
+
`Invalid trailing line after the closing delimiter "${delim}"`,
|
|
92
|
+
] ||
|
|
93
|
+
!seg_label({ source: opener.match(/^~+(?:figure[^\S\n]+)?(\[?\$\S+)/)?.[1] ?? '', context }) && [
|
|
94
|
+
'label',
|
|
95
|
+
'Invalid label',
|
|
96
|
+
] ||
|
|
97
|
+
/^~+(?:figure[^\S\n]+)?(\[?\$\S+)[^\S\n]+\S/.test(opener) && [
|
|
98
|
+
'argument',
|
|
99
|
+
'Invalid argument',
|
|
100
|
+
] ||
|
|
101
|
+
[
|
|
102
|
+
'content',
|
|
103
|
+
'Invalid content',
|
|
104
|
+
];
|
|
105
|
+
return [
|
|
106
|
+
html('pre', {
|
|
107
|
+
class: 'invalid',
|
|
108
|
+
translate: 'no',
|
|
109
|
+
...invalid('figure', violation[0], violation[1]),
|
|
110
|
+
}, `${opener}${body}${overflow || closer}`),
|
|
111
|
+
];
|
|
112
|
+
})));
|
|
110
113
|
|
|
111
114
|
function attributes(label: string, param: string, content: HTMLElement, caption: readonly HTMLElement[]): Record<string, string | undefined> {
|
|
112
115
|
const group = label.split('-', 1)[0];
|
|
113
|
-
let type
|
|
116
|
+
let type = content.className.split(/\s/)[0];
|
|
114
117
|
switch (type || content.tagName) {
|
|
115
118
|
case 'UL':
|
|
116
119
|
case 'OL':
|
|
@@ -135,57 +138,57 @@ function attributes(label: string, param: string, content: HTMLElement, caption:
|
|
|
135
138
|
default:
|
|
136
139
|
assert(false);
|
|
137
140
|
}
|
|
138
|
-
const
|
|
139
|
-
param.trimStart() !== '' &&
|
|
140
|
-
'
|
|
141
|
-
'
|
|
142
|
-
|
|
143
|
-
/^[^-]+-(?:[0-9]+\.)*0$/.test(label) &&
|
|
144
|
-
'
|
|
145
|
-
'
|
|
146
|
-
|
|
147
|
-
group === '$' && (type !== 'math' || caption.length > 0) &&
|
|
148
|
-
'
|
|
149
|
-
'
|
|
150
|
-
|
|
151
|
-
type === 'media' &&
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
'
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
'
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
'
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
'
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
'
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
'
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
'
|
|
179
|
-
|
|
141
|
+
const violation =
|
|
142
|
+
param.trimStart() !== '' && [
|
|
143
|
+
'argument',
|
|
144
|
+
'Invalid argument',
|
|
145
|
+
] ||
|
|
146
|
+
/^[^-]+-(?:[0-9]+\.)*0$/.test(label) && [
|
|
147
|
+
'label',
|
|
148
|
+
'The last part of the fixed label numbers must not be 0',
|
|
149
|
+
] ||
|
|
150
|
+
group === '$' && (type !== 'math' || caption.length > 0) && [
|
|
151
|
+
'label',
|
|
152
|
+
'"$" label group must be used to math formulas with no caption',
|
|
153
|
+
] ||
|
|
154
|
+
type === 'media' && [
|
|
155
|
+
] ||
|
|
156
|
+
['fig', 'figure'].includes(group) && [
|
|
157
|
+
'label',
|
|
158
|
+
'"fig" and "figure" label groups must be used to media',
|
|
159
|
+
] ||
|
|
160
|
+
group === 'table' && type !== group && [
|
|
161
|
+
'label',
|
|
162
|
+
'"table" label group must be used to tables',
|
|
163
|
+
] ||
|
|
164
|
+
group === 'list' && type !== group && [
|
|
165
|
+
'label',
|
|
166
|
+
'"list" label group must be used to lists',
|
|
167
|
+
] ||
|
|
168
|
+
group === 'quote' && type !== group && [
|
|
169
|
+
'label',
|
|
170
|
+
'"quote" label group must be used to blockquotes',
|
|
171
|
+
] ||
|
|
172
|
+
group === 'text' && type !== group && [
|
|
173
|
+
'label',
|
|
174
|
+
'"text" label group must be used to codeblocks with no language',
|
|
175
|
+
] ||
|
|
176
|
+
group === 'code' && type !== group && [
|
|
177
|
+
'label',
|
|
178
|
+
'"code" label group must be used to codeblocks with any language',
|
|
179
|
+
] ||
|
|
180
|
+
group === 'example' && type !== group && [
|
|
181
|
+
'label',
|
|
182
|
+
'"example" label group must be used to examples',
|
|
183
|
+
] ||
|
|
180
184
|
undefined;
|
|
181
185
|
return {
|
|
182
186
|
'data-type': type,
|
|
183
187
|
'data-label': label,
|
|
184
188
|
'data-group': group,
|
|
185
|
-
...
|
|
189
|
+
...violation?.[0] && {
|
|
186
190
|
class: 'invalid',
|
|
187
|
-
|
|
188
|
-
...invalid,
|
|
191
|
+
...invalid('figure', violation[0], violation[1]),
|
|
189
192
|
},
|
|
190
193
|
};
|
|
191
194
|
}
|
|
@@ -13,6 +13,7 @@ import { sidefence } from '../sidefence';
|
|
|
13
13
|
import { blockquote } from '../blockquote';
|
|
14
14
|
import { mediablock } from '../mediablock';
|
|
15
15
|
import { paragraph } from '../paragraph';
|
|
16
|
+
import { invalid } from '../../util';
|
|
16
17
|
import { unshift, push } from 'spica/array';
|
|
17
18
|
import { html } from 'typed-dom/dom';
|
|
18
19
|
|
|
@@ -25,12 +26,12 @@ export const message: MessageParser = block(validate('~~~', fmap(
|
|
|
25
26
|
if (!closer || overflow || param.trimStart()) return [html('pre', {
|
|
26
27
|
class: 'invalid',
|
|
27
28
|
translate: 'no',
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
...invalid(
|
|
30
|
+
'message',
|
|
31
|
+
!closer || overflow ? 'fence' : 'argument',
|
|
31
32
|
!closer ? `Missing the closing delimiter "${delim}"` :
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
|
|
34
|
+
'Invalid argument'),
|
|
34
35
|
}, `${opener}${body}${overflow || closer}`)];
|
|
35
36
|
switch (type) {
|
|
36
37
|
case 'note':
|
|
@@ -41,9 +42,7 @@ export const message: MessageParser = block(validate('~~~', fmap(
|
|
|
41
42
|
return [html('pre', {
|
|
42
43
|
class: 'invalid',
|
|
43
44
|
translate: 'no',
|
|
44
|
-
|
|
45
|
-
'data-invalid-type': 'type',
|
|
46
|
-
'data-invalid-message': 'Invalid message type',
|
|
45
|
+
...invalid('message', 'type', 'Invalid message type'),
|
|
47
46
|
}, `${opener}${body}${closer}`)];
|
|
48
47
|
}
|
|
49
48
|
return [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../block';
|
|
2
2
|
import { block, validate, fence, clear, fmap } from '../../../combinator';
|
|
3
|
+
import { invalid } from '../../util';
|
|
3
4
|
import { html } from 'typed-dom/dom';
|
|
4
5
|
|
|
5
6
|
const opener = /^(~{3,})(?!~)[^\n]*(?:$|\n)/;
|
|
@@ -16,9 +17,11 @@ export const placeholder: ExtensionParser.PlaceholderParser = block(validate('~~
|
|
|
16
17
|
html('pre', {
|
|
17
18
|
class: 'invalid',
|
|
18
19
|
translate: 'no',
|
|
19
|
-
|
|
20
|
+
...invalid(
|
|
21
|
+
'extension',
|
|
22
|
+
'fence',
|
|
20
23
|
!closer ? `Missing the closing delimiter "${delim}"` :
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
|
|
25
|
+
'Invalid argument'),
|
|
23
26
|
}, `${opener}${body}${overflow || closer}`),
|
|
24
27
|
])));
|
|
@@ -4,7 +4,7 @@ import { Tree, eval } from '../../../combinator/data/parser';
|
|
|
4
4
|
import { union, subsequence, inits, some, block, line, validate, fence, rewrite, surround, open, clear, convert, dup, lazy, fmap } from '../../../combinator';
|
|
5
5
|
import { inline, medialink, media, shortmedia } from '../../inline';
|
|
6
6
|
import { str, anyline, emptyline, contentline } from '../../source';
|
|
7
|
-
import { lineable } from '../../util';
|
|
7
|
+
import { lineable, invalid } from '../../util';
|
|
8
8
|
import { visualize, trimBlank, trimBlankEnd } from '../../visibility';
|
|
9
9
|
import { unshift, splice } from 'spica/array';
|
|
10
10
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
@@ -29,12 +29,12 @@ export const table: TableParser = block(validate('~~~', fmap(
|
|
|
29
29
|
if (!closer || overflow || param.trimStart()) return [html('pre', {
|
|
30
30
|
class: 'invalid',
|
|
31
31
|
translate: 'no',
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
...invalid(
|
|
33
|
+
'table',
|
|
34
|
+
!closer || overflow ? 'fence' : 'argument',
|
|
35
35
|
!closer ? `Missing the closing delimiter "${delim}"` :
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
|
|
37
|
+
'Invalid argument'),
|
|
38
38
|
}, `${opener}${body}${overflow || closer}`)];
|
|
39
39
|
switch (type) {
|
|
40
40
|
case 'grid':
|
|
@@ -45,9 +45,7 @@ export const table: TableParser = block(validate('~~~', fmap(
|
|
|
45
45
|
return [html('pre', {
|
|
46
46
|
class: 'invalid',
|
|
47
47
|
translate: 'no',
|
|
48
|
-
|
|
49
|
-
'data-invalid-type': 'argument',
|
|
50
|
-
'data-invalid-message': 'Invalid table type',
|
|
48
|
+
...invalid('table', 'argument', 'Invalid table type'),
|
|
51
49
|
}, `${opener}${body}${closer}`)];
|
|
52
50
|
}
|
|
53
51
|
})));
|
|
@@ -140,21 +138,12 @@ function attributes(source: string): Record<string, string | undefined> {
|
|
|
140
138
|
class: valid ? highlight && 'highlight' : 'invalid',
|
|
141
139
|
rowspan,
|
|
142
140
|
colspan,
|
|
143
|
-
|
|
144
|
-
!
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
!validE && {
|
|
150
|
-
'data-invalid-syntax': 'table',
|
|
151
|
-
'data-invalid-type': 'syntax',
|
|
152
|
-
'data-invalid-message': 'Extensible cells are only head cells',
|
|
153
|
-
} ||
|
|
154
|
-
{
|
|
155
|
-
'data-highlight-level': level > 1 ? `${level}` : undefined,
|
|
156
|
-
'data-highlight-extension': extension,
|
|
157
|
-
},
|
|
141
|
+
...!validH && invalid('table', 'syntax', 'Too much highlight level')
|
|
142
|
+
|| !validE && invalid('table', 'syntax', 'Extensible cells are only head cells')
|
|
143
|
+
|| {
|
|
144
|
+
'data-highlight-level': level > 1 ? `${level}` : undefined,
|
|
145
|
+
'data-highlight-extension': extension,
|
|
146
|
+
},
|
|
158
147
|
};
|
|
159
148
|
}
|
|
160
149
|
|
|
@@ -69,7 +69,7 @@ describe('Unit: parser/block/heading', () => {
|
|
|
69
69
|
assert.deepStrictEqual(inspect(parser('# a [|b ]')), [['<h1 id="index::b">a<span class="indexer" data-index="b"></span></h1>'], '']);
|
|
70
70
|
assert.deepStrictEqual(inspect(parser('# a [|b ]')), [['<h1 id="index::b">a<span class="indexer" data-index="b"></span></h1>'], '']);
|
|
71
71
|
assert.deepStrictEqual(inspect(parser('# a [|b c]')), [['<h1 id="index::b_c">a<span class="indexer" data-index="b_c"></span></h1>'], '']);
|
|
72
|
-
assert.deepStrictEqual(inspect(parser('# a [|*b*`c`${d}$]')), [['<h1 id="index
|
|
72
|
+
assert.deepStrictEqual(inspect(parser('# a [|*b*`c`${d}$]')), [['<h1 id="index::*b*`c`${d}$">a<span class="indexer" data-index="*b*`c`${d}$"></span></h1>'], '']);
|
|
73
73
|
assert.deepStrictEqual(inspect(parser('# a [|@a]')), [['<h1 id="index::@a">a<span class="indexer" data-index="@a"></span></h1>'], '']);
|
|
74
74
|
assert.deepStrictEqual(inspect(parser('# a [|http://host]')), [['<h1 id="index::http://host">a<span class="indexer" data-index="http://host"></span></h1>'], '']);
|
|
75
75
|
assert.deepStrictEqual(inspect(parser('# a [|!http://host]')), [['<h1 id="index::!http://host">a<span class="indexer" data-index="!http://host"></span></h1>'], '']);
|
|
@@ -4,6 +4,7 @@ import { union, some, state, block, line, validate, focus, rewrite, open, fmap }
|
|
|
4
4
|
import { inline, indexee, indexer, dataindex } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
6
6
|
import { visualize, trimBlank } from '../visibility';
|
|
7
|
+
import { invalid } from '../util';
|
|
7
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
8
9
|
|
|
9
10
|
export const segment: HeadingParser.SegmentParser = block(validate('#', focus(
|
|
@@ -27,8 +28,6 @@ export const heading: HeadingParser = block(rewrite(segment,
|
|
|
27
28
|
? html(`h${h.length as 1}`, { 'data-index': dataindex(ns) }, defrag(ns))
|
|
28
29
|
: html(`h6`, {
|
|
29
30
|
class: 'invalid',
|
|
30
|
-
'
|
|
31
|
-
'data-invalid-type': 'syntax',
|
|
32
|
-
'data-invalid-message': 'Heading level must be up to 6',
|
|
31
|
+
...invalid('heading', 'syntax', 'Heading level must be up to 6'),
|
|
33
32
|
}, defrag(ns))
|
|
34
33
|
]))))));
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { IListParser } from '../block';
|
|
2
|
+
import { Parser } from '../../combinator/data/parser';
|
|
2
3
|
import { Recursion } from '../context';
|
|
3
|
-
import { union, inits, some, recursion, block, line, validate, indent, open, trim, fallback, lazy, fmap } from '../../combinator';
|
|
4
|
-
import { ulist_,
|
|
4
|
+
import { union, inits, some, recursion, block, line, validate, indent, rewrite, open, trim, fallback, lazy, fmap } from '../../combinator';
|
|
5
|
+
import { ulist_, fillFirstLine } from './ulist';
|
|
5
6
|
import { olist_ } from './olist';
|
|
6
7
|
import { inline } from '../inline';
|
|
7
|
-
import {
|
|
8
|
+
import { contentline } from '../source';
|
|
8
9
|
import { visualize, trimBlank } from '../visibility';
|
|
10
|
+
import { lineable, invalid } from '../util';
|
|
9
11
|
import { html, defrag } from 'typed-dom/dom';
|
|
10
12
|
|
|
11
13
|
export const ilist: IListParser = lazy(() => block(validate(
|
|
@@ -20,14 +22,22 @@ export const ilist_: IListParser = lazy(() => block(fmap(validate(
|
|
|
20
22
|
line(open(/^[-+*](?:$|\s)/, trim(visualize(trimBlank(lineable(some(inline))))), true)),
|
|
21
23
|
indent(union([ulist_, olist_, ilist_])),
|
|
22
24
|
]),
|
|
23
|
-
|
|
25
|
+
ilistitem),
|
|
24
26
|
ns => [html('li', defrag(fillFirstLine(ns)))]),
|
|
25
27
|
])))),
|
|
26
28
|
es => [
|
|
27
29
|
html('ul', {
|
|
28
30
|
class: 'invalid',
|
|
29
|
-
'
|
|
30
|
-
'data-invalid-type': 'syntax',
|
|
31
|
-
'data-invalid-message': 'Use "-" instead of "+" or "*"',
|
|
31
|
+
...invalid('list', 'syntax', 'Use "-" instead of "+" or "*"'),
|
|
32
32
|
}, es),
|
|
33
33
|
])));
|
|
34
|
+
|
|
35
|
+
export const ilistitem = rewrite(
|
|
36
|
+
inits([contentline, indent<Parser<string>>(({ source }) => [[source], ''])]),
|
|
37
|
+
({ source }) => [[
|
|
38
|
+
'',
|
|
39
|
+
html('span', {
|
|
40
|
+
class: 'invalid',
|
|
41
|
+
...invalid('list', 'syntax', 'Fix the indent or the head of the list item'),
|
|
42
|
+
}, source.replace('\n', ''))
|
|
43
|
+
], '']);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MathBlockParser } from '../block';
|
|
2
2
|
import { block, validate, fence, clear, fmap } from '../../combinator';
|
|
3
|
+
import { invalid } from '../util';
|
|
3
4
|
import { html } from 'typed-dom/dom';
|
|
4
5
|
|
|
5
6
|
const opener = /^(\${2,})(?!\$)([^\n]*)(?:$|\n)/;
|
|
@@ -20,11 +21,12 @@ export const mathblock: MathBlockParser = block(validate('$$', fmap(
|
|
|
20
21
|
: html('pre', {
|
|
21
22
|
class: 'invalid',
|
|
22
23
|
translate: 'no',
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
...invalid(
|
|
25
|
+
'mathblock',
|
|
26
|
+
delim.length > 2 ? 'syntax' : !closer || overflow ? 'fence' : 'argument',
|
|
27
|
+
delim.length > 2 ? 'Invalid syntax' :
|
|
28
|
+
!closer ? `Missing the closing delimiter "${delim}"` :
|
|
29
|
+
overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
|
|
30
|
+
'Invalid argument'),
|
|
29
31
|
}, `${opener}${body}${overflow || closer}`),
|
|
30
32
|
])));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MediaBlockParser } from '../block';
|
|
2
2
|
import { union, inits, some, block, line, validate, fallback, fmap } from '../../combinator';
|
|
3
3
|
import { medialink, media, shortmedia } from '../inline';
|
|
4
|
+
import { invalid } from '../util';
|
|
4
5
|
import { html } from 'typed-dom/dom';
|
|
5
6
|
|
|
6
7
|
export const mediablock: MediaBlockParser = block(validate(['[!', '!'], fmap(
|
|
@@ -14,13 +15,9 @@ export const mediablock: MediaBlockParser = block(validate(['[!', '!'], fmap(
|
|
|
14
15
|
medialink,
|
|
15
16
|
media,
|
|
16
17
|
shortmedia,
|
|
17
|
-
]), ({ source }) => [[html('div', [html('span',
|
|
18
|
+
]), ({ source }) => [[html('div', [html('span', {
|
|
19
|
+
class: 'invalid',
|
|
20
|
+
...invalid('mediablock', 'syntax', 'Not media syntax'),
|
|
21
|
+
}, source.replace('\n', ''))])], '']))),
|
|
18
22
|
]),
|
|
19
23
|
ns => [html('div', ns)])));
|
|
20
|
-
|
|
21
|
-
const attrs = {
|
|
22
|
-
class: 'invalid',
|
|
23
|
-
'data-invalid-syntax': 'mediablock',
|
|
24
|
-
'data-invalid-type': 'syntax',
|
|
25
|
-
'data-invalid-message': 'Not media syntax',
|
|
26
|
-
} as const;
|