securemark 0.299.3 → 0.300.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 (241) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/design.md +0 -6
  3. package/dist/index.js +3479 -2750
  4. package/index.d.ts +2 -1
  5. package/index.ts +2 -2
  6. package/markdown.d.ts +209 -183
  7. package/package.json +1 -1
  8. package/src/{parser/api → api}/bind.test.ts +2 -24
  9. package/src/{parser/api → api}/bind.ts +18 -13
  10. package/src/{parser/api → api}/body.test.ts +1 -1
  11. package/src/{parser/api → api}/cache.ts +1 -1
  12. package/src/{parser/api → api}/header.test.ts +1 -1
  13. package/src/{parser/api → api}/header.ts +9 -6
  14. package/src/{parser/api → api}/normalize.test.ts +1 -1
  15. package/src/{parser/api → api}/parse.test.ts +120 -124
  16. package/src/api/parse.ts +30 -0
  17. package/src/api/run.ts +6 -0
  18. package/src/{parser/api.ts → api.ts} +1 -0
  19. package/src/combinator/control/inits.ts +26 -0
  20. package/src/combinator/control/sequence.test.ts +38 -0
  21. package/src/combinator/control/sequence.ts +17 -0
  22. package/src/combinator/control/some.test.ts +41 -0
  23. package/src/combinator/{data/parser → control}/some.ts +39 -26
  24. package/src/combinator/control/state.ts +42 -0
  25. package/src/combinator/control/subsequence.test.ts +47 -0
  26. package/src/combinator/control/subsequence.ts +16 -0
  27. package/src/combinator/control/tails.ts +8 -0
  28. package/src/combinator/control/union.test.ts +37 -0
  29. package/src/combinator/control/union.ts +18 -0
  30. package/src/combinator/{data/delimiter.ts → delimiter.ts} +40 -60
  31. package/src/combinator/effect/backtrack.ts +64 -0
  32. package/src/combinator/effect/clock.ts +10 -0
  33. package/src/combinator/effect/precedence.ts +50 -0
  34. package/src/combinator/effect/recursion.ts +30 -0
  35. package/src/combinator/effect/scope.ts +100 -0
  36. package/src/combinator/effect/state.ts +72 -0
  37. package/src/combinator/{data/node.ts → parser/list.ts} +38 -13
  38. package/src/combinator/parser.ts +293 -0
  39. package/src/combinator/process/bind.ts +34 -0
  40. package/src/combinator/process/block.test.ts +20 -0
  41. package/src/combinator/process/block.ts +33 -0
  42. package/src/combinator/process/clear.ts +16 -0
  43. package/src/combinator/process/contract.ts +35 -0
  44. package/src/combinator/process/duplicate.ts +7 -0
  45. package/src/combinator/process/error.ts +13 -0
  46. package/src/combinator/{control/manipulation → process}/fallback.ts +3 -3
  47. package/src/combinator/process/fence.ts +59 -0
  48. package/src/combinator/process/fmap.ts +10 -0
  49. package/src/combinator/process/indent.test.ts +31 -0
  50. package/src/combinator/process/indent.ts +51 -0
  51. package/src/combinator/process/lazy.ts +8 -0
  52. package/src/combinator/process/line.test.ts +21 -0
  53. package/src/combinator/process/line.ts +55 -0
  54. package/src/combinator/process/match.ts +37 -0
  55. package/src/combinator/process/reverse.ts +7 -0
  56. package/src/combinator/process/scope.ts +102 -0
  57. package/src/combinator/process/surround.ts +271 -0
  58. package/src/combinator.ts +28 -24
  59. package/src/debug.test.ts +11 -8
  60. package/src/parser/autolink.test.ts +17 -18
  61. package/src/parser/block/blockquote.test.ts +78 -79
  62. package/src/parser/block/blockquote.ts +32 -25
  63. package/src/parser/block/codeblock.test.ts +56 -57
  64. package/src/parser/block/codeblock.ts +44 -26
  65. package/src/parser/block/dlist.test.ts +56 -57
  66. package/src/parser/block/dlist.ts +5 -5
  67. package/src/parser/block/extension/aside.test.ts +8 -9
  68. package/src/parser/block/extension/aside.ts +76 -47
  69. package/src/parser/block/extension/example.test.ts +18 -19
  70. package/src/parser/block/extension/example.ts +88 -48
  71. package/src/parser/block/extension/fig.test.ts +37 -36
  72. package/src/parser/block/extension/fig.ts +20 -25
  73. package/src/parser/block/extension/figbase.test.ts +18 -19
  74. package/src/parser/block/extension/figbase.ts +3 -3
  75. package/src/parser/block/extension/figure.test.ts +62 -63
  76. package/src/parser/block/extension/figure.ts +23 -21
  77. package/src/parser/block/extension/message.test.ts +13 -14
  78. package/src/parser/block/extension/message.ts +52 -39
  79. package/src/parser/block/extension/placeholder.test.ts +13 -13
  80. package/src/parser/block/extension/placeholder.ts +23 -21
  81. package/src/parser/block/extension/table.test.ts +70 -71
  82. package/src/parser/block/extension/table.ts +43 -31
  83. package/src/parser/block/extension.test.ts +24 -24
  84. package/src/parser/block/extension.ts +3 -3
  85. package/src/parser/block/heading.test.ts +58 -59
  86. package/src/parser/block/heading.ts +19 -18
  87. package/src/parser/block/ilist.test.ts +8 -8
  88. package/src/parser/block/ilist.ts +9 -7
  89. package/src/parser/block/mathblock.test.ts +31 -32
  90. package/src/parser/block/mathblock.ts +24 -23
  91. package/src/parser/block/mediablock.ts +7 -7
  92. package/src/parser/block/olist.test.ts +102 -103
  93. package/src/parser/block/olist.ts +11 -12
  94. package/src/parser/block/pagebreak.test.ts +15 -16
  95. package/src/parser/block/pagebreak.ts +5 -5
  96. package/src/parser/block/paragraph.test.ts +57 -58
  97. package/src/parser/block/paragraph.ts +1 -1
  98. package/src/parser/block/reply/cite.test.ts +39 -40
  99. package/src/parser/block/reply/cite.ts +5 -5
  100. package/src/parser/block/reply/quote.test.ts +50 -51
  101. package/src/parser/block/reply/quote.ts +8 -7
  102. package/src/parser/block/reply.test.ts +19 -20
  103. package/src/parser/block/reply.ts +2 -2
  104. package/src/parser/block/sidefence.test.ts +41 -48
  105. package/src/parser/block/sidefence.ts +17 -11
  106. package/src/parser/block/table.test.ts +48 -49
  107. package/src/parser/block/table.ts +10 -9
  108. package/src/parser/block/ulist.test.ts +52 -53
  109. package/src/parser/block/ulist.ts +9 -8
  110. package/src/parser/block.ts +63 -51
  111. package/src/parser/context.ts +35 -32
  112. package/src/parser/document.ts +48 -0
  113. package/src/parser/header.test.ts +19 -20
  114. package/src/parser/header.ts +31 -25
  115. package/src/parser/inline/annotation.test.ts +49 -50
  116. package/src/parser/inline/annotation.ts +14 -16
  117. package/src/parser/inline/autolink/account.test.ts +32 -33
  118. package/src/parser/inline/autolink/account.ts +18 -19
  119. package/src/parser/inline/autolink/anchor.test.ts +21 -22
  120. package/src/parser/inline/autolink/anchor.ts +7 -8
  121. package/src/parser/inline/autolink/channel.test.ts +14 -15
  122. package/src/parser/inline/autolink/email.test.ts +36 -37
  123. package/src/parser/inline/autolink/email.ts +6 -6
  124. package/src/parser/inline/autolink/hashnum.test.ts +32 -33
  125. package/src/parser/inline/autolink/hashnum.ts +7 -8
  126. package/src/parser/inline/autolink/hashtag.test.ts +59 -60
  127. package/src/parser/inline/autolink/hashtag.ts +8 -9
  128. package/src/parser/inline/autolink/url.test.ts +75 -76
  129. package/src/parser/inline/autolink/url.ts +13 -14
  130. package/src/parser/inline/autolink.ts +24 -11
  131. package/src/parser/inline/bracket.test.ts +73 -74
  132. package/src/parser/inline/bracket.ts +88 -63
  133. package/src/parser/inline/code.test.ts +30 -31
  134. package/src/parser/inline/code.ts +6 -6
  135. package/src/parser/inline/deletion.test.ts +27 -28
  136. package/src/parser/inline/deletion.ts +5 -5
  137. package/src/parser/inline/emphasis.test.ts +39 -40
  138. package/src/parser/inline/emphasis.ts +5 -5
  139. package/src/parser/inline/emstrong.test.ts +101 -102
  140. package/src/parser/inline/emstrong.ts +103 -85
  141. package/src/parser/inline/extension/index.test.ts +91 -92
  142. package/src/parser/inline/extension/index.ts +17 -13
  143. package/src/parser/inline/extension/indexee.ts +4 -4
  144. package/src/parser/inline/extension/indexer.test.ts +23 -24
  145. package/src/parser/inline/extension/indexer.ts +6 -5
  146. package/src/parser/inline/extension/label.test.ts +32 -33
  147. package/src/parser/inline/extension/label.ts +14 -5
  148. package/src/parser/inline/extension/placeholder.test.ts +42 -43
  149. package/src/parser/inline/extension/placeholder.ts +8 -9
  150. package/src/parser/inline/html.test.ts +109 -109
  151. package/src/parser/inline/html.ts +27 -27
  152. package/src/parser/inline/htmlentity.test.ts +37 -38
  153. package/src/parser/inline/htmlentity.ts +6 -7
  154. package/src/parser/inline/insertion.test.ts +27 -28
  155. package/src/parser/inline/insertion.ts +5 -5
  156. package/src/parser/inline/italic.test.ts +55 -56
  157. package/src/parser/inline/italic.ts +5 -5
  158. package/src/parser/inline/link.test.ts +186 -187
  159. package/src/parser/inline/link.ts +31 -32
  160. package/src/parser/inline/mark.test.ts +31 -32
  161. package/src/parser/inline/mark.ts +6 -6
  162. package/src/parser/inline/math.test.ts +140 -141
  163. package/src/parser/inline/math.ts +6 -7
  164. package/src/parser/inline/media.test.ts +92 -93
  165. package/src/parser/inline/media.ts +32 -38
  166. package/src/parser/inline/reference.test.ts +111 -112
  167. package/src/parser/inline/reference.ts +61 -32
  168. package/src/parser/inline/remark.test.ts +49 -50
  169. package/src/parser/inline/remark.ts +13 -13
  170. package/src/parser/inline/ruby.test.ts +49 -50
  171. package/src/parser/inline/ruby.ts +60 -49
  172. package/src/parser/inline/shortmedia.test.ts +9 -10
  173. package/src/parser/inline/shortmedia.ts +11 -9
  174. package/src/parser/inline/strong.test.ts +36 -37
  175. package/src/parser/inline/strong.ts +5 -5
  176. package/src/parser/inline/template.test.ts +22 -23
  177. package/src/parser/inline/template.ts +13 -16
  178. package/src/parser/inline.test.ts +225 -226
  179. package/src/parser/inline.ts +68 -34
  180. package/src/parser/node.ts +1 -1
  181. package/src/parser/parser.ts +51 -0
  182. package/src/parser/repeat.ts +118 -91
  183. package/src/parser/segment.test.ts +0 -11
  184. package/src/parser/segment.ts +25 -28
  185. package/src/parser/source/escapable.test.ts +23 -24
  186. package/src/parser/source/escapable.ts +20 -20
  187. package/src/parser/source/line.test.ts +17 -18
  188. package/src/parser/source/line.ts +19 -24
  189. package/src/parser/source/str.ts +17 -10
  190. package/src/parser/source/text.test.ts +88 -89
  191. package/src/parser/source/text.ts +19 -20
  192. package/src/parser/source/unescapable.test.ts +23 -24
  193. package/src/parser/source/unescapable.ts +16 -16
  194. package/src/parser/util.ts +1 -1
  195. package/src/parser/visibility.ts +36 -15
  196. package/src/{parser/processor → processor}/figure.test.ts +23 -23
  197. package/src/{parser/processor → processor}/figure.ts +20 -12
  198. package/src/{parser/processor → processor}/note.test.ts +15 -15
  199. package/src/{parser/processor → processor}/note.ts +6 -4
  200. package/src/renderer/render/media/pdf.ts +2 -2
  201. package/src/renderer/render/media/twitter.ts +2 -2
  202. package/src/renderer/render/media.test.ts +12 -13
  203. package/src/renderer/render.test.ts +11 -11
  204. package/src/util/info.test.ts +2 -2
  205. package/src/util/quote.test.ts +3 -3
  206. package/src/util/quote.ts +6 -5
  207. package/src/util/toc.test.ts +12 -12
  208. package/src/combinator/control/constraint/block.test.ts +0 -20
  209. package/src/combinator/control/constraint/block.ts +0 -28
  210. package/src/combinator/control/constraint/contract.ts +0 -27
  211. package/src/combinator/control/constraint/line.test.ts +0 -21
  212. package/src/combinator/control/constraint/line.ts +0 -42
  213. package/src/combinator/control/manipulation/clear.ts +0 -5
  214. package/src/combinator/control/manipulation/convert.ts +0 -22
  215. package/src/combinator/control/manipulation/duplicate.ts +0 -7
  216. package/src/combinator/control/manipulation/fence.ts +0 -54
  217. package/src/combinator/control/manipulation/indent.test.ts +0 -31
  218. package/src/combinator/control/manipulation/indent.ts +0 -39
  219. package/src/combinator/control/manipulation/lazy.ts +0 -8
  220. package/src/combinator/control/manipulation/match.ts +0 -27
  221. package/src/combinator/control/manipulation/recovery.ts +0 -18
  222. package/src/combinator/control/manipulation/reverse.ts +0 -8
  223. package/src/combinator/control/manipulation/scope.ts +0 -61
  224. package/src/combinator/control/manipulation/surround.ts +0 -223
  225. package/src/combinator/control/monad/bind.ts +0 -26
  226. package/src/combinator/control/monad/fmap.ts +0 -10
  227. package/src/combinator/data/parser/context.ts +0 -96
  228. package/src/combinator/data/parser/inits.ts +0 -20
  229. package/src/combinator/data/parser/sequence.test.ts +0 -33
  230. package/src/combinator/data/parser/sequence.ts +0 -20
  231. package/src/combinator/data/parser/some.test.ts +0 -37
  232. package/src/combinator/data/parser/subsequence.test.ts +0 -41
  233. package/src/combinator/data/parser/subsequence.ts +0 -13
  234. package/src/combinator/data/parser/tails.ts +0 -8
  235. package/src/combinator/data/parser/union.test.ts +0 -33
  236. package/src/combinator/data/parser/union.ts +0 -18
  237. package/src/combinator/data/parser.ts +0 -144
  238. package/src/parser/api/parse.ts +0 -48
  239. package/src/parser.ts +0 -1
  240. /package/src/{parser/api → api}/body.ts +0 -0
  241. /package/src/{parser/api → api}/normalize.ts +0 -0
@@ -1,61 +0,0 @@
1
- import { Parser, input, failsafe } from '../../data/parser';
2
- import { matcher } from '../../data/delimiter';
3
-
4
- export function focus<P extends Parser>(scope: string | RegExp, parser: P, slice?: boolean): P;
5
- export function focus<N>(scope: string | RegExp, parser: Parser<N>, slice = true): Parser<N> {
6
- assert(parser);
7
- const match = matcher(scope, false);
8
- return failsafe(context => {
9
- const { SID, source, position } = context;
10
- if (position === source.length) return;
11
- const src = match(context)?.head?.value ?? '';
12
- assert(source.startsWith(src, position));
13
- if (src === '') return;
14
- const range = context.range = src.length;
15
- if (!slice) {
16
- const result = parser(context);
17
- context.position += result && context.position === position ? range : 0;
18
- return result;
19
- }
20
- context.offset += position;
21
- const result = parser(input(src, context));
22
- context.source = source;
23
- context.SID = SID;
24
- context.position += position;
25
- context.position += result && context.position === position ? src.length : 0;
26
- context.offset -= position;
27
- return result;
28
- });
29
- }
30
-
31
- //export function rewrite<N, C extends Ctx, D extends Parser<unknown, C>[]>(scope: Parser<unknown, C, D>, parser: Parser<N, C, never>): Parser<N, C, D>;
32
- export function rewrite<P extends Parser>(scope: Parser<unknown, Parser.Context<P>>, parser: P, slice?: boolean): P;
33
- export function rewrite<N>(scope: Parser, parser: Parser<N>, slice = true): Parser<N> {
34
- assert(scope);
35
- assert(parser);
36
- return failsafe(context => {
37
- const { SID, source, position } = context;
38
- if (position === source.length) return;
39
- const res1 = scope(context);
40
- assert(context.position > position || !res1);
41
- if (res1 === undefined || context.position < position) return;
42
- const range = context.range = context.position - position;
43
- if (!slice) {
44
- context.position = position;
45
- const res2 = parser(context);
46
- context.position += res2 && context.position === position ? range : 0;
47
- return res2;
48
- }
49
- const src = source.slice(position, context.position);
50
- assert(src !== '');
51
- assert(source.startsWith(src, position));
52
- context.offset += position;
53
- const res2 = parser(input(src, context));
54
- context.SID = SID;
55
- context.source = source;
56
- context.position += position;
57
- context.position += res2 && context.position === position ? src.length : 0;
58
- context.offset -= position;
59
- return res2;
60
- });
61
- }
@@ -1,223 +0,0 @@
1
- import { Parser, Result, List, Node, Context, failsafe } from '../../data/parser';
2
- import { tester } from '../../data/delimiter';
3
-
4
- export function surround<P extends Parser, S = string>(
5
- opener: string | RegExp | Parser<S, Parser.Context<P>>,
6
- parser: Parser.IntermediateParser<P>,
7
- closer: string | RegExp | Parser<S, Parser.Context<P>>,
8
- optional?: false,
9
- backtracks?: readonly number[],
10
- f?: (rss: [List<Node<S>>, List<Node<Parser.SubNode<P>>>, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
11
- g?: (rss: [List<Node<S>>, List<Node<Parser.SubNode<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
12
- ): P;
13
- export function surround<P extends Parser, S = string>(
14
- opener: string | RegExp | Parser<S, Parser.Context<P>>,
15
- parser: Parser.IntermediateParser<P>,
16
- closer: string | RegExp | Parser<S, Parser.Context<P>>,
17
- optional?: boolean,
18
- backtracks?: readonly number[],
19
- f?: (rss: [List<Node<S>>, List<Node<Parser.SubNode<P>>> | undefined, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
20
- g?: (rss: [List<Node<S>>, List<Node<Parser.SubNode<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
21
- ): P;
22
- export function surround<P extends Parser, S = string>(
23
- opener: string | RegExp | Parser<S, Parser.Context<P>>,
24
- parser: P,
25
- closer: string | RegExp | Parser<S, Parser.Context<P>>,
26
- optional?: false,
27
- backtracks?: readonly number[],
28
- f?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>>, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
29
- g?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
30
- ): P;
31
- export function surround<P extends Parser, S = string>(
32
- opener: string | RegExp | Parser<S, Parser.Context<P>>,
33
- parser: P,
34
- closer: string | RegExp | Parser<S, Parser.Context<P>>,
35
- optional?: boolean,
36
- backtracks?: readonly number[],
37
- f?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
38
- g?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
39
- ): P;
40
- export function surround<P extends Parser<string>, S = string>(
41
- opener: string | RegExp | Parser<S, Parser.Context<P>>,
42
- parser: string | RegExp | P,
43
- closer: string | RegExp | Parser<S, Parser.Context<P>>,
44
- optional?: false,
45
- backtracks?: readonly number[],
46
- f?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>>, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
47
- g?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
48
- ): P;
49
- export function surround<P extends Parser<string>, S = string>(
50
- opener: string | RegExp | Parser<S, Parser.Context<P>>,
51
- parser: string | RegExp | P,
52
- closer: string | RegExp | Parser<S, Parser.Context<P>>,
53
- optional?: boolean,
54
- backtracks?: readonly number[],
55
- f?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined, List<Node<S>>], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
56
- g?: (rss: [List<Node<S>>, List<Node<Parser.Node<P>>> | undefined], context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>,
57
- ): P;
58
- export function surround<N>(
59
- opener: string | RegExp | Parser<N>,
60
- parser: string | RegExp | Parser<N>,
61
- closer: string | RegExp | Parser<N>,
62
- optional: boolean = false,
63
- backtracks: readonly number[] = [],
64
- f?: (rss: [List<Node<N>>, List<Node<N>>, List<Node<N>>], context: Context) => Result<N>,
65
- g?: (rss: [List<Node<N>>, List<Node<N>> | undefined], context: Context) => Result<N>,
66
- ): Parser<N> {
67
- switch (typeof opener) {
68
- case 'string':
69
- case 'object':
70
- opener = tester(opener, true);
71
- }
72
- assert(opener);
73
- switch (typeof parser) {
74
- case 'string':
75
- case 'object':
76
- parser = tester(parser, true);
77
- }
78
- assert(parser);
79
- switch (typeof closer) {
80
- case 'string':
81
- case 'object':
82
- closer = tester(closer, true);
83
- }
84
- assert(closer);
85
- const [blen, rbs, wbs] = reduce(backtracks);
86
- return failsafe(input => {
87
- const context = input;
88
- const { source, position } = context;
89
- if (position === source.length) return;
90
- const { linebreak } = context;
91
- context.linebreak = 0;
92
- const nodesO = opener(input);
93
- if (nodesO === undefined) {
94
- return void revert(context, linebreak);
95
- }
96
- if (rbs && isBacktrack(context, rbs, position, blen)) {
97
- return void revert(context, linebreak);
98
- }
99
- const nodesM = context.position < source.length ? parser(input) : undefined;
100
- context.range = context.position - position;
101
- if (nodesM === undefined && !optional) {
102
- wbs && setBacktrack(context, wbs, position);
103
- const result = g?.([nodesO, nodesM], context);
104
- return result || void revert(context, linebreak);
105
- }
106
- const nodesC = optional || nodesM ? closer(input) : undefined;
107
- context.range = context.position - position;
108
- if (nodesC === undefined) {
109
- wbs && setBacktrack(context, wbs, position);
110
- const result = g?.([nodesO, nodesM], context);
111
- return result || void revert(context, linebreak);
112
- }
113
- if (context.position === position) {
114
- return void revert(context, linebreak);
115
- }
116
- context.range = context.position - position;
117
- const result = f
118
- ? f([nodesO, nodesM!, nodesC], context)
119
- : nodesM
120
- ? nodesO.import(nodesM).import(nodesC)
121
- : nodesO.import(nodesC);
122
- if (result) {
123
- context.linebreak ||= linebreak;
124
- }
125
- return result || void revert(context, linebreak);
126
- });
127
- }
128
- export function open<P extends Parser>(
129
- opener: string | RegExp | Parser<Parser.Node<P>, Parser.Context<P>>,
130
- parser: P,
131
- optional?: boolean,
132
- backtracks?: readonly number[],
133
- ): P;
134
- export function open<P extends Parser<string>>(
135
- opener: string | RegExp | Parser<Parser.Node<P>, Parser.Context<P>>,
136
- parser: string | RegExp | P,
137
- optional?: boolean,
138
- backtracks?: readonly number[],
139
- ): P;
140
- export function open<N>(
141
- opener: string | RegExp | Parser<N, Context>,
142
- parser: string | RegExp | Parser<N>,
143
- optional?: boolean,
144
- backtracks: readonly number[] = [],
145
- ): Parser<N> {
146
- return surround(opener, parser as Parser<N>, '', optional, backtracks);
147
- }
148
- export function close<P extends Parser>(
149
- parser: P,
150
- closer: string | RegExp | Parser<Parser.Node<P>, Parser.Context<P>>,
151
- optional?: boolean,
152
- backtracks?: readonly number[],
153
- ): P;
154
- export function close<P extends Parser<string>>(
155
- parser: string | RegExp | P,
156
- closer: string | RegExp | Parser<Parser.Node<P>, Parser.Context<P>>,
157
- optional?: boolean,
158
- backtracks?: readonly number[],
159
- ): P;
160
- export function close<N>(
161
- parser: string | RegExp | Parser<N>,
162
- closer: string | RegExp | Parser<N, Context>,
163
- optional?: boolean,
164
- backtracks: readonly number[] = [],
165
- ): Parser<N> {
166
- return surround('', parser as Parser<N>, closer, optional, backtracks);
167
- }
168
-
169
- const commandsize = 2;
170
- export function isBacktrack(
171
- context: Context,
172
- backtrack: number,
173
- position: number = context.position,
174
- length: number = 1,
175
- ): boolean {
176
- assert(1 & backtrack);
177
- assert(backtrack >>> commandsize);
178
- assert(0 < length && length < 3);
179
- const { backtracks, offset } = context;
180
- for (let i = 0; i < length; ++i) {
181
- if (backtracks[position + i + offset] & backtrack >>> commandsize) return true;
182
- }
183
- return false;
184
- }
185
- export function setBacktrack(
186
- context: Context,
187
- backtrack: number,
188
- position: number,
189
- length: number = 1,
190
- ): void {
191
- // バックトラックの可能性がなく記録不要の場合もあるが判別が面倒なので省略
192
- assert(2 & backtrack);
193
- assert(backtrack >>> commandsize);
194
- assert(0 < length && length < 3);
195
- const { backtracks, offset } = context;
196
- for (let i = 0; i < length; ++i) {
197
- backtracks[position + i + offset] |= backtrack >>> commandsize;
198
- }
199
- }
200
- function reduce(backtracks: readonly number[]): readonly [number, number, number] {
201
- let len = 1;
202
- let rbs = 0;
203
- let wbs = 0;
204
- for (const backtrack of backtracks) {
205
- if (backtrack >>> commandsize === 0) {
206
- len = backtrack;
207
- assert(len > 0);
208
- continue;
209
- }
210
- assert(backtrack >>> commandsize);
211
- if (1 & backtrack) {
212
- rbs |= backtrack;
213
- }
214
- if (2 & backtrack) {
215
- wbs |= backtrack;
216
- }
217
- }
218
- return [len, rbs, wbs];
219
- }
220
-
221
- function revert(context: Context, linebreak: number): void {
222
- context.linebreak = linebreak;
223
- }
@@ -1,26 +0,0 @@
1
- import { Parser, Result, List, Node, Context } from '../../data/parser';
2
-
3
- export function bind<P extends Parser>(parser: Parser.IntermediateParser<P>, f: (nodes: List<Node<Parser.SubNode<P>>>, context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>): P;
4
- export function bind<P extends Parser>(parser: P, f: (nodes: List<Node<Parser.Node<P>>>, context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>): P;
5
- export function bind<N, P extends Parser>(parser: Parser<N, Parser.Context<P>, Parser.SubParsers<P>>, f: (nodes: List<Node<N>>, context: Parser.Context<P>) => Result<Parser.Node<P>, Parser.Context<P>, Parser.SubParsers<P>>): P;
6
- export function bind<U, P extends Parser>(parser: P, f: (nodes: List<Node<Parser.Node<P>>>, context: Parser.Context<P>) => Result<U, Parser.Context<P>, Parser.SubParsers<P>>): Parser<U, Parser.Context<P>, Parser.SubParsers<P>>;
7
- export function bind<N, U>(parser: Parser<N>, f: (nodes: List<Node<N>>, context: Context) => Result<U>): Parser<U> {
8
- assert(parser);
9
- return input => {
10
- const context = input;
11
- const { source, position } = context;
12
- if (position === source.length) return;
13
- const res1 = parser(input);
14
- if (res1 === undefined) {
15
- context.position = position;
16
- return;
17
- }
18
- context.range = context.position - position;
19
- const res2 = f(res1, context);
20
- if (res2 === undefined) {
21
- context.position = position;
22
- return;
23
- }
24
- return res2;
25
- };
26
- }
@@ -1,10 +0,0 @@
1
- import { Parser, List, Node, Context } from '../../data/parser';
2
- import { bind } from './bind';
3
-
4
- export function fmap<P extends Parser>(parser: Parser.IntermediateParser<P>, f: (nodes: List<Node<Parser.SubNode<P>>>, context: Parser.Context<P>) => List<Node<Parser.Node<P>>>): P;
5
- export function fmap<P extends Parser>(parser: P, f: (nodes: List<Node<Parser.Node<P>>>, context: Parser.Context<P>) => List<Node<Parser.Node<P>>>): P;
6
- export function fmap<N, P extends Parser>(parser: Parser<N, Parser.Context<P>, Parser.SubParsers<P>>, f: (nodes: List<Node<N>>, context: Parser.Context<P>) => List<Node<Parser.Node<P>>>): P;
7
- export function fmap<U, P extends Parser>(parser: P, f: (nodes: List<Node<Parser.Node<P>>>, context: Parser.Context<P>) => List<Node<U>>): Parser<U, Parser.Context<P>, Parser.SubParsers<P>>;
8
- export function fmap<N, U>(parser: Parser<N>, f: (nodes: List<Node<N>>, context: Context) => List<Node<U>>): Parser<U> {
9
- return bind(parser, (nodes, context) => f(nodes, context));
10
- }
@@ -1,96 +0,0 @@
1
- import { Parser, Context } from '../../data/parser';
2
- import { min } from 'spica/alias';
3
-
4
- export function creation<P extends Parser>(cost: number, parser: P): P;
5
- export function creation(cost: number, parser: Parser): Parser {
6
- assert(cost >= 0);
7
- return input => {
8
- const context = input;
9
- const result = parser(input);
10
- if (result === undefined) return;
11
- spend(context, cost);
12
- return result;
13
- };
14
- }
15
- export function spend(context: Context, cost: number): void {
16
- const resources = context.resources ?? { clock: cost || 1, recursions: [1] };
17
- if (resources.clock < cost) throw new Error('Too many creations');
18
- resources.clock -= cost;
19
- }
20
-
21
- export function recursion<P extends Parser>(index: number, parser: P): P;
22
- export function recursion(index: number, parser: Parser): Parser {
23
- assert(index >= 0);
24
- return input => {
25
- const context = input;
26
- const resources = context.resources ?? { clock: 1, recursions: [1] };
27
- const { recursions } = resources;
28
- recur(recursions, index, 1);
29
- const result = parser(input);
30
- recur(recursions, index, -1);
31
- return result;
32
- };
33
- }
34
- export function recur(recursions: number[], index: number, size: number, force: boolean = false): void {
35
- index = min(index, recursions.length && recursions.length - 1);
36
- if (recursions[index] < size - +force) throw new Error('Too much recursion');
37
- recursions[index] -= size;
38
- }
39
-
40
- export function precedence<P extends Parser>(precedence: number, parser: P): P;
41
- export function precedence<N>(precedence: number, parser: Parser<N>): Parser<N> {
42
- assert(precedence >= 0);
43
- return input => {
44
- const context = input;
45
- const { delimiters, precedence: p } = context;
46
- const shift = delimiters && precedence > p;
47
- context.precedence = precedence;
48
- // デリミタはシフト後に設定しなければならない
49
- shift && delimiters.shift(precedence);
50
- const result = parser(input);
51
- shift && delimiters.unshift();
52
- context.precedence = p;
53
- return result;
54
- };
55
- }
56
-
57
- export function state<P extends Parser>(state: number, parser: P): P;
58
- export function state<P extends Parser>(state: number, positive: boolean, parser: P): P;
59
- export function state<N>(state: number, positive: boolean | Parser<N>, parser?: Parser<N>): Parser<N> {
60
- if (typeof positive === 'function') {
61
- parser = positive;
62
- positive = true;
63
- }
64
- assert(state);
65
- assert(parser = parser!);
66
- return input => {
67
- const context = input;
68
- const s = context.state ?? 0;
69
- context.state = positive
70
- ? s | state
71
- : s & ~state;
72
- const result = parser(input);
73
- context.state = s;
74
- return result;
75
- };
76
- }
77
-
78
- export function constraint<P extends Parser>(state: number, parser: P): P;
79
- //export function constraint<P extends Parser>(state: number, positive: boolean, parser: P): P;
80
- export function constraint<N>(state: number, positive: boolean | Parser<N>, parser?: Parser<N>): Parser<N> {
81
- if (typeof positive === 'function') {
82
- parser = positive;
83
- positive = false;
84
- }
85
- assert(state);
86
- assert(parser = parser!);
87
- return input => {
88
- const context = input;
89
- const s = positive
90
- ? state & context.state
91
- : state & ~context.state;
92
- return s === state
93
- ? parser(input)
94
- : undefined;
95
- };
96
- }
@@ -1,20 +0,0 @@
1
- import { Parser, List, Node, Context } from '../parser';
2
-
3
- export function inits<P extends Parser>(parsers: Parser.SubParsers<P>): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
4
- export function inits<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context, D> {
5
- assert(parsers.every(f => f));
6
- if (parsers.length === 1) return parsers[0];
7
- return input => {
8
- const context = input;
9
- const { source } = context;
10
- let nodes: List<Node<N>> | undefined;
11
- for (let len = parsers.length, i = 0; i < len; ++i) {
12
- if (context.position === source.length) break;
13
- if (context.delimiters.test(input)) break;
14
- const result = parsers[i](input);
15
- if (result === undefined) break;
16
- nodes = nodes?.import(result) ?? result;
17
- }
18
- return nodes;
19
- };
20
- }
@@ -1,33 +0,0 @@
1
- import { Parser, List, Node, Context, input } from '../parser';
2
- import { sequence } from './sequence';
3
- import { inspect } from '../../../debug.test';
4
-
5
- describe('Unit: combinator/data/parser/sequence', () => {
6
- describe('sequence', () => {
7
- const a: Parser<string> = context => {
8
- return context.source[context.position] === 'a'
9
- ? void ++context.position || new List([new Node('A')])
10
- : undefined;
11
- };
12
- const b: Parser<string> = context => {
13
- return context.source[context.position] === 'b'
14
- ? void ++context.position || new List([new Node('B')])
15
- : undefined;
16
- };
17
- const ab = sequence<Parser<string, Context, [typeof a, typeof b]>>([a, b]);
18
-
19
- it('basic', () => {
20
- const parser = ab;
21
- assert.deepStrictEqual(inspect(parser, input('', new Context())), undefined);
22
- assert.deepStrictEqual(inspect(parser, input('a', new Context())), undefined);
23
- assert.deepStrictEqual(inspect(parser, input('b', new Context())), undefined);
24
- assert.deepStrictEqual(inspect(parser, input('ab', new Context())), [['A', 'B'], '']);
25
- assert.deepStrictEqual(inspect(parser, input('ba', new Context())), undefined);
26
- assert.deepStrictEqual(inspect(parser, input('aab', new Context())), undefined);
27
- assert.deepStrictEqual(inspect(parser, input('abb', new Context())), [['A', 'B'], 'b']);
28
- assert.deepStrictEqual(inspect(parser, input('bba', new Context())), undefined);
29
- });
30
-
31
- });
32
-
33
- });
@@ -1,20 +0,0 @@
1
- import { Parser, List, Node, Context, failsafe } from '../parser';
2
-
3
- export function sequence<P extends Parser>(parsers: Parser.SubParsers<P>): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
4
- export function sequence<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context, D> {
5
- assert(parsers.every(f => f));
6
- if (parsers.length === 1) return parsers[0];
7
- return failsafe(input => {
8
- const context = input;
9
- const { source } = context;
10
- let nodes: List<Node<N>> | undefined;
11
- for (let len = parsers.length, i = 0; i < len; ++i) {
12
- if (context.position === source.length) return;
13
- if (context.delimiters.test(input)) return;
14
- const result = parsers[i](input);
15
- if (result === undefined) return;
16
- nodes = nodes?.import(result) ?? result;
17
- }
18
- return nodes;
19
- });
20
- }
@@ -1,37 +0,0 @@
1
- import { Parser, List, Node, Context, input } from '../parser';
2
- import { union } from './union';
3
- import { some } from './some';
4
- import { inspect } from '../../../debug.test';
5
-
6
- describe('Unit: combinator/data/parser/some', () => {
7
- describe('some', () => {
8
- const a: Parser<string> = context => {
9
- return context.source[context.position] === 'a'
10
- ? void ++context.position || new List([new Node('A')])
11
- : undefined;
12
- };
13
- const b: Parser<string> = context => {
14
- return context.source[context.position] === 'b'
15
- ? void ++context.position || new List([new Node('B')])
16
- : undefined;
17
- };
18
- const ab = union<Parser<string, Context, [typeof a, typeof b]>>([a, b]);
19
-
20
- it('basic', () => {
21
- const parser = some(ab, /aaa/y);
22
- assert.deepStrictEqual(inspect(parser, input('', new Context())), undefined);
23
- assert.deepStrictEqual(inspect(parser, input('a', new Context())), [['A'], '']);
24
- assert.deepStrictEqual(inspect(parser, input('b', new Context())), [['B'], '']);
25
- assert.deepStrictEqual(inspect(parser, input('ab', new Context())), [['A', 'B'], '']);
26
- assert.deepStrictEqual(inspect(parser, input('ba', new Context())), [['B', 'A'], '']);
27
- assert.deepStrictEqual(inspect(parser, input('aab', new Context())), [['A', 'A', 'B'], '']);
28
- assert.deepStrictEqual(inspect(parser, input('bba', new Context())), [['B', 'B', 'A'], '']);
29
- assert.deepStrictEqual(inspect(parser, input('aaa', new Context())), undefined);
30
- assert.deepStrictEqual(inspect(parser, input('bbb', new Context())), [['B', 'B', 'B'], '']);
31
- assert.deepStrictEqual(inspect(parser, input('aaab', new Context())), undefined);
32
- assert.deepStrictEqual(inspect(parser, input('baaa', new Context())), [['B'], 'aaa']);
33
- });
34
-
35
- });
36
-
37
- });
@@ -1,41 +0,0 @@
1
- import { Parser, List, Node, Context, input } from '../parser';
2
- import { subsequence } from './subsequence';
3
- import { inspect } from '../../../debug.test';
4
-
5
- describe('Unit: combinator/data/parser/subsequence', () => {
6
- describe('subsequence', () => {
7
- const a: Parser<string> = context => {
8
- return context.source[context.position] === 'a'
9
- ? void ++context.position || new List([new Node('A')])
10
- : undefined;
11
- };
12
- const b: Parser<string> = context => {
13
- return context.source[context.position] === 'b'
14
- ? void ++context.position || new List([new Node('B')])
15
- : undefined;
16
- };
17
- const c: Parser<string> = context => {
18
- return context.source[context.position] === 'c'
19
- ? void ++context.position || new List([new Node('C')])
20
- : undefined;
21
- };
22
- const abc = subsequence<Parser<string, Context, [typeof a, typeof b, typeof c]>>([a, b, c]);
23
-
24
- it('basic', () => {
25
- const parser = abc;
26
- assert.deepStrictEqual(inspect(parser, input('', new Context())), undefined);
27
- assert.deepStrictEqual(inspect(parser, input('a', new Context())), [['A'], '']);
28
- assert.deepStrictEqual(inspect(parser, input('b', new Context())), [['B'], '']);
29
- assert.deepStrictEqual(inspect(parser, input('c', new Context())), [['C'], '']);
30
- assert.deepStrictEqual(inspect(parser, input('ab', new Context())), [['A', 'B'], '']);
31
- assert.deepStrictEqual(inspect(parser, input('ba', new Context())), [['B'], 'a']);
32
- assert.deepStrictEqual(inspect(parser, input('aab', new Context())), [['A'], 'ab']);
33
- assert.deepStrictEqual(inspect(parser, input('abb', new Context())), [['A', 'B'], 'b']);
34
- assert.deepStrictEqual(inspect(parser, input('bba', new Context())), [['B'], 'ba']);
35
- assert.deepStrictEqual(inspect(parser, input('ac', new Context())), [['A', 'C'], '']);
36
- assert.deepStrictEqual(inspect(parser, input('bc', new Context())), [['B', 'C'], '']);
37
- });
38
-
39
- });
40
-
41
- });
@@ -1,13 +0,0 @@
1
- import { Parser, Context } from '../parser';
2
- import { union } from './union';
3
- import { inits } from './inits';
4
-
5
- export function subsequence<P extends Parser>(parsers: Parser.SubParsers<P>): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
6
- export function subsequence<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context, D> {
7
- assert(parsers.every(f => f));
8
- return union(
9
- parsers.map((_, i) =>
10
- i + 1 < parsers.length
11
- ? inits([parsers[i], subsequence(parsers.slice(i + 1))])
12
- : parsers[i]) as D);
13
- }
@@ -1,8 +0,0 @@
1
- import { Parser, Context } from '../parser';
2
- import { union } from './union';
3
- import { sequence } from './sequence';
4
-
5
- export function tails<P extends Parser>(parsers: Parser.SubParsers<P>): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
6
- export function tails<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context, D> {
7
- return union(parsers.map((_, i) => sequence(parsers.slice(i))) as D);
8
- }
@@ -1,33 +0,0 @@
1
- import { Parser, List, Node, Context, input } from '../parser';
2
- import { union } from './union';
3
- import { inspect } from '../../../debug.test';
4
-
5
- describe('Unit: combinator/data/parser/union', () => {
6
- describe('union', () => {
7
- const a: Parser<string> = context => {
8
- return context.source[context.position] === 'a'
9
- ? void ++context.position || new List([new Node('A')])
10
- : undefined;
11
- };
12
- const b: Parser<string> = context => {
13
- return context.source[context.position] === 'b'
14
- ? void ++context.position || new List([new Node('B')])
15
- : undefined;
16
- };
17
- const ab = union<Parser<string, Context, [typeof a, typeof b]>>([a, b]);
18
-
19
- it('basic', () => {
20
- const parser = ab;
21
- assert.deepStrictEqual(inspect(parser, input('', new Context())), undefined);
22
- assert.deepStrictEqual(inspect(parser, input('a', new Context())), [['A'], '']);
23
- assert.deepStrictEqual(inspect(parser, input('b', new Context())), [['B'], '']);
24
- assert.deepStrictEqual(inspect(parser, input('ab', new Context())), [['A'], 'b']);
25
- assert.deepStrictEqual(inspect(parser, input('ba', new Context())), [['B'], 'a']);
26
- assert.deepStrictEqual(inspect(parser, input('aab', new Context())), [['A'], 'ab']);
27
- assert.deepStrictEqual(inspect(parser, input('abb', new Context())), [['A'], 'bb']);
28
- assert.deepStrictEqual(inspect(parser, input('bba', new Context())), [['B'], 'ba']);
29
- });
30
-
31
- });
32
-
33
- });
@@ -1,18 +0,0 @@
1
- import { Parser, Context } from '../parser';
2
-
3
- export function union<P extends Parser>(parsers: Parser.SubParsers<P>): Parser.SubNode<P> extends Parser.Node<P> ? P : Parser<Parser.SubNode<P>, Parser.Context<P>, Parser.SubParsers<P>>;
4
- export function union<N, D extends Parser<N>[]>(parsers: D): Parser<N, Context, D> {
5
- assert(parsers.every(f => f));
6
- switch (parsers.length) {
7
- case 0:
8
- return () => undefined;
9
- case 1:
10
- return parsers[0];
11
- default:
12
- return eval([
13
- '(', parsers.map((_, i) => `parser${i},`).join(''), ') =>',
14
- 'input =>',
15
- parsers.map((_, i) => `|| parser${i}(input)`).join('').slice(2),
16
- ].join(''))(...parsers);
17
- }
18
- }