securemark 0.233.3 → 0.234.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/dist/securemark.js +69 -46
- package/markdown.d.ts +8 -3
- package/package-lock.json +20 -20
- package/package.json +1 -1
- package/src/combinator/data/parser.ts +2 -1
- package/src/parser/api/parse.test.ts +2 -2
- package/src/parser/block/paragraph.test.ts +15 -7
- package/src/parser/block/reply/cite.test.ts +2 -2
- package/src/parser/block/reply/cite.ts +7 -2
- package/src/parser/block/reply.ts +10 -4
- package/src/parser/inline/autolink/anchor.test.ts +4 -3
- package/src/parser/inline/autolink/anchor.ts +16 -2
- package/src/parser/inline/comment.test.ts +37 -38
- package/src/parser/inline/comment.ts +12 -12
- package/src/parser/inline/emphasis.test.ts +9 -4
- package/src/parser/inline/emphasis.ts +7 -3
- package/src/parser/inline/emstrong.ts +34 -17
- package/src/parser/inline/extension/index.test.ts +4 -4
- package/src/parser/inline/extension/placeholder.test.ts +4 -4
- package/src/parser/inline/htmlentity.test.ts +1 -0
- package/src/parser/inline/htmlentity.ts +1 -1
- package/src/parser/inline/mark.test.ts +8 -4
- package/src/parser/inline/mark.ts +6 -3
- package/src/parser/inline/math.ts +8 -11
- package/src/parser/inline/strong.test.ts +8 -5
- package/src/parser/inline/strong.ts +6 -4
- package/src/parser/inline.test.ts +49 -2
- package/src/parser/util.ts +6 -3
|
@@ -3,13 +3,27 @@ import { union, validate, focus, context, convert, fmap, lazy } from '../../../c
|
|
|
3
3
|
import { link } from '../link';
|
|
4
4
|
import { define } from 'typed-dom';
|
|
5
5
|
|
|
6
|
+
// Timeline(pseudonym): user/tid
|
|
7
|
+
// Thread(anonymous): cid
|
|
8
|
+
|
|
9
|
+
// tid: YYYY-MM-DD-HH-MM-SS-TMZ
|
|
10
|
+
// cid: YYYY-MM-DD-HH-MM-SS-mmm-TMZ
|
|
11
|
+
|
|
12
|
+
// 内部表現はUnixTimeに統一する(時系列順)
|
|
13
|
+
// 外部表現は投稿ごとに投稿者の投稿時のタイムゾーンに統一する(非時系列順)
|
|
14
|
+
|
|
6
15
|
export const anchor: AutolinkParser.AnchorParser = lazy(() => validate('>>', fmap(focus(
|
|
7
|
-
/^>>[0-
|
|
16
|
+
/^>>(?:[A-Za-z][0-9A-Za-z]*(?:-[0-9A-Za-z]+)*\/)?[0-9A-Za-z]+(?:-[0-9A-Za-z]+)*(?![0-9A-Za-z@#:])/,
|
|
8
17
|
context({ syntax: { inline: {
|
|
9
18
|
link: true,
|
|
10
19
|
autolink: false,
|
|
11
20
|
}}},
|
|
12
21
|
convert(
|
|
13
|
-
source =>
|
|
22
|
+
source =>
|
|
23
|
+
`[${source}]{ ${
|
|
24
|
+
source.includes('/')
|
|
25
|
+
? `/@${source.slice(2).replace('/', '/timeline/')}`
|
|
26
|
+
: `?at=${source.slice(2)}`
|
|
27
|
+
} }`,
|
|
14
28
|
union([link])))),
|
|
15
29
|
([el]) => [define(el, { class: 'anchor' })])));
|
|
@@ -13,50 +13,49 @@ describe('Unit: parser/inline/comment', () => {
|
|
|
13
13
|
assert.deepStrictEqual(inspect(parser('[#[#')), undefined);
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('[#a#]')), undefined);
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('[#a b#]')), undefined);
|
|
16
|
-
assert.deepStrictEqual(inspect(parser('[# ')), [['[
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('[# \n a')), [['[
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('[# ')), [['[#'], '']);
|
|
17
|
+
assert.deepStrictEqual(inspect(parser('[# \n a')), [['[#', '<br>', ' ', 'a'], '']);
|
|
18
18
|
assert.deepStrictEqual(inspect(parser('[##]')), undefined);
|
|
19
|
-
assert.deepStrictEqual(inspect(parser('[# #
|
|
20
|
-
assert.deepStrictEqual(inspect(parser('[# #
|
|
21
|
-
assert.deepStrictEqual(inspect(parser('[# [#')), [['[', '
|
|
22
|
-
assert.deepStrictEqual(inspect(parser('[# [# ')), [['[', '
|
|
23
|
-
assert.deepStrictEqual(inspect(parser('[# [#
|
|
24
|
-
assert.deepStrictEqual(inspect(parser('[#
|
|
25
|
-
assert.deepStrictEqual(inspect(parser('[# a[#')), [['[
|
|
26
|
-
assert.deepStrictEqual(inspect(parser('[# a [#')), [['[
|
|
27
|
-
assert.deepStrictEqual(inspect(parser('[# a [
|
|
28
|
-
assert.deepStrictEqual(inspect(parser('[
|
|
29
|
-
assert.deepStrictEqual(inspect(parser('[# a [## b')), [['[', '#', ' ', 'a', ' ', '[', '#', '#', ' ', 'b'], '']);
|
|
30
|
-
assert.deepStrictEqual(inspect(parser('[## a [# b')), [['[', '#', '#', ' ', 'a', ' ', '[', '#', ' ', 'b'], '']);
|
|
19
|
+
assert.deepStrictEqual(inspect(parser('[# [#')), [['[#', ' ', '[', '#'], '']);
|
|
20
|
+
assert.deepStrictEqual(inspect(parser('[# [# ')), [['[#', ' ', '[#'], '']);
|
|
21
|
+
assert.deepStrictEqual(inspect(parser('[# [# a')), [['[#', ' ', '[#', ' ', 'a'], '']);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser('[# [# a #]')), [['[#', ' ', '<span class="comment"><input type="checkbox"><span>[# a #]</span></span>'], '']);
|
|
23
|
+
assert.deepStrictEqual(inspect(parser('[# a[#')), [['[#', ' ', 'a', '[', '#'], '']);
|
|
24
|
+
assert.deepStrictEqual(inspect(parser('[# a [#')), [['[#', ' ', 'a', ' ', '[', '#'], '']);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser('[# a [# ')), [['[#', ' ', 'a', ' ', '[#'], '']);
|
|
26
|
+
assert.deepStrictEqual(inspect(parser('[# a [# b')), [['[#', ' ', 'a', ' ', '[#', ' ', 'b'], '']);
|
|
27
|
+
assert.deepStrictEqual(inspect(parser('[# a [## b')), [['[#', ' ', 'a', ' ', '[##', ' ', 'b'], '']);
|
|
28
|
+
assert.deepStrictEqual(inspect(parser('[## a [# b')), [['[##', ' ', 'a', ' ', '[#', ' ', 'b'], '']);
|
|
31
29
|
assert.deepStrictEqual(inspect(parser('[#\\ a #]')), undefined);
|
|
32
|
-
assert.deepStrictEqual(inspect(parser('[# a\\ #]')), [['[
|
|
33
|
-
assert.deepStrictEqual(inspect(parser('[# a#]')), [['[
|
|
34
|
-
assert.deepStrictEqual(inspect(parser('[# a ##]')), [['[
|
|
35
|
-
assert.deepStrictEqual(inspect(parser('[# [## #]')), [['[
|
|
36
|
-
assert.deepStrictEqual(inspect(parser('[## [# ##]')), [['[', '
|
|
37
|
-
assert.deepStrictEqual(inspect(parser('[## a #]')), [['[', '
|
|
30
|
+
assert.deepStrictEqual(inspect(parser('[# a\\ #]')), [['[#', ' ', 'a', ' ', '#', ']'], '']);
|
|
31
|
+
assert.deepStrictEqual(inspect(parser('[# a#]')), [['[#', ' ', 'a#', ']'], '']);
|
|
32
|
+
assert.deepStrictEqual(inspect(parser('[# a ##]')), [['[#', ' ', 'a', ' ', '##', ']'], '']);
|
|
33
|
+
assert.deepStrictEqual(inspect(parser('[# [## #]')), [['[#', ' ', '[##', ' ', '#', ']'], '']);
|
|
34
|
+
assert.deepStrictEqual(inspect(parser('[## [# ##]')), [['[##', ' ', '[#', ' ', '##', ']'], '']);
|
|
35
|
+
assert.deepStrictEqual(inspect(parser('[## a #]')), [['[##', ' ', 'a', ' ', '#', ']'], '']);
|
|
38
36
|
assert.deepStrictEqual(inspect(parser(' [# a #]')), undefined);
|
|
39
37
|
});
|
|
40
38
|
|
|
41
39
|
it('basic', () => {
|
|
42
|
-
assert.deepStrictEqual(inspect(parser('[#
|
|
43
|
-
assert.deepStrictEqual(inspect(parser('[#
|
|
44
|
-
assert.deepStrictEqual(inspect(parser('[#
|
|
45
|
-
assert.deepStrictEqual(inspect(parser('[# a
|
|
46
|
-
assert.deepStrictEqual(inspect(parser('[# a
|
|
47
|
-
assert.deepStrictEqual(inspect(parser('[# a #]
|
|
48
|
-
assert.deepStrictEqual(inspect(parser('[#
|
|
49
|
-
assert.deepStrictEqual(inspect(parser('[#
|
|
50
|
-
assert.deepStrictEqual(inspect(parser('[# [
|
|
51
|
-
assert.deepStrictEqual(inspect(parser('[## a ##]')), [['<span class="comment">[## a ##]</span>'], '']);
|
|
52
|
-
assert.deepStrictEqual(inspect(parser('[##
|
|
53
|
-
assert.deepStrictEqual(inspect(parser('[##
|
|
54
|
-
assert.deepStrictEqual(inspect(parser('[# a #]
|
|
55
|
-
assert.deepStrictEqual(inspect(parser('[
|
|
56
|
-
assert.deepStrictEqual(inspect(parser('[#
|
|
57
|
-
assert.deepStrictEqual(inspect(parser('[# &
|
|
58
|
-
assert.deepStrictEqual(inspect(parser('[# &
|
|
59
|
-
assert.deepStrictEqual(inspect(parser('[#
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('[# #]')), [['<span class="comment"><input type="checkbox"><span>[# #]</span></span>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('[# #]')), [['<span class="comment"><input type="checkbox"><span>[# #]</span></span>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('[# #]')), [['<span class="comment"><input type="checkbox"><span>[# #]</span></span>'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('[# a #]')), [['<span class="comment"><input type="checkbox"><span>[# a #]</span></span>'], '']);
|
|
44
|
+
assert.deepStrictEqual(inspect(parser('[# a b #]')), [['<span class="comment"><input type="checkbox"><span>[# a b #]</span></span>'], '']);
|
|
45
|
+
assert.deepStrictEqual(inspect(parser('[# a\nb #]')), [['<span class="comment"><input type="checkbox"><span>[# a<br>b #]</span></span>'], '']);
|
|
46
|
+
assert.deepStrictEqual(inspect(parser('[# a #] #]')), [['<span class="comment"><input type="checkbox"><span>[# a #]</span></span>'], ' #]']);
|
|
47
|
+
assert.deepStrictEqual(inspect(parser('[# ##] #]')), [['<span class="comment"><input type="checkbox"><span>[# ##] #]</span></span>'], '']);
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('[# [# a #] #]')), [['<span class="comment"><input type="checkbox"><span>[# <span class="comment"><input type="checkbox"><span>[# a #]</span></span> #]</span></span>'], '']);
|
|
49
|
+
assert.deepStrictEqual(inspect(parser('[# [## a ##] #]')), [['<span class="comment"><input type="checkbox"><span>[# <span class="comment"><input type="checkbox"><span>[## a ##]</span></span> #]</span></span>'], '']);
|
|
50
|
+
assert.deepStrictEqual(inspect(parser('[## a ##]')), [['<span class="comment"><input type="checkbox"><span>[## a ##]</span></span>'], '']);
|
|
51
|
+
assert.deepStrictEqual(inspect(parser('[## #] ##]')), [['<span class="comment"><input type="checkbox"><span>[## #] ##]</span></span>'], '']);
|
|
52
|
+
assert.deepStrictEqual(inspect(parser('[## [# a #] ##]')), [['<span class="comment"><input type="checkbox"><span>[## <span class="comment"><input type="checkbox"><span>[# a #]</span></span> ##]</span></span>'], '']);
|
|
53
|
+
assert.deepStrictEqual(inspect(parser('[# a #]b')), [['<span class="comment"><input type="checkbox"><span>[# a #]</span></span>'], 'b']);
|
|
54
|
+
assert.deepStrictEqual(inspect(parser('[#\na\n#]')), [['<span class="comment"><input type="checkbox"><span>[#<br>a<br>#]</span></span>'], '']);
|
|
55
|
+
assert.deepStrictEqual(inspect(parser('[# &a; #]')), [['<span class="comment"><input type="checkbox"><span>[# <span class="invalid">&a;</span> #]</span></span>'], '']);
|
|
56
|
+
assert.deepStrictEqual(inspect(parser('[# © #]')), [['<span class="comment"><input type="checkbox"><span>[# © #]</span></span>'], '']);
|
|
57
|
+
assert.deepStrictEqual(inspect(parser('[# &copy; #]')), [['<span class="comment"><input type="checkbox"><span>[# &copy; #]</span></span>'], '']);
|
|
58
|
+
assert.deepStrictEqual(inspect(parser('[# \\ a #]')), [['<span class="comment"><input type="checkbox"><span>[# a #]</span></span>'], '']);
|
|
60
59
|
});
|
|
61
60
|
|
|
62
61
|
});
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { CommentParser } from '../inline';
|
|
2
|
-
import {
|
|
3
|
-
import { union, some, validate, creator, surround, match, lazy } from '../../combinator';
|
|
2
|
+
import { union, some, validate, creator, surround, open, close, match, lazy } from '../../combinator';
|
|
4
3
|
import { inline } from '../inline';
|
|
5
4
|
import { text, str } from '../source';
|
|
6
5
|
import { html, defrag } from 'typed-dom';
|
|
7
6
|
import { memoize } from 'spica/memoize';
|
|
8
|
-
import { unshift, push
|
|
7
|
+
import { unshift, push } from 'spica/array';
|
|
9
8
|
|
|
10
9
|
export const comment: CommentParser = lazy(() => creator(validate('[#', match(
|
|
11
10
|
/^(?=\[(#+)\s)/,
|
|
12
11
|
memoize(
|
|
13
|
-
([, fence]
|
|
12
|
+
([, fence]) =>
|
|
14
13
|
surround(
|
|
15
|
-
str(
|
|
16
|
-
union([some(inline,
|
|
17
|
-
str(
|
|
18
|
-
([, bs = []], rest) => [[
|
|
19
|
-
html('span',
|
|
20
|
-
{
|
|
21
|
-
defrag(push(unshift(
|
|
14
|
+
open(str(`[${fence}`), some(text, new RegExp(String.raw`^\s+${fence}\]|^\S`)), true),
|
|
15
|
+
union([some(inline, new RegExp(String.raw`^\s+${fence}\]`))]),
|
|
16
|
+
close(some(text, /^\S/), str(`${fence}]`)), true,
|
|
17
|
+
([as, bs = [], cs], rest) => [[
|
|
18
|
+
html('span', { class: 'comment' }, [
|
|
19
|
+
html('input', { type: 'checkbox' }),
|
|
20
|
+
html('span', defrag(push(unshift(as, bs), cs))),
|
|
21
|
+
]),
|
|
22
22
|
], rest],
|
|
23
|
-
([as, bs = []], rest
|
|
23
|
+
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
24
24
|
([, fence]) => fence)))));
|
|
@@ -9,10 +9,10 @@ describe('Unit: parser/inline/emphasis', () => {
|
|
|
9
9
|
it('invalid', () => {
|
|
10
10
|
assert.deepStrictEqual(inspect(parser('*')), undefined);
|
|
11
11
|
assert.deepStrictEqual(inspect(parser('*a')), [['*', 'a'], '']);
|
|
12
|
-
assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a', ' '
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('*a\n*')), [['*', 'a', '<br>'
|
|
14
|
-
assert.deepStrictEqual(inspect(parser('*a\\ *')), [['*', 'a', ' '
|
|
15
|
-
assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['*', 'a', '<span class="linebreak"> </span>'
|
|
12
|
+
assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a', ' ', '*'], '']);
|
|
13
|
+
assert.deepStrictEqual(inspect(parser('*a\n*')), [['*', 'a', '<br>', '*'], '']);
|
|
14
|
+
assert.deepStrictEqual(inspect(parser('*a\\ *')), [['*', 'a', ' ', '*'], '']);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['*', 'a', '<span class="linebreak"> </span>', '*'], '']);
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('*a**b')), [['*', 'a', '**', 'b'], '']);
|
|
17
17
|
assert.deepStrictEqual(inspect(parser('*a**b*')), [['*', 'a', '**', 'b', '*'], '']);
|
|
18
18
|
assert.deepStrictEqual(inspect(parser('* *')), undefined);
|
|
@@ -37,6 +37,11 @@ describe('Unit: parser/inline/emphasis', () => {
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
it('nest', () => {
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('*a *b**')), [['<em>a <em>b</em></em>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('*a **b***')), [['<em>a <strong>b</strong></em>'], '']);
|
|
42
|
+
assert.deepStrictEqual(inspect(parser('*a\\ *b**')), [['<em>a <em>b</em></em>'], '']);
|
|
43
|
+
assert.deepStrictEqual(inspect(parser('*a	*b**')), [['<em>a\t<em>b</em></em>'], '']);
|
|
44
|
+
assert.deepStrictEqual(inspect(parser('*a<wbr>*b**')), [['<em>a<wbr><em>b</em></em>'], '']);
|
|
40
45
|
assert.deepStrictEqual(inspect(parser('*a**b**c*')), [['<em>a<strong>b</strong>c</em>'], '']);
|
|
41
46
|
assert.deepStrictEqual(inspect(parser('*a**b**c*d')), [['<em>a<strong>b</strong>c</em>'], 'd']);
|
|
42
47
|
assert.deepStrictEqual(inspect(parser('*`a`*')), [['<em><code data-src="`a`">a</code></em>'], '']);
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { EmphasisParser } from '../inline';
|
|
2
|
-
import { union, some, creator, surround, close, lazy } from '../../combinator';
|
|
2
|
+
import { union, some, creator, surround, open, close, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { strong } from './strong';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
-
import { startTight, isEndTightNodes } from '../util';
|
|
6
|
+
import { startTight, isEndTightNodes, delimiter } from '../util';
|
|
7
7
|
import { html, defrag } from 'typed-dom';
|
|
8
8
|
import { unshift } from 'spica/array';
|
|
9
9
|
|
|
10
10
|
export const emphasis: EmphasisParser = lazy(() => creator(surround(close(
|
|
11
11
|
str('*'), /^(?!\*)/),
|
|
12
|
-
startTight(some(union([
|
|
12
|
+
startTight(some(union([
|
|
13
|
+
strong,
|
|
14
|
+
some(inline, delimiter(String.raw`\*`)),
|
|
15
|
+
open(some(inline, '*'), inline),
|
|
16
|
+
]))),
|
|
13
17
|
str('*'), false,
|
|
14
18
|
([as, bs, cs], rest) =>
|
|
15
19
|
isEndTightNodes(bs)
|
|
@@ -1,36 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { MarkdownParser } from '../../../markdown';
|
|
2
|
+
import { EmStrongParser, EmphasisParser, StrongParser } from '../inline';
|
|
3
|
+
import { Result, IntermediateParser } from '../../combinator/data/parser';
|
|
4
|
+
import { union, some, creator, surround, open, lazy, bind } from '../../combinator';
|
|
3
5
|
import { inline } from '../inline';
|
|
6
|
+
import { strong } from './strong';
|
|
4
7
|
import { str } from '../source';
|
|
5
|
-
import { startTight, isEndTightNodes } from '../util';
|
|
8
|
+
import { startTight, isEndTightNodes, delimiter } from '../util';
|
|
6
9
|
import { html, defrag } from 'typed-dom';
|
|
7
10
|
import { unshift } from 'spica/array';
|
|
8
11
|
|
|
12
|
+
const substrong: IntermediateParser<StrongParser> = lazy(() => some(union([
|
|
13
|
+
some(inline, delimiter(String.raw`\*\*`)),
|
|
14
|
+
open(some(inline, '*'), inline),
|
|
15
|
+
])));
|
|
16
|
+
const subemphasis: IntermediateParser<EmphasisParser> = lazy(() => some(union([
|
|
17
|
+
strong,
|
|
18
|
+
some(inline, delimiter(String.raw`\*`)),
|
|
19
|
+
open(some(inline, '*'), inline),
|
|
20
|
+
])));
|
|
21
|
+
|
|
9
22
|
export const emstrong: EmStrongParser = lazy(() => creator(surround(
|
|
10
23
|
str('***'),
|
|
11
|
-
startTight(union([
|
|
24
|
+
startTight(some(union([
|
|
25
|
+
some(inline, delimiter(String.raw`\*`)),
|
|
26
|
+
open(some(inline, '*'), inline),
|
|
27
|
+
]))),
|
|
12
28
|
str(/^\*{1,3}/), false,
|
|
13
|
-
([as, bs, cs], rest, context) => {
|
|
29
|
+
([as, bs, cs], rest, context): Result<HTMLElement | string, MarkdownParser.Context> => {
|
|
30
|
+
assert(cs.length === 1);
|
|
14
31
|
if (!isEndTightNodes(bs)) return [unshift(as, bs), cs[0] + rest];
|
|
15
32
|
switch (cs[0]) {
|
|
16
|
-
case '
|
|
17
|
-
return
|
|
18
|
-
union([some(inline, '**')]),
|
|
19
|
-
(ds, rest) =>
|
|
20
|
-
rest.slice(0, 2) === '**' && isEndTightNodes(ds)
|
|
21
|
-
? [[html('strong', unshift([html('em', defrag(bs))], defrag(ds)))], rest.slice(2)]
|
|
22
|
-
: [unshift(['**', html('em', defrag(bs))], ds), rest])
|
|
23
|
-
(rest, context) ?? [['**', html('em', defrag(bs))], rest];
|
|
33
|
+
case '***':
|
|
34
|
+
return [[html('em', [html('strong', defrag(bs))])], rest];
|
|
24
35
|
case '**':
|
|
25
|
-
return bind<
|
|
26
|
-
|
|
36
|
+
return bind<EmphasisParser>(
|
|
37
|
+
subemphasis,
|
|
27
38
|
(ds, rest) =>
|
|
28
39
|
rest.slice(0, 1) === '*' && isEndTightNodes(ds)
|
|
29
40
|
? [[html('em', unshift([html('strong', defrag(bs))], defrag(ds)))], rest.slice(1)]
|
|
30
41
|
: [unshift(['*', html('strong', defrag(bs))], ds), rest])
|
|
31
42
|
(rest, context) ?? [['*', html('strong', defrag(bs))], rest];
|
|
32
|
-
case '
|
|
33
|
-
return
|
|
43
|
+
case '*':
|
|
44
|
+
return bind<StrongParser>(
|
|
45
|
+
substrong,
|
|
46
|
+
(ds, rest) =>
|
|
47
|
+
rest.slice(0, 2) === '**' && isEndTightNodes(ds)
|
|
48
|
+
? [[html('strong', unshift([html('em', defrag(bs))], defrag(ds)))], rest.slice(2)]
|
|
49
|
+
: [unshift(['**', html('em', defrag(bs))], ds), rest])
|
|
50
|
+
(rest, context) ?? [['**', html('em', defrag(bs))], rest];
|
|
34
51
|
}
|
|
35
52
|
assert(false);
|
|
36
53
|
},
|
|
@@ -38,7 +38,7 @@ describe('Unit: parser/inline/extension/index', () => {
|
|
|
38
38
|
assert.deepStrictEqual(inspect(parser('[#a b]')), [['<a class="index" href="#index:a_b">a b</a>'], '']);
|
|
39
39
|
assert.deepStrictEqual(inspect(parser('[#a ]')), [['<a class="index" href="#index:a">a</a>'], '']);
|
|
40
40
|
assert.deepStrictEqual(inspect(parser('[#a <wbr>]')), [['<a class="index" href="#index:a">a</a>'], '']);
|
|
41
|
-
assert.deepStrictEqual(inspect(parser('[#a [# b #]]')), [['<a class="index" href="#index:a">a <span class="comment">[# b #]</span></a>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('[#a [# b #]]')), [['<a class="index" href="#index:a">a <span class="comment"><input type="checkbox"><span>[# b #]</span></span></a>'], '']);
|
|
42
42
|
assert.deepStrictEqual(inspect(parser('[#a\\ ]')), [['<a class="index" href="#index:a">a</a>'], '']);
|
|
43
43
|
assert.deepStrictEqual(inspect(parser('[#a\\ b]')), [['<a class="index" href="#index:a_b">a b</a>'], '']);
|
|
44
44
|
assert.deepStrictEqual(inspect(parser('[#[]]')), [['<a class="index" href="#index:[]">[]</a>'], '']);
|
|
@@ -54,8 +54,8 @@ describe('Unit: parser/inline/extension/index', () => {
|
|
|
54
54
|
assert.deepStrictEqual(inspect(parser('[#@a]')), [['<a class="index" href="#index:@a">@a</a>'], '']);
|
|
55
55
|
assert.deepStrictEqual(inspect(parser('[#http://host]')), [['<a class="index" href="#index:http://host">http://host</a>'], '']);
|
|
56
56
|
assert.deepStrictEqual(inspect(parser('[#!http://host]')), [['<a class="index" href="#index:!http://host">!http://host</a>'], '']);
|
|
57
|
-
assert.deepStrictEqual(inspect(parser('[#[# #]]')), [['<a class="index"><span class="comment">[# #]</span></a>'], '']);
|
|
58
|
-
assert.deepStrictEqual(inspect(parser('[#[# a #]]')), [['<a class="index"><span class="comment">[# a #]</span></a>'], '']);
|
|
57
|
+
assert.deepStrictEqual(inspect(parser('[#[# #]]')), [['<a class="index"><span class="comment"><input type="checkbox"><span>[# #]</span></span></a>'], '']);
|
|
58
|
+
assert.deepStrictEqual(inspect(parser('[#[# a #]]')), [['<a class="index"><span class="comment"><input type="checkbox"><span>[# a #]</span></span></a>'], '']);
|
|
59
59
|
assert.deepStrictEqual(inspect(parser('[#a((b))]')), [['<a class="index" href="#index:a((b))">a<span class="paren">((b))</span></a>'], '']);
|
|
60
60
|
assert.deepStrictEqual(inspect(parser('[#a[[b]]]')), [['<a class="index" href="#index:a[[b]]">a[[b]]</a>'], '']);
|
|
61
61
|
});
|
|
@@ -83,7 +83,7 @@ describe('Unit: parser/inline/extension/index', () => {
|
|
|
83
83
|
assert.deepStrictEqual(inspect(parser('[#a |#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
|
|
84
84
|
assert.deepStrictEqual(inspect(parser('[#a |#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
|
|
85
85
|
assert.deepStrictEqual(inspect(parser('[#a <wbr>|#b]')), [['<a class="index" href="#index:b">a<span class="indexer" data-index="b"></span></a>'], '']);
|
|
86
|
-
assert.deepStrictEqual(inspect(parser('[#a [# b #]|#b]')), [['<a class="index" href="#index:b">a <span class="comment">[# b #]</span><span class="indexer" data-index="b"></span></a>'], '']);
|
|
86
|
+
assert.deepStrictEqual(inspect(parser('[#a [# b #]|#b]')), [['<a class="index" href="#index:b">a <span class="comment"><input type="checkbox"><span>[# b #]</span></span><span class="indexer" data-index="b"></span></a>'], '']);
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
});
|
|
@@ -45,13 +45,13 @@ describe('Unit: parser/inline/extension/placeholder', () => {
|
|
|
45
45
|
assert.deepStrictEqual(inspect(parser('[^a\\ \\ ]')), [['<span class="invalid">a </span>'], '']);
|
|
46
46
|
assert.deepStrictEqual(inspect(parser('[^a<wbr>]')), [['<span class="invalid">a<wbr></span>'], '']);
|
|
47
47
|
assert.deepStrictEqual(inspect(parser('[^a<wbr><wbr>]')), [['<span class="invalid">a<wbr><wbr></span>'], '']);
|
|
48
|
-
assert.deepStrictEqual(inspect(parser('[^a[# b #]]')), [['<span class="invalid">a<span class="comment">[# b #]</span></span>'], '']);
|
|
49
|
-
assert.deepStrictEqual(inspect(parser('[^a[# b #][# c #]]')), [['<span class="invalid">a<span class="comment">[# b #]</span><span class="comment">[# c #]</span></span>'], '']);
|
|
48
|
+
assert.deepStrictEqual(inspect(parser('[^a[# b #]]')), [['<span class="invalid">a<span class="comment"><input type="checkbox"><span>[# b #]</span></span></span>'], '']);
|
|
49
|
+
assert.deepStrictEqual(inspect(parser('[^a[# b #][# c #]]')), [['<span class="invalid">a<span class="comment"><input type="checkbox"><span>[# b #]</span></span><span class="comment"><input type="checkbox"><span>[# c #]</span></span></span>'], '']);
|
|
50
50
|
assert.deepStrictEqual(inspect(parser('[^\\]]')), [['<span class="invalid">]</span>'], '']);
|
|
51
51
|
assert.deepStrictEqual(inspect(parser('[^(])]')), [['<span class="invalid"><span class="paren">(])</span></span>'], '']);
|
|
52
52
|
assert.deepStrictEqual(inspect(parser('[^!http://host]')), [['<span class="invalid"><a href="http://host" target="_blank"><img class="media" data-src="http://host" alt=""></a></span>'], '']);
|
|
53
|
-
assert.deepStrictEqual(inspect(parser('[^[# a #]]')), [['<span class="invalid"><span class="comment">[# a #]</span></span>'], '']);
|
|
54
|
-
assert.deepStrictEqual(inspect(parser('[^[# a #]b]')), [['<span class="invalid"><span class="comment">[# a #]</span>b</span>'], '']);
|
|
53
|
+
assert.deepStrictEqual(inspect(parser('[^[# a #]]')), [['<span class="invalid"><span class="comment"><input type="checkbox"><span>[# a #]</span></span></span>'], '']);
|
|
54
|
+
assert.deepStrictEqual(inspect(parser('[^[# a #]b]')), [['<span class="invalid"><span class="comment"><input type="checkbox"><span>[# a #]</span></span>b</span>'], '']);
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
});
|
|
@@ -14,6 +14,7 @@ describe('Unit: parser/inline/htmlentity', () => {
|
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('& ;')), undefined);
|
|
15
15
|
assert.deepStrictEqual(inspect(parser('&\n;')), undefined);
|
|
16
16
|
assert.deepStrictEqual(inspect(parser('&a;')), [['<span class="invalid">&a;</span>'], '']);
|
|
17
|
+
assert.deepStrictEqual(inspect(parser('
')), undefined);
|
|
17
18
|
assert.deepStrictEqual(inspect(parser('&#;')), undefined);
|
|
18
19
|
assert.deepStrictEqual(inspect(parser('&#g;')), undefined);
|
|
19
20
|
assert.deepStrictEqual(inspect(parser('&#x;')), undefined);
|
|
@@ -5,7 +5,7 @@ import { html } from 'typed-dom';
|
|
|
5
5
|
const parser = html('textarea');
|
|
6
6
|
|
|
7
7
|
export const unsafehtmlentity: UnsafeHTMLEntityParser = creator(validate('&', fmap(focus(
|
|
8
|
-
/^&[0-9A-Za-z]+;/,
|
|
8
|
+
/^&(?!NewLine;)[0-9A-Za-z]+;/,
|
|
9
9
|
entity => [[(parser.innerHTML = entity, parser.value)], '']),
|
|
10
10
|
([str]) => [
|
|
11
11
|
str[0] !== '&' || str.length < 3
|
|
@@ -12,10 +12,10 @@ describe('Unit: parser/inline/mark', () => {
|
|
|
12
12
|
assert.deepStrictEqual(inspect(parser('==')), undefined);
|
|
13
13
|
assert.deepStrictEqual(inspect(parser('==a')), [['==', 'a'], '']);
|
|
14
14
|
assert.deepStrictEqual(inspect(parser('==a=')), [['==', 'a', '='], '']);
|
|
15
|
-
assert.deepStrictEqual(inspect(parser('==a ==')), [['==', 'a', ' '
|
|
16
|
-
assert.deepStrictEqual(inspect(parser('==a\n==')), [['==', 'a', '<br>'
|
|
17
|
-
assert.deepStrictEqual(inspect(parser('==a\\ ==')), [['==', 'a', ' '
|
|
18
|
-
assert.deepStrictEqual(inspect(parser('==a\\\n==')), [['==', 'a', '<span class="linebreak"> </span>'
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('==a ==')), [['==', 'a', ' ', '=='], '']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('==a\n==')), [['==', 'a', '<br>', '=='], '']);
|
|
17
|
+
assert.deepStrictEqual(inspect(parser('==a\\ ==')), [['==', 'a', ' ', '=='], '']);
|
|
18
|
+
assert.deepStrictEqual(inspect(parser('==a\\\n==')), [['==', 'a', '<span class="linebreak"> </span>', '=='], '']);
|
|
19
19
|
assert.deepStrictEqual(inspect(parser('== ==')), undefined);
|
|
20
20
|
assert.deepStrictEqual(inspect(parser('== a==')), undefined);
|
|
21
21
|
assert.deepStrictEqual(inspect(parser('== a ==')), undefined);
|
|
@@ -35,6 +35,10 @@ describe('Unit: parser/inline/mark', () => {
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
it('nest', () => {
|
|
38
|
+
assert.deepStrictEqual(inspect(parser('==a ==b====')), [['<mark>a <mark>b</mark></mark>'], '']);
|
|
39
|
+
assert.deepStrictEqual(inspect(parser('==a\\ ==b====')), [['<mark>a <mark>b</mark></mark>'], '']);
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('==a	==b====')), [['<mark>a\t<mark>b</mark></mark>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('==a<wbr>==b====')), [['<mark>a<wbr><mark>b</mark></mark>'], '']);
|
|
38
42
|
assert.deepStrictEqual(inspect(parser('==*==a==*==')), [['<mark><em><mark>a</mark></em></mark>'], '']);
|
|
39
43
|
});
|
|
40
44
|
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { MarkParser } from '../inline';
|
|
2
|
-
import { union, some, creator, surround, lazy } from '../../combinator';
|
|
2
|
+
import { union, some, creator, surround, open, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
-
import { startTight, isEndTightNodes } from '../util';
|
|
5
|
+
import { startTight, isEndTightNodes, delimiter } from '../util';
|
|
6
6
|
import { html, defrag } from 'typed-dom';
|
|
7
7
|
import { unshift } from 'spica/array';
|
|
8
8
|
|
|
9
9
|
export const mark: MarkParser = lazy(() => creator(surround(
|
|
10
10
|
str('=='),
|
|
11
|
-
startTight(union([
|
|
11
|
+
startTight(some(union([
|
|
12
|
+
some(inline, delimiter('==')),
|
|
13
|
+
open(some(inline, '='), inline),
|
|
14
|
+
]))),
|
|
12
15
|
str('=='), false,
|
|
13
16
|
([as, bs, cs], rest) =>
|
|
14
17
|
isEndTightNodes(bs)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { MathParser } from '../inline';
|
|
2
|
-
import { union, some, validate,
|
|
2
|
+
import { union, some, validate, rewrite, creator, surround, lazy } from '../../combinator';
|
|
3
3
|
import { escsource, str } from '../source';
|
|
4
|
-
import { isEndTightNodes } from '../util';
|
|
5
4
|
import { html } from 'typed-dom';
|
|
6
5
|
|
|
7
6
|
const disallowedCommand = /\\(?:begin|tiny|huge|large)(?![0-9a-z])/i;
|
|
@@ -10,15 +9,13 @@ export const math: MathParser = lazy(() => creator(validate('$', rewrite(
|
|
|
10
9
|
union([
|
|
11
10
|
surround(
|
|
12
11
|
'$',
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
str(/^(?![\s{}#$%&]|\d+(?:[,.]\d+)*[^-+*/=<>^_~\\$]|-[\da-z]|[a-z]+-)(?:\\\$|[\x20-\x23\x25-\x7E])+/i),
|
|
21
|
-
isEndTightNodes),
|
|
12
|
+
// Latex's reserved characters: # $ % ^ & _ { } ~ \
|
|
13
|
+
// $[0-9]+ : Dollar
|
|
14
|
+
// $[A-z]*- : Label
|
|
15
|
+
// $[A-z]*(?!-) : Math
|
|
16
|
+
// $[\^_[({|] : Math
|
|
17
|
+
// $[#$%&] : Invalid first character in Latex syntax
|
|
18
|
+
str(/^(?![\s{}#$%&]|\d+(?:[,.]\d+)*[^-+*/=<>^_~\\$]|-[\da-z]|[a-z]+-)(?:\\\$|\x20(?!\$)|[\x21-\x23\x25-\x7E])+/i),
|
|
22
19
|
/^\$(?![0-9a-z])/i),
|
|
23
20
|
surround('$', bracket, '$'),
|
|
24
21
|
]),
|
|
@@ -10,10 +10,10 @@ describe('Unit: parser/inline/strong', () => {
|
|
|
10
10
|
assert.deepStrictEqual(inspect(parser('**')), undefined);
|
|
11
11
|
assert.deepStrictEqual(inspect(parser('**a')), [['**', 'a'], '']);
|
|
12
12
|
assert.deepStrictEqual(inspect(parser('**a*')), [['**', 'a', '*'], '']);
|
|
13
|
-
assert.deepStrictEqual(inspect(parser('**a **')), [['**', 'a', ' '
|
|
14
|
-
assert.deepStrictEqual(inspect(parser('**a\n**')), [['**', 'a', '<br>'
|
|
15
|
-
assert.deepStrictEqual(inspect(parser('**a\\ **')), [['**', 'a', ' '
|
|
16
|
-
assert.deepStrictEqual(inspect(parser('**a\\\n**')), [['**', 'a', '<span class="linebreak"> </span>'
|
|
13
|
+
assert.deepStrictEqual(inspect(parser('**a **')), [['**', 'a', ' ', '**'], '']);
|
|
14
|
+
assert.deepStrictEqual(inspect(parser('**a\n**')), [['**', 'a', '<br>', '**'], '']);
|
|
15
|
+
assert.deepStrictEqual(inspect(parser('**a\\ **')), [['**', 'a', ' ', '**'], '']);
|
|
16
|
+
assert.deepStrictEqual(inspect(parser('**a\\\n**')), [['**', 'a', '<span class="linebreak"> </span>', '**'], '']);
|
|
17
17
|
assert.deepStrictEqual(inspect(parser('**a*b**')), [['**', 'a', '<em>b</em>', '*'], '']);
|
|
18
18
|
assert.deepStrictEqual(inspect(parser('** **')), undefined);
|
|
19
19
|
assert.deepStrictEqual(inspect(parser('** a**')), undefined);
|
|
@@ -35,9 +35,12 @@ describe('Unit: parser/inline/strong', () => {
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
it('nest', () => {
|
|
38
|
+
assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
|
|
39
|
+
assert.deepStrictEqual(inspect(parser('**a **b****')), [['<strong>a <strong>b</strong></strong>'], '']);
|
|
40
|
+
assert.deepStrictEqual(inspect(parser('**a	**b****')), [['<strong>a\t<strong>b</strong></strong>'], '']);
|
|
41
|
+
assert.deepStrictEqual(inspect(parser('**a<wbr>**b****')), [['<strong>a<wbr><strong>b</strong></strong>'], '']);
|
|
38
42
|
assert.deepStrictEqual(inspect(parser('**a*b*c**')), [['<strong>a<em>b</em>c</strong>'], '']);
|
|
39
43
|
assert.deepStrictEqual(inspect(parser('**a*b*c**d')), [['<strong>a<em>b</em>c</strong>'], 'd']);
|
|
40
|
-
assert.deepStrictEqual(inspect(parser('**a *b***')), [['<strong>a <em>b</em></strong>'], '']);
|
|
41
44
|
assert.deepStrictEqual(inspect(parser('**`a`**')), [['<strong><code data-src="`a`">a</code></strong>'], '']);
|
|
42
45
|
assert.deepStrictEqual(inspect(parser('**<small>**')), [['<strong><small></strong>'], '']);
|
|
43
46
|
assert.deepStrictEqual(inspect(parser('**(*a*)**')), [['<strong><span class="paren">(<em>a</em>)</span></strong>'], '']);
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { StrongParser } from '../inline';
|
|
2
|
-
import { union, some, creator, surround, close, lazy } from '../../combinator';
|
|
2
|
+
import { union, some, creator, surround, open, close, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
|
-
import { emphasis } from './emphasis';
|
|
5
4
|
import { str } from '../source';
|
|
6
|
-
import { startTight, isEndTightNodes } from '../util';
|
|
5
|
+
import { startTight, isEndTightNodes, delimiter } from '../util';
|
|
7
6
|
import { html, defrag } from 'typed-dom';
|
|
8
7
|
import { unshift } from 'spica/array';
|
|
9
8
|
|
|
10
9
|
export const strong: StrongParser = lazy(() => creator(surround(close(
|
|
11
10
|
str('**'), /^(?!\*)/),
|
|
12
|
-
startTight(some(union([
|
|
11
|
+
startTight(some(union([
|
|
12
|
+
some(inline, delimiter(String.raw`\*\*`)),
|
|
13
|
+
open(some(inline, '*'), inline),
|
|
14
|
+
]))),
|
|
13
15
|
str('**'), false,
|
|
14
16
|
([as, bs, cs], rest) =>
|
|
15
17
|
isEndTightNodes(bs)
|