securemark 0.241.0 → 0.243.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.
@@ -5,7 +5,7 @@ import { parse } from '../../api/parse';
5
5
  import { mathblock } from '../mathblock';
6
6
  import { html } from 'typed-dom/dom';
7
7
 
8
- const opener = /^(~{3,})(?:example\/(\S+)|(?!\S))([^\n]*)(?:$|\n)/;
8
+ const opener = /^(~{3,})(?:example\/(\S+))?(?!\S)([^\n]*)(?:$|\n)/;
9
9
 
10
10
  export const example: ExtensionParser.ExampleParser = creator(100, block(validate('~~~', fmap(
11
11
  fence(opener, 300),
@@ -26,9 +26,9 @@ describe('Unit: parser/block/extension/fig', () => {
26
26
  assert.deepStrictEqual(inspect(parser('[$group-name]\n!https://host\n')), [['<figure data-type="media" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
27
27
  assert.deepStrictEqual(inspect(parser('[$group-name]\n|\n|-\n|')), [['<figure data-type="table" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><table><thead><tr></tr></thead><tbody><tr></tr></tbody></table></div></figure>'], '']);
28
28
  assert.deepStrictEqual(inspect(parser('[$group-name]\n|\n|-\n|\n')), [['<figure data-type="table" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><table><thead><tr></tr></thead><tbody><tr></tr></tbody></table></div></figure>'], '']);
29
- assert.deepStrictEqual(inspect(parser('[$group-name]\n```\n\n```')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text" translate="no"></pre></div></figure>'], '']);
30
- assert.deepStrictEqual(inspect(parser('[$group-name]\n```\n\n```\n')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text" translate="no"></pre></div></figure>'], '']);
31
- assert.deepStrictEqual(inspect(parser('[$group-name]\n```\n~~~\n```')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text" translate="no">~~~</pre></div></figure>'], '']);
29
+ assert.deepStrictEqual(inspect(parser('[$group-name]\n```\n\n```')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text"></pre></div></figure>'], '']);
30
+ assert.deepStrictEqual(inspect(parser('[$group-name]\n```\n\n```\n')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text"></pre></div></figure>'], '']);
31
+ assert.deepStrictEqual(inspect(parser('[$group-name]\n```\n~~~\n```')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text">~~~</pre></div></figure>'], '']);
32
32
  assert.deepStrictEqual(inspect(parser('[$group-name]\n$$\n\n$$')), [['<figure data-type="math" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
33
33
  assert.deepStrictEqual(inspect(parser('[$group-name]\n$$\n\n$$\n')), [['<figure data-type="math" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
34
34
  assert.deepStrictEqual(inspect(parser('[$group-name]\n~~~example/markdown\n~~~')), [['<figure data-type="example" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><aside class="example" data-type="markdown"><pre translate="no"></pre><hr><section><ol class="annotations"></ol><ol class="references"></ol></section></aside></div></figure>'], '']);
@@ -1,12 +1,12 @@
1
1
  import { ExtensionParser } from '../../block';
2
- import { union, sequence, some, block, line, validate, rewrite, close, convert } from '../../../combinator';
2
+ import { union, sequence, some, block, line, validate, verify, rewrite, close, convert } from '../../../combinator';
3
3
  import { contentline } from '../../source';
4
4
  import { figure } from './figure';
5
5
  import { segment as seg_label } from '../../inline/extension/label';
6
6
  import { segment as seg_code } from '../codeblock';
7
7
  import { segment as seg_math } from '../mathblock';
8
- import { segment as seg_blockquote } from '../blockquote';
9
8
  import { segment as seg_table } from './table';
9
+ import { segment as seg_blockquote } from '../blockquote';
10
10
  import { segment as seg_placeholder } from './placeholder';
11
11
 
12
12
  import FigParser = ExtensionParser.FigParser;
@@ -17,17 +17,18 @@ export const segment: FigParser.SegmentParser = block(validate(['[$', '$'],
17
17
  union([
18
18
  seg_code,
19
19
  seg_math,
20
- seg_blockquote,
21
20
  seg_table,
21
+ seg_blockquote,
22
22
  seg_placeholder,
23
23
  some(contentline),
24
24
  ]),
25
25
  ])));
26
26
 
27
- export const fig: FigParser = block(rewrite(segment, convert(
27
+ export const fig: FigParser = block(rewrite(segment, verify(convert(
28
28
  source => {
29
- const fence = (/^[^\n]*\n!?>+\s/.test(source) && source.match(/^~{3,}(?=\s*$)/mg) || [])
29
+ const fence = (/^[^\n]*\n!?>+\s/.test(source) && source.match(/^~{3,}(?=[^\S\n]*$)/mg) || [])
30
30
  .reduce((max, fence) => fence > max ? fence : max, '~~') + '~';
31
31
  return `${fence}figure ${source}\n\n${fence}`;
32
32
  },
33
- union([figure]))));
33
+ union([figure])),
34
+ ([el]) => el.tagName === 'FIGURE')));
@@ -7,25 +7,24 @@ describe('Unit: parser/block/extension/figure', () => {
7
7
  const parser = (source: string) => some(figure)(source, {});
8
8
 
9
9
  it('invalid', () => {
10
- assert.deepStrictEqual(inspect(parser('~~~figure\n!https://host\n~~~')), undefined);
11
- assert.deepStrictEqual(inspect(parser('~~~figure $group-name]\n!https://host\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group" class="invalid"><figcaption><span class="figindex"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
12
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name\n!https://host\n~~~')), undefined);
13
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\nhttps://host\n~~~')), undefined);
14
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\\\n~~~')), undefined);
15
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\\\n~~~')), undefined);
16
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\na\n~~~')), undefined);
17
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n\n\n~~~')), undefined);
18
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n !https://host\n~~~')), undefined);
19
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n\n!https://host\n~~~')), undefined);
20
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n~~~\n~~~')), undefined);
21
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n~~~~')), undefined);
22
- assert.deepStrictEqual(inspect(parser('~~~~figure [$group-name]\n!https://host\n~~~')), undefined);
23
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]a\nhttps://host\n~~~')), undefined);
24
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]a\n!https://host\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group" class="invalid"><figcaption><span class="figindex"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
25
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name] a\nhttps://host\n~~~')), undefined);
10
+ assert.deepStrictEqual(inspect(parser('~~~figure\n!https://host\n~~~')), [['<pre class="invalid" translate="no">~~~figure\n!https://host\n~~~</pre>'], '']);
11
+ assert.deepStrictEqual(inspect(parser('~~~figure $group-name]\n!https://host\n~~~')), [['<pre class="invalid" translate="no">~~~figure $group-name]\n!https://host\n~~~</pre>'], '']);
12
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name\n!https://host\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name\n!https://host\n~~~</pre>'], '']);
13
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\nhttps://host\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name]\nhttps://host\n~~~</pre>'], '']);
14
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\\\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n!https://host\\\n~~~</pre>'], '']);
15
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\\\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n!https://host\n\\\n~~~</pre>'], '']);
16
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\na\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n!https://host\na\n~~~</pre>'], '']);
17
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n\n\n\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n!https://host\n\n\n\n~~~</pre>'], '']);
18
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n !https://host\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n !https://host\n~~~</pre>'], '']);
19
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n~~~\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n!https://host\n~~~\n~~~</pre>'], '']);
20
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n!https://host\n~~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name]\n!https://host\n~~~~</pre>'], '']);
21
+ assert.deepStrictEqual(inspect(parser('~~~~figure [$group-name]\n!https://host\n~~~')), [['<pre class="invalid" translate="no">~~~~figure [$group-name]\n!https://host\n~~~</pre>'], '']);
22
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]a\nhttps://host\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name]a\nhttps://host\n~~~</pre>'], '']);
23
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]a\n!https://host\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name]a\n!https://host\n~~~</pre>'], '']);
24
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name] a\nhttps://host\n~~~')), [['<pre class="invalid" translate="no">~~~figure [$group-name] a\nhttps://host\n~~~</pre>'], '']);
26
25
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name] a\n!https://host\n~~~')), [['<figure data-type="media" data-label="group-name" data-group="group" class="invalid"><figcaption><span class="figindex"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
27
- assert.deepStrictEqual(inspect(parser('~~~figure a[$group-name]\n!https://host\n~~~')), undefined);
28
- assert.deepStrictEqual(inspect(parser('~~~figure a [$group-name]\n!https://host\n~~~')), undefined);
26
+ assert.deepStrictEqual(inspect(parser('~~~figure a[$group-name]\n!https://host\n~~~')), [['<pre class="invalid" translate="no">~~~figure a[$group-name]\n!https://host\n~~~</pre>'], '']);
27
+ assert.deepStrictEqual(inspect(parser('~~~figure a [$group-name]\n!https://host\n~~~')), [['<pre class="invalid" translate="no">~~~figure a [$group-name]\n!https://host\n~~~</pre>'], '']);
29
28
  assert.deepStrictEqual(inspect(parser('~~~ [$group-name]\n!https://host\n~~~')), undefined);
30
29
  assert.deepStrictEqual(inspect(parser('~~~ $group-name\n!https://host\n~~~')), undefined);
31
30
  assert.deepStrictEqual(inspect(parser(' ~~~figure [$group-name]\n!https://host\n~~~')), undefined);
@@ -33,7 +32,8 @@ describe('Unit: parser/block/extension/figure', () => {
33
32
  assert.deepStrictEqual(inspect(parser('~~~figure [$fig-name]\n> \n\n~~~')), [['<figure data-type="quote" data-label="fig-name" data-group="fig" class="invalid"><figcaption><span class="figindex"></span></figcaption><div><blockquote></blockquote></div></figure>'], '']);
34
33
  assert.deepStrictEqual(inspect(parser('~~~figure [$figure-name]\n> \n\n~~~')), [['<figure data-type="quote" data-label="figure-name" data-group="figure" class="invalid"><figcaption><span class="figindex"></span></figcaption><div><blockquote></blockquote></div></figure>'], '']);
35
34
  assert.deepStrictEqual(inspect(parser('~~~figure [$table-name]\n> \n\n~~~')), [['<figure data-type="quote" data-label="table-name" data-group="table" class="invalid"><figcaption><span class="figindex"></span></figcaption><div><blockquote></blockquote></div></figure>'], '']);
36
- assert(!parser('~~~figure [$group-name]\n```\n0' + '\n'.repeat(301) + '```\n~~~'));
35
+ assert.deepStrictEqual(inspect(parser(`~~~figure [$group-name]\n0${'\n'.repeat(301)}~~~`), '>'), [['<pre class="invalid" translate="no">'], '']);
36
+ assert.deepStrictEqual(inspect(parser(`~~~figure [$group-name]\n~~~\n0${'\n'.repeat(301)}~~~\n~~~`), '>'), [['<pre class="invalid" translate="no">'], '\n~~~\n~~~']);
37
37
  });
38
38
 
39
39
  it('valid', () => {
@@ -46,9 +46,9 @@ describe('Unit: parser/block/extension/figure', () => {
46
46
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n- a\n~~~')), [['<figure data-type="list" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><ul><li>a</li></ul></div></figure>'], '']);
47
47
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n1. a\n~~~')), [['<figure data-type="list" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><ol><li>a</li></ol></div></figure>'], '']);
48
48
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n|\n|-\n|\n~~~')), [['<figure data-type="table" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><table><thead><tr></tr></thead><tbody><tr></tr></tbody></table></div></figure>'], '']);
49
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n```\n\n```\n~~~')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text" translate="no"></pre></div></figure>'], '']);
50
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n```\n~~~\n```\n\n~~~')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text" translate="no">~~~</pre></div></figure>'], '']);
51
- assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n```\n```\n\ncaption\n~~~')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span>caption</figcaption><div><pre class="text" translate="no"></pre></div></figure>'], '']);
49
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n```\n\n```\n~~~')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text"></pre></div></figure>'], '']);
50
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n```\n~~~\n```\n\n~~~')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><pre class="text">~~~</pre></div></figure>'], '']);
51
+ assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n```\n```\n\ncaption\n~~~')), [['<figure data-type="text" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span>caption</figcaption><div><pre class="text"></pre></div></figure>'], '']);
52
52
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n$$\n\n$$\n~~~')), [['<figure data-type="math" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
53
53
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n$$\n~~~\n$$\n~~~')), [['<figure data-type="math" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span></figcaption><div><div class="math" translate="no">$$\n~~~\n$$</div></div></figure>'], '']);
54
54
  assert.deepStrictEqual(inspect(parser('~~~figure [$group-name]\n$$\n\n$$\n\ncaption\n~~~')), [['<figure data-type="math" data-label="group-name" data-group="group"><figcaption><span class="figindex"></span>caption</figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
@@ -67,8 +67,8 @@ describe('Unit: parser/block/extension/figure', () => {
67
67
  assert.deepStrictEqual(inspect(parser('~~~figure [$-0.0]\n$$\n\n$$\n~~~')), [['<figure data-type="math" data-label="$-0.0" data-group="$" class="invalid"><figcaption><span class="figindex"></span></figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
68
68
  assert.deepStrictEqual(inspect(parser('~~~figure [$-name]\n!https://host\n~~~')), [['<figure data-type="media" data-label="$-name" data-group="$" class="invalid"><figcaption><span class="figindex"></span></figcaption><div><a href="https://host" target="_blank"><img class="media" data-src="https://host" alt=""></a></div></figure>'], '']);
69
69
  assert.deepStrictEqual(inspect(parser('~~~figure [$-name]\n$$\n\n$$\n\ncaption\n~~~')), [['<figure data-type="math" data-label="$-name" data-group="$" class="invalid"><figcaption><span class="figindex"></span>caption</figcaption><div><div class="math" translate="no">$$\n\n$$</div></div></figure>'], '']);
70
- assert(parser('~~~figure [$group-name]\n```\n0' + '\n'.repeat(300) + '```\n~~~'));
71
- assert(parser('~~~figure [$group-name]\n' + '>\n'.repeat(500) + '\n~~~'));
70
+ assert.deepStrictEqual(inspect(parser(`~~~figure [$group-name]\n${'>\n'.repeat(500)}\n~~~`), '>'), [['<figure data-type="quote" data-label="group-name" data-group="group">'], '']);
71
+ assert.deepStrictEqual(inspect(parser(`~~~figure [$group-name]\n~~~\n0${'\n'.repeat(300)}~~~\n~~~`), '>'), [['<figure data-type="example" data-label="group-name" data-group="group">'], '']);
72
72
  });
73
73
 
74
74
  });
@@ -1,16 +1,17 @@
1
1
  import { undefined } from 'spica/global';
2
2
  import { ExtensionParser } from '../../block';
3
- import { union, inits, sequence, some, block, line, rewrite, context, close, match, convert, trim, fmap } from '../../../combinator';
3
+ import { union, inits, sequence, some, block, line, fence, rewrite, context, close, match, convert, trim, fallback, fmap } from '../../../combinator';
4
4
  import { str, contentline, emptyline } from '../../source';
5
- import { label } from '../../inline/extension/label';
5
+ import { label, segment as seg_label } from '../../inline/extension/label';
6
6
  import { ulist } from '../ulist';
7
7
  import { olist } from '../olist';
8
8
  import { table as styled_table } from '../table';
9
+ import { indentblock } from '../indentblock';
9
10
  import { codeblock, segment_ as seg_code } from '../codeblock';
10
11
  import { mathblock, segment_ as seg_math } from '../mathblock';
11
- import { blockquote, segment as seg_blockquote } from '../blockquote';
12
12
  import { example } from './example';
13
13
  import { table, segment_ as seg_table } from './table';
14
+ import { blockquote, segment as seg_blockquote } from '../blockquote';
14
15
  import { placeholder, segment_ as seg_placeholder } from './placeholder';
15
16
  import { inline, media, shortmedia } from '../../inline';
16
17
  import { localize } from '../../locale';
@@ -22,46 +23,46 @@ import { unshift } from 'spica/array';
22
23
  import FigureParser = ExtensionParser.FigureParser;
23
24
 
24
25
  export const segment: FigureParser.SegmentParser = block(match(
25
- /^(~{3,})(?:figure[^\S\n]+)?(?=\[?\$[A-Za-z-][^\n]*\n)/,
26
+ /^(~{3,})(?:figure[^\S\n]|(?=\[?\$))/,
26
27
  memoize(
27
- ([, fence], closer = new RegExp(String.raw`^${fence}[^\S\n]*(?:$|\n)`)) =>
28
- close(
29
- sequence([
30
- contentline,
31
- inits([
32
- // All parsers which can include closing terms.
33
- union([
34
- seg_code,
35
- seg_math,
36
- seg_blockquote,
37
- seg_table,
38
- seg_placeholder,
39
- some(contentline, closer),
40
- ]),
28
+ ([, fence], closer = new RegExp(String.raw`^${fence}[^\S\n]*(?:$|\n)`)) => close(
29
+ sequence([
30
+ contentline,
31
+ inits([
32
+ // All parsers which can include closing terms.
33
+ union([
34
+ seg_code,
35
+ seg_math,
36
+ seg_table,
37
+ seg_blockquote,
38
+ seg_placeholder,
39
+ some(contentline, closer),
40
+ ]),
41
+ emptyline,
42
+ union([
41
43
  emptyline,
42
- union([
43
- emptyline,
44
- some(contentline, closer),
45
- ]),
44
+ some(contentline, closer),
46
45
  ]),
47
46
  ]),
48
- closer),
47
+ ]),
48
+ closer),
49
49
  ([, fence]) => fence.length, [])));
50
50
 
51
- export const figure: FigureParser = block(rewrite(segment, fmap(
52
- convert(source => source.slice(source.search(/[[$]/), source.trimEnd().lastIndexOf('\n')),
51
+ export const figure: FigureParser = block(fallback(rewrite(segment, fallback(fmap(
52
+ convert(source => source.slice(source.match(/^~+(?:figure[^\S\n]+)?/)![0].length, source.trimEnd().lastIndexOf('\n')),
53
53
  sequence([
54
- line(sequence([label, str(/^.*\n/)])),
54
+ line(sequence([label, str(/^(?=\s).*\n/)])),
55
55
  inits([
56
56
  block(union([
57
57
  ulist,
58
58
  olist,
59
59
  styled_table,
60
+ indentblock,
60
61
  codeblock,
61
62
  mathblock,
62
- blockquote,
63
63
  example,
64
64
  table,
65
+ blockquote,
65
66
  placeholder,
66
67
  line(media),
67
68
  line(shortmedia),
@@ -81,7 +82,53 @@ export const figure: FigureParser = block(rewrite(segment, fmap(
81
82
  defrag(caption))),
82
83
  html('div', [content]),
83
84
  ])
84
- ])));
85
+ ]),
86
+ (source, context) => [[
87
+ html('pre', {
88
+ class: 'invalid',
89
+ translate: 'no',
90
+ 'data-invalid-syntax': 'figure',
91
+ ...
92
+ !seg_label(source.match(/^~+(?:figure[^\S\n]+)?(\[?\$\S+)/)?.[1] ?? '', context) && {
93
+ 'data-invalid-type': 'label',
94
+ 'data-invalid-message': 'Invalid label',
95
+ } ||
96
+ /^~+(?:figure[^\S\n]+)?(\[?\$\S+)[^\S\n]+\S/.test(source) && {
97
+ 'data-invalid-type': 'argument',
98
+ 'data-invalid-message': 'Invalid argument',
99
+ } ||
100
+ {
101
+ 'data-invalid-type': 'content',
102
+ 'data-invalid-message': 'Invalid content',
103
+ },
104
+ }, source),
105
+ ], ''])),
106
+ fmap(
107
+ fence(/^(~{3,})(?:figure|\[?\$\S*)(?!\S)[^\n]*(?:$|\n)/, 300),
108
+ ([body, closer, opener, delim]: string[], _, context) => [
109
+ html('pre', {
110
+ class: 'invalid',
111
+ translate: 'no',
112
+ 'data-invalid-syntax': 'figure',
113
+ ...
114
+ !closer && {
115
+ 'data-invalid-type': 'fence',
116
+ 'data-invalid-message': `Missing the closing delimiter "${delim}"`,
117
+ } ||
118
+ !seg_label(opener.match(/^~+(?:figure[^\S\n]+)?(\[?\$\S+)/)?.[1] ?? '', context) && {
119
+ 'data-invalid-type': 'label',
120
+ 'data-invalid-message': 'Invalid label',
121
+ } ||
122
+ /^~+(?:figure[^\S\n]+)?(\[?\$\S+)[^\S\n]+\S/.test(opener) && {
123
+ 'data-invalid-type': 'argument',
124
+ 'data-invalid-message': 'Invalid argument',
125
+ } ||
126
+ {
127
+ 'data-invalid-type': 'content',
128
+ 'data-invalid-message': 'Invalid content',
129
+ },
130
+ }, `${opener}${body}${closer}`),
131
+ ])));
85
132
 
86
133
  function attributes(label: string, param: string, content: HTMLElement, caption: readonly HTMLElement[]): Record<string, string | undefined> {
87
134
  const group = label.split('-', 1)[0];
@@ -111,14 +158,14 @@ function attributes(label: string, param: string, content: HTMLElement, caption:
111
158
  assert(false);
112
159
  }
113
160
  const invalid =
114
- /^[^-]+-(?:[0-9]+\.)*0$/.test(label) && {
115
- 'data-invalid-type': 'label',
116
- 'data-invalid-message': 'The last part of the fixed label numbers must not be 0',
117
- } ||
118
161
  param.trimStart() !== '' && {
119
162
  'data-invalid-type': 'argument',
120
163
  'data-invalid-message': 'Invalid argument',
121
164
  } ||
165
+ /^[^-]+-(?:[0-9]+\.)*0$/.test(label) && {
166
+ 'data-invalid-type': 'label',
167
+ 'data-invalid-message': 'The last part of the fixed label numbers must not be 0',
168
+ } ||
122
169
  group === '$' && (type !== 'math' || caption.length > 0) && {
123
170
  'data-invalid-type': 'label',
124
171
  'data-invalid-message': '"$" label group must be used to math formulas with no caption',
@@ -15,13 +15,13 @@ describe('Unit: parser/block/extension/message', () => {
15
15
  });
16
16
 
17
17
  it('valid', () => {
18
- assert.deepStrictEqual(inspect(parser('~~~message/note\n~~~')), [['<div class="message type-note"><h6>Note</h6></div>'], '']);
19
- assert.deepStrictEqual(inspect(parser('~~~message/note\n\n~~~')), [['<div class="message type-note"><h6>Note</h6></div>'], '']);
20
- assert.deepStrictEqual(inspect(parser('~~~message/note\na\n~~~')), [['<div class="message type-note"><h6>Note</h6><p>a</p></div>'], '']);
21
- assert.deepStrictEqual(inspect(parser('~~~message/note\na\n\n- \n~~~')), [['<div class="message type-note"><h6>Note</h6><p>a</p><ul><li></li></ul></div>'], '']);
22
- assert.deepStrictEqual(inspect(parser('~~~message/note\n# a\n~~~')), [['<div class="message type-note"><h6>Note</h6><p># a</p></div>'], '']);
23
- assert.deepStrictEqual(inspect(parser('~~~message/caution\n~~~')), [['<div class="message type-caution"><h6>Caution!</h6></div>'], '']);
24
- assert.deepStrictEqual(inspect(parser('~~~message/warning\n~~~')), [['<div class="message type-warning"><h6>WARNING!!</h6></div>'], '']);
18
+ assert.deepStrictEqual(inspect(parser('~~~message/note\n~~~')), [['<div class="message" data-type="note"><h6>Note</h6></div>'], '']);
19
+ assert.deepStrictEqual(inspect(parser('~~~message/note\n\n~~~')), [['<div class="message" data-type="note"><h6>Note</h6></div>'], '']);
20
+ assert.deepStrictEqual(inspect(parser('~~~message/note\na\n~~~')), [['<div class="message" data-type="note"><h6>Note</h6><p>a</p></div>'], '']);
21
+ assert.deepStrictEqual(inspect(parser('~~~message/note\na\n\n- \n~~~')), [['<div class="message" data-type="note"><h6>Note</h6><p>a</p><ul><li></li></ul></div>'], '']);
22
+ assert.deepStrictEqual(inspect(parser('~~~message/note\n# a\n~~~')), [['<div class="message" data-type="note"><h6>Note</h6><p># a</p></div>'], '']);
23
+ assert.deepStrictEqual(inspect(parser('~~~message/caution\n~~~')), [['<div class="message" data-type="caution"><h6>Caution!</h6></div>'], '']);
24
+ assert.deepStrictEqual(inspect(parser('~~~message/warning\n~~~')), [['<div class="message" data-type="warning"><h6>WARNING!!</h6></div>'], '']);
25
25
  });
26
26
 
27
27
  });
@@ -7,8 +7,10 @@ import { ulist } from '../ulist';
7
7
  import { olist } from '../olist';
8
8
  import { ilist } from '../ilist';
9
9
  import { table } from '../table';
10
+ import { indentblock } from '../indentblock';
10
11
  import { codeblock } from '../codeblock';
11
12
  import { mathblock } from '../mathblock';
13
+ import { sidefence } from '../sidefence';
12
14
  import { blockquote } from '../blockquote';
13
15
  import { paragraph } from '../paragraph';
14
16
  import { html } from 'typed-dom/dom';
@@ -41,7 +43,7 @@ export const message: MessageParser = block(validate('~~~', fmap(
41
43
  }, `${opener}${body}${closer}`)];
42
44
  }
43
45
  return [
44
- html('div', { class: `message type-${type}` }, unshift(
46
+ html('div', { class: `message`, 'data-type': type }, unshift(
45
47
  [html('h6', title(type))],
46
48
  [...segment(body)].reduce((acc, seg) => push(acc, eval(content(seg, context), [])), []))),
47
49
  ];
@@ -65,8 +67,10 @@ const content: MessageParser.ContentParser = union([
65
67
  olist,
66
68
  ilist,
67
69
  table,
70
+ indentblock,
68
71
  codeblock,
69
72
  mathblock,
73
+ sidefence,
70
74
  blockquote,
71
75
  paragraph,
72
76
  ]);
@@ -18,6 +18,6 @@ export const placeholder: ExtensionParser.PlaceholderParser = block(validate('~~
18
18
  translate: 'no',
19
19
  'data-invalid-syntax': 'extension',
20
20
  'data-invalid-type': !closer ? 'fence' : 'syntax',
21
- 'data-invalid-message': !closer ? `Missing the closing delimiter "${delim}"` : 'Invalid syntax',
22
- }, `${opener}${body}${closer}`)
21
+ 'data-invalid-message': !closer ? `Missing the closing delimiter "${delim}"` : 'Invalid extension name',
22
+ }, `${opener}${body}${closer}`),
23
23
  ])));
@@ -0,0 +1,30 @@
1
+ import { indentblock } from './indentblock';
2
+ import { some } from '../../combinator';
3
+ import { inspect } from '../../debug.test';
4
+
5
+ describe('Unit: parser/block/indentblock', () => {
6
+ describe('indentblock', () => {
7
+ const parser = (source: string) => some(indentblock)(source, {});
8
+
9
+ it('invalid', () => {
10
+ assert.deepStrictEqual(inspect(parser('')), undefined);
11
+ assert.deepStrictEqual(inspect(parser('\na')), undefined);
12
+ assert.deepStrictEqual(inspect(parser(' a')), undefined);
13
+ assert.deepStrictEqual(inspect(parser(' \ta')), undefined);
14
+ assert.deepStrictEqual(inspect(parser(' a\nb')), undefined);
15
+ assert.deepStrictEqual(inspect(parser(' a\n b')), undefined);
16
+ });
17
+
18
+ it('valid', () => {
19
+ assert.deepStrictEqual(inspect(parser(' a')), [['<pre class="text">a</pre>'], '']);
20
+ assert.deepStrictEqual(inspect(parser(' a ')), [['<pre class="text">a </pre>'], '']);
21
+ assert.deepStrictEqual(inspect(parser(' a \n')), [['<pre class="text">a </pre>'], '']);
22
+ assert.deepStrictEqual(inspect(parser(' a \n b')), [['<pre class="text">a <br> b</pre>'], '']);
23
+ assert.deepStrictEqual(inspect(parser(' a\\\n b')), [['<pre class="text">a\\<br>b</pre>'], '']);
24
+ assert.deepStrictEqual(inspect(parser('\ta')), [['<pre class="text">a</pre>'], '']);
25
+ assert.deepStrictEqual(inspect(parser('\t a')), [['<pre class="text"> a</pre>'], '']);
26
+ });
27
+
28
+ });
29
+
30
+ });
@@ -0,0 +1,13 @@
1
+ import { IndentBlockParser } from '../block';
2
+ import { union, block, validate, indent, convert } from '../../combinator';
3
+ import { codeblock } from './codeblock';
4
+
5
+ // 空行を含むインデントブロックはインデントの違いによるセグメント分割の境界が視認不能となるため採用しない
6
+
7
+ export const indentblock: IndentBlockParser = block(validate(/^(?: |\t)/, indent(convert(
8
+ source => {
9
+ const fence = (source.match(/^`{3,}(?=[^\S\n]*$)/mg) ?? [])
10
+ .reduce((max, fence) => fence > max ? fence : max, '``') + '`';
11
+ return `${fence}\n${source}\n${fence}`;
12
+ },
13
+ union([codeblock])), true)));
@@ -0,0 +1,66 @@
1
+ import { sidefence } from './sidefence';
2
+ import { some } from '../../combinator';
3
+ import { inspect } from '../../debug.test';
4
+
5
+ describe('Unit: parser/block/sidefence', () => {
6
+ describe('sidefence', () => {
7
+ const parser = (source: string) => some(sidefence)(source, {});
8
+
9
+ it('invalid', () => {
10
+ assert.deepStrictEqual(inspect(parser('')), undefined);
11
+ assert.deepStrictEqual(inspect(parser('\n')), undefined);
12
+ assert.deepStrictEqual(inspect(parser('|')), undefined);
13
+ assert.deepStrictEqual(inspect(parser('|a')), undefined);
14
+ assert.deepStrictEqual(inspect(parser('|\n')), undefined);
15
+ assert.deepStrictEqual(inspect(parser(' | ')), undefined);
16
+ assert.deepStrictEqual(inspect(parser('||')), undefined);
17
+ });
18
+
19
+ it('basic', () => {
20
+ assert.deepStrictEqual(inspect(parser('| ')), [['<blockquote class="invalid"></blockquote>'], '']);
21
+ assert.deepStrictEqual(inspect(parser('| \\')), [['<blockquote class="invalid"><pre>\\</pre></blockquote>'], '']);
22
+ assert.deepStrictEqual(inspect(parser('| \\\n')), [['<blockquote class="invalid"><pre>\\</pre></blockquote>'], '']);
23
+ assert.deepStrictEqual(inspect(parser('| a')), [['<blockquote class="invalid"><pre>a</pre></blockquote>'], '']);
24
+ assert.deepStrictEqual(inspect(parser('| a\n')), [['<blockquote class="invalid"><pre>a</pre></blockquote>'], '']);
25
+ assert.deepStrictEqual(inspect(parser('| a\nb')), undefined);
26
+ assert.deepStrictEqual(inspect(parser('| a\n b ')), undefined);
27
+ assert.deepStrictEqual(inspect(parser('| a\n|')), [['<blockquote class="invalid"><pre>a<br></pre></blockquote>'], '']);
28
+ assert.deepStrictEqual(inspect(parser('| a\n>>1')), undefined);
29
+ assert.deepStrictEqual(inspect(parser('| a\n| b ')), [['<blockquote class="invalid"><pre>a<br>b </pre></blockquote>'], '']);
30
+ assert.deepStrictEqual(inspect(parser('| a\n|\n')), [['<blockquote class="invalid"><pre>a<br></pre></blockquote>'], '']);
31
+ assert.deepStrictEqual(inspect(parser('| a\n|\nb')), undefined);
32
+ assert.deepStrictEqual(inspect(parser('| a\n|\n b ')), undefined);
33
+ assert.deepStrictEqual(inspect(parser('| a\n|\n|')), [['<blockquote class="invalid"><pre>a<br><br></pre></blockquote>'], '']);
34
+ assert.deepStrictEqual(inspect(parser('| a\n|\n>>1')), undefined);
35
+ assert.deepStrictEqual(inspect(parser('| a\n|\n| b ')), [['<blockquote class="invalid"><pre>a<br><br>b </pre></blockquote>'], '']);
36
+ assert.deepStrictEqual(inspect(parser('| a\\\nb')), undefined);
37
+ assert.deepStrictEqual(inspect(parser('| a ')), [['<blockquote class="invalid"><pre> a </pre></blockquote>'], '']);
38
+ assert.deepStrictEqual(inspect(parser('| \na')), undefined);
39
+ assert.deepStrictEqual(inspect(parser('|\na')), undefined);
40
+ assert.deepStrictEqual(inspect(parser('|\n a')), undefined);
41
+ assert.deepStrictEqual(inspect(parser('|\n|')), [['<blockquote class="invalid"><pre><br></pre></blockquote>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('|\n| a')), [['<blockquote class="invalid"><pre><br>a</pre></blockquote>'], '']);
43
+ assert.deepStrictEqual(inspect(parser('| http://host')), [['<blockquote class="invalid"><pre><a href="http://host" target="_blank">http://host</a></pre></blockquote>'], '']);
44
+ assert.deepStrictEqual(inspect(parser('| !http://host')), [['<blockquote class="invalid"><pre>!<a href="http://host" target="_blank">http://host</a></pre></blockquote>'], '']);
45
+ assert.deepStrictEqual(inspect(parser('| #a')), [['<blockquote class="invalid"><pre><a href="/hashtags/a" class="hashtag">#a</a></pre></blockquote>'], '']);
46
+ assert.deepStrictEqual(inspect(parser('| @a#b')), [['<blockquote class="invalid"><pre><a href="/@a?ch=b" class="channel">@a#b</a></pre></blockquote>'], '']);
47
+ assert.deepStrictEqual(inspect(parser('| >>1\n| | b')), [['<blockquote class="invalid"><pre><a href="?at=1" class="anchor">&gt;&gt;1</a><br>| b</pre></blockquote>'], '']);
48
+ assert.deepStrictEqual(inspect(parser('| >>1\n| | b\n| c')), [['<blockquote class="invalid"><pre><a href="?at=1" class="anchor">&gt;&gt;1</a><br>| b<br>c</pre></blockquote>'], '']);
49
+ });
50
+
51
+ it('nest', () => {
52
+ assert.deepStrictEqual(inspect(parser('| a\n||')), [['<blockquote class="invalid"><pre>a</pre><blockquote></blockquote></blockquote>'], '']);
53
+ assert.deepStrictEqual(inspect(parser('| a\n|| b\n| c')), [['<blockquote class="invalid"><pre>a</pre><blockquote><pre>b</pre></blockquote><pre>c</pre></blockquote>'], '']);
54
+ assert.deepStrictEqual(inspect(parser('| a\n|| b\n|| c')), [['<blockquote class="invalid"><pre>a</pre><blockquote><pre>b<br>c</pre></blockquote></blockquote>'], '']);
55
+ assert.deepStrictEqual(inspect(parser('| a\n|| b\n||| c')), [['<blockquote class="invalid"><pre>a</pre><blockquote><pre>b</pre><blockquote><pre>c</pre></blockquote></blockquote></blockquote>'], '']);
56
+ assert.deepStrictEqual(inspect(parser('|| a')), [['<blockquote class="invalid"><blockquote><pre>a</pre></blockquote></blockquote>'], '']);
57
+ assert.deepStrictEqual(inspect(parser('|| a\n|')), [['<blockquote class="invalid"><blockquote><pre>a</pre></blockquote></blockquote>'], '']);
58
+ assert.deepStrictEqual(inspect(parser('|| a\n| b')), [['<blockquote class="invalid"><blockquote><pre>a</pre></blockquote><pre>b</pre></blockquote>'], '']);
59
+ assert.deepStrictEqual(inspect(parser('|| a\n||| b\n| c')), [['<blockquote class="invalid"><blockquote><pre>a</pre><blockquote><pre>b</pre></blockquote></blockquote><pre>c</pre></blockquote>'], '']);
60
+ assert.deepStrictEqual(inspect(parser('|| a\n| b\n||| c')), [['<blockquote class="invalid"><blockquote><pre>a</pre></blockquote><pre>b</pre><blockquote><blockquote><pre>c</pre></blockquote></blockquote></blockquote>'], '']);
61
+ assert.deepStrictEqual(inspect(parser('||| a\n|| b\n| c')), [['<blockquote class="invalid"><blockquote><blockquote><pre>a</pre></blockquote><pre>b</pre></blockquote><pre>c</pre></blockquote>'], '']);
62
+ });
63
+
64
+ });
65
+
66
+ });
@@ -0,0 +1,31 @@
1
+ import { SidefenceParser } from '../block';
2
+ import { union, some, block, focus, rewrite, creator, convert, lazy, fmap } from '../../combinator';
3
+ import { autolink } from '../autolink';
4
+ import { contentline } from '../source';
5
+ import { html, define, defrag } from 'typed-dom/dom';
6
+
7
+ export const sidefence: SidefenceParser = lazy(() => block(fmap(focus(
8
+ /^(?=\|+(?:[^\S\n]|\n\|))(?:\|+(?:[^\S\n][^\n]*)?(?:$|\n))+$/,
9
+ union([source])),
10
+ ([el]) => [
11
+ define(el, {
12
+ class: 'invalid',
13
+ 'data-invalid-syntax': 'sidefence',
14
+ 'data-invalid-type': 'syntax',
15
+ 'data-invalid-message': 'Reserved syntax',
16
+ }),
17
+ ])));
18
+
19
+ const opener = /^(?=\|\|+(?:$|\s))/;
20
+ const unindent = (source: string) => source.replace(/(^|\n)\|(?:[^\S\n]|(?=\|*(?:$|\s)))|\n$/g, '$1');
21
+
22
+ const source: SidefenceParser.SourceParser = lazy(() => fmap(
23
+ some(creator(union([
24
+ focus(
25
+ /^(?:\|\|+(?:[^\S\n][^\n]*)?(?:$|\n))+/,
26
+ convert(unindent, source)),
27
+ rewrite(
28
+ some(contentline, opener),
29
+ convert(unindent, fmap(some(autolink), ns => [html('pre', defrag(ns))]))),
30
+ ]))),
31
+ ns => [html('blockquote', ns)]));
@@ -29,9 +29,9 @@ const row = <P extends CellParser | AlignParser>(parser: P, optional: boolean):
29
29
  rewrite(contentline, source => [[
30
30
  html('tr', {
31
31
  class: 'invalid',
32
- 'data-invalid-syntax': 'tablerow',
32
+ 'data-invalid-syntax': 'table-row',
33
33
  'data-invalid-type': 'syntax',
34
- 'data-invalid-message': 'Invalid table row',
34
+ 'data-invalid-message': 'Missing the start symbol of the table row',
35
35
  }, [html('td', source.replace('\n', ''))])
36
36
  ], ''])));
37
37
 
@@ -9,10 +9,12 @@ import { olist } from './block/olist';
9
9
  import { ilist } from './block/ilist';
10
10
  import { dlist } from './block/dlist';
11
11
  import { table } from './block/table';
12
- import { blockquote } from './block/blockquote';
12
+ import { indentblock } from './block/indentblock';
13
13
  import { codeblock } from './block/codeblock';
14
14
  import { mathblock } from './block/mathblock';
15
15
  import { extension } from './block/extension';
16
+ import { sidefence } from './block/sidefence';
17
+ import { blockquote } from './block/blockquote';
16
18
  import { reply } from './block/reply';
17
19
  import { paragraph } from './block/paragraph';
18
20
  import { html } from 'typed-dom/dom';
@@ -26,9 +28,11 @@ export import OListParser = BlockParser.OListParser;
26
28
  export import IListParser = BlockParser.IListParser;
27
29
  export import DListParser = BlockParser.DListParser;
28
30
  export import TableParser = BlockParser.TableParser;
31
+ export import IndentBlockParser = BlockParser.IndentBlockParser;
29
32
  export import CodeBlockParser = BlockParser.CodeBlockParser;
30
33
  export import MathBlockParser = BlockParser.MathBlockParser;
31
34
  export import ExtensionParser = BlockParser.ExtensionParser;
35
+ export import SidefenceParser = BlockParser.SidefenceParser;
32
36
  export import BlockquoteParser = BlockParser.BlockquoteParser;
33
37
  export import ReplyParser = BlockParser.ReplyParser;
34
38
  export import ParagraphParser = BlockParser.ParagraphParser;
@@ -44,9 +48,11 @@ export const block: BlockParser = creator(error(
44
48
  ilist,
45
49
  dlist,
46
50
  table,
51
+ indentblock,
47
52
  codeblock,
48
53
  mathblock,
49
54
  extension,
55
+ sidefence,
50
56
  blockquote,
51
57
  reply,
52
58
  paragraph
@@ -14,12 +14,12 @@ export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => creator
14
14
  str(/^\[[:^]/),
15
15
  startTight(some(union([inline]), ']')),
16
16
  str(']'), false,
17
- ([, bs], rest) => [[
17
+ ([as, bs], rest) => [[
18
18
  html('span', {
19
19
  class: 'invalid',
20
20
  'data-invalid-syntax': 'extension',
21
21
  'data-invalid-type': 'syntax',
22
- 'data-invalid-message': 'Invalid symbol',
22
+ 'data-invalid-message': `Reserved start symbol "${as[0][1]}" cannot be used in "[]"`,
23
23
  }, defrag(bs)),
24
24
  ], rest],
25
25
  ([as, bs], rest) => [unshift(as, bs), rest]))));