securemark 0.300.0 → 0.300.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 (40) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/index.js +197 -113
  3. package/package.json +1 -1
  4. package/src/api/bind.ts +2 -2
  5. package/src/api/parse.ts +2 -2
  6. package/src/combinator/control/inits.ts +13 -4
  7. package/src/combinator/control/sequence.ts +3 -1
  8. package/src/combinator/control/state.ts +1 -10
  9. package/src/combinator/control/union.ts +16 -3
  10. package/src/combinator/parser.ts +18 -8
  11. package/src/combinator/process/fence.ts +3 -3
  12. package/src/combinator/process/surround.ts +2 -0
  13. package/src/parser/block/codeblock.test.ts +0 -2
  14. package/src/parser/block/codeblock.ts +3 -3
  15. package/src/parser/block/extension/aside.test.ts +0 -1
  16. package/src/parser/block/extension/aside.ts +1 -1
  17. package/src/parser/block/extension/example.test.ts +0 -2
  18. package/src/parser/block/extension/example.ts +1 -1
  19. package/src/parser/block/extension/figure.test.ts +0 -4
  20. package/src/parser/block/extension/figure.ts +1 -1
  21. package/src/parser/block/extension/message.test.ts +0 -1
  22. package/src/parser/block/extension/message.ts +1 -1
  23. package/src/parser/block/extension/placeholder.ts +3 -3
  24. package/src/parser/block/extension/table.test.ts +0 -1
  25. package/src/parser/block/extension/table.ts +3 -3
  26. package/src/parser/block/mathblock.test.ts +0 -2
  27. package/src/parser/block/mathblock.ts +3 -3
  28. package/src/parser/context.ts +9 -12
  29. package/src/parser/document.ts +1 -1
  30. package/src/parser/inline/autolink/url.ts +4 -4
  31. package/src/parser/inline/math.ts +1 -1
  32. package/src/parser/inline/media.ts +4 -4
  33. package/src/parser/inline/ruby.ts +45 -8
  34. package/src/parser/inline/template.ts +4 -4
  35. package/src/parser/source/escapable.ts +0 -1
  36. package/src/parser/source/text.ts +14 -43
  37. package/src/parser/source/unescapable.ts +0 -1
  38. package/src/parser/source/whitespace.ts +36 -0
  39. package/src/parser/source.ts +1 -0
  40. package/src/parser/visibility.ts +2 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.300.0",
3
+ "version": "0.300.1",
4
4
  "description": "Secure markdown renderer working on browsers for user input data.",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/falsandtru/securemark",
package/src/api/bind.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ParserSettings, Progress } from '../..';
2
2
  import { Input, Options, Segment } from '../parser/context';
3
- import { Output, subinput, run } from '../combinator/parser';
3
+ import { Output, run } from '../combinator/parser';
4
4
  import { segment } from '../parser/segment';
5
5
  import { block } from '../parser/block';
6
6
  import { headers } from './header';
@@ -74,7 +74,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
74
74
  assert(rev === revision);
75
75
  const seg = sourceSegments[index];
76
76
  options.segment = sourceSegmentAttrs[index] | Segment.write;
77
- for (const _ of run(block, subinput(seg, new Input(options)), output)) {
77
+ for (const _ of run(block, new Input(options, seg), output)) {
78
78
  yield { type: 'break' };
79
79
  }
80
80
  assert(output.data.length === 1);
package/src/api/parse.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ParserOptions } from '../..';
2
- import { Input, Options, input } from '../parser/context';
2
+ import { Input, Options } from '../parser/context';
3
3
  import { Output, run } from '../combinator/parser';
4
4
  import { document } from '../parser/document';
5
5
  import { ReadonlyURL } from 'spica/url';
@@ -23,7 +23,7 @@ export function* parse(source: string, opts: Opts = {}, options?: Options): Gene
23
23
  if (options.id?.match(/[^0-9a-z/-]/i)) throw new Error('Invalid ID: ID must be alphanumeric');
24
24
  if (options.host?.origin === 'null') throw new Error(`Invalid host: ${options.host.href}`);
25
25
  const output = new Output<DocumentFragment>();
26
- for (const _ of run(document, input(source, new Input(options)), output)) yield;
26
+ for (const _ of run(document, new Input(options, source), output)) yield;
27
27
  assert(output.data.length === 1);
28
28
  assert(output.peek().length === 1);
29
29
  return output.peek().head!.value;
@@ -1,16 +1,16 @@
1
- import { Parser, SubParsers } from '../parser';
1
+ import { Parser, SubParsers, Result } from '../parser';
2
2
  import { union } from './union';
3
3
  import { sequence } from './sequence';
4
- import { recovery } from './state';
5
4
 
6
5
  export function inits<P extends Parser>(parsers: Parser.SubParsers<P>): P;
7
6
  export function inits<T>(parsers: SubParsers<T>): Parser<T> {
8
7
  assert(parsers.every(f => f));
9
8
  switch (parsers.length) {
10
9
  case 0:
10
+ assert(false);
11
11
  return (_, output) => output.context;
12
12
  case 1:
13
- return () => parsers;
13
+ return parsers[0];
14
14
  default:
15
15
  return parsers.reduceRight((acc, parser, i) =>
16
16
  sequence([
@@ -19,8 +19,17 @@ export function inits<T>(parsers: SubParsers<T>): Parser<T> {
19
19
  ? acc
20
20
  : union([
21
21
  acc,
22
- recovery(),
22
+ recovery,
23
23
  ]),
24
24
  ]));
25
25
  }
26
26
  }
27
+
28
+ const recovery: Parser<never> = (_, output) => {
29
+ if (output.state) {
30
+ output.state = true;
31
+ // @ts-expect-error
32
+ output.context ??= Result.succ;
33
+ }
34
+ return output.context;
35
+ };
@@ -6,8 +6,10 @@ export function sequence<T>(parsers: SubParsers<T>): Parser<T> {
6
6
  assert(parsers.every(f => f));
7
7
  switch (parsers.length) {
8
8
  case 0:
9
+ assert(false);
10
+ return (_, output) => output.context;
9
11
  case 1:
10
- return () => parsers;
12
+ return parsers[0];
11
13
  default:
12
14
  return parsers.reduceRight((acc, parser) => always([
13
15
  parser,
@@ -1,4 +1,4 @@
1
- import { Parser, SubParsers, Result } from '../parser';
1
+ import { Parser, SubParsers } from '../parser';
2
2
 
3
3
  export function then<P extends Parser>(success: P, failure: P): P;
4
4
  export function then<T>(success: Parser<T>, failure: Parser<T>): Parser<T> {
@@ -31,12 +31,3 @@ export function force<T>(parser: Parser<T>): Parser<T> {
31
31
  ? output.context
32
32
  : parser(input, output);
33
33
  }
34
-
35
- export function recovery<P extends Parser>(parser?: P): P;
36
- export function recovery<T>(parser: Parser<T> = () => Result.succ): Parser<T> {
37
- return (input, output) => {
38
- output.state = true;
39
- output.context = Result.succ;
40
- return parser(input, output);
41
- };
42
- }
@@ -1,14 +1,15 @@
1
- import { Parser, SubParsers } from '../parser';
2
- import { failure, always, recovery } from './state';
1
+ import { Parser, SubParsers, Result } from '../parser';
2
+ import { failure, always } from './state';
3
3
 
4
4
  export function union<P extends Parser>(parsers: Parser.SubParsers<P>): P;
5
5
  export function union<T>(parsers: SubParsers<T>): Parser<T> {
6
6
  assert(parsers.every(f => f));
7
7
  switch (parsers.length) {
8
8
  case 0:
9
+ assert(false);
9
10
  return (_, output) => output.context;
10
11
  case 1:
11
- return () => parsers;
12
+ return parsers[0];
12
13
  default:
13
14
  return parsers.reduceRight((acc, parser) => always([
14
15
  parser,
@@ -16,3 +17,15 @@ export function union<T>(parsers: SubParsers<T>): Parser<T> {
16
17
  ]));
17
18
  }
18
19
  }
20
+
21
+ function recovery<P extends Parser>(parser: P): P;
22
+ function recovery<T>(parser: Parser<T>): Parser<T> {
23
+ return (input, output) => {
24
+ if (!output.state) {
25
+ output.state = true;
26
+ // @ts-expect-error
27
+ output.context ??= Result.succ;
28
+ }
29
+ return parser(input, output);
30
+ };
31
+ }
@@ -140,7 +140,7 @@ export class Output<T> {
140
140
  assert(data.length > 0);
141
141
  }
142
142
  public state: boolean = true;
143
- public context: Result.Succ | Result.Fail = Result.succ;
143
+ public readonly context: Result.Succ | Result.Fail = Result.succ;
144
144
  public error?: Error = undefined;
145
145
  public peek(): List<Node<T>> {
146
146
  assert(this.data.length > 0);
@@ -222,17 +222,24 @@ export function* run
222
222
  time = Date.now();
223
223
  }
224
224
  if (output.state && output.error) {
225
- output.state = false;
226
- output.context = Result.fail;
225
+ if (output.state) {
226
+ output.state = false;
227
+ // @ts-expect-error
228
+ output.context = Result.fail;
229
+ }
227
230
  }
228
231
  const input = scope.peek();
229
232
  //assert(input.position <= input.source.length);
230
- const result = queue.pop()(input, output);
233
+ const parser = queue.pop();
234
+ const result = parser(input, output);
231
235
 
232
236
  if (result) {
233
237
  //assert(result.every(f => f));
234
- output.state = true;
235
- output.context = Result.succ;
238
+ if (!output.state) {
239
+ output.state = true;
240
+ // @ts-expect-error
241
+ output.context ??= Result.succ;
242
+ }
236
243
  if (result.length !== 0) {
237
244
  if (queue.length !== 0) {
238
245
  queue.memory = input.memory;
@@ -249,8 +256,11 @@ export function* run
249
256
  if (result === Result.skip) {
250
257
  queue.length = 0;
251
258
  }
252
- output.state = false;
253
- output.context = Result.fail;
259
+ if (output.state) {
260
+ output.state = false;
261
+ // @ts-expect-error
262
+ output.context = Result.fail;
263
+ }
254
264
  }
255
265
 
256
266
  if (queue.length !== 0) continue;
@@ -2,7 +2,7 @@ import { Parser, SubParsers, Input, List, Node } from '../parser';
2
2
  import { spend } from '../effect/clock';
3
3
  import { firstline, isEmptyline } from './line';
4
4
 
5
- export function fence<I extends Input, S extends SubParsers<never, I>>(opener: RegExp, write: boolean, limit: number, separation = true): Parser<string, I, S> {
5
+ export function fence<I extends Input, S extends SubParsers<never, I>>(opener: RegExp, write: boolean, separation = true): Parser<string, I, S> {
6
6
  assert(!opener.flags.match(/[gm]/) && opener.sticky && !opener.source.startsWith('^'));
7
7
  return (input, output) => {
8
8
  const { source, position } = input;
@@ -29,11 +29,11 @@ export function fence<I extends Input, S extends SubParsers<never, I>>(opener: R
29
29
  for (let count = 1; ; ++count) {
30
30
  if (input.position === source.length) break;
31
31
  const line = firstline(source, input.position);
32
- if ((closer || count > limit + 1) && isEmptyline(line, 0)) break;
32
+ if (closer && isEmptyline(line, 0)) break;
33
33
  if(closer) {
34
34
  overflow += line;
35
35
  }
36
- if (!closer && count <= limit + 1 && line.startsWith(delim) && line.trimEnd() === delim) {
36
+ if (!closer && line.startsWith(delim) && line.trimEnd() === delim) {
37
37
  closer = line;
38
38
  if (isEmptyline(source, input.position + line.length)) {
39
39
  input.position += line.length;
@@ -136,6 +136,7 @@ export function surround<T>(
136
136
  const o = output.pop();
137
137
  if (!g) return;
138
138
  output.state = true;
139
+ // @ts-expect-error
139
140
  output.context = Result.succ;
140
141
  return g([o, state ? m : undefined], input, output);
141
142
  }
@@ -156,6 +157,7 @@ export function surround<T>(
156
157
  wbs && setBacktrack(input, wbs, position);
157
158
  if (!g) return;
158
159
  output.state = true;
160
+ // @ts-expect-error
159
161
  output.context = Result.succ;
160
162
  return g([o, state ? m : undefined], input, output);
161
163
  }
@@ -22,7 +22,6 @@ describe('Unit: parser/block/codeblock', () => {
22
22
  assert.deepStrictEqual(inspect(parser, input('```\n````')), [['<pre class="invalid" translate="no">```\n````</pre>'], '']);
23
23
  assert.deepStrictEqual(inspect(parser, input('````\n```')), [['<pre class="invalid" translate="no">````\n```</pre>'], '']);
24
24
  assert.deepStrictEqual(inspect(parser, input(' ```\n```')), undefined);
25
- assert.deepStrictEqual(inspect(parser, input(`\`\`\`\n0${'\n'.repeat(301)}\`\`\``), '>'), [['<pre class="invalid" translate="no">'], '']);
26
25
  });
27
26
 
28
27
  it('basic', () => {
@@ -44,7 +43,6 @@ describe('Unit: parser/block/codeblock', () => {
44
43
  assert.deepStrictEqual(inspect(parser, input('```\n!http://host)\n```')), [['<pre class="text">!<a class="url" href="http://host)" target="_blank">http://host)</a></pre>'], '']);
45
44
  assert.deepStrictEqual(inspect(parser, input('```\n#a\n```')), [['<pre class="text"><a class="hashtag" href="/hashtags/a">#a</a></pre>'], '']);
46
45
  assert.deepStrictEqual(inspect(parser, input('```\n@a#b\n```')), [['<pre class="text"><a class="channel" href="/@a?ch=b">@a#b</a></pre>'], '']);
47
- assert.deepStrictEqual(inspect(parser, input(`\`\`\`\n0${'\n'.repeat(300)}\`\`\``), '>'), [['<pre class="text">'], '']);
48
46
  });
49
47
 
50
48
  it('attribute', () => {
@@ -9,13 +9,13 @@ const opener = /(`{3,})(?!`)([^\r\n]*)(?:$|\r?\n)/y;
9
9
  const language = /^[0-9a-z]+(?:-[a-z][0-9a-z]*)*$/i;
10
10
 
11
11
  export const segment: CodeBlockParser.SegmentParser = block(
12
- fence(opener, false, 300));
12
+ fence(opener, false));
13
13
 
14
14
  export const segment_: CodeBlockParser.SegmentParser = block(
15
- fence(opener, false, 300, false), false);
15
+ fence(opener, false, false), false);
16
16
 
17
17
  export const codeblock: CodeBlockParser = block(inits([
18
- fence(opener, true, 300),
18
+ fence(opener, true),
19
19
  (input, output) => {
20
20
  const [body, overflow, closer, opener, delim, param] = unwrap(output.pop()) as string[];
21
21
  const params = param.match(/(?:\\.?|\S)+/g)?.reduce<{
@@ -11,7 +11,6 @@ describe('Unit: parser/block/extension/aside', () => {
11
11
  assert.deepStrictEqual(inspect(parser, input('~~~aside\n~~~')), [['<pre class="invalid" translate="no">~~~aside\n~~~</pre>'], '']);
12
12
  assert.deepStrictEqual(inspect(parser, input('~~~aside\n# \n~~~')), [['<pre class="invalid" translate="no">~~~aside\n# \n~~~</pre>'], '']);
13
13
  assert.deepStrictEqual(inspect(parser, input('~~~aside a\n# 0\n~~~')), [['<pre class="invalid" translate="no">~~~aside a\n# 0\n~~~</pre>'], '']);
14
- assert.deepStrictEqual(inspect(parser, input(`~~~aside\n# 0${'\n'.repeat(301)}~~~`), '>'), [['<pre class="invalid" translate="no">'], '']);
15
14
  });
16
15
 
17
16
  it('valid', () => {
@@ -14,7 +14,7 @@ interface Memory {
14
14
  }
15
15
 
16
16
  export const aside: ExtensionParser.AsideParser = block(recursion(Recursion.block, inits([
17
- fence(/(~{3,})aside(?!\S)([^\r\n]*)(?:$|\r?\n)/y, true, 300),
17
+ fence(/(~{3,})aside(?!\S)([^\r\n]*)(?:$|\r?\n)/y, true),
18
18
  (input: Input<Memory>, output) => {
19
19
  const [body, overflow, closer, opener, delim, param] = unwrap(output.pop()) as string[];
20
20
  if (!closer || overflow || param.trimStart()) {
@@ -11,7 +11,6 @@ describe('Unit: parser/block/extension/example', () => {
11
11
  assert.deepStrictEqual(inspect(parser, input('~~~example/\n~~~')), undefined);
12
12
  assert.deepStrictEqual(inspect(parser, input('~~~example/a\n~~~')), [['<pre class="invalid" translate="no">~~~example/a\n~~~</pre>'], '']);
13
13
  assert.deepStrictEqual(inspect(parser, input('~~~example/markdown a\n~~~')), [['<pre class="invalid" translate="no">~~~example/markdown a\n~~~</pre>'], '']);
14
- assert.deepStrictEqual(inspect(parser, input(`~~~example/markdown\n0${'\n'.repeat(301)}~~~`), '>'), [['<pre class="invalid" translate="no">'], '']);
15
14
  });
16
15
 
17
16
  it('valid', () => {
@@ -27,7 +26,6 @@ describe('Unit: parser/block/extension/example', () => {
27
26
  assert.deepStrictEqual(inspect(parser, input('~~~example/markdown\n((a))[[b]]\n~~~')), [['<aside class="example" data-type="markdown"><pre translate="no">((a))[[b]]</pre><hr><section><p><sup class="annotation local" id="annotation:random:ref:a:1" title="a"><a href="#annotation:random:def:a:1">*1</a></sup><sup class="reference local" id="reference:random:ref:b:1" title="b"><a href="#reference:random:def:b">[1]</a></sup></p><ol class="annotations"><li id="annotation:random:def:a:1" data-marker="*1"><span>a</span><sup><a href="#annotation:random:ref:a:1">^1</a></sup></li></ol><h2>References</h2><ol class="references"><li id="reference:random:def:b"><span>b</span><sup><a href="#reference:random:ref:b:1">^1</a></sup></li></ol></section></aside>'], '']);
28
27
  assert.deepStrictEqual(inspect(parser, input('~~~~example/markdown\na\n~~~~')), [['<aside class="example" data-type="markdown"><pre translate="no">a</pre><hr><section><p>a</p><h2>References</h2><ol class="references"></ol></section></aside>'], '']);
29
28
  assert.deepStrictEqual(inspect(parser, input('~~~example/math\na\n~~~')), [['<aside class="example" data-type="math"><pre translate="no">a</pre><hr><div class="math" translate="no">$$\na\n$$</div></aside>'], '']);
30
- assert.deepStrictEqual(inspect(parser, input(`~~~example/math\n0${'\n'.repeat(100)}~~~`), '>'), [['<aside class="example" data-type="math">'], '']);
31
29
  });
32
30
 
33
31
  });
@@ -12,7 +12,7 @@ interface Memory {
12
12
  }
13
13
 
14
14
  export const example: ExtensionParser.ExampleParser = block(recursion(Recursion.block, inits([
15
- fence(/(~{3,})(?:example\/(\S+))?(?!\S)([^\r\n]*)(?:$|\r?\n)/y, true, 300),
15
+ fence(/(~{3,})(?:example\/(\S+))?(?!\S)([^\r\n]*)(?:$|\r?\n)/y, true),
16
16
  (input: Input<Memory>, output) => {
17
17
  const [body, overflow, closer, opener, delim, type = 'markdown', param] = unwrap(output.pop()) as string[];
18
18
  if (!closer || overflow || param.trimStart()) return output.append(
@@ -33,8 +33,6 @@ describe('Unit: parser/block/extension/figure', () => {
33
33
  assert.deepStrictEqual(inspect(parser, input('~~~figure [$fig-name]\n> \n\n~~~')), [['<figure data-type="quote" data-label="fig-name" data-group="fig" class="invalid"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>'], '']);
34
34
  assert.deepStrictEqual(inspect(parser, input('~~~figure [$figure-name]\n> \n\n~~~')), [['<figure data-type="quote" data-label="figure-name" data-group="figure" class="invalid"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>'], '']);
35
35
  assert.deepStrictEqual(inspect(parser, input('~~~figure [$table-name]\n> \n\n~~~')), [['<figure data-type="quote" data-label="table-name" data-group="table" class="invalid"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><blockquote></blockquote></div></figure>'], '']);
36
- assert.deepStrictEqual(inspect(parser, input(`~~~figure [$group-name]\n0${'\n'.repeat(301)}~~~`), '>'), [['<pre class="invalid" translate="no">'], '']);
37
- assert.deepStrictEqual(inspect(parser, input(`~~~figure [$group-name]\n~~~\n0${'\n'.repeat(301)}~~~\n~~~`), '>'), [['<pre class="invalid" translate="no">'], `${'\n'.repeat(300)}~~~\n~~~`]);
38
36
  });
39
37
 
40
38
  it('valid', () => {
@@ -70,8 +68,6 @@ describe('Unit: parser/block/extension/figure', () => {
70
68
  assert.deepStrictEqual(inspect(parser, input('~~~figure [$-0.0]\n$$\n\n$$\n~~~')), [['<figure data-type="math" data-label="$-0.0" data-group="$" class="invalid"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
71
69
  assert.deepStrictEqual(inspect(parser, input('~~~figure [$-name]\n!https://host\n~~~')), [['<figure data-type="media" data-label="$-name" data-group="$" class="invalid"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt="https://host"></a></div></figure>'], '']);
72
70
  assert.deepStrictEqual(inspect(parser, input('~~~figure [$-name]\n$$\n\n$$\n\ncaption\n~~~')), [['<figure data-type="math" data-label="$-name" data-group="$" class="invalid"><figcaption><span class="figindex"></span><span class="figtext">caption</span></figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
73
- assert.deepStrictEqual(inspect(parser, input(`~~~figure [$group-name]\n${'> \n'.repeat(500)}\n~~~`), '>'), [['<figure data-type="quote" data-label="group-name" data-group="group">'], '']);
74
- assert.deepStrictEqual(inspect(parser, input(`~~~figure [$group-name]\n~~~\n0${'\n'.repeat(300)}~~~\n~~~`), '>'), [['<figure data-type="example" data-label="group-name" data-group="group">'], '']);
75
71
  });
76
72
 
77
73
  });
@@ -84,7 +84,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
84
84
  ]);
85
85
  })),
86
86
  inits([
87
- fence(/(~{3,})(?:figure(?=$|[ \r\n])|\[?\$)[^\r\n]*(?:$|\r?\n)/y, true, 300),
87
+ fence(/(~{3,})(?:figure(?=$|[ \r\n])|\[?\$)[^\r\n]*(?:$|\r?\n)/y, true),
88
88
  (_, output) => {
89
89
  const [body, overflow, closer, opener, delim] = unwrap(output.pop()) as string[];
90
90
  const violation =
@@ -12,7 +12,6 @@ describe('Unit: parser/block/extension/message', () => {
12
12
  assert.deepStrictEqual(inspect(parser, input('~~~message/\n~~~')), undefined);
13
13
  assert.deepStrictEqual(inspect(parser, input('~~~message/a\n~~~')), [['<pre class="invalid" translate="no">~~~message/a\n~~~</pre>'], '']);
14
14
  assert.deepStrictEqual(inspect(parser, input('~~~message/note a\n~~~')), [['<pre class="invalid" translate="no">~~~message/note a\n~~~</pre>'], '']);
15
- assert.deepStrictEqual(inspect(parser, input(`~~~message/note\n0${'\n'.repeat(301)}~~~`), '>'), [['<pre class="invalid" translate="no">'], '']);
16
15
  });
17
16
 
18
17
  it('valid', () => {
@@ -20,7 +20,7 @@ import { html } from 'typed-dom/dom';
20
20
  import MessageParser = ExtensionParser.MessageParser;
21
21
 
22
22
  export const message: MessageParser = block(inits([
23
- fence(/(~{3,})message\/(\S+)(?!\S)([^\r\n]*)(?:$|\r?\n)/y, true, 300),
23
+ fence(/(~{3,})message\/(\S+)(?!\S)([^\r\n]*)(?:$|\r?\n)/y, true),
24
24
  (input, output) => {
25
25
  const [body, overflow, closer, opener, delim, type, param] = unwrap(output.pop()) as string[];
26
26
  if (!closer || overflow || param.trimStart()) {
@@ -7,13 +7,13 @@ import { html } from 'typed-dom/dom';
7
7
  const opener = /(~{3,})(?!~)[^\r\n]*(?:$|\r?\n)/y;
8
8
 
9
9
  export const segment: ExtensionParser.PlaceholderParser.SegmentParser = block(
10
- fence(opener, false, 300));
10
+ fence(opener, false));
11
11
 
12
12
  export const segment_: ExtensionParser.PlaceholderParser.SegmentParser = block(
13
- fence(opener, false, 300, false), false);
13
+ fence(opener, false, false), false);
14
14
 
15
15
  export const placeholder: ExtensionParser.PlaceholderParser = block(inits([
16
- fence(opener, true, 300),
16
+ fence(opener, true),
17
17
  (_, output) => {
18
18
  const [body, overflow, closer, opener, delim] = unwrap(output.pop()) as string[];
19
19
  return output.append(
@@ -10,7 +10,6 @@ describe('Unit: parser/block/extension/table', () => {
10
10
 
11
11
  it('invalid', () => {
12
12
  assert.deepStrictEqual(inspect(parser, input('~~~table a\n-\n~~~')), [['<pre class="invalid" translate="no">~~~table a\n-\n~~~</pre>'], '']);
13
- assert.deepStrictEqual(inspect(parser, input(`~~~table\n0${'\n'.repeat(10001)}~~~`), '>'), [['<pre class="invalid" translate="no">'], '']);
14
13
  });
15
14
 
16
15
  it('data', () => {
@@ -18,13 +18,13 @@ import CellParser = TableParser.CellParser;
18
18
  const opener = /(~{3,})table(?:\/(\S+))?(?!\S)([^\r\n]*)(?:$|\r?\n)/y;
19
19
 
20
20
  export const segment: TableParser.SegmentParser = block(
21
- fence(opener, false, 10000));
21
+ fence(opener, false));
22
22
 
23
23
  export const segment_: TableParser.SegmentParser = block(
24
- fence(opener, false, 10000, false), false);
24
+ fence(opener, false, false), false);
25
25
 
26
26
  export const table: TableParser = block(inits([
27
- fence(opener, true, 10000),
27
+ fence(opener, true),
28
28
  (_, output) => {
29
29
  const [body, overflow, closer, opener, delim, type, param] = unwrap(output.pop()) as string[];
30
30
  if (!closer || overflow || param.trimStart()) return output.append(
@@ -25,7 +25,6 @@ describe('Unit: parser/block/mathblock', () => {
25
25
  assert.deepStrictEqual(inspect(parser, input('$$$\n$$')), [['<pre class="invalid" translate="no">$$$\n$$</pre>'], '']);
26
26
  assert.deepStrictEqual(inspect(parser, input('$$$\n$$$')), [['<pre class="invalid" translate="no">$$$\n$$$</pre>'], '']);
27
27
  assert.deepStrictEqual(inspect(parser, input(' $$\n$$')), undefined);
28
- assert.deepStrictEqual(inspect(parser, input(`$$\n0${'\n'.repeat(301)}$$`), '>'), [['<pre class="invalid" translate="no">'], '']);
29
28
  });
30
29
 
31
30
  it('basic', () => {
@@ -40,7 +39,6 @@ describe('Unit: parser/block/mathblock', () => {
40
39
  assert.deepStrictEqual(inspect(parser, input('$$\n$$\n\n$$')), [['<div class="math" translate="no">$$\n$$</div>'], '\n$$']);
41
40
  assert.deepStrictEqual(inspect(parser, input('$$\n$$$\n$$')), [['<div class="math" translate="no">$$\n$$$\n$$</div>'], '']);
42
41
  assert.deepStrictEqual(inspect(parser, input('$$\n$$$\n\n$$')), [['<div class="math" translate="no">$$\n$$$\n\n$$</div>'], '']);
43
- assert.deepStrictEqual(inspect(parser, input(`$$\n0${'\n'.repeat(300)}$$`), '>'), [['<div class="math" translate="no">'], '']);
44
42
  });
45
43
 
46
44
  });
@@ -7,13 +7,13 @@ import { html } from 'typed-dom/dom';
7
7
  const opener = /(\${2,})(?!\$)([^\r\n]*)(?:$|\r?\n)/y;
8
8
 
9
9
  export const segment: MathBlockParser.SegmentParser = block(
10
- fence(opener, false, 300));
10
+ fence(opener, false));
11
11
 
12
12
  export const segment_: MathBlockParser.SegmentParser = block(
13
- fence(opener, false, 300, false), false);
13
+ fence(opener, false, false), false);
14
14
 
15
15
  export const mathblock: MathBlockParser = block(inits([
16
- fence(opener, true, 300),
16
+ fence(opener, true),
17
17
  ({ caches: { math: cache = undefined } = {} }, output) => {
18
18
  const [body, overflow, closer, opener, delim, param] = unwrap(output.pop()) as string[];
19
19
  return output.append(
@@ -8,13 +8,14 @@ export function input(source: string, input: Input = new Input()): Input {
8
8
  export class Input<M extends object = object> extends Ipt<M> {
9
9
  constructor(
10
10
  options: Partial<Input> = {},
11
+ source?: string,
11
12
  ) {
12
13
  super(options);
13
14
  const {
14
15
  segment,
15
16
  header,
16
17
  local,
17
- sequential,
18
+ whitespace,
18
19
  host,
19
20
  url,
20
21
  id,
@@ -22,20 +23,21 @@ export class Input<M extends object = object> extends Ipt<M> {
22
23
  caches,
23
24
  test,
24
25
  } = options;
26
+ this.source = source ?? options.source ?? '';
25
27
  this.resources ??= {
26
28
  clock: -1,
27
29
  interval: 200,
28
30
  recursions: [
29
- 10 || Recursion.scope,
31
+ 10 || Recursion.document,
30
32
  100 || Recursion.block,
31
33
  100 || Recursion.inline,
32
- 100 || Recursion.terminal,
34
+ 100 || Recursion.bracket,
33
35
  ],
34
36
  };
35
37
  this.segment = segment ?? Segment.unknown;
36
38
  this.header = header ?? true;
37
39
  this.local = local ?? false;
38
- this.sequential = sequential ?? false;
40
+ this.whitespace = whitespace ?? false;
39
41
  this.host = host;
40
42
  this.url = url;
41
43
  this.id = id;
@@ -51,7 +53,7 @@ export class Input<M extends object = object> extends Ipt<M> {
51
53
  public override segment: Segment;
52
54
  public header: boolean;
53
55
  public local: boolean;
54
- public sequential: boolean;
56
+ public whitespace: boolean;
55
57
  public recursion = new RecursionCounter(2);
56
58
  public readonly host?: URL;
57
59
  public readonly url?: URL;
@@ -115,10 +117,10 @@ export const enum State {
115
117
  }
116
118
 
117
119
  export const enum Recursion {
118
- scope,
120
+ document,
119
121
  block,
120
122
  inline,
121
- terminal,
123
+ bracket,
122
124
  }
123
125
 
124
126
  export const enum Backtrack {
@@ -134,12 +136,7 @@ export const enum Backtrack {
134
136
  }
135
137
 
136
138
  export const enum Command {
137
- Error = '\x07',
138
139
  Cancel = '\x18',
139
140
  Escape = '\x1B',
140
141
  Separator = '\x1F',
141
142
  }
142
-
143
- export const CmdRegExp = {
144
- Error: /\x07/g,
145
- } as const;
@@ -29,7 +29,7 @@ export const document: MarkdownParser = (() => {
29
29
  output.push();
30
30
  return output.context;
31
31
  },
32
- recursion(Recursion.scope, force(() => loop)),
32
+ recursion(Recursion.document, force(() => loop)),
33
33
  (input, output) => {
34
34
  assert(input.position === input.source.length);
35
35
  const doc = frag(unwrap(output.pop()));
@@ -39,12 +39,12 @@ export const lineurl: AutolinkParser.UrlParser.LineUrlParser = lazy(() => focus(
39
39
  ])));
40
40
 
41
41
  const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => backtrack(union([
42
- surround(str('('), recursion(Recursion.terminal, some(union([bracket, unescsource]), ')')), str(')'),
42
+ surround(str('('), recursion(Recursion.bracket, some(union([bracket, unescsource]), ')')), str(')'),
43
43
  true, [3 | Backtrack.unescapable]),
44
- surround(str('['), recursion(Recursion.terminal, some(union([bracket, unescsource]), ']')), str(']'),
44
+ surround(str('['), recursion(Recursion.bracket, some(union([bracket, unescsource]), ']')), str(']'),
45
45
  true, [3 | Backtrack.unescapable]),
46
- surround(str('{'), recursion(Recursion.terminal, some(union([bracket, unescsource]), '}')), str('}'),
46
+ surround(str('{'), recursion(Recursion.bracket, some(union([bracket, unescsource]), '}')), str('}'),
47
47
  true, [3 | Backtrack.unescapable]),
48
- surround(str('"'), precedence(2, recursion(Recursion.terminal, some(unescsource, '"'))), str('"'),
48
+ surround(str('"'), precedence(2, recursion(Recursion.bracket, some(unescsource, '"'))), str('"'),
49
49
  true, [3 | Backtrack.unescapable]),
50
50
  ])));
@@ -41,7 +41,7 @@ export const math: MathParser = lazy(() => rewrite(
41
41
 
42
42
  const bracket: MathParser.BracketParser = lazy(() => backtrack(surround(
43
43
  str('{'),
44
- recursion(Recursion.terminal,
44
+ recursion(Recursion.bracket,
45
45
  some(union([
46
46
  bracket,
47
47
  some(escsource, /[{}$\r\n]|(?<=[0-9A-Za-z]):\/\/[[0-9A-Za-z]/y),
@@ -107,13 +107,13 @@ export const media: MediaParser = lazy(() => constraint(State.media, backtrack(o
107
107
  })))));
108
108
 
109
109
  const bracket: MediaParser.TextParser.BracketParser = lazy(() => union([
110
- surround(str('('), recursion(Recursion.terminal, some(union([unsafehtmlentity, bracket, txt]), ')')), str(')'),
110
+ surround(str('('), recursion(Recursion.bracket, some(union([unsafehtmlentity, bracket, txt]), ')')), str(')'),
111
111
  true, [], undefined, () => Result.succ),
112
- surround(str('['), recursion(Recursion.terminal, some(union([unsafehtmlentity, bracket, txt]), ']')), str(']'),
112
+ surround(str('['), recursion(Recursion.bracket, some(union([unsafehtmlentity, bracket, txt]), ']')), str(']'),
113
113
  true, [], undefined, () => Result.succ),
114
- surround(str('{'), recursion(Recursion.terminal, some(union([unsafehtmlentity, bracket, txt]), '}')), str('}'),
114
+ surround(str('{'), recursion(Recursion.bracket, some(union([unsafehtmlentity, bracket, txt]), '}')), str('}'),
115
115
  true, [], undefined, () => Result.succ),
116
- surround(str('"'), precedence(2, recursion(Recursion.terminal, some(union([unsafehtmlentity, txt]), '"'))), str('"'),
116
+ surround(str('"'), precedence(2, recursion(Recursion.bracket, some(union([unsafehtmlentity, txt]), '"'))), str('"'),
117
117
  true, [], undefined, () => Result.succ),
118
118
  ]));
119
119