securemark 0.259.2 → 0.260.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 +13 -0
- package/design.md +14 -4
- package/dist/index.js +253 -207
- package/package.json +1 -1
- package/src/combinator/control/constraint/block.ts +2 -3
- package/src/combinator/control/constraint/contract.ts +5 -7
- package/src/combinator/control/constraint/line.ts +1 -2
- package/src/combinator/control/manipulation/convert.ts +1 -2
- package/src/combinator/control/manipulation/fence.ts +1 -2
- package/src/combinator/control/manipulation/match.ts +2 -3
- package/src/combinator/control/manipulation/scope.ts +3 -5
- package/src/combinator/control/manipulation/surround.ts +2 -2
- package/src/combinator/control/monad/bind.ts +2 -3
- package/src/combinator/data/parser/context.ts +20 -22
- package/src/combinator/data/parser/inits.ts +1 -2
- package/src/combinator/data/parser/sequence.ts +1 -2
- package/src/combinator/data/parser/some.ts +1 -2
- package/src/parser/api/parse.test.ts +19 -19
- package/src/parser/autolink.test.ts +6 -6
- package/src/parser/block/blockquote.test.ts +8 -8
- package/src/parser/block/blockquote.ts +3 -3
- package/src/parser/block/codeblock.test.ts +4 -4
- package/src/parser/block/dlist.test.ts +1 -1
- package/src/parser/block/dlist.ts +2 -2
- package/src/parser/block/extension/figure.test.ts +1 -1
- package/src/parser/block/extension/table.ts +3 -3
- package/src/parser/block/heading.test.ts +5 -5
- package/src/parser/block/ilist.ts +1 -1
- package/src/parser/block/olist.test.ts +1 -1
- package/src/parser/block/olist.ts +1 -1
- package/src/parser/block/paragraph.test.ts +14 -14
- package/src/parser/block/reply/cite.test.ts +11 -11
- package/src/parser/block/reply/cite.ts +1 -1
- package/src/parser/block/reply/quote.test.ts +3 -3
- package/src/parser/block/reply/quote.ts +1 -1
- package/src/parser/block/reply.test.ts +8 -8
- package/src/parser/block/sidefence.test.ts +6 -6
- package/src/parser/block/sidefence.ts +1 -1
- package/src/parser/block/table.ts +4 -4
- package/src/parser/block/ulist.test.ts +1 -1
- package/src/parser/block/ulist.ts +2 -2
- package/src/parser/block.ts +1 -1
- package/src/parser/context.ts +8 -7
- package/src/parser/inline/annotation.test.ts +3 -3
- package/src/parser/inline/autolink/account.test.ts +11 -11
- package/src/parser/inline/autolink/account.ts +4 -2
- package/src/parser/inline/autolink/anchor.test.ts +9 -9
- package/src/parser/inline/autolink/anchor.ts +14 -11
- package/src/parser/inline/autolink/channel.test.ts +3 -3
- package/src/parser/inline/autolink/hashnum.ts +4 -2
- package/src/parser/inline/autolink/hashtag.test.ts +20 -20
- package/src/parser/inline/autolink/hashtag.ts +4 -2
- package/src/parser/inline/autolink/url.test.ts +55 -55
- package/src/parser/inline/html.test.ts +0 -2
- package/src/parser/inline/html.ts +1 -1
- package/src/parser/inline/link.test.ts +110 -110
- package/src/parser/inline/link.ts +30 -28
- package/src/parser/inline/media.test.ts +1 -0
- package/src/parser/inline/media.ts +1 -1
- package/src/parser/inline/reference.test.ts +3 -3
- package/src/parser/inline/ruby.ts +1 -1
- package/src/parser/inline.test.ts +51 -51
- package/src/parser/source/escapable.ts +1 -1
- package/src/parser/source/str.ts +4 -4
- package/src/parser/source/text.ts +2 -3
- package/src/parser/source/unescapable.ts +1 -1
- package/src/renderer/render/media/pdf.ts +1 -0
- package/src/renderer/render/media/twitter.ts +7 -1
- package/src/util/info.ts +2 -4
package/package.json
CHANGED
|
@@ -6,11 +6,10 @@ import { firstline, isEmpty } from './line';
|
|
|
6
6
|
export function block<P extends Parser<unknown>>(parser: P, separation?: boolean): P;
|
|
7
7
|
export function block<T>(parser: Parser<T>, separation = true): Parser<T> {
|
|
8
8
|
assert(parser);
|
|
9
|
-
return
|
|
10
|
-
const { source, context } = input;
|
|
9
|
+
return ({ source, context }) => {
|
|
11
10
|
if (source === '') return;
|
|
12
11
|
context.memo ??= new Memo();
|
|
13
|
-
const result = parser(
|
|
12
|
+
const result = parser({ source, context });
|
|
14
13
|
if (!result) return;
|
|
15
14
|
const rest = exec(result);
|
|
16
15
|
if (separation && !isEmpty(firstline(rest))) return;
|
|
@@ -24,11 +24,10 @@ export function validate<T>(patterns: string | RegExp | (string | RegExp)[], has
|
|
|
24
24
|
? `|| source.slice(0, ${pattern.length}) === '${pattern}'`
|
|
25
25
|
: `|| /${pattern.source}/${pattern.flags}.test(source)`),
|
|
26
26
|
].join(''))();
|
|
27
|
-
return
|
|
28
|
-
const { source } = input;
|
|
27
|
+
return ({ source, context }) => {
|
|
29
28
|
if (source === '') return;
|
|
30
29
|
if (!match(source)) return;
|
|
31
|
-
const result = parser!(
|
|
30
|
+
const result = parser!({ source, context });
|
|
32
31
|
assert(check(source, result));
|
|
33
32
|
if (!result) return;
|
|
34
33
|
assert(exec(result).length < source.length);
|
|
@@ -41,13 +40,12 @@ export function validate<T>(patterns: string | RegExp | (string | RegExp)[], has
|
|
|
41
40
|
export function verify<P extends Parser<unknown>>(parser: P, cond: (results: readonly Tree<P>[], rest: string, context: Context<P>) => boolean): P;
|
|
42
41
|
export function verify<T>(parser: Parser<T>, cond: (results: readonly T[], rest: string, context: Ctx) => boolean): Parser<T> {
|
|
43
42
|
assert(parser);
|
|
44
|
-
return
|
|
45
|
-
const { source } = input;
|
|
43
|
+
return ({ source, context }) => {
|
|
46
44
|
if (source === '') return;
|
|
47
|
-
const result = parser(
|
|
45
|
+
const result = parser({ source, context });
|
|
48
46
|
assert(check(source, result));
|
|
49
47
|
if (!result) return;
|
|
50
|
-
if (!cond(eval(result), exec(result),
|
|
48
|
+
if (!cond(eval(result), exec(result), context)) return;
|
|
51
49
|
assert(exec(result).length < source.length);
|
|
52
50
|
return exec(result).length < source.length
|
|
53
51
|
? result
|
|
@@ -5,8 +5,7 @@ import { Memo } from '../../data/parser/context/memo';
|
|
|
5
5
|
export function line<P extends Parser<unknown>>(parser: P): P;
|
|
6
6
|
export function line<T>(parser: Parser<T>): Parser<T> {
|
|
7
7
|
assert(parser);
|
|
8
|
-
return
|
|
9
|
-
const { source, context } = input;
|
|
8
|
+
return ({ source, context }) => {
|
|
10
9
|
if (source === '') return;
|
|
11
10
|
context.memo ??= new Memo();
|
|
12
11
|
const line = firstline(source);
|
|
@@ -3,8 +3,7 @@ import { Parser, check } from '../../data/parser';
|
|
|
3
3
|
export function convert<P extends Parser<unknown>>(conv: (source: string) => string, parser: P): P;
|
|
4
4
|
export function convert<T>(conv: (source: string) => string, parser: Parser<T>): Parser<T> {
|
|
5
5
|
assert(parser);
|
|
6
|
-
return
|
|
7
|
-
const { source, context } = input;
|
|
6
|
+
return ({ source, context }) => {
|
|
8
7
|
if (source === '') return;
|
|
9
8
|
const src = conv(source);
|
|
10
9
|
if (src === '') return [[], ''];
|
|
@@ -3,8 +3,7 @@ import { firstline, isEmpty } from '../constraint/line';
|
|
|
3
3
|
import { unshift } from 'spica/array';
|
|
4
4
|
|
|
5
5
|
export function fence<C extends Ctx, D extends Parser<unknown, C>[]>(opener: RegExp, limit: number, separation = true): Parser<string, C, D> {
|
|
6
|
-
return
|
|
7
|
-
const { source } = input;
|
|
6
|
+
return ({ source }) => {
|
|
8
7
|
if (source === '') return;
|
|
9
8
|
const matches = source.match(opener);
|
|
10
9
|
if (!matches) return;
|
|
@@ -4,13 +4,12 @@ import { Parser, exec, check } from '../../data/parser';
|
|
|
4
4
|
export function match<P extends Parser<unknown>>(pattern: RegExp, f: (matched: RegExpMatchArray) => P): P;
|
|
5
5
|
export function match<T>(pattern: RegExp, f: (matched: RegExpMatchArray) => Parser<T>): Parser<T> {
|
|
6
6
|
assert(!pattern.flags.match(/[gmy]/) && pattern.source.startsWith('^'));
|
|
7
|
-
return
|
|
8
|
-
const { source } = input;
|
|
7
|
+
return ({ source, context }) => {
|
|
9
8
|
if (source === '') return;
|
|
10
9
|
const param = source.match(pattern);
|
|
11
10
|
if (!param) return;
|
|
12
11
|
assert(source.startsWith(param[0]));
|
|
13
|
-
const result = f(param)(
|
|
12
|
+
const result = f(param)({ source, context });
|
|
14
13
|
assert(check(source, result, false));
|
|
15
14
|
if (!result) return;
|
|
16
15
|
return exec(result).length < source.length && exec(result).length <= source.length
|
|
@@ -8,8 +8,7 @@ export function focus<T>(scope: string | RegExp, parser: Parser<T>): Parser<T> {
|
|
|
8
8
|
const match: (source: string) => string = typeof scope === 'string'
|
|
9
9
|
? source => source.slice(0, scope.length) === scope ? scope : ''
|
|
10
10
|
: source => source.match(scope)?.[0] ?? '';
|
|
11
|
-
return
|
|
12
|
-
const { source, context } = input;
|
|
11
|
+
return ({ source, context }) => {
|
|
13
12
|
if (source === '') return;
|
|
14
13
|
const src = match(source);
|
|
15
14
|
assert(source.startsWith(src));
|
|
@@ -32,12 +31,11 @@ export function rewrite<P extends Parser<unknown>>(scope: Parser<unknown, Contex
|
|
|
32
31
|
export function rewrite<T>(scope: Parser<unknown>, parser: Parser<T>): Parser<T> {
|
|
33
32
|
assert(scope);
|
|
34
33
|
assert(parser);
|
|
35
|
-
return
|
|
36
|
-
const { source, context } = input;
|
|
34
|
+
return ({ source, context }) => {
|
|
37
35
|
if (source === '') return;
|
|
38
36
|
const memo = context.memo;
|
|
39
37
|
context.memo = undefined;
|
|
40
|
-
const res1 = scope(
|
|
38
|
+
const res1 = scope({ source, context });
|
|
41
39
|
assert(check(source, res1));
|
|
42
40
|
context.memo = memo;
|
|
43
41
|
if (!res1 || exec(res1).length >= source.length) return;
|
|
@@ -38,8 +38,8 @@ export function surround<T>(
|
|
|
38
38
|
case 'object':
|
|
39
39
|
return surround(opener, parser, match(closer), optional, f, g);
|
|
40
40
|
}
|
|
41
|
-
return
|
|
42
|
-
const
|
|
41
|
+
return ({ source, context }) => {
|
|
42
|
+
const lmr_ = source;
|
|
43
43
|
if (lmr_ === '') return;
|
|
44
44
|
const res1 = opener({ source: lmr_, context });
|
|
45
45
|
assert(check(lmr_, res1, false));
|
|
@@ -7,10 +7,9 @@ export function bind<T, P extends Parser<unknown>>(parser: Parser<T, Context<P>,
|
|
|
7
7
|
export function bind<U, P extends Parser<unknown>>(parser: P, f: (nodes: Tree<P>[], rest: string, context: Context<P>) => Result<U, Context<P>, SubParsers<P>>): Parser<U, Context<P>, SubParsers<P>>;
|
|
8
8
|
export function bind<T, U>(parser: Parser<T>, f: (nodes: T[], rest: string, context: Ctx) => Result<U>): Parser<U> {
|
|
9
9
|
assert(parser);
|
|
10
|
-
return
|
|
11
|
-
const { source, context } = input;
|
|
10
|
+
return ({ source, context }) => {
|
|
12
11
|
if (source === '') return;
|
|
13
|
-
const res1 = parser(
|
|
12
|
+
const res1 = parser({ source, context });
|
|
14
13
|
assert(check(source, res1));
|
|
15
14
|
if (!res1) return;
|
|
16
15
|
const res2 = f(eval(res1), exec(res1), context);
|
|
@@ -58,8 +58,7 @@ function apply<T>(parser: Parser<T>, source: string, context: Ctx, changes: [str
|
|
|
58
58
|
|
|
59
59
|
export function syntax<P extends Parser<unknown>>(syntax: number, precedence: number, cost: number, state: number, parser: P): P;
|
|
60
60
|
export function syntax<T>(syntax: number, prec: number, cost: number, state: number, parser?: Parser<T>): Parser<T> {
|
|
61
|
-
return creation(cost, precedence(prec,
|
|
62
|
-
const { source, context } = input;
|
|
61
|
+
return creation(cost, precedence(prec, ({ source, context }) => {
|
|
63
62
|
if (source === '') return;
|
|
64
63
|
const memo = context.memo ??= new Memo();
|
|
65
64
|
context.memorable ??= ~0;
|
|
@@ -72,7 +71,7 @@ export function syntax<T>(syntax: number, prec: number, cost: number, state: num
|
|
|
72
71
|
? cache.length === 0
|
|
73
72
|
? undefined
|
|
74
73
|
: [cache[0], source.slice(cache[1])]
|
|
75
|
-
: parser!(
|
|
74
|
+
: parser!({ source, context });
|
|
76
75
|
if (syntax && st0 & context.memorable!) {
|
|
77
76
|
cache ?? memo.set(position, syntax, st1, eval(result), source.length - exec(result, '').length);
|
|
78
77
|
assert.deepStrictEqual(cache && cache, cache && memo.get(position, syntax, st1));
|
|
@@ -88,16 +87,18 @@ export function syntax<T>(syntax: number, prec: number, cost: number, state: num
|
|
|
88
87
|
|
|
89
88
|
export function creation<P extends Parser<unknown>>(parser: P): P;
|
|
90
89
|
export function creation<P extends Parser<unknown>>(cost: number, parser: P): P;
|
|
91
|
-
export function creation(cost: number
|
|
92
|
-
|
|
90
|
+
export function creation<P extends Parser<unknown>>(cost: number, recursion: boolean, parser: P): P;
|
|
91
|
+
export function creation(cost: number | Parser<unknown>, recursion?: boolean | Parser<unknown>, parser?: Parser<unknown>): Parser<unknown> {
|
|
92
|
+
if (typeof cost === 'function') return creation(1, true, cost);
|
|
93
|
+
if (typeof recursion === 'function') return creation(cost, true, recursion);
|
|
93
94
|
assert(cost > 0);
|
|
94
|
-
return
|
|
95
|
-
const resources =
|
|
95
|
+
return ({ source, context }) => {
|
|
96
|
+
const resources = context.resources ?? { clock: 1, recursion: 1 };
|
|
96
97
|
if (resources.clock <= 0) throw new Error('Too many creations');
|
|
97
98
|
if (resources.recursion <= 0) throw new Error('Too much recursion');
|
|
98
|
-
--resources.recursion;
|
|
99
|
-
const result = parser!(
|
|
100
|
-
++resources.recursion;
|
|
99
|
+
recursion && --resources.recursion;
|
|
100
|
+
const result = parser!({ source, context });
|
|
101
|
+
recursion && ++resources.recursion;
|
|
101
102
|
if (result) {
|
|
102
103
|
resources.clock -= cost;
|
|
103
104
|
}
|
|
@@ -108,11 +109,10 @@ export function creation(cost: number | Parser<unknown>, parser?: Parser<unknown
|
|
|
108
109
|
export function precedence<P extends Parser<unknown>>(precedence: number, parser: P): P;
|
|
109
110
|
export function precedence<T>(precedence: number, parser: Parser<T>): Parser<T> {
|
|
110
111
|
assert(precedence > 0);
|
|
111
|
-
return
|
|
112
|
-
const { context } = input;
|
|
112
|
+
return ({ source, context }) => {
|
|
113
113
|
const p = context.precedence;
|
|
114
114
|
context.precedence = precedence;
|
|
115
|
-
const result = parser(
|
|
115
|
+
const result = parser({ source, context });
|
|
116
116
|
context.precedence = p;
|
|
117
117
|
return result;
|
|
118
118
|
};
|
|
@@ -120,9 +120,9 @@ export function precedence<T>(precedence: number, parser: Parser<T>): Parser<T>
|
|
|
120
120
|
|
|
121
121
|
export function guard<P extends Parser<unknown>>(f: (context: Context<P>) => boolean | number, parser: P): P;
|
|
122
122
|
export function guard<T>(f: (context: Ctx) => boolean | number, parser: Parser<T>): Parser<T> {
|
|
123
|
-
return
|
|
124
|
-
f(
|
|
125
|
-
? parser(
|
|
123
|
+
return ({ source, context }) =>
|
|
124
|
+
f(context)
|
|
125
|
+
? parser({ source, context })
|
|
126
126
|
: undefined;
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -134,13 +134,12 @@ export function constraint<T>(state: number, positive: boolean | Parser<T>, pars
|
|
|
134
134
|
positive = true;
|
|
135
135
|
}
|
|
136
136
|
assert(state);
|
|
137
|
-
return
|
|
138
|
-
const { context } = input;
|
|
137
|
+
return ({ source, context }) => {
|
|
139
138
|
const s = positive
|
|
140
139
|
? state & context.state!
|
|
141
140
|
: state & ~context.state!;
|
|
142
141
|
return s === state
|
|
143
|
-
? parser!(
|
|
142
|
+
? parser!({ source, context })
|
|
144
143
|
: undefined;
|
|
145
144
|
};
|
|
146
145
|
}
|
|
@@ -153,13 +152,12 @@ export function state<T>(state: number, positive: boolean | Parser<T>, parser?:
|
|
|
153
152
|
positive = true;
|
|
154
153
|
}
|
|
155
154
|
assert(state);
|
|
156
|
-
return
|
|
157
|
-
const { context } = input;
|
|
155
|
+
return ({ source, context }) => {
|
|
158
156
|
const s = context.state ?? 0;
|
|
159
157
|
context.state = positive
|
|
160
158
|
? s | state
|
|
161
159
|
: s & ~state;
|
|
162
|
-
const result = parser!(
|
|
160
|
+
const result = parser!({ source, context });
|
|
163
161
|
context.state = s;
|
|
164
162
|
return result;
|
|
165
163
|
};
|
|
@@ -6,8 +6,7 @@ export function inits<P extends Parser<unknown>>(parsers: SubParsers<P>, resume?
|
|
|
6
6
|
export function inits<T, D extends Parser<T>[]>(parsers: D, resume?: (nodes: T[], rest: string) => boolean): Parser<T, Ctx, D> {
|
|
7
7
|
assert(parsers.every(f => f));
|
|
8
8
|
if (parsers.length === 1) return parsers[0];
|
|
9
|
-
return
|
|
10
|
-
const { source, context } = input;
|
|
9
|
+
return ({ source, context }) => {
|
|
11
10
|
let rest = source;
|
|
12
11
|
let nodes: T[] | undefined;
|
|
13
12
|
for (let i = 0, len = parsers.length; i < len; ++i) {
|
|
@@ -6,8 +6,7 @@ export function sequence<P extends Parser<unknown>>(parsers: SubParsers<P>, resu
|
|
|
6
6
|
export function sequence<T, D extends Parser<T>[]>(parsers: D, resume?: (nodes: T[], rest: string) => boolean): Parser<T, Ctx, D> {
|
|
7
7
|
assert(parsers.every(f => f));
|
|
8
8
|
if (parsers.length === 1) return parsers[0];
|
|
9
|
-
return
|
|
10
|
-
const { source, context } = input;
|
|
9
|
+
return ({ source, context }) => {
|
|
11
10
|
let rest = source;
|
|
12
11
|
let nodes: T[] | undefined;
|
|
13
12
|
for (let i = 0, len = parsers.length; i < len; ++i) {
|
|
@@ -16,8 +16,7 @@ export function some<T>(parser: Parser<T>, end?: string | RegExp | number, delim
|
|
|
16
16
|
matcher: Delimiters.matcher(delimiter),
|
|
17
17
|
precedence,
|
|
18
18
|
}));
|
|
19
|
-
return
|
|
20
|
-
const { source, context } = input;
|
|
19
|
+
return ({ source, context }) => {
|
|
21
20
|
if (source === '') return;
|
|
22
21
|
let rest = source;
|
|
23
22
|
let nodes: T[] | undefined;
|
|
@@ -117,23 +117,23 @@ describe('Unit: parser/api/parse', () => {
|
|
|
117
117
|
].join('\n\n'), { host: new URL(`${location.origin}/z`) }).children].map(el => el.outerHTML),
|
|
118
118
|
[
|
|
119
119
|
'<aside class="header"><details open=""><summary>Header</summary><span class="field" data-name="url" data-value="https://source/x/y"><span class="field-name">URL</span>: <span class="field-value">https://source/x/y</span>\n</span></details></aside>',
|
|
120
|
-
'<p><a href="https://source/@a" target="_blank"
|
|
121
|
-
'<p><a href="https://domain/@a" target="_blank"
|
|
122
|
-
'<p><a href="https://source/@a?ch=b" target="_blank"
|
|
123
|
-
'<p><a href="https://domain/@a?ch=b" target="_blank"
|
|
124
|
-
'<p><a href="https://source/hashtags/a" target="_blank"
|
|
125
|
-
'<p><a href="https://domain/hashtags/a" target="_blank"
|
|
120
|
+
'<p><a class="account" href="https://source/@a" target="_blank">@a</a></p>',
|
|
121
|
+
'<p><a class="account" href="https://domain/@a" target="_blank">@domain/a</a></p>',
|
|
122
|
+
'<p><a class="channel" href="https://source/@a?ch=b" target="_blank">@a#b</a></p>',
|
|
123
|
+
'<p><a class="channel" href="https://domain/@a?ch=b" target="_blank">@domain/a#b</a></p>',
|
|
124
|
+
'<p><a class="hashtag" href="https://source/hashtags/a" target="_blank">#a</a></p>',
|
|
125
|
+
'<p><a class="hashtag" href="https://domain/hashtags/a" target="_blank">#domain/a</a></p>',
|
|
126
126
|
'<p><a class="index" href="#index:a">a</a></p>',
|
|
127
127
|
'<figure data-type="math" data-label="$-a" data-group="$" data-number="1" id="label:$-a"><figcaption><span class="figindex">(1)</span><span class="figtext"></span></figcaption><div><div class="math" translate="no">$$\n$$</div></div></figure>',
|
|
128
128
|
'<p><a class="label" data-label="$-a" href="#label:$-a">(1)</a></p>',
|
|
129
129
|
'<p><sup class="annotation" id="annotation:ref:1" title="a"><span hidden="">a</span><a href="#annotation:def:1">*1</a></sup></p>',
|
|
130
|
-
'<p><a href="https://source/x/a" target="_blank">a</a></p>',
|
|
131
|
-
'<p><a href="https://source/a" target="_blank">/a</a></p>',
|
|
132
|
-
'<p><a href="/z/a">^/a</a></p>',
|
|
133
|
-
'<p><a href="https://source/x/a" target="_blank">./a</a></p>',
|
|
134
|
-
'<p><a href="https://source/a" target="_blank">../a</a></p>',
|
|
135
|
-
'<p><a href="https://source/a" target="_blank">../../a</a></p>',
|
|
136
|
-
'<p><a href="//domain/a" target="_blank">//domain/a</a></p>',
|
|
130
|
+
'<p><a class="url" href="https://source/x/a" target="_blank">a</a></p>',
|
|
131
|
+
'<p><a class="url" href="https://source/a" target="_blank">/a</a></p>',
|
|
132
|
+
'<p><a class="url" href="/z/a">^/a</a></p>',
|
|
133
|
+
'<p><a class="url" href="https://source/x/a" target="_blank">./a</a></p>',
|
|
134
|
+
'<p><a class="url" href="https://source/a" target="_blank">../a</a></p>',
|
|
135
|
+
'<p><a class="url" href="https://source/a" target="_blank">../../a</a></p>',
|
|
136
|
+
'<p><a class="url" href="//domain/a" target="_blank">//domain/a</a></p>',
|
|
137
137
|
'<p><a href="https://source/x/a" target="_blank"><img class="media" data-src="https://source/x/a" alt=""></a></p>',
|
|
138
138
|
'<p><a href="/z/a" target="_blank"><img class="media" data-src="/z/a" alt=""></a></p>',
|
|
139
139
|
'<p><a href="https://source/a" target="_blank"><img class="media" data-src="https://source/a" alt=""></a></p>',
|
|
@@ -151,8 +151,8 @@ describe('Unit: parser/api/parse', () => {
|
|
|
151
151
|
].join('\n\n'), { host: new URL(`${location.origin}/index.md`) }).children].map(el => el.outerHTML),
|
|
152
152
|
[
|
|
153
153
|
'<aside class="header"><details open=""><summary>Header</summary><span class="field" data-name="url" data-value="https://source/x/y"><span class="field-name">URL</span>: <span class="field-value">https://source/x/y</span>\n</span></details></aside>',
|
|
154
|
-
'<p><a href="/a">^/a</a></p>',
|
|
155
|
-
'<p><a href="https://source/x/a" target="_blank">./a</a></p>',
|
|
154
|
+
'<p><a class="url" href="/a">^/a</a></p>',
|
|
155
|
+
'<p><a class="url" href="https://source/x/a" target="_blank">./a</a></p>',
|
|
156
156
|
]);
|
|
157
157
|
assert.deepStrictEqual(
|
|
158
158
|
[...parse([
|
|
@@ -166,8 +166,8 @@ describe('Unit: parser/api/parse', () => {
|
|
|
166
166
|
].join('\n\n'), { host: new URL(`${location.origin}/z`) }).children].map(el => el.outerHTML),
|
|
167
167
|
[
|
|
168
168
|
`<aside class="header"><details open=""><summary>Header</summary><span class="field" data-name="url" data-value="${location.origin}/x/y"><span class="field-name">URL</span>: <span class="field-value">${location.origin}/x/y</span>\n</span></details></aside>`,
|
|
169
|
-
'<p><a href="/z/a">^/a</a></p>',
|
|
170
|
-
'<p><a href="/x/a">./a</a></p>',
|
|
169
|
+
'<p><a class="url" href="/z/a">^/a</a></p>',
|
|
170
|
+
'<p><a class="url" href="/x/a">./a</a></p>',
|
|
171
171
|
]);
|
|
172
172
|
});
|
|
173
173
|
|
|
@@ -198,8 +198,8 @@ describe('Unit: parser/api/parse', () => {
|
|
|
198
198
|
[
|
|
199
199
|
`<aside class="header"><details open=""><summary>Header</summary><span class="field" data-name="url" data-value="https://example/x"><span class="field-name">URL</span>: <span class="field-value">https://example/x</span>\n</span></details></aside>`,
|
|
200
200
|
'<pre class="invalid" translate="no" data-invalid-syntax="header" data-invalid-type="syntax" data-invalid-message="Invalid syntax">---\nURL: https://example/y\n---\n</pre>',
|
|
201
|
-
'<aside class="example" data-type="markdown"><pre translate="no">---\nURL: https://example/y\n---\n\n{#}</pre><hr><section><aside class="header"><details open=""><summary>Header</summary><span class="field" data-name="url" data-value="https://example/y"><span class="field-name">URL</span>: <span class="field-value">https://example/y</span>\n</span></details></aside><p><a href="https://example/y#" target="_blank">#</a></p><ol class="references"></ol></section></aside>',
|
|
202
|
-
'<p><a href="https://example/x#" target="_blank">#</a></p>',
|
|
201
|
+
'<aside class="example" data-type="markdown"><pre translate="no">---\nURL: https://example/y\n---\n\n{#}</pre><hr><section><aside class="header"><details open=""><summary>Header</summary><span class="field" data-name="url" data-value="https://example/y"><span class="field-name">URL</span>: <span class="field-value">https://example/y</span>\n</span></details></aside><p><a class="url" href="https://example/y#" target="_blank">#</a></p><ol class="references"></ol></section></aside>',
|
|
202
|
+
'<p><a class="url" href="https://example/x#" target="_blank">#</a></p>',
|
|
203
203
|
]);
|
|
204
204
|
});
|
|
205
205
|
|
|
@@ -7,10 +7,10 @@ describe('Unit: parser/autolink', () => {
|
|
|
7
7
|
const parser = (source: string) => some(autolink)({ source, context: {} });
|
|
8
8
|
|
|
9
9
|
it('basic', () => {
|
|
10
|
-
assert.deepStrictEqual(inspect(parser(' http://host')), [[' ', '<a href="http://host" target="_blank">http://host</a>'], '']);
|
|
11
|
-
assert.deepStrictEqual(inspect(parser('!http://host')), [['!', '<a href="http://host" target="_blank">http://host</a>'], '']);
|
|
12
|
-
assert.deepStrictEqual(inspect(parser('#a')), [['<a href="/hashtags/a"
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('@a#b')), [['<a href="/@a?ch=b"
|
|
10
|
+
assert.deepStrictEqual(inspect(parser(' http://host')), [[' ', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
|
|
11
|
+
assert.deepStrictEqual(inspect(parser('!http://host')), [['!', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
|
|
12
|
+
assert.deepStrictEqual(inspect(parser('#a')), [['<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
|
|
13
|
+
assert.deepStrictEqual(inspect(parser('@a#b')), [['<a class="channel" href="/@a?ch=b">@a#b</a>'], '']);
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('\\\n')), [['\\', '<br>'], '']);
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('a#b')), [['a#b'], '']);
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('0a#b')), [['0a#b'], '']);
|
|
@@ -18,8 +18,8 @@ describe('Unit: parser/autolink', () => {
|
|
|
18
18
|
assert.deepStrictEqual(inspect(parser('あい#b')), [['あ', 'い#b'], '']);
|
|
19
19
|
assert.deepStrictEqual(inspect(parser('0aあ#b')), [['0aあ#b'], '']);
|
|
20
20
|
assert.deepStrictEqual(inspect(parser('0aあい#b')), [['0a', 'あ', 'い#b'], '']);
|
|
21
|
-
assert.deepStrictEqual(inspect(parser('a\n#b')), [['a', '<br>', '<a href="/hashtags/b"
|
|
22
|
-
assert.deepStrictEqual(inspect(parser('a\\\n#b')), [['a', '\\', '<br>', '<a href="/hashtags/b"
|
|
21
|
+
assert.deepStrictEqual(inspect(parser('a\n#b')), [['a', '<br>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser('a\\\n#b')), [['a', '\\', '<br>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
|
|
23
23
|
assert.deepStrictEqual(inspect(parser('0a>>b')), [['0a>>b'], '']);
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -25,13 +25,13 @@ describe('Unit: parser/block/blockquote', () => {
|
|
|
25
25
|
assert.deepStrictEqual(inspect(parser('> a\nb')), [['<blockquote><pre>a<br>b</pre></blockquote>'], '']);
|
|
26
26
|
assert.deepStrictEqual(inspect(parser('> a\n b ')), [['<blockquote><pre>a<br> b </pre></blockquote>'], '']);
|
|
27
27
|
assert.deepStrictEqual(inspect(parser('> a\n>')), [['<blockquote><pre>a<br></pre></blockquote>'], '']);
|
|
28
|
-
assert.deepStrictEqual(inspect(parser('> a\n>>1')), [['<blockquote><pre>a<br><a href="?at=1"
|
|
28
|
+
assert.deepStrictEqual(inspect(parser('> a\n>>1')), [['<blockquote><pre>a<br><a class="anchor" href="?at=1">>>1</a></pre></blockquote>'], '']);
|
|
29
29
|
assert.deepStrictEqual(inspect(parser('> a\n> b ')), [['<blockquote><pre>a<br>b </pre></blockquote>'], '']);
|
|
30
30
|
assert.deepStrictEqual(inspect(parser('> a\n>\n')), [['<blockquote><pre>a<br></pre></blockquote>'], '']);
|
|
31
31
|
assert.deepStrictEqual(inspect(parser('> a\n>\nb')), [['<blockquote><pre>a<br><br>b</pre></blockquote>'], '']);
|
|
32
32
|
assert.deepStrictEqual(inspect(parser('> a\n>\n b ')), [['<blockquote><pre>a<br><br> b </pre></blockquote>'], '']);
|
|
33
33
|
assert.deepStrictEqual(inspect(parser('> a\n>\n>')), [['<blockquote><pre>a<br><br></pre></blockquote>'], '']);
|
|
34
|
-
assert.deepStrictEqual(inspect(parser('> a\n>\n>>1')), [['<blockquote><pre>a<br><br><a href="?at=1"
|
|
34
|
+
assert.deepStrictEqual(inspect(parser('> a\n>\n>>1')), [['<blockquote><pre>a<br><br><a class="anchor" href="?at=1">>>1</a></pre></blockquote>'], '']);
|
|
35
35
|
assert.deepStrictEqual(inspect(parser('> a\n>\n> b ')), [['<blockquote><pre>a<br><br>b </pre></blockquote>'], '']);
|
|
36
36
|
assert.deepStrictEqual(inspect(parser('> a\\\nb')), [['<blockquote><pre>a\\<br>b</pre></blockquote>'], '']);
|
|
37
37
|
assert.deepStrictEqual(inspect(parser('> a ')), [['<blockquote><pre> a </pre></blockquote>'], '']);
|
|
@@ -40,12 +40,12 @@ describe('Unit: parser/block/blockquote', () => {
|
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('>\n a')), [['<blockquote><pre><br> a</pre></blockquote>'], '']);
|
|
41
41
|
assert.deepStrictEqual(inspect(parser('>\n>')), [['<blockquote><pre><br></pre></blockquote>'], '']);
|
|
42
42
|
assert.deepStrictEqual(inspect(parser('>\n> a')), [['<blockquote><pre><br>a</pre></blockquote>'], '']);
|
|
43
|
-
assert.deepStrictEqual(inspect(parser('> http://host')), [['<blockquote><pre><a href="http://host" target="_blank">http://host</a></pre></blockquote>'], '']);
|
|
44
|
-
assert.deepStrictEqual(inspect(parser('> !http://host')), [['<blockquote><pre>!<a href="http://host" target="_blank">http://host</a></pre></blockquote>'], '']);
|
|
45
|
-
assert.deepStrictEqual(inspect(parser('> #a')), [['<blockquote><pre><a href="/hashtags/a"
|
|
46
|
-
assert.deepStrictEqual(inspect(parser('> @a#b')), [['<blockquote><pre><a href="/@a?ch=b"
|
|
47
|
-
assert.deepStrictEqual(inspect(parser('> >>1\n> > b')), [['<blockquote><pre><a href="?at=1"
|
|
48
|
-
assert.deepStrictEqual(inspect(parser('> >>1\n> > b\n> c')), [['<blockquote><pre><a href="?at=1"
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('> http://host')), [['<blockquote><pre><a class="url" href="http://host" target="_blank">http://host</a></pre></blockquote>'], '']);
|
|
44
|
+
assert.deepStrictEqual(inspect(parser('> !http://host')), [['<blockquote><pre>!<a class="url" href="http://host" target="_blank">http://host</a></pre></blockquote>'], '']);
|
|
45
|
+
assert.deepStrictEqual(inspect(parser('> #a')), [['<blockquote><pre><a class="hashtag" href="/hashtags/a">#a</a></pre></blockquote>'], '']);
|
|
46
|
+
assert.deepStrictEqual(inspect(parser('> @a#b')), [['<blockquote><pre><a class="channel" href="/@a?ch=b">@a#b</a></pre></blockquote>'], '']);
|
|
47
|
+
assert.deepStrictEqual(inspect(parser('> >>1\n> > b')), [['<blockquote><pre><a class="anchor" href="?at=1">>>1</a><br>> b</pre></blockquote>'], '']);
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('> >>1\n> > b\n> c')), [['<blockquote><pre><a class="anchor" href="?at=1">>>1</a><br>> b<br>c</pre></blockquote>'], '']);
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
it('nest', () => {
|
|
@@ -19,7 +19,7 @@ const indent = block(open(opener, some(contentline, /^>(?:$|\s)/)), false);
|
|
|
19
19
|
const unindent = (source: string) => source.replace(/(^|\n)>(?:[^\S\n]|(?=>*(?:$|\s)))|\n$/g, '$1');
|
|
20
20
|
|
|
21
21
|
const source: BlockquoteParser.SourceParser = lazy(() => fmap(
|
|
22
|
-
some(creation(union([
|
|
22
|
+
some(creation(1, false, union([
|
|
23
23
|
rewrite(
|
|
24
24
|
indent,
|
|
25
25
|
convert(unindent, source)),
|
|
@@ -30,11 +30,11 @@ const source: BlockquoteParser.SourceParser = lazy(() => fmap(
|
|
|
30
30
|
ns => [html('blockquote', ns)]));
|
|
31
31
|
|
|
32
32
|
const markdown: BlockquoteParser.MarkdownParser = lazy(() => fmap(
|
|
33
|
-
some(creation(union([
|
|
33
|
+
some(creation(1, false, union([
|
|
34
34
|
rewrite(
|
|
35
35
|
indent,
|
|
36
36
|
convert(unindent, markdown)),
|
|
37
|
-
creation(99,
|
|
37
|
+
creation(99, false,
|
|
38
38
|
rewrite(
|
|
39
39
|
some(contentline, opener),
|
|
40
40
|
convert(unindent, ({ source, context }) => {
|
|
@@ -37,10 +37,10 @@ describe('Unit: parser/block/codeblock', () => {
|
|
|
37
37
|
assert.deepStrictEqual(inspect(parser('````\n```\n````')), [['<pre class="text">```</pre>'], '']);
|
|
38
38
|
assert.deepStrictEqual(inspect(parser('````\n```\n\n````')), [['<pre class="text">```<br></pre>'], '']);
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('```\n\n```\n')), [['<pre class="text"></pre>'], '']);
|
|
40
|
-
assert.deepStrictEqual(inspect(parser('```\nhttp://host\n```')), [['<pre class="text"><a href="http://host" target="_blank">http://host</a></pre>'], '']);
|
|
41
|
-
assert.deepStrictEqual(inspect(parser('```\n!http://host\n```')), [['<pre class="text">!<a href="http://host" target="_blank">http://host</a></pre>'], '']);
|
|
42
|
-
assert.deepStrictEqual(inspect(parser('```\n#a\n```')), [['<pre class="text"><a href="/hashtags/a"
|
|
43
|
-
assert.deepStrictEqual(inspect(parser('```\n@a#b\n```')), [['<pre class="text"><a href="/@a?ch=b"
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('```\nhttp://host\n```')), [['<pre class="text"><a class="url" href="http://host" target="_blank">http://host</a></pre>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('```\n!http://host\n```')), [['<pre class="text">!<a class="url" href="http://host" target="_blank">http://host</a></pre>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('```\n#a\n```')), [['<pre class="text"><a class="hashtag" href="/hashtags/a">#a</a></pre>'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('```\n@a#b\n```')), [['<pre class="text"><a class="channel" href="/@a?ch=b">@a#b</a></pre>'], '']);
|
|
44
44
|
assert.deepStrictEqual(inspect(parser(`\`\`\`\n0${'\n'.repeat(300)}\`\`\``), '>'), [['<pre class="text">'], '']);
|
|
45
45
|
});
|
|
46
46
|
|
|
@@ -66,7 +66,7 @@ describe('Unit: parser/block/dlist', () => {
|
|
|
66
66
|
|
|
67
67
|
it('index', () => {
|
|
68
68
|
assert.deepStrictEqual(inspect(parser('~ a [#b]')), [['<dl><dt id="index:b">a<span class="indexer" data-index="b"></span></dt><dd></dd></dl>'], '']);
|
|
69
|
-
assert.deepStrictEqual(inspect(parser('~ a [#b]\\')), [['<dl><dt id="index:a_[#b]">a [<a href="/hashtags/b"
|
|
69
|
+
assert.deepStrictEqual(inspect(parser('~ a [#b]\\')), [['<dl><dt id="index:a_[#b]">a [<a class="hashtag" href="/hashtags/b">#b</a>]</dt><dd></dd></dl>'], '']);
|
|
70
70
|
assert.deepStrictEqual(inspect(parser('~ A')), [['<dl><dt id="index:A">A</dt><dd></dd></dl>'], '']);
|
|
71
71
|
assert.deepStrictEqual(inspect(parser('~ *A*')), [['<dl><dt id="index:A"><em>A</em></dt><dd></dd></dl>'], '']);
|
|
72
72
|
assert.deepStrictEqual(inspect(parser('~ `A`')), [['<dl><dt id="index:`A`"><code data-src="`A`">A</code></dt><dd></dd></dl>'], '']);
|
|
@@ -17,13 +17,13 @@ export const dlist: DListParser = lazy(() => block(localize(fmap(validate(
|
|
|
17
17
|
]))),
|
|
18
18
|
es => [html('dl', fillTrailingDescription(es))]))));
|
|
19
19
|
|
|
20
|
-
const term: DListParser.TermParser = creation(line(indexee(fmap(open(
|
|
20
|
+
const term: DListParser.TermParser = creation(1, false, line(indexee(fmap(open(
|
|
21
21
|
/^~[^\S\n]+(?=\S)/,
|
|
22
22
|
visualize(trimBlank(some(union([indexer, inline])))),
|
|
23
23
|
true),
|
|
24
24
|
ns => [html('dt', defrag(ns))]))));
|
|
25
25
|
|
|
26
|
-
const desc: DListParser.DescriptionParser = creation(block(fmap(open(
|
|
26
|
+
const desc: DListParser.DescriptionParser = creation(1, false, block(fmap(open(
|
|
27
27
|
/^:[^\S\n]+(?=\S)|/,
|
|
28
28
|
rewrite(
|
|
29
29
|
some(anyline, /^[~:][^\S\n]+\S/),
|
|
@@ -43,7 +43,7 @@ describe('Unit: parser/block/extension/figure', () => {
|
|
|
43
43
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
44
44
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n\\\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext">\\</span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
46
|
-
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n!https://caption\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext">!<a href="https://caption" target="_blank">https://caption</a></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
46
|
+
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n!https://caption\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext">!<a class="url" href="https://caption" target="_blank">https://caption</a></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
|
|
47
47
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n- a\n~~~')), [['<figure data-type="list" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><ul><li>a</li></ul></div></figure>'], '']);
|
|
48
48
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n1. a\n~~~')), [['<figure data-type="list" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><ol><li>a</li></ol></div></figure>'], '']);
|
|
49
49
|
assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n|\n|-\n|\n~~~')), [['<figure data-type="table" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><table><thead><tr></tr></thead><tbody><tr></tr></tbody></table></div></figure>'], '']);
|
|
@@ -79,7 +79,7 @@ const align: AlignParser = line(fmap(
|
|
|
79
79
|
|
|
80
80
|
const delimiter = /^[-=<>]+(?:\/[-=^v]*)?(?=[^\S\n]*\n)|^[#:](?:(?!:\D|0)\d*:(?!0)\d*)?!*(?=\s)/;
|
|
81
81
|
|
|
82
|
-
const head: CellParser.HeadParser = creation(block(fmap(open(
|
|
82
|
+
const head: CellParser.HeadParser = creation(1, false, block(fmap(open(
|
|
83
83
|
str(/^#(?:(?!:\D|0)\d*:(?!0)\d*)?!*(?=\s)/),
|
|
84
84
|
rewrite(
|
|
85
85
|
inits([
|
|
@@ -91,7 +91,7 @@ const head: CellParser.HeadParser = creation(block(fmap(open(
|
|
|
91
91
|
ns => [html('th', attributes(ns.shift()! as string), defrag(ns))]),
|
|
92
92
|
false));
|
|
93
93
|
|
|
94
|
-
const data: CellParser.DataParser = creation(block(fmap(open(
|
|
94
|
+
const data: CellParser.DataParser = creation(1, false, block(fmap(open(
|
|
95
95
|
str(/^:(?:(?!:\D|0)\d*:(?!0)\d*)?!*(?=\s)/),
|
|
96
96
|
rewrite(
|
|
97
97
|
inits([
|
|
@@ -103,7 +103,7 @@ const data: CellParser.DataParser = creation(block(fmap(open(
|
|
|
103
103
|
ns => [html('td', attributes(ns.shift()! as string), defrag(ns))]),
|
|
104
104
|
false));
|
|
105
105
|
|
|
106
|
-
const dataline: CellParser.DatalineParser = creation(line(
|
|
106
|
+
const dataline: CellParser.DatalineParser = creation(1, false, line(
|
|
107
107
|
rewrite(
|
|
108
108
|
contentline,
|
|
109
109
|
union([
|
|
@@ -43,11 +43,11 @@ describe('Unit: parser/block/heading', () => {
|
|
|
43
43
|
assert.deepStrictEqual(inspect(parser('# \\ a')), [['<h1 id="index:a">a</h1>'], '']);
|
|
44
44
|
assert.deepStrictEqual(inspect(parser('## \\')), [['<h2 id="index:\\">\\</h2>'], '']);
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('# @a')), [['<h1 id="index:@a">@a</h1>'], '']);
|
|
46
|
-
assert.deepStrictEqual(inspect(parser('## @a')), [['<h2 id="index:@a"><a
|
|
46
|
+
assert.deepStrictEqual(inspect(parser('## @a')), [['<h2 id="index:@a"><a class="account" href="/@a">@a</a></h2>'], '']);
|
|
47
47
|
assert.deepStrictEqual(inspect(parser('# http://host')), [['<h1 id="index:http://host">http://host</h1>'], '']);
|
|
48
|
-
assert.deepStrictEqual(inspect(parser('## http://host')), [['<h2 id="index:http://host"><a href="http://host" target="_blank">http://host</a></h2>'], '']);
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('## http://host')), [['<h2 id="index:http://host"><a class="url" href="http://host" target="_blank">http://host</a></h2>'], '']);
|
|
49
49
|
assert.deepStrictEqual(inspect(parser('# !http://host')), [['<h1 id="index:!http://host">!http://host</h1>'], '']);
|
|
50
|
-
assert.deepStrictEqual(inspect(parser('## !http://host')), [['<h2 id="index:!http://host">!<a href="http://host" target="_blank">http://host</a></h2>'], '']);
|
|
50
|
+
assert.deepStrictEqual(inspect(parser('## !http://host')), [['<h2 id="index:!http://host">!<a class="url" href="http://host" target="_blank">http://host</a></h2>'], '']);
|
|
51
51
|
assert.deepStrictEqual(inspect(parser('# a((b))')), [['<h1 id="index:a((b))">a<span class="paren">((b))</span></h1>'], '']);
|
|
52
52
|
assert.deepStrictEqual(inspect(parser('## a((b))')), [['<h2 id="index:a((b))">a<span class="paren">((b))</span></h2>'], '']);
|
|
53
53
|
assert.deepStrictEqual(inspect(parser('# a[[b]]')), [['<h1 id="index:a[[b]]">a[[b]]</h1>'], '']);
|
|
@@ -79,8 +79,8 @@ describe('Unit: parser/block/heading', () => {
|
|
|
79
79
|
assert.deepStrictEqual(inspect(parser('# a [#b] [#c]')), [['<h1 id="index:c">a [#b]<span class="indexer" data-index="c"></span></h1>'], '']);
|
|
80
80
|
assert.deepStrictEqual(inspect(parser('# a [#b] \n')), [['<h1 id="index:b">a<span class="indexer" data-index="b"></span></h1>'], '']);
|
|
81
81
|
assert.deepStrictEqual(inspect(parser('# a \\[#b]')), [['<h1 id="index:a_[#b]">a [#b]</h1>'], '']);
|
|
82
|
-
assert.deepStrictEqual(inspect(parser('## a [#b] [#c]')), [['<h2 id="index:c">a [<a href="/hashtags/b"
|
|
83
|
-
assert.deepStrictEqual(inspect(parser('## a [#b ] [#c ]')), [['<h2 id="index:c">a [<a href="/hashtags/b"
|
|
82
|
+
assert.deepStrictEqual(inspect(parser('## a [#b] [#c]')), [['<h2 id="index:c">a [<a class="hashtag" href="/hashtags/b">#b</a>]<span class="indexer" data-index="c"></span></h2>'], '']);
|
|
83
|
+
assert.deepStrictEqual(inspect(parser('## a [#b ] [#c ]')), [['<h2 id="index:c">a [<a class="hashtag" href="/hashtags/b">#b</a> ]<span class="indexer" data-index="c"></span></h2>'], '']);
|
|
84
84
|
});
|
|
85
85
|
|
|
86
86
|
});
|
|
@@ -13,7 +13,7 @@ export const ilist: IListParser = lazy(() => block(validate(
|
|
|
13
13
|
|
|
14
14
|
export const ilist_: IListParser = lazy(() => block(fmap(validate(
|
|
15
15
|
/^[-+*](?:$|\s)/,
|
|
16
|
-
some(creation(union([
|
|
16
|
+
some(creation(1, false, union([
|
|
17
17
|
fmap(fallback(
|
|
18
18
|
inits([
|
|
19
19
|
line(open(/^[-+*](?:$|\s)/, some(inline), true)),
|