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.
@@ -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-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:])/,
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 => `[${source}]{ ?at=${source.slice(2)} }`,
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')), [['[', '#', '<br>', ' ', '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('[# #]')), undefined);
20
- assert.deepStrictEqual(inspect(parser('[# #] #]')), undefined);
21
- assert.deepStrictEqual(inspect(parser('[# [#')), [['[', '#', ' ', '[', '#'], '']);
22
- assert.deepStrictEqual(inspect(parser('[# [# ')), [['[', '#', ' ', '[', '#', ' '], '']);
23
- assert.deepStrictEqual(inspect(parser('[# [# a')), [['[', '#', ' ', '[', '#', ' ', 'a'], '']);
24
- assert.deepStrictEqual(inspect(parser('[# [# a #]')), [['[', '#', ' ', '<span class="comment">[# a #]</span>'], '']);
25
- assert.deepStrictEqual(inspect(parser('[# a[#')), [['[', '#', ' ', 'a', '[', '#'], '']);
26
- assert.deepStrictEqual(inspect(parser('[# a [#')), [['[', '#', ' ', 'a', ' ', '[', '#'], '']);
27
- assert.deepStrictEqual(inspect(parser('[# a [# ')), [['[', '#', ' ', 'a', ' ', '[', '#', ' '], '']);
28
- assert.deepStrictEqual(inspect(parser('[# a [# b')), [['[', '#', ' ', 'a', ' ', '[', '#', ' ', 'b'], '']);
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\\ #]')), [['[', '#', ' ', 'a', ' ', '#', ']'], '']);
33
- assert.deepStrictEqual(inspect(parser('[# a#]')), [['[', '#', ' ', 'a#', ']'], '']);
34
- assert.deepStrictEqual(inspect(parser('[# a ##]')), [['[', '#', ' ', 'a', ' ', '##', ']'], '']);
35
- assert.deepStrictEqual(inspect(parser('[# [## #]')), [['[', '#', ' ', '[', '#', '#', ' ', '#', ']'], '']);
36
- assert.deepStrictEqual(inspect(parser('[## [# ##]')), [['[', '#', '#', ' ', '[', '#', ' ', '##', ']'], '']);
37
- assert.deepStrictEqual(inspect(parser('[## a #]')), [['[', '#', '#', ' ', '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('[# #]')), [['<span class="comment">[# #]</span>'], '']);
43
- assert.deepStrictEqual(inspect(parser('[# #]')), [['<span class="comment">[# #]</span>'], '']);
44
- assert.deepStrictEqual(inspect(parser('[# a #]')), [['<span class="comment">[# a #]</span>'], '']);
45
- assert.deepStrictEqual(inspect(parser('[# a b #]')), [['<span class="comment">[# a b #]</span>'], '']);
46
- assert.deepStrictEqual(inspect(parser('[# a\nb #]')), [['<span class="comment">[# a<br>b #]</span>'], '']);
47
- assert.deepStrictEqual(inspect(parser('[# a #] #]')), [['<span class="comment">[# a #]</span>'], ' #]']);
48
- assert.deepStrictEqual(inspect(parser('[# ##] #]')), [['<span class="comment">[# ##] #]</span>'], '']);
49
- assert.deepStrictEqual(inspect(parser('[# [# a #] #]')), [['<span class="comment">[# <span class="comment">[# a #]</span> #]</span>'], '']);
50
- assert.deepStrictEqual(inspect(parser('[# [## a ##] #]')), [['<span class="comment">[# <span class="comment">[## a ##]</span> #]</span>'], '']);
51
- assert.deepStrictEqual(inspect(parser('[## a ##]')), [['<span class="comment">[## a ##]</span>'], '']);
52
- assert.deepStrictEqual(inspect(parser('[## #] ##]')), [['<span class="comment">[## #] ##]</span>'], '']);
53
- assert.deepStrictEqual(inspect(parser('[## [# a #] ##]')), [['<span class="comment">[## <span class="comment">[# a #]</span> ##]</span>'], '']);
54
- assert.deepStrictEqual(inspect(parser('[# a #]b')), [['<span class="comment">[# a #]</span>'], 'b']);
55
- assert.deepStrictEqual(inspect(parser('[#\na\n#]')), [['<span class="comment">[# a #]</span>'], '']);
56
- assert.deepStrictEqual(inspect(parser('[# &a; #]')), [['<span class="comment">[# <span class="invalid">&amp;a;</span> #]</span>'], '']);
57
- assert.deepStrictEqual(inspect(parser('[# &copy; #]')), [['<span class="comment">[# © #]</span>'], '']);
58
- assert.deepStrictEqual(inspect(parser('[# &amp;copy; #]')), [['<span class="comment">[# &amp;copy; #]</span>'], '']);
59
- assert.deepStrictEqual(inspect(parser('[# \\ a #]')), [['<span class="comment">[# a #]</span>'], '']);
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">&amp;a;</span> #]</span></span>'], '']);
56
+ assert.deepStrictEqual(inspect(parser('[# &copy; #]')), [['<span class="comment"><input type="checkbox"><span>[# © #]</span></span>'], '']);
57
+ assert.deepStrictEqual(inspect(parser('[# &amp;copy; #]')), [['<span class="comment"><input type="checkbox"><span>[# &amp;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 { eval } from '../../combinator/data/parser';
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, pop } from 'spica/array';
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], closer = new RegExp(String.raw`^\s+${fence}\]`)) =>
12
+ ([, fence]) =>
14
13
  surround(
15
- str(/^\[(\S+)\s+(?!\1\])/),
16
- union([some(inline, closer)]),
17
- str(closer), true,
18
- ([, bs = []], rest) => [[
19
- html('span',
20
- { class: 'comment' },
21
- defrag(push(unshift([`[${fence} `], bs), [` ${fence}]`]))),
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, context) => [unshift(pop(eval(some(text)(`${as[0]}!`, context))!)[0], 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&Tab;*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([strong, some(inline, '*')]))),
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 { EmStrongParser } from '../inline';
2
- import { union, some, creator, surround, lazy, bind } from '../../combinator';
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([some(inline, '*')])),
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 bind<EmStrongParser>(
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<EmStrongParser>(
26
- union([some(inline, '*')]),
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 [[html('em', [html('strong', defrag(bs))])], rest];
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 &nbsp;]')), [['<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 &nbsp;|#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">&amp;a;</span>'], '']);
17
+ assert.deepStrictEqual(inspect(parser('&NewLine;')), 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&Tab;==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([some(inline, '==')])),
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, verify, rewrite, creator, surround, lazy } from '../../combinator';
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
- verify(
14
- // Latex's reserved characters: # $ % ^ & _ { } ~ \
15
- // $[0-9]+ : Dollar
16
- // $[A-z]*- : Label
17
- // $[A-z]*(?!-) : Math
18
- // $[\^_[({|] : Math
19
- // $[#$%&] : Invalid first character in Latex syntax
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&Tab;**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>&lt;small&gt;</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([emphasis, some(inline, '*'), str('*')]), '**')),
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)