securemark 0.293.5 → 0.294.0

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 (105) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/index.js +845 -534
  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 +3 -3
  7. package/src/combinator/control/constraint/line.test.ts +7 -7
  8. package/src/combinator/control/constraint/line.ts +1 -1
  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 -4
  15. package/src/combinator/control/manipulation/reverse.ts +2 -2
  16. package/src/combinator/control/manipulation/scope.ts +3 -4
  17. package/src/combinator/control/manipulation/surround.ts +12 -13
  18. package/src/combinator/control/monad/bind.ts +6 -6
  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 +6 -7
  24. package/src/combinator/data/parser/sequence.test.ts +3 -3
  25. package/src/combinator/data/parser/sequence.ts +6 -7
  26. package/src/combinator/data/parser/some.test.ts +3 -3
  27. package/src/combinator/data/parser/some.ts +4 -4
  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 +16 -7
  33. package/src/debug.test.ts +6 -5
  34. package/src/parser/api/bind.ts +4 -6
  35. package/src/parser/api/header.ts +1 -1
  36. package/src/parser/api/normalize.ts +1 -1
  37. package/src/parser/api/parse.ts +3 -1
  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 +23 -19
  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 +7 -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 +39 -30
  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/segment.ts +3 -1
  99. package/src/parser/source/escapable.ts +9 -8
  100. package/src/parser/source/line.ts +4 -3
  101. package/src/parser/source/str.ts +2 -2
  102. package/src/parser/source/text.ts +9 -8
  103. package/src/parser/source/unescapable.ts +6 -5
  104. package/src/parser/util.ts +18 -13
  105. package/src/parser/visibility.ts +19 -20
@@ -1,10 +1,11 @@
1
1
  import { AnyLineParser, EmptyLineParser, ContentLineParser } from '../source';
2
+ import { List } from '../../combinator/data/parser';
2
3
 
3
4
  export const anyline: AnyLineParser = input => {
4
5
  const { context } = input;
5
6
  const { source, position } = context;
6
7
  context.position = source.indexOf('\n', position) + 1 || source.length;
7
- return [[]];
8
+ return new List();
8
9
  };
9
10
  const regEmptyline = /[^\S\n]*(?:$|\n)/y;
10
11
  export const emptyline: EmptyLineParser = input => {
@@ -15,7 +16,7 @@ export const emptyline: EmptyLineParser = input => {
15
16
  const i = regEmptyline.lastIndex;
16
17
  if (i === 0) return;
17
18
  context.position = i;
18
- return [[]];
19
+ return new List();
19
20
  };
20
21
  const regContentline = /[^\S\n]*\S[^\n]*(?:$|\n)/y;
21
22
  export const contentline: ContentLineParser = input => {
@@ -26,5 +27,5 @@ export const contentline: ContentLineParser = input => {
26
27
  const i = regContentline.lastIndex;
27
28
  if (i === 0) return;
28
29
  context.position = i;
29
- return [[]];
30
+ return new List();
30
31
  }
@@ -1,5 +1,5 @@
1
1
  import { StrParser } from '../source';
2
- import { Parser } from '../../combinator/data/parser';
2
+ import { Parser, List, Data } from '../../combinator/data/parser';
3
3
  import { matcher } from '../../combinator';
4
4
 
5
5
  export function str(pattern: string | RegExp): StrParser;
@@ -17,6 +17,6 @@ export function strs(pattern: string): Parser<string> {
17
17
  acc += pattern;
18
18
  context.position += pattern.length;
19
19
  }
20
- return [[acc]];
20
+ return new List([new Data(acc)]);
21
21
  };
22
22
  }
@@ -1,5 +1,6 @@
1
1
  import { TextParser, TxtParser, LinebreakParser } from '../source';
2
2
  import { Command } from '../context';
3
+ import { List, Data } from '../../combinator/data/parser';
3
4
  import { union, consume, focus } from '../../combinator';
4
5
  import { html } from 'typed-dom/dom';
5
6
 
@@ -17,26 +18,26 @@ export const text: TextParser = input => {
17
18
  case '\r':
18
19
  assert(!source.includes('\r', position + 1));
19
20
  consume(-1, context);
20
- return [[]];
21
+ return new List();
21
22
  case Command.Escape:
22
23
  case '\\':
23
24
  switch (source[position + 1]) {
24
25
  case undefined:
25
- return [[]];
26
+ return new List();
26
27
  case '\n':
27
28
  assert(char !== Command.Escape);
28
- return [[]];
29
+ return new List();
29
30
  default:
30
31
  consume(1, context);
31
32
  context.position += 1;
32
- return [[source.slice(position + 1, context.position)]];
33
+ return new List([new Data(source.slice(position + 1, context.position))]);
33
34
  }
34
35
  case '\n':
35
36
  context.linebreak ||= source.length - position;
36
- return [[html('br')]];
37
+ return new List([new Data(html('br'))]);
37
38
  default:
38
39
  assert(char !== '\n');
39
- if (context.sequential) return [[char]];
40
+ if (context.sequential) return new List([new Data(char)]);
40
41
  nonWhitespace.lastIndex = position + 1;
41
42
  const s = canSkip(source, position);
42
43
  let i = s
@@ -54,8 +55,8 @@ export const text: TextParser = input => {
54
55
  context.position += i - 1;
55
56
  const linestart = position === 0 || source[position - 1] === '\n';
56
57
  return position === context.position || s && !linestart || lineend
57
- ? [[]]
58
- : [[source.slice(position, context.position)]];
58
+ ? new List()
59
+ : new List([new Data(source.slice(position, context.position))]);
59
60
  }
60
61
  };
61
62
 
@@ -1,5 +1,6 @@
1
1
  import { UnescapableSourceParser } from '../source';
2
2
  import { Command } from '../context';
3
+ import { List, Data } from '../../combinator/data/parser';
3
4
  import { consume } from '../../combinator';
4
5
  import { nonWhitespace, canSkip, next } from './text';
5
6
  import { html } from 'typed-dom/dom';
@@ -16,17 +17,17 @@ export const unescsource: UnescapableSourceParser = ({ context }) => {
16
17
  case '\r':
17
18
  assert(!source.includes('\r', position + 1));
18
19
  consume(-1, context);
19
- return [[]];
20
+ return new List();
20
21
  case Command.Escape:
21
22
  consume(1, context);
22
23
  context.position += 1;
23
- return [[source.slice(position + 1, position + 2)]];
24
+ return new List([new Data(source.slice(position + 1, position + 2))]);
24
25
  case '\n':
25
26
  context.linebreak ||= source.length - position;
26
- return [[html('br')]];
27
+ return new List([new Data(html('br'))]);
27
28
  default:
28
29
  assert(char !== '\n');
29
- if (context.sequential) return [[char]];
30
+ if (context.sequential) return new List([new Data(char)]);
30
31
  nonWhitespace.lastIndex = position + 1;
31
32
  let i = canSkip(source, position)
32
33
  ? nonWhitespace.test(source)
@@ -37,6 +38,6 @@ export const unescsource: UnescapableSourceParser = ({ context }) => {
37
38
  i -= position;
38
39
  consume(i - 1, context);
39
40
  context.position += i - 1;
40
- return [[source.slice(position, context.position)]];
41
+ return new List([new Data(source.slice(position, context.position))]);
41
42
  }
42
43
  };
@@ -1,28 +1,34 @@
1
1
  import { min } from 'spica/alias';
2
2
  import { MarkdownParser } from '../../markdown';
3
3
  import { Command } from './context';
4
- import { Parser, Result, Ctx, Node, Context, eval, failsafe } from '../combinator/data/parser';
4
+ import { Parser, Result, List, Data, Ctx, Node, Context, eval, failsafe } from '../combinator/data/parser';
5
5
  import { define } from 'typed-dom/dom';
6
6
 
7
- export function repeat<P extends Parser<HTMLElement | string, MarkdownParser.Context>>(symbol: string, parser: P, cons: (nodes: Node<P>[], context: Context<P>) => Node<P>[], termination?: (acc: Node<P>[], context: Ctx, prefix: number, postfix: number, state: boolean) => Result<string | Node<P>>): P;
8
- export function repeat<N extends HTMLElement | string>(symbol: string, parser: Parser<N>, cons: (nodes: N[], context: MarkdownParser.Context) => N[], termination: (acc: N[], context: Ctx, prefix: number, postfix: number, state: boolean) => Result<string | N, MarkdownParser.Context> = (nodes, context, prefix, postfix) => {
9
- const acc = [];
7
+ export function* unwrap<N>(nodes: List<Data<N>>): Iterable<N> {
8
+ for (const node of nodes) {
9
+ yield node.value;
10
+ }
11
+ }
12
+
13
+ export function repeat<P extends Parser<HTMLElement | string, MarkdownParser.Context>>(symbol: string, parser: P, cons: (nodes: List<Data<Node<P>>>, context: Context<P>) => List<Data<Node<P>>>, termination?: (acc: List<Data<Node<P>>>, context: Ctx, prefix: number, postfix: number, state: boolean) => Result<string | Node<P>>): P;
14
+ export function repeat<N extends HTMLElement | string>(symbol: string, parser: Parser<N>, cons: (nodes: List<Data<N>>, context: MarkdownParser.Context) => List<Data<N>>, termination: (acc: List<Data<N>>, context: Ctx, prefix: number, postfix: number, state: boolean) => Result<string | N, MarkdownParser.Context> = (nodes, context, prefix, postfix) => {
15
+ const acc = new List<Data<string | N>>();
10
16
  if (prefix > 0) {
11
- acc.push(symbol[0].repeat(prefix));
17
+ acc.push(new Data(symbol[0].repeat(prefix)));
12
18
  }
13
- acc.push(...nodes);
19
+ acc.import(nodes);
14
20
  if (postfix > 0) {
15
21
  const { source, position } = context;
16
- acc.push(source.slice(position, position + postfix));
22
+ acc.push(new Data(source.slice(position, position + postfix)));
17
23
  context.position += postfix;
18
24
  }
19
- return [acc];
25
+ return acc;
20
26
  }): Parser<string | N, MarkdownParser.Context> {
21
27
  return failsafe(input => {
22
28
  const { context } = input;
23
29
  const { source, position } = context;
24
30
  assert(source.startsWith(symbol, context.position));
25
- let nodes: N[] = [];
31
+ let nodes = new List<Data<N>>();
26
32
  let i = symbol.length;
27
33
  while (source[context.position + i] === source[context.position]) ++i;
28
34
  context.position += i;
@@ -39,7 +45,7 @@ export function repeat<N extends HTMLElement | string>(symbol: string, parser:
39
45
  context.buffer = buf;
40
46
  if (result === undefined) break;
41
47
  nodes = eval(result);
42
- switch (nodes.at(-1)) {
48
+ switch (nodes.last?.value) {
43
49
  case Command.Cancel:
44
50
  assert(!source.startsWith(symbol, context.position));
45
51
  nodes.pop();
@@ -105,10 +111,9 @@ export function unmarkInvalid<N extends HTMLElement>(el: N): N {
105
111
  });
106
112
  }
107
113
 
108
- export function stringify(nodes: readonly (HTMLElement | string)[]): string {
114
+ export function stringify(nodes: Iterable<HTMLElement | string>): string {
109
115
  let acc = '';
110
- for (let i = 0; i < nodes.length; ++i) {
111
- const node = nodes[i];
116
+ for (const node of nodes) {
112
117
  if (typeof node === 'string') {
113
118
  assert(!node.includes('\n'));
114
119
  acc += node;
@@ -1,10 +1,9 @@
1
1
  import { MarkdownParser } from '../../markdown';
2
2
  import { Command } from './context';
3
- import { Parser, Input, eval, failsafe } from '../combinator/data/parser';
3
+ import { Parser, Input, List, Data, eval, failsafe } from '../combinator/data/parser';
4
4
  import { convert, fmap } from '../combinator';
5
5
  import { unsafehtmlentity } from './inline/htmlentity';
6
6
  import { invisibleHTMLEntityNames } from './api/normalize';
7
- import { push } from 'spica/array';
8
7
 
9
8
  export namespace blank {
10
9
  export const line = new RegExp(
@@ -94,7 +93,7 @@ function isTightStart(input: Input<MarkdownParser.Context>, except?: string): bo
94
93
  switch (true) {
95
94
  case source.length - position > 2
96
95
  && source[position + 1] !== ' '
97
- && eval(unsafehtmlentity(input))?.[0]?.trimStart() === '':
96
+ && eval(unsafehtmlentity(input))?.head?.value.trimStart() === '':
98
97
  context.position = position;
99
98
  return false;
100
99
  }
@@ -114,18 +113,17 @@ function isTightStart(input: Input<MarkdownParser.Context>, except?: string): bo
114
113
  }
115
114
  }
116
115
 
117
- export function isLooseNodeStart(nodes: readonly (HTMLElement | string)[]): boolean {
116
+ export function isLooseNodeStart(nodes: List<Data<HTMLElement | string>>): boolean {
118
117
  if (nodes.length === 0) return true;
119
- for (let i = 0; i < nodes.length; ++i) {
120
- const node = nodes[i];
118
+ for (const { value: node } of nodes) {
121
119
  if (isVisible(node)) return true;
122
120
  if (typeof node === 'object' && node.tagName === 'BR') break;
123
121
  }
124
122
  return false;
125
123
  }
126
- export function isTightNodeStart(nodes: readonly (HTMLElement | string)[]): boolean {
124
+ export function isTightNodeStart(nodes: List<Data<HTMLElement | string>>): boolean {
127
125
  if (nodes.length === 0) return true;
128
- return isVisible(nodes[0], 0);
126
+ return isVisible(nodes.head!.value, 0);
129
127
  }
130
128
  //export function isTightNodeEnd(nodes: readonly (HTMLElement | string)[]): boolean {
131
129
  // if (nodes.length === 0) return true;
@@ -173,12 +171,12 @@ export function trimBlankStart<N>(parser: Parser<N>): Parser<N> {
173
171
  reg.test(source);
174
172
  context.position = reg.lastIndex || position;
175
173
  return context.position === source.length
176
- ? [[]]
174
+ ? new List()
177
175
  : parser(input);
178
176
  });
179
177
  }
180
178
  export function trimBlankEnd<P extends Parser<HTMLElement | string>>(parser: P): P;
181
- export function trimBlankEnd<N extends HTMLElement | string>(parser: Parser<N>): Parser<N> {
179
+ export function trimBlankEnd<N extends HTMLElement>(parser: Parser<N>): Parser<string | N> {
182
180
  return fmap(parser, trimBlankNodeEnd);
183
181
  }
184
182
  //export function trimBlankNode<N extends HTMLElement | string>(nodes: N[]): N[] {
@@ -200,21 +198,22 @@ export function trimBlankEnd<N extends HTMLElement | string>(parser: Parser<N>):
200
198
  // }
201
199
  // return nodes;
202
200
  //}
203
- export function trimBlankNodeEnd<N extends HTMLElement | string>(nodes: N[]): N[] {
201
+ export function trimBlankNodeEnd<N extends HTMLElement>(nodes: List<Data<string | N>>): List<Data<string | N>> {
204
202
  const skip = nodes.length > 0 &&
205
- typeof nodes.at(-1) === 'object' &&
206
- nodes.at(-1)!['className'] === 'indexer'
207
- ? [nodes.pop()!]
208
- : [];
209
- for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes.at(-1)!, -1);) {
210
- if (typeof node === 'string') {
211
- const str = node.trimEnd();
203
+ typeof nodes.last?.value === 'object' &&
204
+ nodes.last.value.className === 'indexer'
205
+ ? nodes.pop()
206
+ : undefined;
207
+ for (let node = nodes.last; nodes.length > 0 && !isVisible((node = nodes.last!).value, -1);) {
208
+ if (typeof node.value === 'string') {
209
+ const str = node.value.trimEnd();
212
210
  if (str.length > 0) {
213
- nodes[nodes.length - 1] = str as N;
211
+ node.value = str;
214
212
  break;
215
213
  }
216
214
  }
217
215
  nodes.pop();
218
216
  }
219
- return push(nodes, skip);
217
+ skip && nodes.push(skip);
218
+ return nodes;
220
219
  }