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,9 +1,10 @@
1
1
  import { TableParser } from '../block';
2
+ import { List, Data } from '../../combinator/data/parser';
2
3
  import { union, sequence, some, block, line, validate, focus, rewrite, surround, open, close, fallback, lazy, fmap } from '../../combinator';
3
4
  import { inline, media, medialink, shortmedia } from '../inline';
4
5
  import { contentline } from '../source';
5
6
  import { trimBlank } from '../visibility';
6
- import { invalid } from '../util';
7
+ import { unwrap, invalid } from '../util';
7
8
  import { duffReduce } from 'spica/duff';
8
9
  import { push } from 'spica/array';
9
10
  import { html, defrag } from 'typed-dom/dom';
@@ -19,32 +20,32 @@ export const table: TableParser = lazy(() => block(fmap(validate(
19
20
  row(some(align), false),
20
21
  some(row(some(data), true)),
21
22
  ])),
22
- rows => [
23
- html('table', [
24
- html('thead', [rows.shift()!]),
25
- html('tbody', format(rows)),
26
- ]),
27
- ])));
23
+ rows => new List([
24
+ new Data(html('table', [
25
+ html('thead', [rows.shift()!.value]),
26
+ html('tbody', unwrap(format(rows))),
27
+ ])),
28
+ ]))));
28
29
 
29
30
  const row = <P extends CellParser | AlignParser>(parser: P, optional: boolean): RowParser<P> => fallback(fmap(
30
31
  line(surround(/(?=\|)/y, some(union([parser])), /[|\\]?\s*$/y, optional)),
31
- es => [html('tr', es)]),
32
- rewrite(contentline, ({ context: { source } }) => [[
33
- html('tr', {
32
+ ns => new List([new Data(html('tr', unwrap(ns)))])),
33
+ rewrite(contentline, ({ context: { source } }) => new List([
34
+ new Data(html('tr', {
34
35
  class: 'invalid',
35
36
  ...invalid('table-row', 'syntax', 'Missing the start symbol of the table row'),
36
- }, [html('td', source.replace('\n', ''))])
37
- ]]));
37
+ }, [html('td', source.replace('\n', ''))]))
38
+ ])));
38
39
 
39
40
  const align: AlignParser = fmap(open(
40
41
  '|',
41
42
  union([
42
43
  focus(/:-+:?/y, ({ context: { source } }) =>
43
- [[source.at(-1) === ':' ? 'center' : 'start']]),
44
+ new List([new Data(source.at(-1) === ':' ? 'center' : 'start')])),
44
45
  focus(/-+:?/y, ({ context: { source } }) =>
45
- [[source.at(-1) === ':' ? 'end' : '']]),
46
+ new List([new Data(source.at(-1) === ':' ? 'end' : '')])),
46
47
  ])),
47
- ns => [html('td', defrag(ns))]);
48
+ ns => new List([new Data(html('td', defrag(unwrap(ns))))]));
48
49
 
49
50
  const cell: CellParser = surround(
50
51
  /\|\s*(?=\S)/y,
@@ -58,18 +59,18 @@ const cell: CellParser = surround(
58
59
 
59
60
  const head: CellParser.HeadParser = fmap(
60
61
  cell,
61
- ns => [html('th', defrag(ns))]);
62
+ ns => new List([new Data(html('th', defrag(unwrap(ns))))]));
62
63
 
63
64
  const data: CellParser.DataParser = fmap(
64
65
  cell,
65
- ns => [html('td', defrag(ns))]);
66
+ ns => new List([new Data(html('td', defrag(unwrap(ns))))]));
66
67
 
67
- function format(rows: HTMLTableRowElement[]): HTMLTableRowElement[] {
68
- const aligns = rows[0].className === 'invalid'
68
+ function format(rows: List<Data<HTMLTableRowElement>>): List<Data<HTMLTableRowElement>> {
69
+ const aligns = rows.head!.value.className === 'invalid'
69
70
  ? []
70
- : duffReduce(rows.shift()!.children, (acc, el) => push(acc, [el.textContent!]), [] as string[]);
71
- for (let i = 0; i < rows.length; ++i) {
72
- for (let cols = rows[i].children, len = cols.length, j = 0; j < len; ++j) {
71
+ : duffReduce(rows.shift()!.value.children, (acc, el) => push(acc, [el.textContent!]), [] as string[]);
72
+ for (const { value: row } of rows) {
73
+ for (let cols = row.children, len = cols.length, j = 0; j < len; ++j) {
73
74
  if (j > 0 && !aligns[j]) {
74
75
  aligns[j] = aligns[j - 1];
75
76
  }
@@ -1,11 +1,12 @@
1
1
  import { UListParser } from '../block';
2
2
  import { Recursion } from '../context';
3
+ import { List, Data } from '../../combinator/data/parser';
3
4
  import { union, inits, subsequence, some, recursion, block, line, validate, indent, focus, open, fallback, lazy, fmap } from '../../combinator';
4
5
  import { olist_ } from './olist';
5
6
  import { ilist_, ilistitem } from './ilist';
6
7
  import { inline, indexer, indexee, dataindex } from '../inline';
7
8
  import { visualize, trimBlank } from '../visibility';
8
- import { unshift } from 'spica/array';
9
+ import { unwrap } from '../util';
9
10
  import { html, defrag } from 'typed-dom/dom';
10
11
 
11
12
  export const ulist: UListParser = lazy(() => block(validate(
@@ -24,22 +25,25 @@ export const ulist_: UListParser = lazy(() => block(fmap(validate(
24
25
  indent(union([ulist_, olist_, ilist_])),
25
26
  ]),
26
27
  ilistitem),
27
- ns => [html('li', { 'data-index': dataindex(ns) }, defrag(fillFirstLine(ns)))])),
28
+ ns => new List([new Data(html('li', { 'data-index': dataindex(ns) }, defrag(unwrap(fillFirstLine(ns)))))]))),
28
29
  ])))),
29
- es => [format(html('ul', es))])));
30
+ ns => new List([new Data(format(html('ul', unwrap(ns))))]))));
30
31
 
31
32
  export const checkbox = focus(
32
33
  /\[[xX ]\](?=$|[ \n])/y,
33
- ({ context: { source } }) => [[
34
- html('span', { class: 'checkbox' }, source[1].trimStart() ? '☑' : '☐'),
35
- ]]);
34
+ ({ context: { source } }) => new List([
35
+ new Data(html('span', { class: 'checkbox' }, source[1].trimStart() ? '☑' : '☐')),
36
+ ]));
36
37
 
37
- export function fillFirstLine(ns: (HTMLElement | string)[]): (HTMLElement | string)[] {
38
- return ns.length === 1
39
- && typeof ns[0] === 'object'
40
- && ['UL', 'OL'].includes(ns[0].tagName)
41
- ? unshift([html('br')], ns)
42
- : ns;
38
+ export function fillFirstLine(nodes: List<Data<string | HTMLElement>>): List<Data<string | HTMLElement>> {
39
+ const node = nodes.head?.value;
40
+ if (typeof node !== 'object') return nodes;
41
+ switch (node.tagName) {
42
+ case 'UL':
43
+ case 'OL':
44
+ nodes.unshift(new Data(html('br')));
45
+ }
46
+ return nodes;
43
47
  }
44
48
 
45
49
  function format(list: HTMLUListElement): HTMLUListElement {
@@ -1,5 +1,6 @@
1
1
  import { MarkdownParser } from '../../markdown';
2
2
  import { Recursion, Command } from './context';
3
+ import { List, Data } from '../combinator/data/parser';
3
4
  import { union, reset, open, fallback, recover } from '../combinator';
4
5
  import { MAX_SEGMENT_SIZE } from './segment';
5
6
  import { emptyline } from './source';
@@ -60,6 +61,10 @@ export const block: BlockParser = reset(
60
61
  if (position === source.length) return;
61
62
  const fst = source[position];
62
63
  switch (fst) {
64
+ case '\n':
65
+ assert(source.trim() === '');
66
+ input.context.position = source.length;
67
+ return new List();
63
68
  case '=':
64
69
  if (source.startsWith('===', position)) return pagebreak(input);
65
70
  break;
@@ -113,16 +118,16 @@ function error(parser: BlockParser): BlockParser {
113
118
  return recover<BlockParser>(fallback(
114
119
  open(Command.Error, ({ context: { source, position } }) => { throw new Error(source.slice(position).split('\n', 1)[0]); }),
115
120
  parser),
116
- ({ context: { source, position, id } }, reason) => [[
117
- html('h1',
121
+ ({ context: { source, position, id } }, reason) => new List([
122
+ new Data(html('h1',
118
123
  {
119
124
  id: id !== '' ? `error:${rnd0Z(8)}` : undefined,
120
125
  class: 'error',
121
126
  },
122
127
  reason instanceof Error
123
128
  ? `${reason.name}: ${reason.message}`
124
- : `UnknownError: ${reason}`),
125
- html('pre',
129
+ : `UnknownError: ${reason}`)),
130
+ new Data(html('pre',
126
131
  {
127
132
  class: 'error',
128
133
  translate: 'no',
@@ -130,6 +135,6 @@ function error(parser: BlockParser): BlockParser {
130
135
  source.slice(position)
131
136
  .replace(reg, '')
132
137
  .slice(0, 1001)
133
- .replace(/^(.{997}).{4}$/s, '$1...') || undefined),
134
- ]]);
138
+ .replace(/^(.{997}).{4}$/s, '$1...') || undefined)),
139
+ ]));
135
140
  }
@@ -1,8 +1,9 @@
1
1
  import { MarkdownParser } from '../../markdown';
2
+ import { List, Data } from '../combinator/data/parser';
2
3
  import { union, inits, some, block, line, validate, focus, rewrite, clear, convert, lazy, fmap } from '../combinator';
3
4
  import { segment } from './segment';
4
5
  import { str } from './source';
5
- import { invalid } from './util';
6
+ import { unwrap, invalid } from './util';
6
7
  import { normalize } from './api/normalize';
7
8
  import { html, defrag } from 'typed-dom/dom';
8
9
 
@@ -18,7 +19,7 @@ export const header: MarkdownParser.HeaderParser = lazy(() => validate(
18
19
  else {
19
20
  context.position = source.length;
20
21
  }
21
- return [[]];
22
+ return new List();
22
23
  },
23
24
  block(
24
25
  union([
@@ -28,24 +29,23 @@ export const header: MarkdownParser.HeaderParser = lazy(() => validate(
28
29
  normalize(source.slice(source.indexOf('\n') + 1, source.trimEnd().lastIndexOf('\n'))).replace(/(\S)\s+$/mg, '$1'),
29
30
  fmap(
30
31
  some(union([field])),
31
- es => [
32
- html('aside', { class: 'header' }, [
33
- html('details', { open: '' }, defrag([
34
- html('summary', 'Header'),
35
- ...es,
36
- ])),
37
- ]),
38
- ]), false))),
32
+ ns => new List([
33
+ new Data(html('aside', { class: 'header' }, [
34
+ html('details',
35
+ { open: '' },
36
+ defrag(unwrap(ns.unshift(new Data(html('summary', 'Header'))) && ns))),
37
+ ])),
38
+ ])), false))),
39
39
  ({ context }) => {
40
40
  const { source, position } = context;
41
41
  context.position += source.length;
42
- return [[
43
- html('pre', {
42
+ return new List([
43
+ new Data(html('pre', {
44
44
  class: 'invalid',
45
45
  translate: 'no',
46
46
  ...invalid('header', 'syntax', 'Invalid syntax'),
47
- }, normalize(source.slice(position))),
48
- ]];
47
+ }, normalize(source.slice(position)))),
48
+ ]);
49
49
  },
50
50
  ]))),
51
51
  clear(str(/[^\S\v\f\r\n]*\r?\n/y)),
@@ -54,12 +54,12 @@ export const header: MarkdownParser.HeaderParser = lazy(() => validate(
54
54
  const field: MarkdownParser.HeaderParser.FieldParser = line(({ context: { source, position } }) => {
55
55
  const name = source.slice(position, source.indexOf(':', position));
56
56
  const value = source.slice(position + name.length + 1).trim();
57
- return [[
58
- html('span', { class: 'field', 'data-name': name.toLowerCase(), 'data-value': value }, [
57
+ return new List([
58
+ new Data(html('span', { class: 'field', 'data-name': name.toLowerCase(), 'data-value': value }, [
59
59
  html('span', { class: 'field-name' }, name),
60
60
  ': ',
61
61
  html('span', { class: 'field-value' }, value),
62
62
  '\n',
63
- ]),
64
- ]];
63
+ ])),
64
+ ]);
65
65
  });
@@ -1,8 +1,10 @@
1
1
  import { AnnotationParser } from '../inline';
2
2
  import { State, Backtrack } from '../context';
3
+ import { List, Data } from '../../combinator/data/parser';
3
4
  import { union, some, precedence, state, constraint, surround, lazy } from '../../combinator';
4
5
  import { inline } from '../inline';
5
6
  import { trimBlankStart, trimBlankNodeEnd } from '../visibility';
7
+ import { unwrap } from '../util';
6
8
  import { html, defrag } from 'typed-dom/dom';
7
9
 
8
10
  export const annotation: AnnotationParser = lazy(() => constraint(State.annotation, surround(
@@ -13,7 +15,7 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
13
15
  false,
14
16
  ([, ns], context) =>
15
17
  context.linebreak === 0
16
- ? [[html('sup', { class: 'annotation' }, [html('span', defrag(trimBlankNodeEnd(ns)))])]]
18
+ ? new List([new Data(html('sup', { class: 'annotation' }, [html('span', defrag(unwrap(trimBlankNodeEnd(ns))))]))])
17
19
  : undefined,
18
20
  undefined,
19
21
  [1 | Backtrack.bracket, 3 | Backtrack.doublebracket])));
@@ -1,5 +1,6 @@
1
1
  import { AutolinkParser } from '../../inline';
2
2
  import { State, Backtrack } from '../../context';
3
+ import { List, Data } from '../../../combinator/data/parser';
3
4
  import { union, tails, state, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
4
5
  import { unsafelink } from '../link';
5
6
  import { str } from '../../source';
@@ -26,6 +27,6 @@ export const account: AutolinkParser.AccountParser = lazy(() => rewrite(
26
27
  } }`,
27
28
  unsafelink,
28
29
  false),
29
- ([el]) => [define(el, { class: 'account' })]))),
30
- ({ context: { source } }) => [[source]],
30
+ ([{ value }]) => new List([new Data(define(value, { class: 'account' }))])))),
31
+ ({ context: { source } }) => new List([new Data(source)]),
31
32
  ])));
@@ -1,5 +1,6 @@
1
1
  import { AutolinkParser } from '../../inline';
2
2
  import { State, Backtrack } from '../../context';
3
+ import { List, Data } from '../../../combinator/data/parser';
3
4
  import { union, state, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
4
5
  import { unsafelink } from '../link';
5
6
  import { str } from '../../source';
@@ -30,6 +31,6 @@ export const anchor: AutolinkParser.AnchorParser = lazy(() => rewrite(
30
31
  } }`,
31
32
  unsafelink,
32
33
  false),
33
- ([el]) => [define(el, { class: 'anchor' })]))),
34
- ({ context: { source } }) => [[source]],
34
+ ([{ value }]) => new List([new Data(define(value, { class: 'anchor' }))])))),
35
+ ({ context: { source } }) => new List([new Data(source)]),
35
36
  ])));
@@ -1,5 +1,6 @@
1
1
  import { AutolinkParser } from '../../inline';
2
2
  import { State, Backtrack } from '../../context';
3
+ import { List, Data } from '../../../combinator/data/parser';
3
4
  import { union, tails, sequence, some, state, constraint, verify, rewrite, open, convert, fmap, lazy } from '../../../combinator';
4
5
  import { unsafelink } from '../link';
5
6
  import { emoji } from './hashtag';
@@ -24,7 +25,7 @@ export const channel: AutolinkParser.ChannelParser = lazy(() => rewrite(
24
25
  str(new RegExp([
25
26
  /(?!['_])(?:[^\p{C}\p{S}\p{P}\s]|emoji|'(?=[0-9A-Za-z])|_(?=[^'\p{C}\p{S}\p{P}\s]|emoji))+(?![0-9a-z@]|>>|:\S|[^\p{C}\p{S}\p{P}\s]|emoji)/yu.source,
26
27
  ].join('').replace(/emoji/g, emoji), 'yu')),
27
- ([source]) => !/^[0-9]{1,4}$|^[0-9]{5}/.test(source)),
28
+ ([{ value }]) => !/^[0-9]{1,4}$|^[0-9]{5}/.test(value)),
28
29
  false,
29
30
  [3 | Backtrack.autolink])),
30
31
  ]),
@@ -38,10 +39,10 @@ export const channel: AutolinkParser.ChannelParser = lazy(() => rewrite(
38
39
  } }`,
39
40
  unsafelink,
40
41
  false),
41
- ([el], { source, position, range = 0 }) => {
42
+ ([{ value: el }], { source, position, range = 0 }) => {
42
43
  const src = source.slice(position - range, position);
43
44
  const url = `${el.getAttribute('href')}?ch=${src.slice(src.indexOf('#') + 1).replace(/#/g, '+')}`;
44
- return [define(el, { class: 'channel', href: url }, src)];
45
+ return new List([new Data(define(el, { class: 'channel', href: url }, src))]);
45
46
  }))),
46
- ({ context: { source } }) => [[source]],
47
+ ({ context: { source } }) => new List([new Data(source)]),
47
48
  ])));
@@ -1,5 +1,6 @@
1
1
  import { AutolinkParser } from '../../inline';
2
2
  import { State, Backtrack } from '../../context';
3
+ import { List, Data } from '../../../combinator/data/parser';
3
4
  import { union, state, constraint, verify, rewrite, open } from '../../../combinator';
4
5
  import { str } from '../../source';
5
6
  import { html } from 'typed-dom/dom';
@@ -10,11 +11,11 @@ export const email: AutolinkParser.EmailParser = rewrite(
10
11
  open(/(?<![0-9a-z][_.+-]?)(?=[0-9a-z])/yi,
11
12
  verify(
12
13
  str(/[0-9a-z](?:[_.+-](?=[0-9a-z])|[0-9a-z]){0,255}@[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*(?![0-9a-z@#]|>>|:\S)/yi),
13
- ([source]) => source.length <= 255),
14
+ ([{ value }]) => value.length <= 255),
14
15
  false,
15
16
  [3 | Backtrack.autolink]),
16
17
  union([
17
18
  constraint(State.autolink, state(State.autolink,
18
- ({ context: { source } }) => [[html('a', { class: 'email', href: `mailto:${source}` }, source)]])),
19
- ({ context: { source } }) => [[source]],
19
+ ({ context: { source } }) => new List([new Data(html('a', { class: 'email', href: `mailto:${source}` }, source))]))),
20
+ ({ context: { source } }) => new List([new Data(source)]),
20
21
  ]));
@@ -1,5 +1,6 @@
1
1
  import { AutolinkParser } from '../../inline';
2
2
  import { State, Backtrack } from '../../context';
3
+ import { List, Data } from '../../../combinator/data/parser';
3
4
  import { union, state, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
4
5
  import { unsafelink } from '../link';
5
6
  import { emoji } from './hashtag';
@@ -21,6 +22,6 @@ export const hashnum: AutolinkParser.HashnumParser = lazy(() => rewrite(
21
22
  source => `[${source}]{ ${source.slice(1)} }`,
22
23
  unsafelink,
23
24
  false),
24
- ([el]) => [define(el, { class: 'hashnum', href: null })]))),
25
- ({ context: { source } }) => [[source]],
25
+ ([{ value }]) => new List([new Data(define(value, { class: 'hashnum', href: null }))])))),
26
+ ({ context: { source } }) => new List([new Data(source)]),
26
27
  ])));
@@ -1,5 +1,6 @@
1
1
  import { AutolinkParser } from '../../inline';
2
2
  import { State, Backtrack } from '../../context';
3
+ import { List, Data } from '../../../combinator/data/parser';
3
4
  import { union, state, constraint, verify, rewrite, open, convert, fmap, lazy } from '../../../combinator';
4
5
  import { unsafelink } from '../link';
5
6
  import { str } from '../../source';
@@ -19,7 +20,7 @@ export const hashtag: AutolinkParser.HashtagParser = lazy(() => rewrite(
19
20
  str(new RegExp([
20
21
  /(?!['_])(?:[^\p{C}\p{S}\p{P}\s]|emoji|'(?=[0-9A-Za-z])|_(?=[^'\p{C}\p{S}\p{P}\s]|emoji))+(?![0-9a-z@#]|>>|:\S|[^\p{C}\p{S}\p{P}\s]|emoji)/yu.source,
21
22
  ].join('').replace(/emoji/g, emoji), 'yu')),
22
- ([source]) => !/^[0-9]{1,4}$|^[0-9]{5}/.test(source)),
23
+ ([{ value }]) => !/^[0-9]{1,4}$|^[0-9]{5}/.test(value)),
23
24
  false,
24
25
  [3 | Backtrack.autolink]),
25
26
  union([
@@ -27,6 +28,6 @@ export const hashtag: AutolinkParser.HashtagParser = lazy(() => rewrite(
27
28
  source => `[${source}]{ ${`/hashtags/${source.slice(1)}`} }`,
28
29
  unsafelink,
29
30
  false),
30
- ([el]) => [define(el, { class: 'hashtag' })]))),
31
- ({ context: { source } }) => [[source]],
31
+ ([{ value }]) => new List([new Data(define(value, { class: 'hashtag' }))])))),
32
+ ({ context: { source } }) => new List([new Data(source)]),
32
33
  ])));
@@ -1,5 +1,6 @@
1
1
  import { AutolinkParser } from '../../inline';
2
2
  import { State, Recursion, Backtrack } from '../../context';
3
+ import { List, Data } from '../../../combinator/data/parser';
3
4
  import { union, tails, some, recursion, precedence, state, constraint, verify, focus, rewrite, convert, surround, open, lazy } from '../../../combinator';
4
5
  import { unsafelink } from '../link';
5
6
  import { unescsource, str } from '../../source';
@@ -18,7 +19,7 @@ export const url: AutolinkParser.UrlParser = lazy(() => rewrite(
18
19
  url => `{ ${url} }`,
19
20
  unsafelink,
20
21
  false))),
21
- ({ context: { source } }) => [[source]],
22
+ ({ context: { source } }) => new List([new Data(source)]),
22
23
  ])));
23
24
 
24
25
  export const lineurl: AutolinkParser.UrlParser.LineUrlParser = lazy(() => focus(
@@ -30,17 +31,17 @@ export const lineurl: AutolinkParser.UrlParser.LineUrlParser = lazy(() => focus(
30
31
  url => `{ ${url} }`,
31
32
  unsafelink,
32
33
  false))),
33
- ({ context: { source } }) => [[source]],
34
+ ({ context: { source } }) => new List([new Data(source)]),
34
35
  ]),
35
36
  ])));
36
37
 
37
38
  const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => union([
38
39
  surround(str('('), recursion(Recursion.terminal, some(union([bracket, unescsource]), ')')), str(')'), true,
39
- undefined, () => [[]], [3 | Backtrack.autolink]),
40
+ undefined, () => new List(), [3 | Backtrack.autolink]),
40
41
  surround(str('['), recursion(Recursion.terminal, some(union([bracket, unescsource]), ']')), str(']'), true,
41
- undefined, () => [[]], [3 | Backtrack.autolink]),
42
+ undefined, () => new List(), [3 | Backtrack.autolink]),
42
43
  surround(str('{'), recursion(Recursion.terminal, some(union([bracket, unescsource]), '}')), str('}'), true,
43
- undefined, () => [[]], [3 | Backtrack.autolink]),
44
+ undefined, () => new List(), [3 | Backtrack.autolink]),
44
45
  surround(str('"'), precedence(2, recursion(Recursion.terminal, some(unescsource, '"'))), str('"'), true,
45
- undefined, () => [[]], [3 | Backtrack.autolink]),
46
+ undefined, () => new List(), [3 | Backtrack.autolink]),
46
47
  ]));
@@ -1,10 +1,11 @@
1
1
  import { BracketParser } from '../inline';
2
2
  import { State, Recursion, Backtrack } from '../context';
3
+ import { List, Data } from '../../combinator/data/parser';
3
4
  import { union, some, recursion, precedence, surround, isBacktrack, setBacktrack, lazy } from '../../combinator';
4
5
  import { inline } from '../inline';
5
6
  import { textlink } from './link';
6
7
  import { str } from '../source';
7
- import { unshift, push } from 'spica/array';
8
+ import { unwrap } from '../util';
8
9
  import { html, defrag } from 'typed-dom/dom';
9
10
 
10
11
  const indexA = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*$/;
@@ -38,13 +39,13 @@ const p1 = lazy(() => surround(
38
39
  precedence(1, recursion(Recursion.bracket, some(inline, ')', [[')', 1]]))),
39
40
  str(')'),
40
41
  true,
41
- ([as, bs = [], cs], { source, position, range = 0 }) => {
42
+ ([as, bs = new List(), cs], { source, position, range = 0 }) => {
42
43
  const str = source.slice(position - range + 1, position - 1);
43
44
  return indexA.test(str)
44
- ? [[as[0], str, cs[0]]]
45
- : [[html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))]];
45
+ ? new List([new Data(as.head!.value), new Data(str), new Data(cs.head!.value)])
46
+ : new List([new Data(html('span', { class: 'paren' }, defrag(unwrap(as.import(bs as List<Data<string>>).import(cs)))))]);
46
47
  },
47
- ([as, bs = []]) => [unshift(as, bs)],
48
+ ([as, bs = new List()]) => as.import(bs as List<Data<string>>),
48
49
  [2 | Backtrack.bracket]));
49
50
 
50
51
  const p2 = lazy(() => surround(
@@ -55,10 +56,10 @@ const p2 = lazy(() => surround(
55
56
  ([as, bs = [], cs], { source, position, range = 0 }) => {
56
57
  const str = source.slice(position - range + 1, position - 1);
57
58
  return indexF.test(str)
58
- ? [[as[0], str, cs[0]]]
59
- : [[html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))]];
59
+ ? new List([new Data(as.head!.value), new Data(str), new Data(cs.head!.value)])
60
+ : new List([new Data(html('span', { class: 'paren' }, defrag(unwrap(as.import(bs as List<Data<string>>).import(cs)))))]);
60
61
  },
61
- ([as, bs = []]) => [unshift(as, bs)],
62
+ ([as, bs = new List()]) => as.import(bs as List<Data<string>>),
62
63
  [2 | Backtrack.bracket]));
63
64
 
64
65
  const s1 = lazy(() => surround(
@@ -66,7 +67,7 @@ const s1 = lazy(() => surround(
66
67
  precedence(1, recursion(Recursion.bracket, some(inline, ']', [[']', 1]]))),
67
68
  str(']'),
68
69
  true,
69
- ([as, bs = [], cs], context) => {
70
+ ([as, bs = new List(), cs], context) => {
70
71
  if (context.state! & State.link) {
71
72
  const { source, position, range = 0 } = context;
72
73
  const head = position - range;
@@ -86,9 +87,9 @@ const s1 = lazy(() => surround(
86
87
  context.range = range;
87
88
  }
88
89
  }
89
- return [push(unshift(as, bs), cs)];
90
+ return as.import(bs as List<Data<string>>).import(cs);
90
91
  },
91
- ([as, bs = []]) => [unshift(as, bs)],
92
+ ([as, bs = new List()]) => as.import(bs as List<Data<string>>),
92
93
  [2 | Backtrack.bracket]));
93
94
 
94
95
  const s2 = lazy(() => surround(
@@ -97,7 +98,7 @@ const s2 = lazy(() => surround(
97
98
  str(']'),
98
99
  true,
99
100
  undefined,
100
- ([as, bs = []]) => [unshift(as, bs)],
101
+ ([as, bs = new List()]) => as.import(bs as List<Data<string>>),
101
102
  [2 | Backtrack.bracket]));
102
103
 
103
104
  const c1 = lazy(() => surround(
@@ -106,7 +107,7 @@ const c1 = lazy(() => surround(
106
107
  str('}'),
107
108
  true,
108
109
  undefined,
109
- ([as, bs = []]) => [unshift(as, bs)],
110
+ ([as, bs = new List()]) => as.import(bs as List<Data<string>>),
110
111
  [2 | Backtrack.bracket]));
111
112
 
112
113
  const c2 = lazy(() => surround(
@@ -115,7 +116,7 @@ const c2 = lazy(() => surround(
115
116
  str('}'),
116
117
  true,
117
118
  undefined,
118
- ([as, bs = []]) => [unshift(as, bs)],
119
+ ([as, bs = new List()]) => as.import(bs as List<Data<string>>),
119
120
  [2 | Backtrack.bracket]));
120
121
 
121
122
  const d1 = lazy(() => surround(
@@ -125,5 +126,5 @@ const d1 = lazy(() => surround(
125
126
  str('"'),
126
127
  true,
127
128
  undefined,
128
- ([as, bs = []]) => [unshift(as, bs)],
129
+ ([as, bs = new List()]) => as.import(bs as List<Data<string>>),
129
130
  [2 | Backtrack.bracket]));
@@ -1,4 +1,5 @@
1
1
  import { CodeParser } from '../inline';
2
+ import { List, Data } from '../../combinator/data/parser';
2
3
  import { open, match } from '../../combinator';
3
4
  import { Backtrack } from '../context';
4
5
  import { invalid } from '../util';
@@ -10,13 +11,13 @@ export const code: CodeParser = open(
10
11
  /(`+)(?!`)([^\n]*?)(?:((?<!`)\1(?!`))|(?=$|\n))/y,
11
12
  ([whole, opener, body, closer]) => () =>
12
13
  closer
13
- ? [[html('code', { 'data-src': whole }, format(body))]]
14
+ ? new List([new Data(html('code', { 'data-src': whole }, format(body)))])
14
15
  : body
15
- ? [[html('code', {
16
+ ? new List([new Data(html('code', {
16
17
  class: 'invalid',
17
18
  ...invalid('code', 'syntax', `Missing the closing symbol "${opener}"`)
18
- }, whole)]]
19
- : [[opener]],
19
+ }, whole))])
20
+ : new List([new Data(opener)]),
20
21
  true),
21
22
  false,
22
23
  [3 | Backtrack.bracket]);
@@ -1,10 +1,10 @@
1
1
  import { DeletionParser } from '../inline';
2
2
  import { Recursion, Command } from '../context';
3
+ import { List, Data } from '../../combinator/data/parser';
3
4
  import { union, some, recursion, precedence, validate, surround, open, lazy } from '../../combinator';
4
5
  import { inline } from '../inline';
5
6
  import { blankWith } from '../visibility';
6
- import { repeat } from '../util';
7
- import { push } from 'spica/array';
7
+ import { unwrap, repeat } from '../util';
8
8
  import { html, defrag } from 'typed-dom/dom';
9
9
 
10
10
  export const deletion: DeletionParser = lazy(() => validate('~~',
@@ -16,6 +16,6 @@ export const deletion: DeletionParser = lazy(() => validate('~~',
16
16
  open('\n', some(inline, '~'), true),
17
17
  ]))),
18
18
  '~~', false,
19
- ([, bs], { buffer }) => [push(buffer!, bs)],
20
- ([, bs], { buffer }) => bs && [push(push(buffer!, bs), [Command.Cancel])]),
21
- nodes => [html('del', defrag(nodes))]))));
19
+ ([, bs], { buffer }) => buffer!.import(bs),
20
+ ([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
21
+ nodes => new List([new Data(html('del', defrag(unwrap(nodes))))])))));
@@ -1,11 +1,12 @@
1
1
  import { EmphasisParser } from '../inline';
2
2
  import { Recursion } from '../context';
3
+ import { List, Data } from '../../combinator/data/parser';
3
4
  import { union, some, recursion, precedence, surround, open, lazy } from '../../combinator';
4
5
  import { inline } from '../inline';
5
6
  import { strong } from './strong';
6
7
  import { str } from '../source';
7
8
  import { tightStart, blankWith } from '../visibility';
8
- import { unshift } from 'spica/array';
9
+ import { unwrap } from '../util';
9
10
  import { html, defrag } from 'typed-dom/dom';
10
11
 
11
12
  export const emphasis: EmphasisParser = lazy(() => surround(
@@ -17,5 +18,5 @@ export const emphasis: EmphasisParser = lazy(() => surround(
17
18
  open(some(inline, '*'), inline),
18
19
  ]))))),
19
20
  str('*'), false,
20
- ([, bs]) => [[html('em', defrag(bs))]],
21
- ([as, bs]) => bs && [unshift(as, bs)]));
21
+ ([, bs]) => new List([new Data(html('em', defrag(unwrap(bs))))]),
22
+ ([as, bs]) => bs && as.import(bs as List<Data<string>>)));