securemark 0.293.0 → 0.293.2

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 (66) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/index.js +254 -193
  3. package/markdown.d.ts +13 -21
  4. package/package.json +1 -1
  5. package/src/combinator/control/manipulation/scope.ts +3 -4
  6. package/src/combinator/data/parser/context.ts +5 -5
  7. package/src/combinator.ts +0 -1
  8. package/src/parser/api/parse.test.ts +2 -2
  9. package/src/parser/autolink.test.ts +7 -7
  10. package/src/parser/block/blockquote.ts +2 -2
  11. package/src/parser/block/codeblock.ts +7 -7
  12. package/src/parser/block/dlist.ts +1 -2
  13. package/src/parser/block/extension/aside.ts +3 -3
  14. package/src/parser/block/extension/example.ts +3 -3
  15. package/src/parser/block/extension/fig.ts +2 -2
  16. package/src/parser/block/extension/figure.test.ts +1 -1
  17. package/src/parser/block/extension/figure.ts +2 -2
  18. package/src/parser/block/extension/message.ts +3 -3
  19. package/src/parser/block/extension/placeholder.ts +7 -7
  20. package/src/parser/block/extension/table.ts +26 -16
  21. package/src/parser/block/extension.ts +3 -3
  22. package/src/parser/block/ilist.ts +3 -3
  23. package/src/parser/block/mathblock.ts +7 -7
  24. package/src/parser/block/mediablock.ts +6 -6
  25. package/src/parser/block/olist.ts +3 -3
  26. package/src/parser/block/paragraph.test.ts +1 -2
  27. package/src/parser/block/paragraph.ts +1 -2
  28. package/src/parser/block/reply/cite.ts +3 -5
  29. package/src/parser/block/reply/quote.ts +2 -3
  30. package/src/parser/block/sidefence.ts +2 -2
  31. package/src/parser/block/table.ts +5 -5
  32. package/src/parser/block/ulist.ts +2 -3
  33. package/src/parser/block.ts +2 -2
  34. package/src/parser/context.ts +4 -4
  35. package/src/parser/inline/annotation.ts +1 -1
  36. package/src/parser/inline/autolink/url.test.ts +7 -7
  37. package/src/parser/inline/autolink/url.ts +1 -2
  38. package/src/parser/inline/autolink.ts +1 -1
  39. package/src/parser/inline/bracket.test.ts +2 -2
  40. package/src/parser/inline/extension/index.ts +5 -4
  41. package/src/parser/inline/extension/indexer.test.ts +0 -1
  42. package/src/parser/inline/extension/indexer.ts +1 -1
  43. package/src/parser/inline/html.ts +7 -6
  44. package/src/parser/inline/htmlentity.ts +3 -3
  45. package/src/parser/inline/italic.test.ts +11 -11
  46. package/src/parser/inline/link.ts +1 -6
  47. package/src/parser/inline/mark.test.ts +5 -5
  48. package/src/parser/inline/math.ts +3 -3
  49. package/src/parser/inline/media.ts +3 -8
  50. package/src/parser/inline/reference.ts +1 -1
  51. package/src/parser/inline/remark.test.ts +14 -18
  52. package/src/parser/inline/remark.ts +17 -19
  53. package/src/parser/inline/ruby.ts +3 -3
  54. package/src/parser/inline/shortmedia.ts +1 -1
  55. package/src/parser/inline.test.ts +25 -24
  56. package/src/parser/inline.ts +21 -9
  57. package/src/parser/segment.ts +23 -5
  58. package/src/parser/source/escapable.test.ts +1 -1
  59. package/src/parser/source/escapable.ts +4 -12
  60. package/src/parser/source/text.test.ts +40 -40
  61. package/src/parser/source/text.ts +77 -24
  62. package/src/parser/source/unescapable.test.ts +3 -3
  63. package/src/parser/source/unescapable.ts +4 -12
  64. package/src/parser/visibility.ts +32 -32
  65. package/src/combinator/control/manipulation/trim.test.ts +0 -23
  66. package/src/combinator/control/manipulation/trim.ts +0 -17
package/markdown.d.ts CHANGED
@@ -355,7 +355,7 @@ export namespace MarkdownParser {
355
355
  BlockquoteParser,
356
356
  PlaceholderParser,
357
357
  InlineParser.MediaParser,
358
- InlineParser.ShortMediaParser,
358
+ InlineParser.ShortMediaParser.LineShortMediaParser,
359
359
  ]>,
360
360
  SourceParser.EmptyLineParser,
361
361
  InlineParser,
@@ -456,18 +456,22 @@ export namespace MarkdownParser {
456
456
  export interface HeadParser extends
457
457
  Block<'extension/table/cell/head'>,
458
458
  Parser<HTMLTableCellElement, Context, [
459
- InlineParser.LinkParser.MediaLinkParser,
460
- InlineParser.MediaParser,
461
- InlineParser.ShortMediaParser,
459
+ Parser<HTMLElement, Context, [
460
+ InlineParser.LinkParser.MediaLinkParser,
461
+ InlineParser.MediaParser,
462
+ InlineParser.ShortMediaParser.LineShortMediaParser,
463
+ ]>,
462
464
  InlineParser,
463
465
  ]> {
464
466
  }
465
467
  export interface DataParser extends
466
468
  Block<'extension/table/cell/data'>,
467
469
  Parser<HTMLTableCellElement, Context, [
468
- InlineParser.LinkParser.MediaLinkParser,
469
- InlineParser.MediaParser,
470
- InlineParser.ShortMediaParser,
470
+ Parser<HTMLElement, Context, [
471
+ InlineParser.LinkParser.MediaLinkParser,
472
+ InlineParser.MediaParser,
473
+ InlineParser.ShortMediaParser.LineShortMediaParser,
474
+ ]>,
471
475
  InlineParser,
472
476
  ]> {
473
477
  }
@@ -575,12 +579,12 @@ export namespace MarkdownParser {
575
579
  Parser<HTMLElement, Context, [
576
580
  InlineParser.LinkParser.MediaLinkParser,
577
581
  InlineParser.MediaParser,
578
- InlineParser.ShortMediaParser,
582
+ InlineParser.ShortMediaParser.LineShortMediaParser,
579
583
  ]>,
580
584
  Parser<HTMLElement, Context, [
581
585
  InlineParser.LinkParser.MediaLinkParser,
582
586
  InlineParser.MediaParser,
583
- InlineParser.ShortMediaParser,
587
+ InlineParser.ShortMediaParser.LineShortMediaParser,
584
588
  ]>,
585
589
  ]> {
586
590
  }
@@ -785,12 +789,6 @@ export namespace MarkdownParser {
785
789
  ]> {
786
790
  }
787
791
  export namespace LinkParser {
788
- export interface LineMediaLinkParser extends
789
- Inline<'link/linemedialink'>,
790
- Parser<HTMLElement, Context, [
791
- LinkParser.MediaLinkParser,
792
- ]> {
793
- }
794
792
  export interface TextLinkParser extends
795
793
  Inline<'link/textlink'>,
796
794
  Parser<HTMLAnchorElement | HTMLSpanElement, Context, [
@@ -866,12 +864,6 @@ export namespace MarkdownParser {
866
864
  ]> {
867
865
  }
868
866
  export namespace MediaParser {
869
- export interface LineMediaParser extends
870
- Inline<'media/linemedia'>,
871
- Parser<HTMLElement, Context, [
872
- MediaParser,
873
- ]> {
874
- }
875
867
  export interface TextParser extends
876
868
  Inline<'media/text'>,
877
869
  Parser<string[], Context, [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.293.0",
3
+ "version": "0.293.2",
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",
@@ -1,8 +1,8 @@
1
1
  import { Parser, Context, input, eval, failsafe } from '../../data/parser';
2
- import { consume, matcher } from '../../../combinator';
2
+ import { matcher } from '../../../combinator';
3
3
 
4
- export function focus<P extends Parser<unknown>>(scope: string | RegExp, parser: P, cost?: boolean): P;
5
- export function focus<N>(scope: string | RegExp, parser: Parser<N>, cost = true): Parser<N> {
4
+ export function focus<P extends Parser<unknown>>(scope: string | RegExp, parser: P): P;
5
+ export function focus<N>(scope: string | RegExp, parser: Parser<N>): Parser<N> {
6
6
  assert(parser);
7
7
  const match = matcher(scope, false);
8
8
  return failsafe(({ context }) => {
@@ -11,7 +11,6 @@ export function focus<N>(scope: string | RegExp, parser: Parser<N>, cost = true)
11
11
  const src = eval(match({ context }))?.[0] ?? '';
12
12
  assert(source.startsWith(src, position));
13
13
  if (src === '') return;
14
- cost && consume(src.length, context);
15
14
  context.range = src.length;
16
15
  context.offset ??= 0;
17
16
  context.offset += position;
@@ -179,13 +179,13 @@ export function matcher(pattern: string | RegExp, advance: boolean): Parser<stri
179
179
  return ({ context }) => {
180
180
  const { source, position } = context;
181
181
  pattern.lastIndex = position;
182
- const m = pattern.exec(source);
183
- if (m === null) return;
184
- count && consume(m[0].length, context);
182
+ if (!pattern.test(source)) return;
183
+ const src = source.slice(position, pattern.lastIndex);
184
+ count && consume(src.length, context);
185
185
  if (advance) {
186
- context.position += m[0].length;
186
+ context.position += src.length;
187
187
  }
188
- return [[m[0]]];
188
+ return [[src]];
189
189
  };
190
190
  }
191
191
  }
package/src/combinator.ts CHANGED
@@ -15,7 +15,6 @@ export * from './combinator/control/manipulation/clear';
15
15
  export * from './combinator/control/manipulation/surround';
16
16
  export * from './combinator/control/manipulation/match';
17
17
  export * from './combinator/control/manipulation/convert';
18
- export * from './combinator/control/manipulation/trim';
19
18
  export * from './combinator/control/manipulation/duplicate';
20
19
  export * from './combinator/control/manipulation/reverse';
21
20
  export * from './combinator/control/manipulation/fallback';
@@ -363,7 +363,7 @@ describe('Unit: parser/api/parse', () => {
363
363
  this.timeout(5000);
364
364
  // 最悪計算量での実行速度はCommonMarkの公式JS実装の32nに対して3倍遅い程度。
365
365
  // 5n = annotation/reference + link + url/math + ruby + text
366
- const source = `${'.'.repeat(0 + 0)}((([[[[#$[${'.'.repeat(19998)}`;
366
+ const source = `${'.'.repeat(0 + 0)}((([[[[#$[${'&'.repeat(19998)}`;
367
367
  assert.deepStrictEqual(
368
368
  [...parse(source, {}, { resources: { clock: 100000, recursions: [100] } }).children]
369
369
  .map(el => el.tagName),
@@ -372,7 +372,7 @@ describe('Unit: parser/api/parse', () => {
372
372
 
373
373
  it('backtrack error', function () {
374
374
  this.timeout(5000);
375
- const source = `${'.'.repeat(0 + 1)}((([[[[#$[${'.'.repeat(19998)}`;
375
+ const source = `${'.'.repeat(0 + 1)}((([[[[#$[${'&'.repeat(19998)}`;
376
376
  assert.deepStrictEqual(
377
377
  [...parse(source, {}, { resources: { clock: 100000, recursions: [100] } }).children]
378
378
  .map(el => el.tagName),
@@ -15,15 +15,15 @@ describe('Unit: parser/autolink', () => {
15
15
  assert.deepStrictEqual(inspect(parser('#a'), ctx), [['<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
16
16
  assert.deepStrictEqual(inspect(parser('@a#b'), ctx), [['<a class="channel" href="/@a?ch=b">@a#b</a>'], '']);
17
17
  assert.deepStrictEqual(inspect(parser('\\\n'), ctx), [['\\', '<br>'], '']);
18
- assert.deepStrictEqual(inspect(parser('a#b'), ctx), [['a', '#', 'b'], '']);
19
- assert.deepStrictEqual(inspect(parser('0a#b'), ctx), [['0a', '#', 'b'], '']);
20
- assert.deepStrictEqual(inspect(parser('あ#b'), ctx), [['あ', '#', 'b'], '']);
21
- assert.deepStrictEqual(inspect(parser('あい#b'), ctx), [['あい', '#', 'b'], '']);
22
- assert.deepStrictEqual(inspect(parser('0aあ#b'), ctx), [['0a', 'あ', '#', 'b'], '']);
23
- assert.deepStrictEqual(inspect(parser('0aあい#b'), ctx), [['0a', 'あい', '#', 'b'], '']);
18
+ assert.deepStrictEqual(inspect(parser('a#b'), ctx), [['a', '#b'], '']);
19
+ assert.deepStrictEqual(inspect(parser('0a#b'), ctx), [['0a', '#b'], '']);
20
+ assert.deepStrictEqual(inspect(parser('あ#b'), ctx), [['あ', '#b'], '']);
21
+ assert.deepStrictEqual(inspect(parser('あい#b'), ctx), [['あい', '#b'], '']);
22
+ assert.deepStrictEqual(inspect(parser('0aあ#b'), ctx), [['0a', 'あ', '#b'], '']);
23
+ assert.deepStrictEqual(inspect(parser('0aあい#b'), ctx), [['0a', 'あい', '#b'], '']);
24
24
  assert.deepStrictEqual(inspect(parser('a\n#b'), ctx), [['a', '<br>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
25
25
  assert.deepStrictEqual(inspect(parser('a\\\n#b'), ctx), [['a', '\\', '<br>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
26
- assert.deepStrictEqual(inspect(parser('0a>>b'), ctx), [['0a', '>', '>', 'b'], '']);
26
+ assert.deepStrictEqual(inspect(parser('0a>>b'), ctx), [['0a', '>', '>b'], '']);
27
27
  });
28
28
 
29
29
  });
@@ -6,9 +6,9 @@ import { contentline } from '../source';
6
6
  import { parse } from '../api/parse';
7
7
  import { html, defrag } from 'typed-dom/dom';
8
8
 
9
- export const segment: BlockquoteParser.SegmentParser = block(validate(/!?>/y, union([
9
+ export const segment: BlockquoteParser.SegmentParser = block(union([
10
10
  validate(/!?>+(?=[^\S\n]|\n[^\S\n]*\S)/y, some(contentline)),
11
- ])));
11
+ ]));
12
12
 
13
13
  export const blockquote: BlockquoteParser = lazy(() => block(rewrite(segment, union([
14
14
  open(/(?=>)/y, source),
@@ -1,6 +1,6 @@
1
1
  import { CodeBlockParser } from '../block';
2
2
  import { input, eval } from '../../combinator/data/parser';
3
- import { block, validate, fence, clear, fmap } from '../../combinator';
3
+ import { block, fence, clear, fmap } from '../../combinator';
4
4
  import { autolink } from '../autolink';
5
5
  import { invalid } from '../util';
6
6
  import { html, defrag } from 'typed-dom/dom';
@@ -8,13 +8,13 @@ import { html, defrag } from 'typed-dom/dom';
8
8
  const opener = /(`{3,})(?!`)([^\n]*)(?:$|\n)/y;
9
9
  const language = /^[0-9a-z]+(?:-[a-z][0-9a-z]*)*$/i;
10
10
 
11
- export const segment: CodeBlockParser.SegmentParser = block(validate('```',
12
- clear(fence(opener, 300))));
11
+ export const segment: CodeBlockParser.SegmentParser = block(
12
+ clear(fence(opener, 300)));
13
13
 
14
- export const segment_: CodeBlockParser.SegmentParser = block(validate('```',
15
- clear(fence(opener, 300, false))), false);
14
+ export const segment_: CodeBlockParser.SegmentParser = block(
15
+ clear(fence(opener, 300, false)), false);
16
16
 
17
- export const codeblock: CodeBlockParser = block(validate('```', fmap(
17
+ export const codeblock: CodeBlockParser = block(fmap(
18
18
  fence(opener, 300),
19
19
  // Bug: Type mismatch between outer and inner.
20
20
  ([body, overflow, closer, opener, delim, param]: string[], context) => {
@@ -74,4 +74,4 @@ export const codeblock: CodeBlockParser = block(validate('```', fmap(
74
74
  body.slice(0, -1) || undefined
75
75
  : defrag(eval(autolink(input(body.slice(0, -1), { ...context })), [])));
76
76
  return [el];
77
- })));
77
+ }));
@@ -3,7 +3,6 @@ import { State } from '../context';
3
3
  import { union, inits, some, state, block, line, validate, rewrite, open, lazy, fmap } from '../../combinator';
4
4
  import { inline, indexee, indexer, dataindex } from '../inline';
5
5
  import { anyline } from '../source';
6
- import { linearize } from '../util';
7
6
  import { visualize, trimBlank, trimBlankEnd } from '../visibility';
8
7
  import { push } from 'spica/array';
9
8
  import { html, defrag } from 'typed-dom/dom';
@@ -27,7 +26,7 @@ const desc: DListParser.DescriptionParser = block(fmap(open(
27
26
  /:[^\S\n]+(?=\S)|/y,
28
27
  rewrite(
29
28
  some(anyline, /[~:][^\S\n]+\S/y),
30
- visualize(trimBlankEnd(linearize(some(union([inline])), -1)))),
29
+ visualize(trimBlankEnd(some(union([inline]))))),
31
30
  true),
32
31
  ns => [html('dd', defrag(ns))]),
33
32
  false);
@@ -1,12 +1,12 @@
1
1
  import { ExtensionParser } from '../../block';
2
2
  import { Recursion } from '../../context';
3
- import { recursion, block, validate, fence, fmap } from '../../../combinator';
3
+ import { recursion, block, fence, fmap } from '../../../combinator';
4
4
  import { identity } from '../../inline/extension/indexee';
5
5
  import { invalid } from '../../util';
6
6
  import { parse } from '../../api/parse';
7
7
  import { html } from 'typed-dom/dom';
8
8
 
9
- export const aside: ExtensionParser.AsideParser = recursion(Recursion.block, block(validate('~~~', fmap(
9
+ export const aside: ExtensionParser.AsideParser = recursion(Recursion.block, block(fmap(
10
10
  fence(/(~{3,})aside(?!\S)([^\n]*)(?:$|\n)/y, 300),
11
11
  // Bug: Type mismatch between outer and inner.
12
12
  ([body, overflow, closer, opener, delim, param]: string[], context) => {
@@ -42,4 +42,4 @@ export const aside: ExtensionParser.AsideParser = recursion(Recursion.block, blo
42
42
  references,
43
43
  ]),
44
44
  ];
45
- }))));
45
+ })));
@@ -1,7 +1,7 @@
1
1
  import { ExtensionParser } from '../../block';
2
2
  import { Recursion } from '../../context';
3
3
  import { input, eval } from '../../../combinator/data/parser';
4
- import { recursion, block, validate, fence, fmap } from '../../../combinator';
4
+ import { recursion, block, fence, fmap } from '../../../combinator';
5
5
  import { mathblock } from '../mathblock';
6
6
  import { invalid } from '../../util';
7
7
  import { parse } from '../../api/parse';
@@ -9,7 +9,7 @@ import { html } from 'typed-dom/dom';
9
9
 
10
10
  const opener = /(~{3,})(?:example\/(\S+))?(?!\S)([^\n]*)(?:$|\n)/y;
11
11
 
12
- export const example: ExtensionParser.ExampleParser = recursion(Recursion.block, block(validate('~~~', fmap(
12
+ export const example: ExtensionParser.ExampleParser = recursion(Recursion.block, block(fmap(
13
13
  fence(opener, 300),
14
14
  // Bug: Type mismatch between outer and inner.
15
15
  ([body, overflow, closer, opener, delim, type = 'markdown', param]: string[], context) => {
@@ -58,4 +58,4 @@ export const example: ExtensionParser.ExampleParser = recursion(Recursion.block,
58
58
  }, `${opener}${body}${closer}`),
59
59
  ];
60
60
  }
61
- }))));
61
+ })));
@@ -8,7 +8,7 @@ import { segment as seg_math } from '../mathblock';
8
8
  import { segment as seg_table } from './table';
9
9
  import { segment as seg_blockquote } from '../blockquote';
10
10
  import { segment as seg_placeholder } from './placeholder';
11
- import { media, shortmedia } from '../../inline';
11
+ import { media, lineshortmedia } from '../../inline';
12
12
 
13
13
  import FigParser = ExtensionParser.FigParser;
14
14
 
@@ -42,7 +42,7 @@ const parser = sequence([
42
42
  line(close(seg_label, /(?=\s).*\n/y)),
43
43
  line(union([
44
44
  media,
45
- shortmedia,
45
+ lineshortmedia,
46
46
  ])),
47
47
  some(contentline),
48
48
  ]);
@@ -13,7 +13,6 @@ describe('Unit: parser/block/extension/figure', () => {
13
13
  assert.deepStrictEqual(inspect(parser('~~~figure $group-name]\n!https://host\n~~~'), ctx), [['<pre class="invalid" translate="no">~~~figure $group-name]\n!https://host\n~~~</pre>'], '']);
14
14
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name\n!https://host\n~~~'), ctx), [['<pre class="invalid" translate="no">~~~figure [$group-name\n!https://host\n~~~</pre>'], '']);
15
15
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\nhttps://host\n~~~'), ctx), [['<pre class="invalid" translate="no">~~~figure [$group-name]\nhttps://host\n~~~</pre>'], '']);
16
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\\\n~~~'), ctx), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n!https://host\\\n~~~</pre>'], '']);
17
16
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\\\n~~~'), ctx), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n!https://host\n\\\n~~~</pre>'], '']);
18
17
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\na\n~~~'), ctx), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n!https://host\na\n~~~</pre>'], '']);
19
18
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n\n\n~~~'), ctx), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n!https://host\n\n\n\n~~~</pre>'], '']);
@@ -60,6 +59,7 @@ describe('Unit: parser/block/extension/figure', () => {
60
59
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n~~~table\n~~~\n\ncaption\n~~~'), ctx), [['<figure data-type="table" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext">caption</span></figcaption><div><table></table></div></figure>'], '']);
61
60
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n> \n~~~\n\n~~~'), ctx), [['<figure data-type="quote" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext"></span></figcaption><div><blockquote><pre><br>~~~</pre></blockquote></div></figure>'], '']);
62
61
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n> \n~~~\n\ncaption\n~~~'), ctx), [['<figure data-type="quote" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span><span class="figtext">caption</span></figcaption><div><blockquote><pre><br>~~~</pre></blockquote></div></figure>'], '']);
62
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\\\n~~~'), ctx), [['<figure data-type="media" data-label="group-name" data-group="group"><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>'], '']);
63
63
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n![]{https://host}\n~~~'), ctx), [['<figure data-type="media" data-label="group-name" data-group="group"><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>'], '']);
64
64
  assert.deepStrictEqual(inspect(parser('~~~~figure [$group-name]\n!https://host\n~~~~'), ctx), [['<figure data-type="media" data-label="group-name" data-group="group"><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>'], '']);
65
65
  assert.deepStrictEqual(inspect(parser('~~~figure $group-name\n!https://host\n~~~'), ctx), [['<figure data-type="media" data-label="group-name" data-group="group"><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>'], '']);
@@ -12,7 +12,7 @@ import { example } from './example';
12
12
  import { table, segment_ as seg_table } from './table';
13
13
  import { blockquote, segment as seg_blockquote } from '../blockquote';
14
14
  import { placeholder, segment_ as seg_placeholder } from './placeholder';
15
- import { inline, media, shortmedia } from '../../inline';
15
+ import { inline, media, lineshortmedia } from '../../inline';
16
16
  import { visualize, trimBlank } from '../../visibility';
17
17
  import { invalid } from '../../util';
18
18
  import { memoize } from 'spica/memoize';
@@ -62,7 +62,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
62
62
  blockquote,
63
63
  placeholder,
64
64
  line(media),
65
- line(shortmedia),
65
+ line(lineshortmedia),
66
66
  ])),
67
67
  emptyline,
68
68
  block(visualize(trimBlank(some(inline)))),
@@ -1,6 +1,6 @@
1
1
  import { ExtensionParser } from '../../block';
2
2
  import { input, eval } from '../../../combinator/data/parser';
3
- import { union, block, validate, fence, fmap } from '../../../combinator';
3
+ import { union, block, fence, fmap } from '../../../combinator';
4
4
  import { segment } from '../../segment';
5
5
  import { emptyline } from '../../source';
6
6
  import { ulist } from '../ulist';
@@ -19,7 +19,7 @@ import { html } from 'typed-dom/dom';
19
19
 
20
20
  import MessageParser = ExtensionParser.MessageParser;
21
21
 
22
- export const message: MessageParser = block(validate('~~~', fmap(
22
+ export const message: MessageParser = block(fmap(
23
23
  fence(/(~{3,})message\/(\S+)([^\n]*)(?:$|\n)/y, 300),
24
24
  // Bug: Type mismatch between outer and inner.
25
25
  ([body, overflow, closer, opener, delim, type, param]: string[], context) => {
@@ -50,7 +50,7 @@ export const message: MessageParser = block(validate('~~~', fmap(
50
50
  [html('h1', title(type))],
51
51
  [...segment(body)].reduce((acc, seg) => push(acc, eval(content(input(seg, { ...context })), [])), []))),
52
52
  ];
53
- })));
53
+ }));
54
54
 
55
55
  function title(type: string): string {
56
56
  switch (type) {
@@ -1,17 +1,17 @@
1
1
  import { ExtensionParser } from '../../block';
2
- import { block, validate, fence, clear, fmap } from '../../../combinator';
2
+ import { block, fence, clear, fmap } from '../../../combinator';
3
3
  import { invalid } from '../../util';
4
4
  import { html } from 'typed-dom/dom';
5
5
 
6
6
  const opener = /(~{3,})(?!~)[^\n]*(?:$|\n)/y;
7
7
 
8
- export const segment: ExtensionParser.PlaceholderParser.SegmentParser = block(validate('~~~',
9
- clear(fence(opener, 300))));
8
+ export const segment: ExtensionParser.PlaceholderParser.SegmentParser = block(
9
+ clear(fence(opener, 300)));
10
10
 
11
- export const segment_: ExtensionParser.PlaceholderParser.SegmentParser = block(validate('~~~',
12
- clear(fence(opener, 300, false))), false);
11
+ export const segment_: ExtensionParser.PlaceholderParser.SegmentParser = block(
12
+ clear(fence(opener, 300, false)), false);
13
13
 
14
- export const placeholder: ExtensionParser.PlaceholderParser = block(validate('~~~', fmap(
14
+ export const placeholder: ExtensionParser.PlaceholderParser = block(fmap(
15
15
  fence(opener, Infinity),
16
16
  ([body, overflow, closer, opener, delim]) => [
17
17
  html('pre', {
@@ -24,4 +24,4 @@ export const placeholder: ExtensionParser.PlaceholderParser = block(validate('~~
24
24
  overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
25
25
  'Invalid argument'),
26
26
  }, `${opener}${body}${overflow || closer}`),
27
- ])));
27
+ ]));
@@ -2,9 +2,9 @@ import { max, min, isArray } from 'spica/alias';
2
2
  import { ExtensionParser } from '../../block';
3
3
  import { Node, eval, input } from '../../../combinator/data/parser';
4
4
  import { union, subsequence, inits, some, block, line, validate, fence, rewrite, clear, surround, open, convert, dup, lazy, fmap } from '../../../combinator';
5
- import { inline, medialink, media, shortmedia } from '../../inline';
5
+ import { inline, medialink, media, lineshortmedia } from '../../inline';
6
6
  import { str, anyline, emptyline, contentline } from '../../source';
7
- import { linearize, invalid } from '../../util';
7
+ import { invalid } from '../../util';
8
8
  import { visualize, trimBlank, trimBlankEnd } from '../../visibility';
9
9
  import { unshift, splice } from 'spica/array';
10
10
  import { html, define, defrag } from 'typed-dom/dom';
@@ -16,13 +16,13 @@ import CellParser = TableParser.CellParser;
16
16
 
17
17
  const opener = /(~{3,})table(?:\/(\S+))?(?!\S)([^\n]*)(?:$|\n)/y;
18
18
 
19
- export const segment: TableParser.SegmentParser = block(validate('~~~',
20
- clear(fence(opener, 10000))));
19
+ export const segment: TableParser.SegmentParser = block(
20
+ clear(fence(opener, 10000)));
21
21
 
22
- export const segment_: TableParser.SegmentParser = block(validate('~~~',
23
- clear(fence(opener, 10000, false))), false);
22
+ export const segment_: TableParser.SegmentParser = block(
23
+ clear(fence(opener, 10000, false)), false);
24
24
 
25
- export const table: TableParser = block(validate('~~~', fmap(
25
+ export const table: TableParser = block(fmap(
26
26
  fence(opener, 10000),
27
27
  // Bug: Type mismatch between outer and inner.
28
28
  ([body, overflow, closer, opener, delim, type, param]: string[], context) => {
@@ -48,7 +48,7 @@ export const table: TableParser = block(validate('~~~', fmap(
48
48
  ...invalid('table', 'argument', 'Invalid table type'),
49
49
  }, `${opener}${body}${closer}`)];
50
50
  }
51
- })));
51
+ }));
52
52
 
53
53
  const parser: TableParser = lazy(() => block(fmap(
54
54
  some(union([row])),
@@ -84,10 +84,15 @@ const head: CellParser.HeadParser = block(fmap(open(
84
84
  some(contentline, delimiter),
85
85
  ]),
86
86
  union([
87
- block(surround(/[^\n]/y, medialink, /\s*$/y)),
88
- block(surround(/[^\n]/y, media, /\s*$/y)),
89
- block(surround(/[^\n]/y, shortmedia, /\s*$/y)),
90
- open(/(?:\s*\n|\s)/y, visualize(trimBlank(some(inline))), true),
87
+ block(surround(
88
+ /\s/y,
89
+ union([
90
+ medialink,
91
+ media,
92
+ lineshortmedia,
93
+ ]),
94
+ /\s*$/y)),
95
+ open(/(?:[^\S\n]*\n|\s)/y, visualize(trimBlank(some(inline))), true),
91
96
  ])),
92
97
  true),
93
98
  ns => [html('th', attributes(ns.shift()! as string), defrag(ns))]),
@@ -101,10 +106,15 @@ const data: CellParser.DataParser = block(fmap(open(
101
106
  some(contentline, delimiter),
102
107
  ]),
103
108
  union([
104
- block(surround(/[^\n]/y, medialink, /\s*$/y)),
105
- block(surround(/[^\n]/y, media, /\s*$/y)),
106
- block(surround(/[^\n]/y, shortmedia, /\s*$/y)),
107
- open(/(?:\s*\n|\s)/y, visualize(trimBlankEnd(linearize(some(inline), -1))), true),
109
+ block(surround(
110
+ /\s/y,
111
+ union([
112
+ medialink,
113
+ media,
114
+ lineshortmedia,
115
+ ]),
116
+ /\s*$/y)),
117
+ open(/(?:[^\S\n]*\n|\s)/y, visualize(trimBlankEnd(some(inline))), true),
108
118
  ])),
109
119
  true),
110
120
  ns => [html('td', attributes(ns.shift()! as string), defrag(ns))]),
@@ -1,5 +1,5 @@
1
1
  import { ExtensionParser } from '../block';
2
- import { union, validate } from '../../combinator';
2
+ import { union } from '../../combinator';
3
3
  import { figbase } from './extension/figbase';
4
4
  import { fig, segment as seg_fig } from './extension/fig';
5
5
  import { figure, segment as seg_figure } from './extension/figure';
@@ -9,12 +9,12 @@ import { aside } from './extension/aside';
9
9
  import { example } from './extension/example';
10
10
  import { placeholder, segment as seg_placeholder } from './extension/placeholder';
11
11
 
12
- export const segment: ExtensionParser.SegmentParser = validate(/~~~|\[?\$|~{3,}|\[?\$[A-Za-z-]\S+[^\S\n]*(?:$|\n)/y, union([
12
+ export const segment: ExtensionParser.SegmentParser = union([
13
13
  seg_fig,
14
14
  seg_figure,
15
15
  seg_table,
16
16
  seg_placeholder,
17
- ]));
17
+ ]);
18
18
 
19
19
  export const extension: ExtensionParser = union([
20
20
  figbase,
@@ -1,13 +1,13 @@
1
1
  import { IListParser } from '../block';
2
2
  import { Parser } from '../../combinator/data/parser';
3
3
  import { Recursion } from '../context';
4
- import { union, inits, some, recursion, block, line, validate, indent, rewrite, open, trim, fallback, lazy, fmap } from '../../combinator';
4
+ import { union, inits, some, recursion, block, line, validate, indent, rewrite, open, fallback, lazy, fmap } from '../../combinator';
5
5
  import { ulist_, fillFirstLine } from './ulist';
6
6
  import { olist_ } from './olist';
7
7
  import { inline } from '../inline';
8
8
  import { contentline } from '../source';
9
9
  import { visualize, trimBlank } from '../visibility';
10
- import { linearize, invalid } from '../util';
10
+ import { invalid } from '../util';
11
11
  import { html, defrag } from 'typed-dom/dom';
12
12
 
13
13
  export const ilist: IListParser = lazy(() => block(validate(
@@ -19,7 +19,7 @@ export const ilist_: IListParser = lazy(() => block(fmap(validate(
19
19
  some(recursion(Recursion.listitem, union([
20
20
  fmap(fallback(
21
21
  inits([
22
- line(open(/[-+*](?:$|[ \n])/y, trim(visualize(trimBlank(linearize(some(inline), -1)))), true)),
22
+ line(open(/[-+*](?:$|[ \n])/y, visualize(trimBlank(some(inline))), true)),
23
23
  indent(union([ulist_, olist_, ilist_])),
24
24
  ]),
25
25
  ilistitem),
@@ -1,17 +1,17 @@
1
1
  import { MathBlockParser } from '../block';
2
- import { block, validate, fence, clear, fmap } from '../../combinator';
2
+ import { block, fence, clear, fmap } from '../../combinator';
3
3
  import { invalid } from '../util';
4
4
  import { html } from 'typed-dom/dom';
5
5
 
6
6
  const opener = /(\${2,})(?!\$)([^\n]*)(?:$|\n)/y;
7
7
 
8
- export const segment: MathBlockParser.SegmentParser = block(validate('$$',
9
- clear(fence(opener, 300))));
8
+ export const segment: MathBlockParser.SegmentParser = block(
9
+ clear(fence(opener, 300)));
10
10
 
11
- export const segment_: MathBlockParser.SegmentParser = block(validate('$$',
12
- clear(fence(opener, 300, false))), false);
11
+ export const segment_: MathBlockParser.SegmentParser = block(
12
+ clear(fence(opener, 300, false)), false);
13
13
 
14
- export const mathblock: MathBlockParser = block(validate('$$', fmap(
14
+ export const mathblock: MathBlockParser = block(fmap(
15
15
  fence(opener, 300),
16
16
  // Bug: Type mismatch between outer and inner.
17
17
  ([body, overflow, closer, opener, delim, param]: string[], { caches: { math: cache = undefined } = {} }) => [
@@ -29,4 +29,4 @@ export const mathblock: MathBlockParser = block(validate('$$', fmap(
29
29
  overflow ? `Invalid trailing line after the closing delimiter "${delim}"` :
30
30
  'Invalid argument'),
31
31
  }, `${opener}${body}${overflow || closer}`),
32
- ])));
32
+ ]));
@@ -1,23 +1,23 @@
1
1
  import { MediaBlockParser } from '../block';
2
- import { union, inits, some, block, line, validate, fallback, fmap } from '../../combinator';
3
- import { medialink, media, shortmedia } from '../inline';
2
+ import { union, inits, some, block, line, fallback, fmap } from '../../combinator';
3
+ import { medialink, media, lineshortmedia } from '../inline';
4
4
  import { invalid } from '../util';
5
5
  import { html } from 'typed-dom/dom';
6
6
 
7
- export const mediablock: MediaBlockParser = block(validate(/\[?!/y, fmap(
7
+ export const mediablock: MediaBlockParser = block(fmap(
8
8
  inits([
9
9
  line(union([
10
10
  medialink,
11
11
  media,
12
- shortmedia,
12
+ lineshortmedia,
13
13
  ])),
14
14
  some(line(fallback(union([
15
15
  medialink,
16
16
  media,
17
- shortmedia,
17
+ lineshortmedia,
18
18
  ]), ({ context: { source } }) => [[html('span', {
19
19
  class: 'invalid',
20
20
  ...invalid('mediablock', 'syntax', 'Not media syntax'),
21
21
  }, source.replace('\n', ''))]]))),
22
22
  ]),
23
- ns => [html('div', ns)])));
23
+ ns => [html('div', ns)]));
@@ -1,10 +1,10 @@
1
1
  import { OListParser } from '../block';
2
2
  import { Recursion } from '../context';
3
- import { union, inits, subsequence, some, recursion, block, line, validate, indent, focus, open, match, trim, fallback, lazy, fmap } from '../../combinator';
3
+ import { union, inits, subsequence, some, recursion, block, line, validate, indent, focus, open, match, fallback, lazy, fmap } from '../../combinator';
4
4
  import { ulist_, checkbox, fillFirstLine } from './ulist';
5
5
  import { ilist_, ilistitem } from './ilist';
6
6
  import { inline, indexee, indexer, dataindex } from '../inline';
7
- import { invalid, linearize } from '../util';
7
+ import { invalid } from '../util';
8
8
  import { visualize, trimBlank } from '../visibility';
9
9
  import { memoize } from 'spica/memoize';
10
10
  import { html, define, defrag } from 'typed-dom/dom';
@@ -36,7 +36,7 @@ const list = (type: string, form: string): OListParser.ListParser => fmap(
36
36
  inits([
37
37
  line(open(heads[form], subsequence([
38
38
  checkbox,
39
- trim(visualize(linearize(trimBlank(some(union([indexer, inline]))), -1)))]), true)),
39
+ visualize(trimBlank(some(union([indexer, inline]))))]), true)),
40
40
  indent(union([ulist_, olist_, ilist_])),
41
41
  ]),
42
42
  ilistitem),