securemark 0.293.5 → 0.294.1

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.
Files changed (106) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/index.js +973 -617
  3. package/markdown.d.ts +13 -13
  4. package/package.json +3 -3
  5. package/src/combinator/control/constraint/block.test.ts +6 -6
  6. package/src/combinator/control/constraint/contract.ts +4 -4
  7. package/src/combinator/control/constraint/line.test.ts +7 -7
  8. package/src/combinator/control/constraint/line.ts +2 -2
  9. package/src/combinator/control/manipulation/clear.ts +2 -3
  10. package/src/combinator/control/manipulation/convert.ts +2 -2
  11. package/src/combinator/control/manipulation/duplicate.ts +4 -5
  12. package/src/combinator/control/manipulation/fence.ts +2 -2
  13. package/src/combinator/control/manipulation/indent.test.ts +2 -2
  14. package/src/combinator/control/manipulation/indent.ts +4 -8
  15. package/src/combinator/control/manipulation/reverse.ts +2 -2
  16. package/src/combinator/control/manipulation/scope.ts +4 -7
  17. package/src/combinator/control/manipulation/surround.ts +16 -20
  18. package/src/combinator/control/monad/bind.ts +7 -8
  19. package/src/combinator/control/monad/fmap.ts +7 -7
  20. package/src/combinator/data/data.ts +135 -0
  21. package/src/combinator/data/parser/context.test.ts +8 -8
  22. package/src/combinator/data/parser/context.ts +3 -3
  23. package/src/combinator/data/parser/inits.ts +8 -11
  24. package/src/combinator/data/parser/sequence.test.ts +3 -3
  25. package/src/combinator/data/parser/sequence.ts +8 -11
  26. package/src/combinator/data/parser/some.test.ts +3 -3
  27. package/src/combinator/data/parser/some.ts +7 -9
  28. package/src/combinator/data/parser/subsequence.test.ts +4 -4
  29. package/src/combinator/data/parser/subsequence.ts +3 -3
  30. package/src/combinator/data/parser/tails.ts +3 -3
  31. package/src/combinator/data/parser/union.test.ts +3 -3
  32. package/src/combinator/data/parser.ts +11 -20
  33. package/src/debug.test.ts +7 -6
  34. package/src/parser/api/bind.ts +8 -10
  35. package/src/parser/api/header.ts +2 -2
  36. package/src/parser/api/normalize.ts +2 -2
  37. package/src/parser/api/parse.ts +4 -2
  38. package/src/parser/block/blockquote.ts +6 -4
  39. package/src/parser/block/codeblock.ts +8 -7
  40. package/src/parser/block/dlist.ts +9 -8
  41. package/src/parser/block/extension/aside.ts +27 -21
  42. package/src/parser/block/extension/example.ts +29 -26
  43. package/src/parser/block/extension/fig.ts +1 -1
  44. package/src/parser/block/extension/figbase.ts +6 -5
  45. package/src/parser/block/extension/figure.ts +24 -20
  46. package/src/parser/block/extension/message.ts +35 -24
  47. package/src/parser/block/extension/placeholder.ts +17 -13
  48. package/src/parser/block/extension/table.ts +47 -40
  49. package/src/parser/block/heading.test.ts +3 -12
  50. package/src/parser/block/heading.ts +12 -8
  51. package/src/parser/block/ilist.ts +13 -12
  52. package/src/parser/block/mathblock.ts +21 -17
  53. package/src/parser/block/mediablock.ts +7 -5
  54. package/src/parser/block/olist.ts +15 -5
  55. package/src/parser/block/pagebreak.ts +2 -1
  56. package/src/parser/block/paragraph.ts +3 -1
  57. package/src/parser/block/reply/cite.ts +20 -15
  58. package/src/parser/block/reply/quote.ts +6 -4
  59. package/src/parser/block/reply.ts +6 -3
  60. package/src/parser/block/sidefence.ts +8 -7
  61. package/src/parser/block/table.ts +23 -22
  62. package/src/parser/block/ulist.ts +16 -12
  63. package/src/parser/block.ts +11 -6
  64. package/src/parser/header.ts +18 -18
  65. package/src/parser/inline/annotation.ts +3 -1
  66. package/src/parser/inline/autolink/account.ts +3 -2
  67. package/src/parser/inline/autolink/anchor.ts +3 -2
  68. package/src/parser/inline/autolink/channel.ts +5 -4
  69. package/src/parser/inline/autolink/email.ts +4 -3
  70. package/src/parser/inline/autolink/hashnum.ts +3 -2
  71. package/src/parser/inline/autolink/hashtag.ts +4 -3
  72. package/src/parser/inline/autolink/url.ts +7 -6
  73. package/src/parser/inline/bracket.ts +16 -15
  74. package/src/parser/inline/code.ts +5 -4
  75. package/src/parser/inline/deletion.ts +5 -5
  76. package/src/parser/inline/emphasis.ts +4 -3
  77. package/src/parser/inline/emstrong.test.ts +18 -18
  78. package/src/parser/inline/emstrong.ts +37 -28
  79. package/src/parser/inline/extension/index.ts +22 -19
  80. package/src/parser/inline/extension/indexee.ts +2 -2
  81. package/src/parser/inline/extension/indexer.ts +2 -1
  82. package/src/parser/inline/extension/label.ts +7 -3
  83. package/src/parser/inline/extension/placeholder.ts +6 -6
  84. package/src/parser/inline/html.ts +27 -28
  85. package/src/parser/inline/htmlentity.ts +9 -8
  86. package/src/parser/inline/insertion.ts +5 -5
  87. package/src/parser/inline/italic.ts +5 -5
  88. package/src/parser/inline/link.ts +36 -38
  89. package/src/parser/inline/mark.ts +7 -7
  90. package/src/parser/inline/math.ts +5 -4
  91. package/src/parser/inline/media.ts +33 -32
  92. package/src/parser/inline/reference.ts +19 -20
  93. package/src/parser/inline/remark.ts +11 -11
  94. package/src/parser/inline/ruby.ts +50 -53
  95. package/src/parser/inline/strong.ts +4 -3
  96. package/src/parser/inline/template.ts +16 -15
  97. package/src/parser/inline.test.ts +3 -3
  98. package/src/parser/processor/note.ts +2 -2
  99. package/src/parser/segment.ts +5 -3
  100. package/src/parser/source/escapable.ts +9 -8
  101. package/src/parser/source/line.ts +9 -3
  102. package/src/parser/source/str.ts +3 -3
  103. package/src/parser/source/text.ts +9 -8
  104. package/src/parser/source/unescapable.ts +6 -5
  105. package/src/parser/util.ts +20 -15
  106. package/src/parser/visibility.ts +19 -20
@@ -1,8 +1,10 @@
1
1
  import { BlockquoteParser } from '../block';
2
2
  import { Recursion } from '../context';
3
+ import { List, Data } from '../../combinator/data/parser';
3
4
  import { union, some, creation, recursion, block, validate, rewrite, open, convert, lazy, fmap } from '../../combinator';
4
5
  import { autolink } from '../autolink';
5
6
  import { contentline } from '../source';
7
+ import { unwrap } from '../util';
6
8
  import { parse } from '../api/parse';
7
9
  import { html, defrag } from 'typed-dom/dom';
8
10
 
@@ -26,9 +28,9 @@ const source: BlockquoteParser.SourceParser = lazy(() => fmap(
26
28
  convert(unindent, source, false, true)),
27
29
  rewrite(
28
30
  some(contentline, opener),
29
- convert(unindent, fmap(autolink, ns => [html('pre', defrag(ns))]), false, true)),
31
+ convert(unindent, fmap(autolink, ns => new List([new Data(html('pre', defrag(unwrap(ns))))])), false, true)),
30
32
  ]))),
31
- ns => [html('blockquote', ns)]));
33
+ ns => new List([new Data(html('blockquote', unwrap(ns)))])));
32
34
 
33
35
  const markdown: BlockquoteParser.MarkdownParser = lazy(() => fmap(
34
36
  some(recursion(Recursion.blockquote, union([
@@ -48,7 +50,7 @@ const markdown: BlockquoteParser.MarkdownParser = lazy(() => fmap(
48
50
  },
49
51
  }, context);
50
52
  context.position = source.length;
51
- return [[html('section', [document, html('h2', 'References'), references])]];
53
+ return new List([new Data(html('section', [document, html('h2', 'References'), references]))]);
52
54
  }, false, true))),
53
55
  ]))),
54
- ns => [html('blockquote', ns)]));
56
+ ns => new List([new Data(html('blockquote', unwrap(ns)))])));
@@ -1,8 +1,8 @@
1
1
  import { CodeBlockParser } from '../block';
2
- import { input, eval } from '../../combinator/data/parser';
2
+ import { List, Data, subinput } from '../../combinator/data/parser';
3
3
  import { block, fence, clear, fmap } from '../../combinator';
4
4
  import { autolink } from '../autolink';
5
- import { invalid } from '../util';
5
+ import { unwrap, invalid } from '../util';
6
6
  import { html, defrag } from 'typed-dom/dom';
7
7
 
8
8
  const opener = /(`{3,})(?!`)([^\n]*)(?:$|\n)/y;
@@ -17,7 +17,8 @@ export const segment_: CodeBlockParser.SegmentParser = block(
17
17
  export const codeblock: CodeBlockParser = block(fmap(
18
18
  fence(opener, 300),
19
19
  // Bug: Type mismatch between outer and inner.
20
- ([body, overflow, closer, opener, delim, param]: string[], context) => {
20
+ (nodes, context) => {
21
+ const [body, overflow, closer, opener, delim, param] = unwrap<string>(nodes);
21
22
  const params = param.match(/(?:\\.?|\S)+/g)?.reduce<{
22
23
  lang?: string;
23
24
  path?: string;
@@ -49,7 +50,7 @@ export const codeblock: CodeBlockParser = block(fmap(
49
50
  : params[name] = value;
50
51
  return params;
51
52
  }, {}) ?? {};
52
- if (!closer || overflow || params.invalid) return [html('pre', {
53
+ if (!closer || overflow || params.invalid) return new List([new Data(html('pre', {
53
54
  class: 'invalid',
54
55
  translate: 'no',
55
56
  ...invalid(
@@ -60,7 +61,7 @@ export const codeblock: CodeBlockParser = block(fmap(
60
61
  : overflow
61
62
  ? `Invalid trailing line after the closing delimiter "${delim}"`
62
63
  : params.invalid!),
63
- }, `${opener}${body}${overflow || closer}`)];
64
+ }, `${opener}${body}${overflow || closer}`))]);
64
65
  const el = html('pre',
65
66
  {
66
67
  class: params.lang ? `code language-${params.lang}` : 'text',
@@ -72,6 +73,6 @@ export const codeblock: CodeBlockParser = block(fmap(
72
73
  params.lang
73
74
  ? context.caches?.code?.get(`${params.lang ?? ''}\n${body.slice(0, -1)}`)?.cloneNode(true).childNodes ||
74
75
  body.slice(0, -1) || undefined
75
- : defrag(eval(autolink(input(body.slice(0, -1), { ...context })), [])));
76
- return [el];
76
+ : defrag(unwrap(autolink(subinput(body.slice(0, -1), context)))));
77
+ return new List([new Data(el)]);
77
78
  }));
@@ -1,10 +1,11 @@
1
1
  import { DListParser } from '../block';
2
2
  import { State } from '../context';
3
+ import { List, Data } from '../../combinator/data/parser';
3
4
  import { union, inits, some, state, block, line, validate, rewrite, open, lazy, fmap } from '../../combinator';
4
5
  import { inline, indexee, indexer, dataindex } from '../inline';
5
6
  import { anyline } from '../source';
6
7
  import { visualize, trimBlank, trimBlankEnd } from '../visibility';
7
- import { push } from 'spica/array';
8
+ import { unwrap } from '../util';
8
9
  import { html, defrag } from 'typed-dom/dom';
9
10
 
10
11
  export const dlist: DListParser = lazy(() => block(fmap(validate(
@@ -14,13 +15,13 @@ export const dlist: DListParser = lazy(() => block(fmap(validate(
14
15
  some(term)),
15
16
  some(desc),
16
17
  ]))),
17
- es => [html('dl', fillTrailingDescription(es))])));
18
+ ns => new List([new Data(html('dl', unwrap(fillTrailingDescription(ns))))]))));
18
19
 
19
20
  const term: DListParser.TermParser = line(indexee(fmap(open(
20
21
  /~[^\S\n]+(?=\S)/y,
21
22
  visualize(trimBlank(some(union([indexer, inline])))),
22
23
  true),
23
- ns => [html('dt', { 'data-index': dataindex(ns) }, defrag(ns))])));
24
+ ns => new List([new Data(html('dt', { 'data-index': dataindex(ns) }, defrag(unwrap(ns))))]))));
24
25
 
25
26
  const desc: DListParser.DescriptionParser = block(fmap(open(
26
27
  /:[^\S\n]+(?=\S)|/y,
@@ -28,11 +29,11 @@ const desc: DListParser.DescriptionParser = block(fmap(open(
28
29
  some(anyline, /[~:][^\S\n]+\S/y),
29
30
  visualize(trimBlankEnd(some(union([inline]))))),
30
31
  true),
31
- ns => [html('dd', defrag(ns))]),
32
+ ns => new List([new Data(html('dd', defrag(unwrap(ns))))])),
32
33
  false);
33
34
 
34
- function fillTrailingDescription(es: HTMLElement[]): HTMLElement[] {
35
- return es.length > 0 && es.at(-1)!.tagName === 'DT'
36
- ? push(es, [html('dd')])
37
- : es;
35
+ function fillTrailingDescription(nodes: List<Data<HTMLElement>>): List<Data<HTMLElement>> {
36
+ return nodes.last?.value.tagName === 'DT'
37
+ ? nodes.push(new Data(html('dd'))) && nodes
38
+ : nodes;
38
39
  }
@@ -1,25 +1,29 @@
1
1
  import { ExtensionParser } from '../../block';
2
2
  import { Recursion } from '../../context';
3
+ import { List, Data } from '../../../combinator/data/parser';
3
4
  import { recursion, block, fence, fmap } from '../../../combinator';
4
5
  import { identity } from '../../inline/extension/indexee';
5
- import { invalid } from '../../util';
6
+ import { unwrap, invalid } from '../../util';
6
7
  import { parse } from '../../api/parse';
7
8
  import { html } from 'typed-dom/dom';
8
9
 
9
10
  export const aside: ExtensionParser.AsideParser = recursion(Recursion.block, block(fmap(
10
11
  fence(/(~{3,})aside(?!\S)([^\n]*)(?:$|\n)/y, 300),
11
12
  // Bug: Type mismatch between outer and inner.
12
- ([body, overflow, closer, opener, delim, param]: string[], context) => {
13
- if (!closer || overflow || param.trimStart()) return [html('pre', {
14
- class: 'invalid',
15
- translate: 'no',
16
- ...invalid(
17
- 'aside',
18
- !closer || overflow ? 'fence' : 'argument',
19
- !closer ? `Missing the closing delimiter "${delim}"` :
20
- overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
21
- 'Invalid argument'),
22
- }, `${opener}${body}${overflow || closer}`)];
13
+ (nodes: List<Data<string>>, context) => {
14
+ const [body, overflow, closer, opener, delim, param] = unwrap(nodes);
15
+ if (!closer || overflow || param.trimStart()) return new List([
16
+ new Data(html('pre', {
17
+ class: 'invalid',
18
+ translate: 'no',
19
+ ...invalid(
20
+ 'aside',
21
+ !closer || overflow ? 'fence' : 'argument',
22
+ !closer ? `Missing the closing delimiter "${delim}"` :
23
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
24
+ 'Invalid argument'),
25
+ }, `${opener}${body}${overflow || closer}`))
26
+ ]);
23
27
  const references = html('ol', { class: 'references' });
24
28
  const document = parse(body.slice(0, -1), {
25
29
  id: '',
@@ -29,17 +33,19 @@ export const aside: ExtensionParser.AsideParser = recursion(Recursion.block, blo
29
33
  }, context);
30
34
  assert(!document.querySelector('[id]'));
31
35
  const heading = 'H1 H2 H3 H4 H5 H6'.split(' ').includes(document.firstElementChild?.tagName!) && document.firstElementChild as HTMLHeadingElement;
32
- if (!heading) return [html('pre', {
33
- class: 'invalid',
34
- translate: 'no',
35
- ...invalid('aside', 'content', 'Missing the title at the first line'),
36
- }, `${opener}${body}${closer}`)];
36
+ if (!heading) return new List([
37
+ new Data(html('pre', {
38
+ class: 'invalid',
39
+ translate: 'no',
40
+ ...invalid('aside', 'content', 'Missing the title at the first line'),
41
+ }, `${opener}${body}${closer}`))
42
+ ]);
37
43
  assert(identity('index', context.id, heading));
38
- return [
39
- html('aside', { id: identity('index', context.id, heading), class: 'aside' }, [
44
+ return new List([
45
+ new Data(html('aside', { id: identity('index', context.id, heading), class: 'aside' }, [
40
46
  document,
41
47
  html('h2', 'References'),
42
48
  references,
43
- ]),
44
- ];
49
+ ]))
50
+ ]);
45
51
  })));
@@ -1,9 +1,9 @@
1
1
  import { ExtensionParser } from '../../block';
2
2
  import { Recursion } from '../../context';
3
- import { input, eval } from '../../../combinator/data/parser';
3
+ import { List, Data, subinput } from '../../../combinator/data/parser';
4
4
  import { recursion, block, fence, fmap } from '../../../combinator';
5
5
  import { mathblock } from '../mathblock';
6
- import { invalid } from '../../util';
6
+ import { unwrap, invalid } from '../../util';
7
7
  import { parse } from '../../api/parse';
8
8
  import { html } from 'typed-dom/dom';
9
9
 
@@ -12,17 +12,20 @@ const opener = /(~{3,})(?:example\/(\S+))?(?!\S)([^\n]*)(?:$|\n)/y;
12
12
  export const example: ExtensionParser.ExampleParser = recursion(Recursion.block, block(fmap(
13
13
  fence(opener, 300),
14
14
  // Bug: Type mismatch between outer and inner.
15
- ([body, overflow, closer, opener, delim, type = 'markdown', param]: string[], context) => {
16
- if (!closer || overflow || param.trimStart()) return [html('pre', {
17
- class: 'invalid',
18
- translate: 'no',
19
- ...invalid(
20
- 'example',
21
- !closer || overflow ? 'fence' : 'argument',
22
- !closer ? `Missing the closing delimiter "${delim}"` :
23
- overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
24
- 'Invalid argument'),
25
- }, `${opener}${body}${overflow || closer}`)];
15
+ (nodes: List<Data<string>>, context) => {
16
+ const [body, overflow, closer, opener, delim, type = 'markdown', param] = unwrap(nodes);
17
+ if (!closer || overflow || param.trimStart()) return new List([
18
+ new Data(html('pre', {
19
+ class: 'invalid',
20
+ translate: 'no',
21
+ ...invalid(
22
+ 'example',
23
+ !closer || overflow ? 'fence' : 'argument',
24
+ !closer ? `Missing the closing delimiter "${delim}"` :
25
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
26
+ 'Invalid argument'),
27
+ }, `${opener}${body}${overflow || closer}`))
28
+ ]);
26
29
  switch (type) {
27
30
  case 'markdown': {
28
31
  const references = html('ol', { class: 'references' });
@@ -33,29 +36,29 @@ export const example: ExtensionParser.ExampleParser = recursion(Recursion.block,
33
36
  },
34
37
  }, context);
35
38
  assert(!document.querySelector('[id]'));
36
- return [
37
- html('aside', { class: 'example', 'data-type': 'markdown' }, [
39
+ return new List([
40
+ new Data(html('aside', { class: 'example', 'data-type': 'markdown' }, [
38
41
  html('pre', { translate: 'no' }, body.slice(0, -1)),
39
42
  html('hr'),
40
43
  html('section', [document, html('h2', 'References'), references]),
41
- ]),
42
- ];
44
+ ])),
45
+ ]);
43
46
  }
44
47
  case 'math':
45
- return [
46
- html('aside', { class: 'example', 'data-type': 'math' }, [
48
+ return new List([
49
+ new Data(html('aside', { class: 'example', 'data-type': 'math' }, [
47
50
  html('pre', { translate: 'no' }, body.slice(0, -1)),
48
51
  html('hr'),
49
- eval(mathblock(input(`$$\n${body}$$`, { ...context })), [])[0],
50
- ]),
51
- ];
52
+ mathblock(subinput(`$$\n${body}$$`, context))!.head!.value,
53
+ ])),
54
+ ]);
52
55
  default:
53
- return [
54
- html('pre', {
56
+ return new List([
57
+ new Data(html('pre', {
55
58
  class: 'invalid',
56
59
  translate: 'no',
57
60
  ...invalid('example', 'type', 'Invalid example type'),
58
- }, `${opener}${body}${closer}`),
59
- ];
61
+ }, `${opener}${body}${closer}`)),
62
+ ]);
60
63
  }
61
64
  })));
@@ -36,7 +36,7 @@ export const fig: FigParser = block(rewrite(segment, verify(convert(
36
36
  },
37
37
  union([figure]),
38
38
  false),
39
- ([el]) => el.tagName === 'FIGURE')));
39
+ ([{ value: el }]) => el.tagName === 'FIGURE')));
40
40
 
41
41
  const parser = sequence([
42
42
  line(close(seg_label, /(?=\s).*\n/y)),
@@ -1,4 +1,5 @@
1
1
  import { ExtensionParser } from '../../block';
2
+ import { List, Data } from '../../../combinator/data/parser';
2
3
  import { union, block, line, validate, fmap } from '../../../combinator';
3
4
  import { label } from '../../inline/extension/label';
4
5
  import { html } from 'typed-dom/dom';
@@ -6,14 +7,14 @@ import { html } from 'typed-dom/dom';
6
7
  export const figbase: ExtensionParser.FigbaseParser = block(fmap(
7
8
  validate(/\[?\$-(?:[0-9]+\.)*0\]?[^\S\n]*(?!\S|\n[^\S\n]*\S)/y,
8
9
  line(union([label]))),
9
- ([el]) => {
10
+ ([{ value: el }]) => {
10
11
  const label = el.getAttribute('data-label')!;
11
12
  const group = label.split('-', 1)[0];
12
- return [
13
- html('figure', {
13
+ return new List([
14
+ new Data(html('figure', {
14
15
  'data-label': label,
15
16
  'data-group': group,
16
17
  hidden: '',
17
- }),
18
- ];
18
+ })),
19
+ ]);
19
20
  }));
@@ -1,5 +1,5 @@
1
1
  import { ExtensionParser } from '../../block';
2
- import { input } from '../../../combinator/data/parser';
2
+ import { List, Data, subinput } from '../../../combinator/data/parser';
3
3
  import { union, inits, sequence, some, block, line, fence, rewrite, close, match, convert, fallback, fmap } from '../../../combinator';
4
4
  import { str, contentline, emptyline } from '../../source';
5
5
  import { label, segment as seg_label } from '../../inline/extension/label';
@@ -14,7 +14,7 @@ import { blockquote, segment as seg_blockquote } from '../blockquote';
14
14
  import { placeholder, segment_ as seg_placeholder } from './placeholder';
15
15
  import { inline, media, lineshortmedia } from '../../inline';
16
16
  import { visualize, trimBlank } from '../../visibility';
17
- import { invalid } from '../../util';
17
+ import { unwrap, invalid } from '../../util';
18
18
  import { memoize } from 'spica/memoize';
19
19
  import { html, defrag } from 'typed-dom/dom';
20
20
 
@@ -44,7 +44,7 @@ export const segment: FigureParser.SegmentParser = block(match(
44
44
  ]),
45
45
  ]),
46
46
  closer),
47
- ([, fence]) => fence.length, {})));
47
+ ([, fence]) => fence.length <= 16 ? fence.length : -1, [])));
48
48
 
49
49
  export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
50
50
  convert(source => source.slice(source.match(/^~+(?:\w+\s+)?/)![0].length, source.trimEnd().lastIndexOf('\n')),
@@ -68,20 +68,24 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
68
68
  block(visualize(trimBlank(some(inline)))),
69
69
  ]),
70
70
  ]), false),
71
- ([label, param, content, ...caption]: [HTMLAnchorElement, string, ...HTMLElement[]]) => [
72
- html('figure',
73
- attributes(label.getAttribute('data-label')!, param, content, caption),
74
- [
75
- html('figcaption', [
76
- html('span', { class: 'figindex' }),
77
- html('span', { class: 'figtext' }, defrag(caption)),
78
- ]),
79
- html('div', [content]),
80
- ])
81
- ])),
71
+ nodes => {
72
+ const [label, param, content, ...caption] = unwrap(nodes) as [HTMLAnchorElement, string, ...HTMLElement[]];
73
+ return new List([
74
+ new Data(html('figure',
75
+ attributes(label.getAttribute('data-label')!, param, content, caption),
76
+ [
77
+ html('figcaption', [
78
+ html('span', { class: 'figindex' }),
79
+ html('span', { class: 'figtext' }, defrag(caption)),
80
+ ]),
81
+ html('div', [content]),
82
+ ]))
83
+ ]);
84
+ })),
82
85
  fmap(
83
86
  fence(/(~{3,})(?:figure|\[?\$\S*)(?!\S)[^\n]*(?:$|\n)/y, 300),
84
- ([body, overflow, closer, opener, delim]: string[], context) => {
87
+ (nodes, context) => {
88
+ const [body, overflow, closer, opener, delim] = unwrap<string>(nodes);
85
89
  const violation =
86
90
  !closer && [
87
91
  'fence',
@@ -91,7 +95,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
91
95
  'fence',
92
96
  `Invalid trailing line after the closing delimiter "${delim}"`,
93
97
  ] ||
94
- !seg_label(input(opener.match(/^~+(?:figure[^\S\n]+)?(\[?\$\S+)/)?.[1] ?? '', { ...context })) && [
98
+ !seg_label(subinput(opener.match(/^~+(?:figure[^\S\n]+)?(\[?\$\S+)/)?.[1] ?? '', context)) && [
95
99
  'label',
96
100
  'Invalid label',
97
101
  ] ||
@@ -103,13 +107,13 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
103
107
  'content',
104
108
  'Invalid content',
105
109
  ];
106
- return [
107
- html('pre', {
110
+ return new List([
111
+ new Data(html('pre', {
108
112
  class: 'invalid',
109
113
  translate: 'no',
110
114
  ...invalid('figure', violation[0], violation[1]),
111
- }, `${opener}${body}${overflow || closer}`),
112
- ];
115
+ }, `${opener}${body}${overflow || closer}`)),
116
+ ]);
113
117
  })));
114
118
 
115
119
  function attributes(label: string, param: string, content: HTMLElement, caption: readonly HTMLElement[]): Record<string, string | undefined> {
@@ -1,5 +1,5 @@
1
1
  import { ExtensionParser } from '../../block';
2
- import { input, eval } from '../../../combinator/data/parser';
2
+ import { List, Data, subinput } from '../../../combinator/data/parser';
3
3
  import { union, block, fence, fmap } from '../../../combinator';
4
4
  import { segment } from '../../segment';
5
5
  import { emptyline } from '../../source';
@@ -13,8 +13,8 @@ import { sidefence } from '../sidefence';
13
13
  import { blockquote } from '../blockquote';
14
14
  import { mediablock } from '../mediablock';
15
15
  import { paragraph } from '../paragraph';
16
- import { invalid } from '../../util';
17
- import { unshift, push } from 'spica/array';
16
+ import { unwrap, invalid } from '../../util';
17
+ import { push } from 'spica/array';
18
18
  import { html } from 'typed-dom/dom';
19
19
 
20
20
  import MessageParser = ExtensionParser.MessageParser;
@@ -22,34 +22,45 @@ import MessageParser = ExtensionParser.MessageParser;
22
22
  export const message: MessageParser = block(fmap(
23
23
  fence(/(~{3,})message\/(\S+)([^\n]*)(?:$|\n)/y, 300),
24
24
  // Bug: Type mismatch between outer and inner.
25
- ([body, overflow, closer, opener, delim, type, param]: string[], context) => {
26
- if (!closer || overflow || param.trimStart()) return [html('pre', {
27
- class: 'invalid',
28
- translate: 'no',
29
- ...invalid(
30
- 'message',
31
- !closer || overflow ? 'fence' : 'argument',
32
- !closer ? `Missing the closing delimiter "${delim}"` :
33
- overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
34
- 'Invalid argument'),
35
- }, `${opener}${body}${overflow || closer}`)];
25
+ (nodes: List<Data<string>>, context) => {
26
+ const [body, overflow, closer, opener, delim, type, param] = unwrap(nodes);
27
+ if (!closer || overflow || param.trimStart()) return new List([
28
+ new Data(html('pre', {
29
+ class: 'invalid',
30
+ translate: 'no',
31
+ ...invalid(
32
+ 'message',
33
+ !closer || overflow ? 'fence' : 'argument',
34
+ !closer ? `Missing the closing delimiter "${delim}"` :
35
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
36
+ 'Invalid argument'),
37
+ }, `${opener}${body}${overflow || closer}`))
38
+ ]);
36
39
  switch (type) {
37
40
  case 'note':
38
41
  case 'caution':
39
42
  case 'warning':
40
43
  break;
41
44
  default:
42
- return [html('pre', {
43
- class: 'invalid',
44
- translate: 'no',
45
- ...invalid('message', 'type', 'Invalid message type'),
46
- }, `${opener}${body}${closer}`)];
45
+ return new List([
46
+ new Data(html('pre', {
47
+ class: 'invalid',
48
+ translate: 'no',
49
+ ...invalid('message', 'type', 'Invalid message type'),
50
+ }, `${opener}${body}${closer}`))
51
+ ]);
47
52
  }
48
- return [
49
- html('section', { class: `message`, 'data-type': type }, unshift(
50
- [html('h1', title(type))],
51
- [...segment(body)].reduce((acc, seg) => push(acc, eval(content(input(seg, { ...context })), [])), []))),
52
- ];
53
+ return new List([
54
+ new Data(html('section',
55
+ {
56
+ class: `message`,
57
+ 'data-type': type,
58
+ },
59
+ [...segment(body)].reduce(
60
+ (acc, seg) =>
61
+ push(acc, unwrap(content(subinput(seg, context)))),
62
+ [html('h1', title(type))])))
63
+ ]);
53
64
  }));
54
65
 
55
66
  function title(type: string): string {
@@ -1,6 +1,7 @@
1
1
  import { ExtensionParser } from '../../block';
2
+ import { List, Data } from '../../../combinator/data/parser';
2
3
  import { block, fence, clear, fmap } from '../../../combinator';
3
- import { invalid } from '../../util';
4
+ import { unwrap, invalid } from '../../util';
4
5
  import { html } from 'typed-dom/dom';
5
6
 
6
7
  const opener = /(~{3,})(?!~)[^\n]*(?:$|\n)/y;
@@ -13,15 +14,18 @@ export const segment_: ExtensionParser.PlaceholderParser.SegmentParser = block(
13
14
 
14
15
  export const placeholder: ExtensionParser.PlaceholderParser = block(fmap(
15
16
  fence(opener, Infinity),
16
- ([body, overflow, closer, opener, delim]) => [
17
- html('pre', {
18
- class: 'invalid',
19
- translate: 'no',
20
- ...invalid(
21
- 'extension',
22
- 'fence',
23
- !closer ? `Missing the closing delimiter "${delim}"` :
24
- overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
25
- 'Invalid argument'),
26
- }, `${opener}${body}${overflow || closer}`),
27
- ]));
17
+ nodes => {
18
+ const [body, overflow, closer, opener, delim] = unwrap(nodes);
19
+ return new List([
20
+ new Data(html('pre', {
21
+ class: 'invalid',
22
+ translate: 'no',
23
+ ...invalid(
24
+ 'extension',
25
+ 'fence',
26
+ !closer ? `Missing the closing delimiter "${delim}"` :
27
+ overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
28
+ 'Invalid argument'),
29
+ }, `${opener}${body}${overflow || closer}`)),
30
+ ]);
31
+ }));