securemark 0.293.2 → 0.293.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +7 -10
- package/dist/index.js +349 -167
- package/package.json +1 -1
- package/src/combinator/control/manipulation/indent.test.ts +6 -1
- package/src/combinator/control/manipulation/indent.ts +1 -1
- package/src/combinator/control/manipulation/surround.ts +2 -1
- package/src/combinator/data/parser/context/delimiter.ts +7 -12
- package/src/combinator/data/parser/some.ts +4 -8
- package/src/combinator/data/parser.ts +0 -3
- package/src/parser/api/bind.ts +1 -1
- package/src/parser/api/parse.ts +1 -1
- package/src/parser/block/dlist.test.ts +1 -1
- package/src/parser/block/heading.test.ts +1 -0
- package/src/parser/block/olist.test.ts +9 -6
- package/src/parser/block/olist.ts +2 -2
- package/src/parser/block/ulist.test.ts +1 -0
- package/src/parser/block.ts +38 -36
- package/src/parser/inline/annotation.test.ts +1 -1
- package/src/parser/inline/bracket.test.ts +4 -2
- package/src/parser/inline/bracket.ts +114 -88
- package/src/parser/inline/emphasis.test.ts +1 -0
- package/src/parser/inline/html.test.ts +3 -3
- package/src/parser/inline/html.ts +32 -21
- package/src/parser/inline/italic.test.ts +1 -0
- package/src/parser/inline/link.test.ts +10 -8
- package/src/parser/inline/link.ts +18 -18
- package/src/parser/inline/mark.test.ts +1 -0
- package/src/parser/inline/math.ts +2 -2
- package/src/parser/inline/media.test.ts +6 -7
- package/src/parser/inline/media.ts +6 -5
- package/src/parser/inline/reference.test.ts +1 -1
- package/src/parser/inline/remark.test.ts +3 -1
- package/src/parser/inline/remark.ts +2 -2
- package/src/parser/inline/strong.test.ts +1 -0
- package/src/parser/inline/template.ts +1 -1
- package/src/parser/inline.test.ts +16 -16
- package/src/parser/inline.ts +46 -47
- package/src/parser/segment.ts +12 -12
- package/src/parser/source/escapable.test.ts +1 -0
- package/src/parser/source/escapable.ts +3 -9
- package/src/parser/source/text.test.ts +5 -4
- package/src/parser/source/text.ts +175 -24
- package/src/parser/source/unescapable.test.ts +1 -0
- package/src/parser/source/unescapable.ts +2 -3
|
@@ -67,7 +67,7 @@ describe('Unit: parser/inline/html', () => {
|
|
|
67
67
|
assert.deepStrictEqual(inspect(parser('<wbr >'), ctx), [['<wbr>'], '']);
|
|
68
68
|
assert.deepStrictEqual(inspect(parser('<wbr>a'), ctx), [['<wbr>'], 'a']);
|
|
69
69
|
assert.deepStrictEqual(inspect(parser('<bdi >a</bdi>'), ctx), [['<bdi>a</bdi>'], '']);
|
|
70
|
-
assert.deepStrictEqual(inspect(parser('<bdi >a</bdi>'), ctx), [['<bdi
|
|
70
|
+
assert.deepStrictEqual(inspect(parser('<bdi >a</bdi>'), ctx), [['<span class="invalid"><bdi >a</bdi></span>'], '']);
|
|
71
71
|
assert.deepStrictEqual(inspect(parser('<bdi> a</bdi>'), ctx), [['<bdi> a</bdi>'], '']);
|
|
72
72
|
assert.deepStrictEqual(inspect(parser('<bdi> a </bdi>'), ctx), [['<bdi> a </bdi>'], '']);
|
|
73
73
|
assert.deepStrictEqual(inspect(parser('<bdi> a </bdi>'), ctx), [['<bdi> a </bdi>'], '']);
|
|
@@ -122,8 +122,8 @@ describe('Unit: parser/inline/html', () => {
|
|
|
122
122
|
assert.deepStrictEqual(inspect(parser('<bdo diR="rtl">a</bdo>'), ctx), [['<span class="invalid"><bdo diR="rtl">a</bdo></span>'], '']);
|
|
123
123
|
assert.deepStrictEqual(inspect(parser('<bdo dir="rtl">a</bdo>'), ctx), [['<bdo dir="rtl">a</bdo>'], '']);
|
|
124
124
|
assert.deepStrictEqual(inspect(parser('<bdo dir="rtl" >a</bdo>'), ctx), [['<bdo dir="rtl">a</bdo>'], '']);
|
|
125
|
-
assert.deepStrictEqual(inspect(parser('<bdo dir="rtl" >a</bdo>'), ctx), [['<bdo dir="rtl"
|
|
126
|
-
assert.deepStrictEqual(inspect(parser('<bdo dir="rtl">a</bdo>'), ctx), [['<bdo
|
|
125
|
+
assert.deepStrictEqual(inspect(parser('<bdo dir="rtl" >a</bdo>'), ctx), [['<span class="invalid"><bdo dir="rtl" >a</bdo></span>'], '']);
|
|
126
|
+
assert.deepStrictEqual(inspect(parser('<bdo dir="rtl">a</bdo>'), ctx), [['<span class="invalid"><bdo dir="rtl">a</bdo></span>'], '']);
|
|
127
127
|
assert.deepStrictEqual(inspect(parser('<wbr\n>'), ctx), undefined);
|
|
128
128
|
assert.deepStrictEqual(inspect(parser('<wbr \n>'), ctx), [['<span class="invalid"><wbr </span>'], '\n>']);
|
|
129
129
|
assert.deepStrictEqual(inspect(parser('<wbr constructor>'), ctx), [['<span class="invalid"><wbr constructor></span>'], '']);
|
|
@@ -7,7 +7,7 @@ import { str } from '../source';
|
|
|
7
7
|
import { isLooseNodeStart, blankWith } from '../visibility';
|
|
8
8
|
import { invalid } from '../util';
|
|
9
9
|
import { memoize } from 'spica/memoize';
|
|
10
|
-
import { unshift, push
|
|
10
|
+
import { unshift, push } from 'spica/array';
|
|
11
11
|
import { html as h, defrag } from 'typed-dom/dom';
|
|
12
12
|
|
|
13
13
|
const tags: readonly string[] = ['wbr', 'bdo', 'bdi'];
|
|
@@ -20,13 +20,13 @@ const attrspecs = {
|
|
|
20
20
|
Object.setPrototypeOf(attrspecs, null);
|
|
21
21
|
Object.values(attrspecs).forEach(o => Object.setPrototypeOf(o, null));
|
|
22
22
|
|
|
23
|
-
export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[
|
|
23
|
+
export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
24
24
|
union([
|
|
25
25
|
surround(
|
|
26
26
|
// https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
27
|
-
str(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[
|
|
27
|
+
str(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[ >])/yi),
|
|
28
28
|
some(union([attribute])),
|
|
29
|
-
open(str(/
|
|
29
|
+
open(str(/ ?/y), str('>'), true),
|
|
30
30
|
true,
|
|
31
31
|
([as, bs = [], cs], context) =>
|
|
32
32
|
[[elem(as[0].slice(1), false, push(unshift(as, bs), cs), [], [], context)]],
|
|
@@ -38,14 +38,18 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[^\S\n]|>)/yi,
|
|
|
38
38
|
([, tag]) =>
|
|
39
39
|
surround<HTMLParser.TagParser, string>(
|
|
40
40
|
surround(
|
|
41
|
-
str(`<${tag}`), some(attribute), open(str(/
|
|
41
|
+
str(`<${tag}`), some(attribute), open(str(/ ?/y), str('>'), true),
|
|
42
42
|
true,
|
|
43
43
|
([as, bs = [], cs]) => [push(unshift(as, bs), cs)],
|
|
44
44
|
([as, bs = []]) => [unshift(as, bs)]),
|
|
45
|
-
|
|
45
|
+
// 不可視のHTML構造が可視構造を変化させるべきでない。
|
|
46
|
+
// 可視のHTMLは優先度変更を検討する。
|
|
47
|
+
// このため<>は将来的に共通構造を変化させる可能性があり
|
|
48
|
+
// 共通構造を変化させない非構造文字列としては依然としてエスケープを要する。
|
|
49
|
+
precedence(0, recursion(Recursion.inline,
|
|
46
50
|
some(union([
|
|
47
|
-
some(inline, blankWith('\n', `</${tag}>`)
|
|
48
|
-
open('\n', some(inline, `</${tag}
|
|
51
|
+
some(inline, blankWith('\n', `</${tag}>`)),
|
|
52
|
+
open('\n', some(inline, `</${tag}>`), true),
|
|
49
53
|
])))),
|
|
50
54
|
str(`</${tag}>`),
|
|
51
55
|
true,
|
|
@@ -57,9 +61,9 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[^\S\n]|>)/yi,
|
|
|
57
61
|
new Map())),
|
|
58
62
|
surround(
|
|
59
63
|
// https://html.spec.whatwg.org/multipage/syntax.html#void-elements
|
|
60
|
-
str(/<[a-z]+(?=[
|
|
64
|
+
str(/<[a-z]+(?=[ >])/yi),
|
|
61
65
|
some(union([attribute])),
|
|
62
|
-
open(str(/
|
|
66
|
+
open(str(/ ?/y), str('>'), true),
|
|
63
67
|
true,
|
|
64
68
|
([as, bs = [], cs], context) =>
|
|
65
69
|
[[elem(as[0].slice(1), false, push(unshift(as, bs), cs), [], [], context)]],
|
|
@@ -68,8 +72,8 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[^\S\n]|>)/yi,
|
|
|
68
72
|
])));
|
|
69
73
|
|
|
70
74
|
export const attribute: HTMLParser.AttributeParser = union([
|
|
71
|
-
str(/[
|
|
72
|
-
str(/[^\
|
|
75
|
+
str(/ [a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[ >])/yi),
|
|
76
|
+
str(/ [^\s<>]+/y),
|
|
73
77
|
]);
|
|
74
78
|
|
|
75
79
|
function elem(tag: string, content: boolean, as: string[], bs: (HTMLElement | string)[], cs: string[], context: Ctx): HTMLElement {
|
|
@@ -81,7 +85,7 @@ function elem(tag: string, content: boolean, as: string[], bs: (HTMLElement | st
|
|
|
81
85
|
if (bs.length === 0) return ielem('content', `Missing the content`, context);
|
|
82
86
|
if (!isLooseNodeStart(bs)) return ielem('content', `Missing the visible content in the same line`, context);
|
|
83
87
|
}
|
|
84
|
-
const attrs = attributes('html', attrspecs[tag], as.slice(1, as.at(-1) === '>' ? -1 : as.length));
|
|
88
|
+
const [attrs] = attributes('html', attrspecs[tag], as.slice(1, as.at(-1) === '>' ? -1 : as.length));
|
|
85
89
|
if (/(?<!\S)invalid(?!\S)/.test(attrs['class'] ?? '')) return ielem('attribute', 'Invalid HTML attribute', context)
|
|
86
90
|
if (as.at(-1) !== '>') return ielem('tag', `Missing the closing symbol ">"`, context);
|
|
87
91
|
return h(tag as 'span', attrs, defrag(bs));
|
|
@@ -101,11 +105,12 @@ const requiredAttributes = memoize(
|
|
|
101
105
|
export function attributes(
|
|
102
106
|
syntax: string,
|
|
103
107
|
spec: Readonly<Record<string, readonly (string | undefined)[] | undefined>> | undefined,
|
|
104
|
-
params: string[],
|
|
105
|
-
): Record<string, string | undefined
|
|
108
|
+
params: readonly string[],
|
|
109
|
+
): [Record<string, string | undefined>, string[]] {
|
|
106
110
|
assert(spec instanceof Object === false);
|
|
107
111
|
assert(!spec?.['__proto__']);
|
|
108
112
|
assert(!spec?.toString);
|
|
113
|
+
const remains = [];
|
|
109
114
|
let invalidation = false;
|
|
110
115
|
const attrs: Record<string, string | undefined> = {};
|
|
111
116
|
for (let i = 0; i < params.length; ++i) {
|
|
@@ -116,19 +121,25 @@ export function attributes(
|
|
|
116
121
|
? param.slice(name.length + 2, -1).replace(/\\(.?)/g, '$1')
|
|
117
122
|
: undefined;
|
|
118
123
|
invalidation ||= name === '' || !spec || name in attrs;
|
|
119
|
-
if (name === ''
|
|
120
|
-
spec
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
if (name === '')continue;
|
|
125
|
+
if (spec && name in spec && !spec[name]) {
|
|
126
|
+
remains.push(params[i]);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (spec?.[name]?.includes(value) || spec?.[name]?.length === 0 && value !== undefined) {
|
|
130
|
+
attrs[name] = value ?? ''
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
invalidation ||= !!spec;
|
|
134
|
+
}
|
|
123
135
|
assert(!(name in {} && attrs.hasOwnProperty(name)));
|
|
124
|
-
splice(params, i--, 1);
|
|
125
136
|
}
|
|
126
137
|
invalidation ||= !!spec && !requiredAttributes(spec).every(name => name in attrs);
|
|
127
138
|
if (invalidation) {
|
|
128
139
|
attrs['class'] = 'invalid';
|
|
129
140
|
Object.assign(attrs, invalid(syntax, 'argument', 'Invalid argument'));
|
|
130
141
|
}
|
|
131
|
-
return attrs;
|
|
142
|
+
return [attrs, remains];
|
|
132
143
|
}
|
|
133
144
|
|
|
134
145
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
|
|
@@ -58,6 +58,7 @@ describe('Unit: parser/inline/italic', () => {
|
|
|
58
58
|
assert.deepStrictEqual(inspect(parser('//////a//////'), ctx), [['<i><i>a</i></i>'], '']);
|
|
59
59
|
assert.deepStrictEqual(inspect(parser('//////a///b///'), ctx), [['<i><i>a</i>b</i>'], '']);
|
|
60
60
|
assert.deepStrictEqual(inspect(parser('///a ///b//////'), ctx), [['<i>a <i>b</i></i>'], '']);
|
|
61
|
+
assert.deepStrictEqual(inspect(parser('///- ///b//////'), ctx), [['<i>- <i>b</i></i>'], '']);
|
|
61
62
|
assert.deepStrictEqual(inspect(parser('///a\\ ///b//////'), ctx), [['<i>a <i>b</i></i>'], '']);
|
|
62
63
|
assert.deepStrictEqual(inspect(parser('///a //////b/////////'), ctx), [['<i>a <i><i>b</i></i></i>'], '']);
|
|
63
64
|
assert.deepStrictEqual(inspect(parser('///a ///b///c///'), ctx), [['<i>a <i>b</i>c</i>'], '']);
|
|
@@ -63,8 +63,8 @@ describe('Unit: parser/inline/link', () => {
|
|
|
63
63
|
assert.deepStrictEqual(inspect(parser('[]'), ctx), undefined);
|
|
64
64
|
assert.deepStrictEqual(inspect(parser('[]{}'), ctx), undefined);
|
|
65
65
|
assert.deepStrictEqual(inspect(parser('[]{ }'), ctx), [['<span class="invalid">[]{ }</span>'], '']);
|
|
66
|
-
assert.deepStrictEqual(inspect(parser('[]{ }'), ctx),
|
|
67
|
-
assert.deepStrictEqual(inspect(parser('[]{ }'), ctx),
|
|
66
|
+
assert.deepStrictEqual(inspect(parser('[]{ }'), ctx), undefined);
|
|
67
|
+
assert.deepStrictEqual(inspect(parser('[]{ }'), ctx), undefined);
|
|
68
68
|
assert.deepStrictEqual(inspect(parser('[]{{}'), ctx), undefined);
|
|
69
69
|
assert.deepStrictEqual(inspect(parser('[]{}}'), ctx), undefined);
|
|
70
70
|
assert.deepStrictEqual(inspect(parser('[]{{}}'), ctx), undefined);
|
|
@@ -105,12 +105,11 @@ describe('Unit: parser/inline/link', () => {
|
|
|
105
105
|
it('basic', () => {
|
|
106
106
|
assert.deepStrictEqual(inspect(parser('[]{b}'), ctx), [['<a class="url" href="b">b</a>'], '']);
|
|
107
107
|
assert.deepStrictEqual(inspect(parser('[]{b }'), ctx), [['<a class="url" href="b">b</a>'], '']);
|
|
108
|
-
assert.deepStrictEqual(inspect(parser('[]{b }'), ctx), [['<
|
|
108
|
+
assert.deepStrictEqual(inspect(parser('[]{b }'), ctx), [['<span class="invalid">[]{b</span>'], ' }']);
|
|
109
109
|
assert.deepStrictEqual(inspect(parser('[]{ b }'), ctx), [['<a class="url" href="b">b</a>'], '']);
|
|
110
|
-
assert.deepStrictEqual(inspect(parser('[]{ b }'), ctx), [['<
|
|
111
|
-
assert.deepStrictEqual(inspect(parser('[]{ b }'), ctx),
|
|
112
|
-
assert.deepStrictEqual(inspect(parser('[]{ b }'), ctx),
|
|
113
|
-
assert.deepStrictEqual(inspect(parser('[]{ b }'), ctx), [['<a class="url" href="b">b</a>'], '']);
|
|
110
|
+
assert.deepStrictEqual(inspect(parser('[]{ b }'), ctx), [['<span class="invalid">[]{ b</span>'], ' }']);
|
|
111
|
+
assert.deepStrictEqual(inspect(parser('[]{ b }'), ctx), undefined);
|
|
112
|
+
assert.deepStrictEqual(inspect(parser('[]{ b }'), ctx), undefined);
|
|
114
113
|
assert.deepStrictEqual(inspect(parser('[]{"}'), ctx), [[`<a class="url" href=""">"</a>`], '']);
|
|
115
114
|
assert.deepStrictEqual(inspect(parser('[]{"}"}'), ctx), [[`<a class="url" href=""">"</a>`], '"}']);
|
|
116
115
|
assert.deepStrictEqual(inspect(parser('[]{\\}'), ctx), [[`<a class="url" href="\\">\\</a>`], '']);
|
|
@@ -209,7 +208,6 @@ describe('Unit: parser/inline/link', () => {
|
|
|
209
208
|
assert.deepStrictEqual(inspect(parser('[]{/ aspect-ratio="4/3"}'), ctx), [['<a class="invalid" href="/">/</a>'], '']);
|
|
210
209
|
assert.deepStrictEqual(inspect(parser('[]{/ 4:3}'), ctx), [['<a class="invalid" href="/">/</a>'], '']);
|
|
211
210
|
assert.deepStrictEqual(inspect(parser('[]{/ =}'), ctx), [['<a class="invalid" href="/">/</a>'], '']);
|
|
212
|
-
assert.deepStrictEqual(inspect(parser('[]{/ name}'), ctx), [['<a class="invalid" href="/">/</a>'], '']);
|
|
213
211
|
assert.deepStrictEqual(inspect(parser('[]{/\nname}'), ctx), [['<span class="invalid">[]{/</span>'], '\nname}']);
|
|
214
212
|
});
|
|
215
213
|
|
|
@@ -221,8 +219,12 @@ describe('Unit: parser/inline/link', () => {
|
|
|
221
219
|
assert.deepStrictEqual(inspect(parser('[]{/ nofollow nofollow}'), ctx), [['<a class="invalid" href="/" rel="nofollow">/</a>'], '']);
|
|
222
220
|
assert.deepStrictEqual(inspect(parser('[]{/ nofollow}'), ctx), [['<a class="url" href="/" rel="nofollow">/</a>'], '']);
|
|
223
221
|
assert.deepStrictEqual(inspect(parser('[]{/ nofollow }'), ctx), [['<a class="url" href="/" rel="nofollow">/</a>'], '']);
|
|
222
|
+
assert.deepStrictEqual(inspect(parser('[]{/ nofollow }'), ctx), [['<span class="invalid">[]{/ nofollow</span>'], ' }']);
|
|
223
|
+
assert.deepStrictEqual(inspect(parser('[]{/ nofollow}'), ctx), [['<span class="invalid">[]{/</span>'], ' nofollow}']);
|
|
224
224
|
assert.deepStrictEqual(inspect(parser('[]{ / nofollow}'), ctx), [['<a class="url" href="/" rel="nofollow">/</a>'], '']);
|
|
225
225
|
assert.deepStrictEqual(inspect(parser('[]{ / nofollow }'), ctx), [['<a class="url" href="/" rel="nofollow">/</a>'], '']);
|
|
226
|
+
assert.deepStrictEqual(inspect(parser('[]{ / nofollow }'), ctx), [['<span class="invalid">[]{ / nofollow</span>'], ' }']);
|
|
227
|
+
assert.deepStrictEqual(inspect(parser('[]{ / nofollow}'), ctx), [['<span class="invalid">[]{ /</span>'], ' nofollow}']);
|
|
226
228
|
assert.deepStrictEqual(inspect(parser('[]{http://host nofollow}'), ctx), [['<a class="url" href="http://host" target="_blank" rel="nofollow">http://host</a>'], '']);
|
|
227
229
|
assert.deepStrictEqual(inspect(parser('[!http://host]{http://host nofollow}'), ctx), [['<a class="link" href="http://host" target="_blank" rel="nofollow"><img class="media" data-src="http://host" alt="http://host"></a>'], '']);
|
|
228
230
|
});
|
|
@@ -35,7 +35,7 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
35
35
|
dup(surround(
|
|
36
36
|
/{(?![{}])/y,
|
|
37
37
|
inits([uri, some(option)]),
|
|
38
|
-
/
|
|
38
|
+
/ ?}/y,
|
|
39
39
|
false,
|
|
40
40
|
undefined,
|
|
41
41
|
([as, bs], context) => {
|
|
@@ -82,7 +82,7 @@ export const medialink: LinkParser.MediaLinkParser = lazy(() => constraint(State
|
|
|
82
82
|
'[',
|
|
83
83
|
union([media, shortmedia]),
|
|
84
84
|
']')),
|
|
85
|
-
dup(surround(/{(?![{}])/y, inits([uri, some(option)]), /
|
|
85
|
+
dup(surround(/{(?![{}])/y, inits([uri, some(option)]), / ?}/y)),
|
|
86
86
|
])),
|
|
87
87
|
([params, content = []]: [string[], (HTMLElement | string)[]], context) =>
|
|
88
88
|
[[parse(defrag(content), params, context)]]))))));
|
|
@@ -94,20 +94,20 @@ export const unsafelink: LinkParser.UnsafeLinkParser = lazy(() =>
|
|
|
94
94
|
'[',
|
|
95
95
|
some(union([unescsource]), ']'),
|
|
96
96
|
']')),
|
|
97
|
-
dup(surround(/{(?![{}])/y, inits([uri, some(option)]), /
|
|
97
|
+
dup(surround(/{(?![{}])/y, inits([uri, some(option)]), / ?}/y)),
|
|
98
98
|
])),
|
|
99
99
|
([params, content = []], context) =>
|
|
100
100
|
[[parse(defrag(content), params, context)]])));
|
|
101
101
|
|
|
102
102
|
export const uri: LinkParser.ParameterParser.UriParser = union([
|
|
103
|
-
open(/
|
|
103
|
+
open(/ /y, str(/\S+/y)),
|
|
104
104
|
str(/[^\s{}]+/y),
|
|
105
105
|
]);
|
|
106
106
|
|
|
107
107
|
export const option: LinkParser.ParameterParser.OptionParser = union([
|
|
108
|
-
fmap(str(/
|
|
109
|
-
str(/[
|
|
110
|
-
str(/[^\
|
|
108
|
+
fmap(str(/ nofollow(?=[ }])/y), () => [` rel="nofollow"`]),
|
|
109
|
+
str(/ [a-z]+(?:-[a-z]+)*(?:="(?:\\[^\n]|[^\\\n"])*")?(?=[ }])/yi),
|
|
110
|
+
str(/ [^\s{}]+/y),
|
|
111
111
|
]);
|
|
112
112
|
|
|
113
113
|
function parse(
|
|
@@ -135,7 +135,7 @@ function parse(
|
|
|
135
135
|
context.host?.origin || location.origin);
|
|
136
136
|
return el.classList.contains('invalid')
|
|
137
137
|
? el
|
|
138
|
-
: define(el, attributes('link', optspec, params));
|
|
138
|
+
: define(el, attributes('link', optspec, params)[0]);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
function elem(
|
|
@@ -155,11 +155,11 @@ function elem(
|
|
|
155
155
|
case 'https:':
|
|
156
156
|
assert(uri.host);
|
|
157
157
|
switch (true) {
|
|
158
|
-
case /[
|
|
158
|
+
case /[0-9a-z]:\S/i.test(stringify(content)):
|
|
159
159
|
type = 'content';
|
|
160
160
|
message = 'URI must not be contained';
|
|
161
161
|
break;
|
|
162
|
-
case INSECURE_URI.
|
|
162
|
+
case INSECURE_URI.startsWith('^/')
|
|
163
163
|
&& /\/\.\.?(?:\/|$)/.test(INSECURE_URI.slice(0, INSECURE_URI.search(/[?#]|$/))):
|
|
164
164
|
type = 'argument';
|
|
165
165
|
message = 'Dot-segments cannot be used in subresource paths';
|
|
@@ -223,7 +223,7 @@ export function resolve(uri: string, host: URL | Location, source: URL | Locatio
|
|
|
223
223
|
assert(uri);
|
|
224
224
|
assert(uri === uri.trim());
|
|
225
225
|
switch (true) {
|
|
226
|
-
case uri.
|
|
226
|
+
case uri.startsWith('^/'):
|
|
227
227
|
const last = host.pathname.slice(host.pathname.lastIndexOf('/') + 1);
|
|
228
228
|
return last.includes('.') // isFile
|
|
229
229
|
// Exclude ISO 6709.
|
|
@@ -232,7 +232,7 @@ export function resolve(uri: string, host: URL | Location, source: URL | Locatio
|
|
|
232
232
|
: `${host.pathname.replace(/\/?$/, '/')}${uri.slice(2)}`;
|
|
233
233
|
case host.origin === source.origin
|
|
234
234
|
&& host.pathname === source.pathname:
|
|
235
|
-
case uri.
|
|
235
|
+
case uri.startsWith('//'):
|
|
236
236
|
return uri;
|
|
237
237
|
default:
|
|
238
238
|
const target = new ReadonlyURL(uri, source.href);
|
|
@@ -243,13 +243,13 @@ export function resolve(uri: string, host: URL | Location, source: URL | Locatio
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
export function decode(uri: string): string {
|
|
246
|
-
const
|
|
246
|
+
const head = /^[a-z]+(?:[.+-][0-9a-z]+)*:\/*[^/?#\s]+/i;
|
|
247
|
+
const origin = uri.match(head)?.[0] ?? '';
|
|
247
248
|
try {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
uri = origin + path;
|
|
249
|
+
const path = decodeURI(uri.slice(origin.length));
|
|
250
|
+
uri = !origin && head.test(path)
|
|
251
|
+
? uri.slice(origin.length)
|
|
252
|
+
: origin + path;
|
|
253
253
|
}
|
|
254
254
|
finally {
|
|
255
255
|
return uri.replace(/\s+/g, encodeURI);
|
|
@@ -39,6 +39,7 @@ describe('Unit: parser/inline/mark', () => {
|
|
|
39
39
|
|
|
40
40
|
it('nest', () => {
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('==a ==b===='), ctx), [['<mark id="mark::a_b">a <mark id="mark::b">b</mark><a href="#mark::b"></a></mark>', '<a href="#mark::a_b"></a>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('==- ==b===='), ctx), [['<mark id="mark::-_b">- <mark id="mark::b">b</mark><a href="#mark::b"></a></mark>', '<a href="#mark::-_b"></a>'], '']);
|
|
42
43
|
assert.deepStrictEqual(inspect(parser('==a\\ ==b===='), ctx), [['<mark id="mark::a_b">a <mark id="mark::b">b</mark><a href="#mark::b"></a></mark>', '<a href="#mark::a_b"></a>'], '']);
|
|
43
44
|
assert.deepStrictEqual(inspect(parser('==a	==b===='), ctx), [['<mark id="mark::a_b=33Mw2l">a\t<mark id="mark::b">b</mark><a href="#mark::b"></a></mark>', '<a href="#mark::a_b=33Mw2l"></a>'], '']);
|
|
44
45
|
assert.deepStrictEqual(inspect(parser('==a<wbr>==b===='), ctx), [['<mark id="mark::ab">a<wbr><mark id="mark::b">b</mark><a href="#mark::b"></a></mark>', '<a href="#mark::ab"></a>'], '']);
|
|
@@ -11,14 +11,14 @@ export const math: MathParser = lazy(() => rewrite(
|
|
|
11
11
|
union([
|
|
12
12
|
surround(
|
|
13
13
|
/\$(?={)/y,
|
|
14
|
-
precedence(
|
|
14
|
+
precedence(4, bracket),
|
|
15
15
|
'$',
|
|
16
16
|
false, undefined, undefined, [3 | Backtrack.bracket]),
|
|
17
17
|
surround(
|
|
18
18
|
/\$(?![\s{}])/y,
|
|
19
19
|
precedence(2, some(union([
|
|
20
20
|
some(escsource, /\s?\$|[`"{}\n]/y),
|
|
21
|
-
precedence(
|
|
21
|
+
precedence(4, bracket),
|
|
22
22
|
]))),
|
|
23
23
|
/\$(?![-0-9A-Za-z])/y,
|
|
24
24
|
false, undefined, undefined, [3 | Backtrack.bracket]),
|
|
@@ -27,8 +27,8 @@ describe('Unit: parser/inline/media', () => {
|
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('![]'), ctx), undefined);
|
|
28
28
|
assert.deepStrictEqual(inspect(parser('![]{}'), ctx), undefined);
|
|
29
29
|
assert.deepStrictEqual(inspect(parser('![]{ }'), ctx), [['<span class="invalid">![]{ }</span>'], '']);
|
|
30
|
-
assert.deepStrictEqual(inspect(parser('![]{ }'), ctx),
|
|
31
|
-
assert.deepStrictEqual(inspect(parser('![]{ }'), ctx),
|
|
30
|
+
assert.deepStrictEqual(inspect(parser('![]{ }'), ctx), undefined);
|
|
31
|
+
assert.deepStrictEqual(inspect(parser('![]{ }'), ctx), undefined);
|
|
32
32
|
assert.deepStrictEqual(inspect(parser('![]]{/}'), ctx), undefined);
|
|
33
33
|
assert.deepStrictEqual(inspect(parser('![]{{}'), ctx), undefined);
|
|
34
34
|
assert.deepStrictEqual(inspect(parser('![]{}}'), ctx), undefined);
|
|
@@ -66,12 +66,11 @@ describe('Unit: parser/inline/media', () => {
|
|
|
66
66
|
it('basic', () => {
|
|
67
67
|
assert.deepStrictEqual(inspect(parser('![]{b}'), ctx), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="b"></a>'], '']);
|
|
68
68
|
assert.deepStrictEqual(inspect(parser('![]{b }'), ctx), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="b"></a>'], '']);
|
|
69
|
-
assert.deepStrictEqual(inspect(parser('![]{b }'), ctx), [['<
|
|
69
|
+
assert.deepStrictEqual(inspect(parser('![]{b }'), ctx), [['<span class="invalid">![]{b</span>'], ' }']);
|
|
70
70
|
assert.deepStrictEqual(inspect(parser('![]{ b }'), ctx), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="b"></a>'], '']);
|
|
71
|
-
assert.deepStrictEqual(inspect(parser('![]{ b }'), ctx), [['<
|
|
72
|
-
assert.deepStrictEqual(inspect(parser('![]{ b }'), ctx),
|
|
73
|
-
assert.deepStrictEqual(inspect(parser('![]{ b }'), ctx),
|
|
74
|
-
assert.deepStrictEqual(inspect(parser('![]{ b }'), ctx), [['<a href="b" target="_blank"><img class="media" data-src="b" alt="b"></a>'], '']);
|
|
71
|
+
assert.deepStrictEqual(inspect(parser('![]{ b }'), ctx), [['<span class="invalid">![]{ b</span>'], ' }']);
|
|
72
|
+
assert.deepStrictEqual(inspect(parser('![]{ b }'), ctx), undefined);
|
|
73
|
+
assert.deepStrictEqual(inspect(parser('![]{ b }'), ctx), undefined);
|
|
75
74
|
assert.deepStrictEqual(inspect(parser('![]{"}'), ctx), [['<a href=""" target="_blank"><img class="media" data-src=""" alt="""></a>'], '']);
|
|
76
75
|
assert.deepStrictEqual(inspect(parser('![]{"}"}'), ctx), [['<a href=""" target="_blank"><img class="media" data-src=""" alt="""></a>'], '"}']);
|
|
77
76
|
assert.deepStrictEqual(inspect(parser('![]{\\}'), ctx), [['<a href="\\" target="_blank"><img class="media" data-src="\\" alt="\\"></a>'], '']);
|
|
@@ -40,7 +40,7 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
|
|
|
40
40
|
dup(surround(
|
|
41
41
|
/{(?![{}])/y,
|
|
42
42
|
inits([uri, some(option)]),
|
|
43
|
-
/
|
|
43
|
+
/ ?}/y,
|
|
44
44
|
false,
|
|
45
45
|
undefined,
|
|
46
46
|
([as, bs], context) => {
|
|
@@ -87,7 +87,8 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
|
|
|
87
87
|
el.setAttribute('alt', text);
|
|
88
88
|
if (!sanitize(el, uri)) return [[el]];
|
|
89
89
|
assert(!el.matches('.invalid'));
|
|
90
|
-
|
|
90
|
+
const [attrs, linkparams] = attributes('media', optspec, params);
|
|
91
|
+
define(el, attrs);
|
|
91
92
|
assert(el.matches('img') || !el.matches('.invalid'));
|
|
92
93
|
// Awaiting the generic support for attr().
|
|
93
94
|
if (el.hasAttribute('aspect-ratio')) {
|
|
@@ -103,7 +104,7 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
|
|
|
103
104
|
context.position = position;
|
|
104
105
|
return [define(link, { class: null, target: '_blank' }, [el])];
|
|
105
106
|
})
|
|
106
|
-
(subinput(`{ ${INSECURE_URI}${
|
|
107
|
+
(subinput(`{ ${INSECURE_URI}${linkparams.join('')} }`, context));
|
|
107
108
|
})))));
|
|
108
109
|
|
|
109
110
|
const bracket: MediaParser.TextParser.BracketParser = lazy(() => recursion(Recursion.terminal, union([
|
|
@@ -119,9 +120,9 @@ const bracket: MediaParser.TextParser.BracketParser = lazy(() => recursion(Recur
|
|
|
119
120
|
|
|
120
121
|
const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
|
|
121
122
|
surround(
|
|
122
|
-
open(/
|
|
123
|
+
open(/ /y, str(/[1-9][0-9]*/y)),
|
|
123
124
|
str(/[x:]/y),
|
|
124
|
-
str(/[1-9][0-9]*(?=[
|
|
125
|
+
str(/[1-9][0-9]*(?=[ }])/y),
|
|
125
126
|
false,
|
|
126
127
|
([[a], [b], [c]]) => [
|
|
127
128
|
b === 'x'
|
|
@@ -17,7 +17,7 @@ describe('Unit: parser/inline/reference', () => {
|
|
|
17
17
|
assert.deepStrictEqual(inspect(parser('[[]]]'), ctx), undefined);
|
|
18
18
|
assert.deepStrictEqual(inspect(parser('[["]]'), ctx), undefined);
|
|
19
19
|
assert.deepStrictEqual(inspect(parser('[[(]]'), ctx), undefined);
|
|
20
|
-
assert.deepStrictEqual(inspect(parser('[[
|
|
20
|
+
assert.deepStrictEqual(inspect(parser('[[[%]]'), ctx), undefined);
|
|
21
21
|
assert.deepStrictEqual(inspect(parser('[[ ]]'), ctx), undefined);
|
|
22
22
|
assert.deepStrictEqual(inspect(parser('[[ [a'), ctx), undefined);
|
|
23
23
|
assert.deepStrictEqual(inspect(parser('[[\n]]'), ctx), undefined);
|
|
@@ -31,7 +31,7 @@ describe('Unit: parser/inline/remark', () => {
|
|
|
31
31
|
assert.deepStrictEqual(inspect(parser('[%\\ a %]'), ctx), undefined);
|
|
32
32
|
assert.deepStrictEqual(inspect(parser('[% a\\ %]'), ctx), [['[%', ' a', ' ', '%', ']'], '']);
|
|
33
33
|
assert.deepStrictEqual(inspect(parser('[% a%]'), ctx), [['[%', ' a', '%', ']'], '']);
|
|
34
|
-
assert.deepStrictEqual(inspect(parser('[% a %%]'), ctx), [['[%', ' a
|
|
34
|
+
assert.deepStrictEqual(inspect(parser('[% a %%]'), ctx), [['[%', ' a %', '%', ']'], '']);
|
|
35
35
|
assert.deepStrictEqual(inspect(parser('[% [%% %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% <span class="invalid">[%%</span> %]</span></span>'], '']);
|
|
36
36
|
assert.deepStrictEqual(inspect(parser('[%% [% %%]'), ctx), [['<span class="invalid">[%%</span>'], ' [% %%]']);
|
|
37
37
|
assert.deepStrictEqual(inspect(parser('[%% a %]'), ctx), [['<span class="invalid">[%%</span>'], ' a %]']);
|
|
@@ -43,7 +43,9 @@ describe('Unit: parser/inline/remark', () => {
|
|
|
43
43
|
assert.deepStrictEqual(inspect(parser('[% %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% %]</span></span>'], '']);
|
|
44
44
|
assert.deepStrictEqual(inspect(parser('[% %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% %]</span></span>'], '']);
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('[% a %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], '']);
|
|
46
|
+
assert.deepStrictEqual(inspect(parser('[% - %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% - %]</span></span>'], '']);
|
|
46
47
|
assert.deepStrictEqual(inspect(parser('[% a %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], '']);
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('[% - %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% - %]</span></span>'], '']);
|
|
47
49
|
assert.deepStrictEqual(inspect(parser('[% a b %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a b %]</span></span>'], '']);
|
|
48
50
|
assert.deepStrictEqual(inspect(parser('[% a\nb %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a<br>b %]</span></span>'], '']);
|
|
49
51
|
assert.deepStrictEqual(inspect(parser('[% a %] %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], ' %]']);
|
|
@@ -9,8 +9,8 @@ import { html, defrag } from 'typed-dom/dom';
|
|
|
9
9
|
|
|
10
10
|
export const remark: RemarkParser = lazy(() => fallback(surround(
|
|
11
11
|
str(/\[%(?=\s)/y),
|
|
12
|
-
precedence(
|
|
13
|
-
some(union([inline]), /\s%\]/y, [[/\s%\]/y,
|
|
12
|
+
precedence(3, recursion(Recursion.inline,
|
|
13
|
+
some(union([inline]), /\s%\]/y, [[/\s%\]/y, 3]]))),
|
|
14
14
|
close(text, str(`%]`)), true,
|
|
15
15
|
([as, bs = [], cs]) => [[
|
|
16
16
|
html('span', { class: 'remark' }, [
|
|
@@ -39,6 +39,7 @@ describe('Unit: parser/inline/strong', () => {
|
|
|
39
39
|
|
|
40
40
|
it('nest', () => {
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('**a *b***'), ctx), [['<strong>a <em>b</em></strong>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('**- *b***'), ctx), [['<strong>- <em>b</em></strong>'], '']);
|
|
42
43
|
assert.deepStrictEqual(inspect(parser('**a **b****'), ctx), [['<strong>a <strong>b</strong></strong>'], '']);
|
|
43
44
|
assert.deepStrictEqual(inspect(parser('**a	**b****'), ctx), [['<strong>a\t<strong>b</strong></strong>'], '']);
|
|
44
45
|
assert.deepStrictEqual(inspect(parser('**a<wbr>**b****'), ctx), [['<strong>a<wbr><strong>b</strong></strong>'], '']);
|
|
@@ -34,7 +34,7 @@ const bracket: TemplateParser.BracketParser = lazy(() => union([
|
|
|
34
34
|
undefined, () => [[]], [3 | Backtrack.escbracket]),
|
|
35
35
|
surround(
|
|
36
36
|
str('"'),
|
|
37
|
-
precedence(2, recursion(Recursion.terminal, some(escsource,
|
|
37
|
+
precedence(2, recursion(Recursion.terminal, some(escsource, /["\n]/y, [['"', 2], ['\n', 3]]))),
|
|
38
38
|
str('"'),
|
|
39
39
|
true,
|
|
40
40
|
([as, bs = [], cs], context) =>
|
|
@@ -22,7 +22,7 @@ describe('Unit: parser/inline', () => {
|
|
|
22
22
|
it('nest', () => {
|
|
23
23
|
assert.deepStrictEqual(inspect(parser('あ(A)'), ctx), [['あ', '(', 'A', ')'], '']);
|
|
24
24
|
assert.deepStrictEqual(inspect(parser('あ(い)'), ctx), [['あ', '<span class="paren">(い)</span>'], '']);
|
|
25
|
-
assert.deepStrictEqual(inspect(parser('* a*'), ctx), [['*
|
|
25
|
+
assert.deepStrictEqual(inspect(parser('* a*'), ctx), [['* a', '*'], '']);
|
|
26
26
|
assert.deepStrictEqual(inspect(parser('** a**'), ctx), [['**', ' a', '**'], '']);
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('*** a***'), ctx), [['***', ' a', '***'], '']);
|
|
28
28
|
assert.deepStrictEqual(inspect(parser('**** a****'), ctx), [['****', ' a', '****'], '']);
|
|
@@ -82,19 +82,19 @@ describe('Unit: parser/inline', () => {
|
|
|
82
82
|
assert.deepStrictEqual(inspect(parser('*++ a ++*'), ctx), [['<em><ins> a </ins></em>'], '']);
|
|
83
83
|
assert.deepStrictEqual(inspect(parser('*++ a ++*'), ctx), [['<em><ins> a </ins></em>'], '']);
|
|
84
84
|
assert.deepStrictEqual(inspect(parser('*<bdi>`a`</bdi>*'), ctx), [['<em><bdi><code data-src="`a`">a</code></bdi></em>'], '']);
|
|
85
|
-
assert.deepStrictEqual(inspect(parser('*a"\nb*'), ctx), [['
|
|
85
|
+
assert.deepStrictEqual(inspect(parser('*a"\nb*'), ctx), [['<em>a"<br>b</em>'], '']);
|
|
86
86
|
assert.deepStrictEqual(inspect(parser('*a"\n"("b*'), ctx), [['<em>a"<br>"("b</em>'], '']);
|
|
87
|
-
assert.deepStrictEqual(inspect(parser('"*a\nb*'), ctx), [['"', '
|
|
88
|
-
assert.deepStrictEqual(inspect(parser('"*a\n""b*'), ctx), [['"', '
|
|
87
|
+
assert.deepStrictEqual(inspect(parser('"*a\nb*'), ctx), [['"', '*', 'a', '<br>', 'b', '*'], '']);
|
|
88
|
+
assert.deepStrictEqual(inspect(parser('"*a\n""b*'), ctx), [['"', '*', 'a', '<br>', '"', '"', 'b', '*'], '']);
|
|
89
89
|
assert.deepStrictEqual(inspect(parser('"a\n"*b"c*'), ctx), [['"', 'a', '<br>', '"', '*', 'b', '"', 'c', '*'], '']);
|
|
90
|
-
assert.deepStrictEqual(inspect(parser('"*a**b\nc**"("*'), ctx), [['"', '
|
|
91
|
-
assert.deepStrictEqual(inspect(parser('
|
|
92
|
-
assert.deepStrictEqual(inspect(parser('"<bdi>"a\n""b</bdi>"'), ctx), [['"', '<bdi>"a<br>""b</bdi>', '"'], '']);
|
|
90
|
+
assert.deepStrictEqual(inspect(parser('"*a**b\nc**"("*'), ctx), [['"', '*', 'a', '**', 'b', '<br>', 'c', '**', '"', '(', '"', '*'], '']);
|
|
91
|
+
assert.deepStrictEqual(inspect(parser('[% a"\nb %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a"<br>b %]</span></span>'], '']);
|
|
92
|
+
assert.deepStrictEqual(inspect(parser('"<bdi>"a\n""b</bdi>"'), ctx), [['"', '<span class="invalid"><bdi></span>', '"', 'a', '<br>', '"', '"', 'b', '</bdi', '>', '"'], '']);
|
|
93
93
|
assert.deepStrictEqual(inspect(parser('<bdi>*<bdi>a</bdi>*</bdi>'), ctx), [['<bdi><em><bdi>a</bdi></em></bdi>'], '']);
|
|
94
94
|
assert.deepStrictEqual(inspect(parser('<bdi>((<bdi>((a))</bdi>))</bdi>'), ctx), [['<bdi><sup class="annotation"><span><bdi><span class="paren">((a))</span></bdi></span></sup></bdi>'], '']);
|
|
95
95
|
assert.deepStrictEqual(inspect(parser('<bdi>[[<bdi>[[a]]</bdi>]]</bdi>'), ctx), [['<bdi><sup class="reference"><span><bdi>[[a]]</bdi></span></sup></bdi>'], '']);
|
|
96
|
-
assert.deepStrictEqual(inspect(parser('<bdi>[#</bdi>]'), ctx), [['<bdi
|
|
97
|
-
assert.deepStrictEqual(inspect(parser('"<bdi>("")</bdi>'), ctx), [['"', '<
|
|
96
|
+
assert.deepStrictEqual(inspect(parser('<bdi>[#</bdi>]'), ctx), [['<span class="invalid"><bdi>[#</bdi>]</span>'], '']);
|
|
97
|
+
assert.deepStrictEqual(inspect(parser('"<bdi>("")</bdi>'), ctx), [['"', '<span class="invalid"><bdi>(</span>', '"', '"', ')', '</bdi', '>'], '']);
|
|
98
98
|
assert.deepStrictEqual(inspect(parser('++\na\n++\n~~\nb\n~~\nc'), ctx), [['<ins><br>a</ins>', '<br>', '<del><br>b</del>', '<br>', 'c'], '']);
|
|
99
99
|
assert.deepStrictEqual(inspect(parser('[@a]'), ctx), [['[', '<a class="account" href="/@a">@a</a>', ']'], '']);
|
|
100
100
|
assert.deepStrictEqual(inspect(parser('[#1][#2]'), ctx), [['<a class="index" href="#index::1">1</a>', '<a class="index" href="#index::2">2</a>'], '']);
|
|
@@ -121,11 +121,11 @@ describe('Unit: parser/inline', () => {
|
|
|
121
121
|
assert.deepStrictEqual(inspect(parser('{}'), ctx), [['{', '}'], '']);
|
|
122
122
|
assert.deepStrictEqual(inspect(parser('{a}'), ctx), [['<a class="url" href="a">a</a>'], '']);
|
|
123
123
|
assert.deepStrictEqual(inspect(parser('{{a}}'), ctx), [['<span class="template">{{a}}</span>'], '']);
|
|
124
|
-
assert.deepStrictEqual(inspect(parser('
|
|
125
|
-
assert.deepStrictEqual(inspect(parser('
|
|
126
|
-
assert.deepStrictEqual(inspect(parser('
|
|
127
|
-
assert.deepStrictEqual(inspect(parser('
|
|
128
|
-
assert.deepStrictEqual(inspect(parser('
|
|
124
|
+
assert.deepStrictEqual(inspect(parser('!{}'), ctx), [['!', '{', '}'], '']);
|
|
125
|
+
assert.deepStrictEqual(inspect(parser('!{a}'), ctx), [['!', '<a class="url" href="a">a</a>'], '']);
|
|
126
|
+
assert.deepStrictEqual(inspect(parser('!{{a}}'), ctx), [['!', '<span class="template">{{a}}</span>'], '']);
|
|
127
|
+
assert.deepStrictEqual(inspect(parser('!{{{a}}}'), ctx), [['!', '<span class="template">{{{a}}}</span>'], '']);
|
|
128
|
+
assert.deepStrictEqual(inspect(parser('!!{a}'), ctx), [['!', '!', '<a class="url" href="a">a</a>'], '']);
|
|
129
129
|
assert.deepStrictEqual(inspect(parser('${a}'), ctx), [['$', '<a class="url" href="a">a</a>'], '']);
|
|
130
130
|
assert.deepStrictEqual(inspect(parser('${{a}}'), ctx), [['$', '<span class="template">{{a}}</span>'], '']);
|
|
131
131
|
assert.deepStrictEqual(inspect(parser('${{{a}}}'), ctx), [['$', '<span class="template">{{{a}}}</span>'], '']);
|
|
@@ -167,8 +167,8 @@ describe('Unit: parser/inline', () => {
|
|
|
167
167
|
assert.deepStrictEqual(inspect(parser('"{{""}}'), ctx), [['"', '{', '{', '"', '"', '}', '}'], '']);
|
|
168
168
|
assert.deepStrictEqual(inspect(parser('[#http://host/(<bdi>)]</bdi>'), ctx), [['<a class="index" href="#index::http://host/(<bdi>)">http://host/(<bdi>)</a>', '</bdi', '>'], '']);
|
|
169
169
|
assert.deepStrictEqual(inspect(parser('[#@a/http://host/(<bdi>)]</bdi>'), ctx), [['<a class="index" href="#index::@a/http://host/(<bdi>)">@a/http://host/(<bdi>)</a>', '</bdi', '>'], '']);
|
|
170
|
-
assert.deepStrictEqual(inspect(parser('[#a|<bdi>]</bdi>'), ctx), [['
|
|
171
|
-
assert.deepStrictEqual(inspect(parser('[[#a|<bdi>]</bdi>'), ctx), [['[', '
|
|
170
|
+
assert.deepStrictEqual(inspect(parser('[#a|<bdi>]</bdi>'), ctx), [['<a class="index" href="#index::a|<bdi>">a|<span class="invalid"><bdi></span></a>', '</bdi', '>'], '']);
|
|
171
|
+
assert.deepStrictEqual(inspect(parser('[[#a|<bdi>]</bdi>'), ctx), [['[', '<a class="index" href="#index::a|<bdi>">a|<span class="invalid"><bdi></span></a>', '</bdi', '>'], '']);
|
|
172
172
|
});
|
|
173
173
|
|
|
174
174
|
it('uri', () => {
|