securemark 0.279.0 → 0.280.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +10 -10
  3. package/dist/index.js +118 -104
  4. package/markdown.d.ts +2 -2
  5. package/package.json +1 -1
  6. package/src/combinator/control/manipulation/indent.ts +1 -1
  7. package/src/combinator/data/parser/context/delimiter.ts +49 -21
  8. package/src/combinator/data/parser/context/memo.ts +6 -6
  9. package/src/combinator/data/parser/context.ts +23 -7
  10. package/src/debug.test.ts +2 -2
  11. package/src/parser/api/parse.test.ts +13 -13
  12. package/src/parser/block/extension/figure.ts +1 -1
  13. package/src/parser/block/extension/table.ts +1 -1
  14. package/src/parser/block.ts +2 -2
  15. package/src/parser/inline/annotation.ts +4 -4
  16. package/src/parser/inline/autolink/account.ts +1 -1
  17. package/src/parser/inline/autolink/url.ts +1 -1
  18. package/src/parser/inline/autolink.ts +2 -2
  19. package/src/parser/inline/bracket.test.ts +11 -10
  20. package/src/parser/inline/bracket.ts +10 -11
  21. package/src/parser/inline/deletion.ts +4 -4
  22. package/src/parser/inline/emphasis.ts +4 -4
  23. package/src/parser/inline/emstrong.ts +4 -4
  24. package/src/parser/inline/extension/index.test.ts +6 -0
  25. package/src/parser/inline/extension/index.ts +11 -11
  26. package/src/parser/inline/extension/placeholder.ts +4 -4
  27. package/src/parser/inline/html.test.ts +1 -1
  28. package/src/parser/inline/html.ts +6 -7
  29. package/src/parser/inline/insertion.ts +4 -4
  30. package/src/parser/inline/link.ts +6 -6
  31. package/src/parser/inline/mark.ts +4 -4
  32. package/src/parser/inline/media.ts +4 -4
  33. package/src/parser/inline/reference.ts +3 -3
  34. package/src/parser/inline/remark.test.ts +4 -3
  35. package/src/parser/inline/remark.ts +4 -4
  36. package/src/parser/inline/ruby.ts +2 -2
  37. package/src/parser/inline/strong.ts +4 -4
  38. package/src/parser/inline/template.ts +7 -4
  39. package/src/parser/inline.test.ts +12 -15
  40. package/src/parser/processor/figure.ts +0 -1
  41. package/src/parser/processor/note.ts +0 -3
  42. package/src/parser/source/str.ts +0 -19
  43. package/src/parser/source/text.test.ts +1 -1
  44. package/src/parser/source/text.ts +3 -3
  45. package/src/parser/source.ts +1 -1
  46. package/src/parser/visibility.ts +3 -1
@@ -1,23 +1,23 @@
1
1
  import { ExtensionParser } from '../../inline';
2
- import { union, some, syntax, creation, precedence, constraint, validate, surround, open, lazy, fmap } from '../../../combinator';
2
+ import { union, inits, some, syntax, creation, precedence, constraint, validate, surround, open, lazy, fmap } from '../../../combinator';
3
3
  import { inline } from '../../inline';
4
4
  import { indexee, identity } from './indexee';
5
- import { txt, str, stropt } from '../../source';
5
+ import { txt, str } from '../../source';
6
6
  import { Syntax, State } from '../../context';
7
7
  import { startTight, trimNodeEnd } from '../../visibility';
8
8
  import { html, define, defrag } from 'typed-dom/dom';
9
9
 
10
10
  import IndexParser = ExtensionParser.IndexParser;
11
11
 
12
- export const index: IndexParser = lazy(() => validate('[#', fmap(indexee(surround(
12
+ export const index: IndexParser = lazy(() => validate('[#', creation(fmap(indexee(surround(
13
13
  '[#',
14
14
  constraint(State.index, false,
15
- syntax(Syntax.index, 2, 1, State.linkers | State.media,
15
+ syntax(Syntax.index, 2, State.linkers | State.media,
16
16
  startTight(
17
- open(stropt('|'), some(union([
18
- signature,
17
+ some(inits([
19
18
  inline,
20
- ]), ']', [[/^\\?\n/, 9], [']', 2]]), true)))),
19
+ signature,
20
+ ]), ']', [[/^\\?\n/, 9], [']', 2]])))),
21
21
  ']',
22
22
  false,
23
23
  ([, ns], rest) => [[html('a', trimNodeEnd(defrag(ns)))], rest])),
@@ -28,18 +28,18 @@ export const index: IndexParser = lazy(() => validate('[#', fmap(indexee(surroun
28
28
  class: 'index',
29
29
  href: el.id ? `#${el.id}` : undefined,
30
30
  }),
31
- ])));
31
+ ]))));
32
32
 
33
- export const signature: IndexParser.SignatureParser = lazy(() => creation(fmap(open(
33
+ export const signature: IndexParser.SignatureParser = lazy(() => validate('|', creation(fmap(open(
34
34
  '|',
35
35
  startTight(some(union([bracket, txt]), ']'))),
36
36
  ns => [
37
37
  html('span', { class: 'indexer', 'data-index': identity(undefined, ns.join(''))!.slice(7) }),
38
- ])));
38
+ ]))));
39
39
 
40
40
  const bracket: IndexParser.SignatureParser.BracketParser = lazy(() => creation(union([
41
41
  surround(str('('), some(union([bracket, txt]), ')'), str(')'), true),
42
42
  surround(str('['), some(union([bracket, txt]), ']'), str(']'), true),
43
43
  surround(str('{'), some(union([bracket, txt]), '}'), str('}'), true),
44
- surround(str('"'), precedence(8, some(txt, '"')), str('"'), true),
44
+ surround(str('"'), precedence(3, some(txt, '"')), str('"'), true),
45
45
  ])));
@@ -1,5 +1,5 @@
1
1
  import { ExtensionParser } from '../../inline';
2
- import { union, some, syntax, validate, surround, lazy } from '../../../combinator';
2
+ import { union, some, syntax, creation, validate, surround, lazy } from '../../../combinator';
3
3
  import { inline } from '../../inline';
4
4
  import { str } from '../../source';
5
5
  import { Syntax, State } from '../../context';
@@ -11,9 +11,9 @@ import { html, defrag } from 'typed-dom/dom';
11
11
 
12
12
  // All syntax surrounded by square brackets shouldn't contain line breaks.
13
13
 
14
- export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => validate('[', surround(
14
+ export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => validate('[', creation(surround(
15
15
  str(/^\[[:^|]/),
16
- syntax(Syntax.placeholder, 2, 1, State.none,
16
+ syntax(Syntax.placeholder, 2, State.none,
17
17
  startTight(some(union([inline]), ']', [[']', 2]]))),
18
18
  str(']'), false,
19
19
  ([, bs], rest) => [[
@@ -24,4 +24,4 @@ export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => validat
24
24
  'data-invalid-message': `Invalid start symbol or linebreak`,
25
25
  }, defrag(bs)),
26
26
  ], rest],
27
- ([as, bs], rest) => [unshift(as, bs), rest])));
27
+ ([as, bs], rest) => [unshift(as, bs), rest]))));
@@ -75,7 +75,7 @@ describe('Unit: parser/inline/html', () => {
75
75
  });
76
76
 
77
77
  it('nest', () => {
78
- assert.deepStrictEqual(inspect(parser('<bdi>[% </bdi>')), [['<bdi>[% </bdi>'], '']);
78
+ assert.deepStrictEqual(inspect(parser('<bdi>[% </bdi>')), [['<span class="invalid">&lt;bdi&gt;[% &lt;/bdi&gt;</span>'], '']);
79
79
  assert.deepStrictEqual(inspect(parser('<bdi><bdi>a</bdi></bdi>')), [['<bdi><bdi>a</bdi></bdi>'], '']);
80
80
  assert.deepStrictEqual(inspect(parser('<bdi>a<bdi>b</bdi>c</bdi>')), [['<bdi>a<bdi>b</bdi>c</bdi>'], '']);
81
81
  assert.deepStrictEqual(inspect(parser('<bdi>`a`</bdi>')), [['<bdi><code data-src="`a`">a</code></bdi>'], '']);
@@ -1,5 +1,5 @@
1
1
  import { HTMLParser } from '../inline';
2
- import { union, subsequence, some, syntax, validate, focus, surround, open, match, lazy } from '../../combinator';
2
+ import { union, subsequence, some, syntax, creation, validate, focus, surround, open, match, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
5
  import { Syntax, State } from '../context';
@@ -18,7 +18,7 @@ const attrspecs = {
18
18
  Object.setPrototypeOf(attrspecs, null);
19
19
  Object.values(attrspecs).forEach(o => Object.setPrototypeOf(o, null));
20
20
 
21
- export const html: HTMLParser = lazy(() => validate('<', validate(/^<[a-z]+(?=[^\S\n]|>)/i, syntax(Syntax.none, 5, 1, State.none, union([
21
+ export const html: HTMLParser = lazy(() => validate('<', validate(/^<[a-z]+(?=[^\S\n]|>)/i, creation(syntax(Syntax.none, 4, State.none, union([
22
22
  focus(
23
23
  /^<wbr[^\S\n]*>/i,
24
24
  () => [[h('wbr')], '']),
@@ -35,14 +35,13 @@ export const html: HTMLParser = lazy(() => validate('<', validate(/^<[a-z]+(?=[^
35
35
  str(`<${tag}`), some(attribute), str(/^[^\S\n]*>/), true),
36
36
  subsequence([
37
37
  focus(/^[^\S\n]*\n/, some(inline)),
38
- some(open(/^\n?/, some(inline, blankWith('\n', `</${tag}>`), [[blankWith('\n', `</${tag}>`), 5]]), true)),
38
+ some(open(/^\n?/, some(inline, blankWith('\n', `</${tag}>`), [[blankWith('\n', `</${tag}>`), 4]]), true)),
39
39
  ]),
40
40
  str(`</${tag}>`), true,
41
41
  ([as, bs = [], cs], rest) =>
42
42
  [[elem(tag, as, bs, cs)], rest],
43
43
  ([as, bs = []], rest) =>
44
- [[elem(tag, as, bs, [])], rest]),
45
- ([, tag]) => TAGS.indexOf(tag), [])),
44
+ [[elem(tag, as, bs, [])], rest]))),
46
45
  match(
47
46
  /^<([a-z]+)(?=[^\S\n]|>)/i,
48
47
  memoize(
@@ -51,7 +50,7 @@ export const html: HTMLParser = lazy(() => validate('<', validate(/^<[a-z]+(?=[^
51
50
  str(`<${tag}`), some(attribute), str(/^[^\S\n]*>/), true),
52
51
  subsequence([
53
52
  focus(/^[^\S\n]*\n/, some(inline)),
54
- some(inline, `</${tag}>`, [[`</${tag}>`, 5]]),
53
+ some(inline, `</${tag}>`, [[`</${tag}>`, 4]]),
55
54
  ]),
56
55
  str(`</${tag}>`), true,
57
56
  ([as, bs = [], cs], rest) =>
@@ -60,7 +59,7 @@ export const html: HTMLParser = lazy(() => validate('<', validate(/^<[a-z]+(?=[^
60
59
  [[elem(tag, as, bs, [])], rest]),
61
60
  ([, tag]) => tag,
62
61
  new Clock(10000))),
63
- ])))));
62
+ ]))))));
64
63
 
65
64
  export const attribute: HTMLParser.AttributeParser = union([
66
65
  str(/^[^\S\n]+[a-z]+(?:-[a-z]+)*(?:="[^"\n]*")?(?=[^\S\n]|>)/i),
@@ -1,5 +1,5 @@
1
1
  import { InsertionParser } from '../inline';
2
- import { union, some, syntax, surround, open, lazy } from '../../combinator';
2
+ import { union, some, syntax, creation, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
5
  import { Syntax, State } from '../context';
@@ -7,13 +7,13 @@ import { blankWith } from '../visibility';
7
7
  import { unshift } from 'spica/array';
8
8
  import { html, defrag } from 'typed-dom/dom';
9
9
 
10
- export const insertion: InsertionParser = lazy(() => surround(
10
+ export const insertion: InsertionParser = lazy(() => creation(surround(
11
11
  str('++', '+'),
12
- syntax(Syntax.none, 1, 1, State.none,
12
+ syntax(Syntax.none, 1, State.none,
13
13
  some(union([
14
14
  some(inline, blankWith('\n', '++')),
15
15
  open('\n', some(inline, '+'), true),
16
16
  ]))),
17
17
  str('++'), false,
18
18
  ([, bs], rest) => [[html('ins', defrag(bs))], rest],
19
- ([as, bs], rest) => [unshift(as, bs), rest]));
19
+ ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -20,9 +20,9 @@ export const link: LinkParser = lazy(() => validate(['[', '{'], union([
20
20
  textlink,
21
21
  ])));
22
22
 
23
- export const textlink: LinkParser.TextLinkParser = lazy(() =>
23
+ export const textlink: LinkParser.TextLinkParser = lazy(() => creation(10,
24
24
  constraint(State.link, false,
25
- syntax(Syntax.link, 2, 10, State.linkers | State.media,
25
+ syntax(Syntax.link, 2, State.linkers | State.media,
26
26
  bind(reverse(tails([
27
27
  dup(surround(
28
28
  '[',
@@ -36,11 +36,11 @@ export const textlink: LinkParser.TextLinkParser = lazy(() =>
36
36
  assert(content[0] !== '');
37
37
  if (content.length !== 0 && trimNodeEnd(content = defrag(content)).length === 0) return;
38
38
  return [[parse(content, params, context)], rest];
39
- }))));
39
+ })))));
40
40
 
41
- export const medialink: LinkParser.MediaLinkParser = lazy(() =>
41
+ export const medialink: LinkParser.MediaLinkParser = lazy(() => creation(10,
42
42
  constraint(State.link | State.media, false,
43
- syntax(Syntax.link, 2, 10, State.linkers,
43
+ syntax(Syntax.link, 2, State.linkers,
44
44
  bind(reverse(sequence([
45
45
  dup(surround(
46
46
  '[',
@@ -49,7 +49,7 @@ export const medialink: LinkParser.MediaLinkParser = lazy(() =>
49
49
  dup(surround(/^{(?![{}])/, inits([uri, some(option)]), /^[^\S\n]*}/)),
50
50
  ])),
51
51
  ([params, content = []]: [string[], (HTMLElement | string)[]], rest, context) =>
52
- [[parse(defrag(content), params, context)], rest]))));
52
+ [[parse(defrag(content), params, context)], rest])))));
53
53
 
54
54
  export const linemedialink: LinkParser.LineMediaLinkParser = surround(
55
55
  linebreak,
@@ -1,5 +1,5 @@
1
1
  import { MarkParser } from '../inline';
2
- import { union, some, syntax, constraint, surround, open, lazy } from '../../combinator';
2
+ import { union, some, syntax, creation, constraint, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { identity, signature } from './extension/indexee';
5
5
  import { str } from '../source';
@@ -8,10 +8,10 @@ import { Syntax, State } from '../context';
8
8
  import { unshift } from 'spica/array';
9
9
  import { html, define, defrag } from 'typed-dom/dom';
10
10
 
11
- export const mark: MarkParser = lazy(() => surround(
11
+ export const mark: MarkParser = lazy(() => creation(surround(
12
12
  str('==', '='),
13
13
  constraint(State.mark, false,
14
- syntax(Syntax.none, 1, 1, State.none,
14
+ syntax(Syntax.none, 1, State.none,
15
15
  startTight(some(union([
16
16
  some(inline, blankWith('=='), [[/^\\?\n/, 9]]),
17
17
  open(some(inline, '=', [[/^\\?\n/, 9]]), mark),
@@ -24,4 +24,4 @@ export const mark: MarkParser = lazy(() => surround(
24
24
  el.id && html('a', { href: `#${el.id}` }),
25
25
  ], rest];
26
26
  },
27
- ([as, bs], rest) => [unshift(as, bs), rest]));
27
+ ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -18,10 +18,10 @@ const optspec = {
18
18
  } as const;
19
19
  Object.setPrototypeOf(optspec, null);
20
20
 
21
- export const media: MediaParser = lazy(() => validate(['![', '!{'], open(
21
+ export const media: MediaParser = lazy(() => validate(['![', '!{'], creation(10, open(
22
22
  '!',
23
23
  constraint(State.media, false,
24
- syntax(Syntax.media, 2, 10, ~State.link,
24
+ syntax(Syntax.media, 2, ~State.link,
25
25
  bind(verify(fmap(tails([
26
26
  dup(surround(
27
27
  '[',
@@ -60,7 +60,7 @@ export const media: MediaParser = lazy(() => validate(['![', '!{'], open(
60
60
  unsafelink as MediaParser,
61
61
  ([link]) => [define(link, { class: null, target: '_blank' }, [el])])
62
62
  ({ source: `{ ${INSECURE_URI}${params.join('')} }${rest}`, context });
63
- }))))));
63
+ })))))));
64
64
 
65
65
  export const linemedia: MediaParser.LineMediaParser = surround(
66
66
  linebreak,
@@ -71,7 +71,7 @@ const bracket: MediaParser.TextParser.BracketParser = lazy(() => creation(union(
71
71
  surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
72
72
  surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
73
73
  surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
74
- surround(str('"'), precedence(8, some(union([unsafehtmlentity, txt]), '"')), str('"'), true),
74
+ surround(str('"'), precedence(3, some(union([unsafehtmlentity, txt]), '"')), str('"'), true),
75
75
  ])));
76
76
 
77
77
  const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
@@ -6,17 +6,17 @@ import { Syntax, State } from '../context';
6
6
  import { blank, trimBlankStart, trimNodeEnd } from '../visibility';
7
7
  import { html, defrag } from 'typed-dom/dom';
8
8
 
9
- export const reference: ReferenceParser = lazy(() => surround(
9
+ export const reference: ReferenceParser = lazy(() => creation(surround(
10
10
  '[[',
11
11
  constraint(State.reference, false,
12
- syntax(Syntax.reference, 6, 1, State.annotation | State.reference | State.media,
12
+ syntax(Syntax.reference, 6, State.annotation | State.reference | State.media,
13
13
  subsequence([
14
14
  abbr,
15
15
  trimBlankStart(some(inline, ']', [[/^\\?\n/, 9], [']', 2], [']]', 6]])),
16
16
  ]))),
17
17
  ']]',
18
18
  false,
19
- ([, ns], rest) => [[html('sup', attributes(ns), [html('span', trimNodeEnd(defrag(ns)))])], rest]));
19
+ ([, ns], rest) => [[html('sup', attributes(ns), [html('span', trimNodeEnd(defrag(ns)))])], rest])));
20
20
 
21
21
  // Chicago-Style
22
22
  const abbr: ReferenceParser.AbbrParser = creation(surround(
@@ -16,12 +16,12 @@ describe('Unit: parser/inline/remark', () => {
16
16
  assert.deepStrictEqual(inspect(parser('[% ')), [['[%'], '']);
17
17
  assert.deepStrictEqual(inspect(parser('[% \n a')), [['[%', '<br>', ' ', 'a'], '']);
18
18
  assert.deepStrictEqual(inspect(parser('[%%]')), undefined);
19
- assert.deepStrictEqual(inspect(parser('[% [%')), [['[%', ' ', '', '[', '%'], '']);
19
+ assert.deepStrictEqual(inspect(parser('[% [%')), [['[%', ' ', '[', '%'], '']);
20
20
  assert.deepStrictEqual(inspect(parser('[% [% ')), [['[%', ' ', '[%'], '']);
21
21
  assert.deepStrictEqual(inspect(parser('[% [% a')), [['[%', ' ', '[%', ' ', 'a'], '']);
22
22
  assert.deepStrictEqual(inspect(parser('[% [% a %]')), [['[%', ' ', '<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], '']);
23
- assert.deepStrictEqual(inspect(parser('[% a[%')), [['[%', ' ', 'a', '', '[', '%'], '']);
24
- assert.deepStrictEqual(inspect(parser('[% a [%')), [['[%', ' ', 'a', ' ', '', '[', '%'], '']);
23
+ assert.deepStrictEqual(inspect(parser('[% a[%')), [['[%', ' ', 'a', '[', '%'], '']);
24
+ assert.deepStrictEqual(inspect(parser('[% a [%')), [['[%', ' ', 'a', ' ', '[', '%'], '']);
25
25
  assert.deepStrictEqual(inspect(parser('[% a [% ')), [['[%', ' ', 'a', ' ', '[%'], '']);
26
26
  assert.deepStrictEqual(inspect(parser('[% a [% b')), [['[%', ' ', 'a', ' ', '[%', ' ', 'b'], '']);
27
27
  assert.deepStrictEqual(inspect(parser('[% a [%% b')), [['[%', ' ', 'a', ' ', '[%%', ' ', 'b'], '']);
@@ -58,6 +58,7 @@ describe('Unit: parser/inline/remark', () => {
58
58
  assert.deepStrictEqual(inspect(parser('[% [ %]')), [['<span class="remark"><input type="checkbox"><span>[% [ %]</span></span>'], '']);
59
59
  assert.deepStrictEqual(inspect(parser('[% \\ a %]')), [['<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], '']);
60
60
  assert.deepStrictEqual(inspect(parser('[% $-a %]$')), [['<span class="remark"><input type="checkbox"><span>[% <a class="label" data-label="$-a">$-a</a> %]</span></span>'], '$']);
61
+ assert.deepStrictEqual(inspect(parser('[% <bdi> %]')), [['<span class="remark"><input type="checkbox"><span>[% <span class="invalid">&lt;bdi&gt;</span> %]</span></span>'], '']);
61
62
  });
62
63
 
63
64
  });
@@ -1,5 +1,5 @@
1
1
  import { RemarkParser } from '../inline';
2
- import { union, some, syntax, validate, surround, open, close, match, lazy } from '../../combinator';
2
+ import { union, some, syntax, creation, validate, surround, open, close, match, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { text, str } from '../source';
5
5
  import { Syntax, State } from '../context';
@@ -7,13 +7,13 @@ import { memoize } from 'spica/memoize';
7
7
  import { unshift, push } from 'spica/array';
8
8
  import { html, defrag } from 'typed-dom/dom';
9
9
 
10
- export const remark: RemarkParser = lazy(() => validate('[%', syntax(Syntax.none, 4, 1, State.none, match(
10
+ export const remark: RemarkParser = lazy(() => validate('[%', creation(syntax(Syntax.none, 5, State.none, match(
11
11
  /^\[(%+)\s/,
12
12
  memoize(
13
13
  ([, fence]) =>
14
14
  surround(
15
15
  open(str(`[${fence}`), some(text, new RegExp(String.raw`^\s+${fence}\]|^\S`)), true),
16
- some(union([inline]), new RegExp(String.raw`^\s+${fence}\]`), [[new RegExp(String.raw`^\s+${fence}\]`), 4]]),
16
+ some(union([inline]), new RegExp(String.raw`^\s+${fence}\]`), [[new RegExp(String.raw`^\s+${fence}\]`), 5]]),
17
17
  close(some(text, /^\S/), str(`${fence}]`)), true,
18
18
  ([as, bs = [], cs], rest) => [[
19
19
  html('span', { class: 'remark' }, [
@@ -22,4 +22,4 @@ export const remark: RemarkParser = lazy(() => validate('[%', syntax(Syntax.none
22
22
  ]),
23
23
  ], rest],
24
24
  ([as, bs = []], rest) => [unshift(as, bs), rest]),
25
- ([, fence]) => fence.length, [])))));
25
+ ([, fence]) => fence.length, {}))))));
@@ -8,7 +8,7 @@ import { isStartTightNodes } from '../visibility';
8
8
  import { unshift, push } from 'spica/array';
9
9
  import { html, defrag } from 'typed-dom/dom';
10
10
 
11
- export const ruby: RubyParser = lazy(() => validate('[', syntax(Syntax.ruby, 2, 1, State.all, fmap(verify(fmap(
11
+ export const ruby: RubyParser = lazy(() => validate('[', creation(syntax(Syntax.ruby, 2, State.all, fmap(verify(fmap(
12
12
  sequence([
13
13
  surround('[', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']'),
14
14
  surround('(', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ')'),
@@ -49,7 +49,7 @@ export const ruby: RubyParser = lazy(() => validate('[', syntax(Syntax.ruby, 2,
49
49
  [html('rp', '('), html('rt', rubies.join(' ').trim()), html('rp', ')')]))),
50
50
  ];
51
51
  }
52
- }))));
52
+ })))));
53
53
 
54
54
  const text: RubyParser.TextParser = creation(1, false, ({ source, context }) => {
55
55
  const acc = [''];
@@ -1,5 +1,5 @@
1
1
  import { StrongParser } from '../inline';
2
- import { union, some, syntax, surround, open, lazy } from '../../combinator';
2
+ import { union, some, syntax, creation, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { emstrong } from './emstrong';
5
5
  import { str } from '../source';
@@ -8,9 +8,9 @@ import { startTight, blankWith } from '../visibility';
8
8
  import { unshift } from 'spica/array';
9
9
  import { html, defrag } from 'typed-dom/dom';
10
10
 
11
- export const strong: StrongParser = lazy(() => surround(
11
+ export const strong: StrongParser = lazy(() => creation(surround(
12
12
  str('**', '*'),
13
- syntax(Syntax.none, 1, 1, State.none,
13
+ syntax(Syntax.none, 1, State.none,
14
14
  startTight(some(union([
15
15
  some(inline, blankWith('**'), [[/^\\?\n/, 9]]),
16
16
  open(some(inline, '*', [[/^\\?\n/, 9]]), union([
@@ -20,4 +20,4 @@ export const strong: StrongParser = lazy(() => surround(
20
20
  ])))),
21
21
  str('**'), false,
22
22
  ([, bs], rest) => [[html('strong', defrag(bs))], rest],
23
- ([as, bs], rest) => [unshift(as, bs), rest]));
23
+ ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -5,13 +5,16 @@ import { Syntax, State } from '../context';
5
5
  import { unshift } from 'spica/array';
6
6
  import { html } from 'typed-dom/dom';
7
7
 
8
- export const template: TemplateParser = lazy(() => surround(
9
- '{{', syntax(Syntax.none, 2, 1, State.all, some(union([bracket, escsource]), '}')), '}}', true,
10
- ([, ns = []], rest) => [[html('span', { class: 'template' }, `{{${ns.join('').replace(/\x1B/g, '')}}}`)], rest]));
8
+ export const template: TemplateParser = lazy(() => creation(surround(
9
+ '{{',
10
+ syntax(Syntax.none, 6, State.all, some(union([bracket, escsource]), '}', [['}}', 6]])),
11
+ '}}',
12
+ true,
13
+ ([, ns = []], rest) => [[html('span', { class: 'template' }, `{{${ns.join('').replace(/\x1B/g, '')}}}`)], rest])));
11
14
 
12
15
  const bracket: TemplateParser.BracketParser = lazy(() => creation(union([
13
16
  surround(str('('), some(union([bracket, escsource]), ')'), str(')'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
14
17
  surround(str('['), some(union([bracket, escsource]), ']'), str(']'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
15
18
  surround(str('{'), some(union([bracket, escsource]), '}'), str('}'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
16
- surround(str('"'), precedence(8, some(escsource, /^"|^\\?\n/)), str('"'), true),
19
+ surround(str('"'), precedence(3, some(escsource, /^"|^\\?\n/)), str('"'), true),
17
20
  ])));
@@ -18,6 +18,8 @@ describe('Unit: parser/inline', () => {
18
18
  });
19
19
 
20
20
  it('nest', () => {
21
+ assert.deepStrictEqual(inspect(parser('あ(A)')), [['あ', '(', 'A', ')'], '']);
22
+ assert.deepStrictEqual(inspect(parser('あ(い)')), [['あ', '<span class="paren">(い)</span>'], '']);
21
23
  assert.deepStrictEqual(inspect(parser('+++a+++')), [['+++', 'a', '+++'], '']);
22
24
  assert.deepStrictEqual(inspect(parser('~~~a~~~')), [['~~~', 'a', '~~~'], '']);
23
25
  assert.deepStrictEqual(inspect(parser('===a===')), [['===', 'a', '==='], '']);
@@ -143,36 +145,31 @@ describe('Unit: parser/inline', () => {
143
145
  assert.deepStrictEqual(inspect(parser('${{{a}}}')), [['$', '<span class="template">{{{a}}}</span>'], '']);
144
146
  assert.deepStrictEqual(inspect(parser('Di$ney Micro$oft')), [['Di', '$', 'ney', ' ', 'Micro', '$', 'oft'], '']);
145
147
  assert.deepStrictEqual(inspect(parser('Di$ney, Micro$oft')), [['Di', '$', 'ney', ',', ' ', 'Micro', '$', 'oft'], '']);
146
- assert.deepStrictEqual(inspect(parser('(((a))')), [['', '(', '<sup class="annotation"><span>a</span></sup>'], '']);
147
- assert.deepStrictEqual(inspect(parser('((((a))')), [['', '(', '', '(', '<sup class="annotation"><span>a</span></sup>'], '']);
148
+ assert.deepStrictEqual(inspect(parser('(((a))')), [['(', '<sup class="annotation"><span>a</span></sup>'], '']);
149
+ assert.deepStrictEqual(inspect(parser('((((a))')), [['(', '(', '<sup class="annotation"><span>a</span></sup>'], '']);
148
150
  assert.deepStrictEqual(inspect(parser('((((a))))')), [['<sup class="annotation"><span><span class="paren">((a))</span></span></sup>'], '']);
149
151
  assert.deepStrictEqual(inspect(parser('((<bdi>))')), [['<sup class="annotation"><span><span class="invalid">&lt;bdi&gt;</span></span></sup>'], '']);
150
- assert.deepStrictEqual(inspect(parser('((${))}$')), [['', '(', '', '(', '<span class="math" translate="no" data-src="${))}$">${))}$</span>'], '']);
152
+ assert.deepStrictEqual(inspect(parser('((${))}$')), [['(', '(', '<span class="math" translate="no" data-src="${))}$">${))}$</span>'], '']);
151
153
  assert.deepStrictEqual(inspect(parser('"((""))')), [['"', '<sup class="annotation"><span>""</span></sup>'], '']);
152
- assert.deepStrictEqual(inspect(parser('[[[a]]')), [['', '[', '<sup class="reference"><span>a</span></sup>'], '']);
153
- assert.deepStrictEqual(inspect(parser('[[[[a]]')), [['', '[', '', '[', '<sup class="reference"><span>a</span></sup>'], '']);
154
+ assert.deepStrictEqual(inspect(parser('[[[a]]')), [['[', '<sup class="reference"><span>a</span></sup>'], '']);
155
+ assert.deepStrictEqual(inspect(parser('[[[[a]]')), [['[', '[', '<sup class="reference"><span>a</span></sup>'], '']);
154
156
  assert.deepStrictEqual(inspect(parser('[[[[a]]]]')), [['<sup class="reference"><span>[[a]]</span></sup>'], '']);
155
157
  assert.deepStrictEqual(inspect(parser('[[[$-1]]]')), [['<sup class="reference"><span><a class="label" data-label="$-1">$-1</a></span></sup>'], '']);
156
158
  assert.deepStrictEqual(inspect(parser('[[[]{a}]]')), [['<sup class="reference"><span><a class="url" href="a">a</a></span></sup>'], '']);
157
159
  assert.deepStrictEqual(inspect(parser('[[[a]{b}]]')), [['<sup class="reference"><span><a class="link" href="b">a</a></span></sup>'], '']);
158
160
  assert.deepStrictEqual(inspect(parser('[(([a]{#}))]{#}')), [['<a class="link" href="#"><span class="paren">(<span class="paren">([a]{#})</span>)</span></a>'], '']);
159
161
  assert.deepStrictEqual(inspect(parser('[[<bdi>]]')), [['<sup class="reference"><span><span class="invalid">&lt;bdi&gt;</span></span></sup>'], '']);
160
- assert.deepStrictEqual(inspect(parser('[[${]]}$')), [['', '[', '', '[', '<span class="math" translate="no" data-src="${]]}$">${]]}$</span>'], '']);
162
+ assert.deepStrictEqual(inspect(parser('[[${]]}$')), [['[', '[', '<span class="math" translate="no" data-src="${]]}$">${]]}$</span>'], '']);
161
163
  assert.deepStrictEqual(inspect(parser('"[[""]]')), [['"', '<sup class="reference"><span>""</span></sup>'], '']);
162
164
  assert.deepStrictEqual(inspect(parser('[==a==]{b}')), [['<a class="link" href="b">==a==</a>'], '']);
163
165
  assert.deepStrictEqual(inspect(parser('[[a](b)]{c}')), [['<a class="link" href="c"><ruby>a<rp>(</rp><rt>b</rt><rp>)</rp></ruby></a>'], '']);
164
- assert.deepStrictEqual(inspect(parser('[[[[[[[{a}')), [['', '[', '', '[', '', '[', '', '[', '', '[', '', '[', '', '[', '<a class="url" href="a">a</a>'], '']);
166
+ assert.deepStrictEqual(inspect(parser('[[[[[[[{a}')), [['[', '[', '[', '[', '[', '[', '[', '<a class="url" href="a">a</a>'], '']);
165
167
  assert.deepStrictEqual(inspect(parser('<http://host>')), [['<', '<a class="url" href="http://host" target="_blank">http://host</a>', '>'], '']);
166
- assert.deepStrictEqual(inspect(parser('[~http://host')), [['', '[', '~', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
167
- assert.deepStrictEqual(inspect(parser('[~a@b')), [['', '[', '~', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
168
+ assert.deepStrictEqual(inspect(parser('[~http://host')), [['[', '~', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
169
+ assert.deepStrictEqual(inspect(parser('[~a@b')), [['[', '~', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
168
170
  assert.deepStrictEqual(inspect(parser('[~~a~~]')), [['[', '<del>a</del>', ']'], '']);
169
171
  assert.deepStrictEqual(inspect(parser('[^http://host')), [['[^', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
170
172
  assert.deepStrictEqual(inspect(parser('[^a@b')), [['[^', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
171
- assert.deepStrictEqual(inspect(parser('[#a++b\nc++]')), [['[', '<a class="hashtag" href="/hashtags/a">#a</a>', '<ins>b<br>c</ins>', ']'], '']);
172
- assert.deepStrictEqual(inspect(parser('[++a\nb++]{/}')), [['[', '<ins>a<br>b</ins>', ']', '<a class="url" href="/">/</a>'], '']);
173
- assert.deepStrictEqual(inspect(parser('[++a\nb]++')), [['[', '++', 'a', '<br>', 'b', ']', '++'], '']);
174
- assert.deepStrictEqual(inspect(parser('[++[a\nb++]')), [['', '[', '++', '[', 'a', '<br>', 'b', '++', ']'], '']);
175
- assert.deepStrictEqual(inspect(parser('[[++a\nb++]]')), [['[', '[', '<ins>a<br>b</ins>', ']', ']'], '']);
176
173
  assert.deepStrictEqual(inspect(parser('"[% *"*"*')), [['"', '[%', ' ', '*', '"', '*', '"', '*'], '']);
177
174
  assert.deepStrictEqual(inspect(parser('"[% "*"* %]')), [['"', '<span class="remark"><input type="checkbox"><span>[% "*"* %]</span></span>'], '']);
178
175
  });
@@ -242,7 +239,7 @@ describe('Unit: parser/inline', () => {
242
239
  assert.deepStrictEqual(inspect(parser('*a*#b')), [['<em>a</em>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
243
240
  assert.deepStrictEqual(inspect(parser('((a))#b')), [['<sup class="annotation"><span>a</span></sup>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
244
241
  assert.deepStrictEqual(inspect(parser('[[a]]#b')), [['<sup class="reference"><span>a</span></sup>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
245
- assert.deepStrictEqual(inspect(parser('[#a')), [['', '[', '<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
242
+ assert.deepStrictEqual(inspect(parser('[#a')), [['[', '<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
246
243
  assert.deepStrictEqual(inspect(parser('|#a')), [['|', '<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
247
244
  assert.deepStrictEqual(inspect(parser(' #a')), [[' ', '<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
248
245
  });
@@ -127,7 +127,6 @@ export function* figure(
127
127
  }
128
128
  yield ref;
129
129
  }
130
- return;
131
130
  }
132
131
 
133
132
  const messages = {
@@ -14,7 +14,6 @@ export function* note(
14
14
  ): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
15
15
  yield* annotation(target, notes?.annotations, opts, bottom);
16
16
  yield* reference(target, notes?.references, opts, bottom);
17
- return;
18
17
  }
19
18
 
20
19
  export const annotation = build('annotation', n => `*${n}`, 'h1, h2, h3, h4, h5, h6, aside.aside, hr');
@@ -180,7 +179,6 @@ function build(
180
179
  el.remove();
181
180
  }
182
181
  }
183
- return;
184
182
  }
185
183
 
186
184
  function* proc(defs: Map<string, HTMLLIElement>, note: HTMLOListElement): Generator<HTMLLIElement | undefined, undefined, undefined> {
@@ -213,7 +211,6 @@ function build(
213
211
  --length;
214
212
  assert(children.length === length);
215
213
  }
216
- return;
217
214
  }
218
215
  }
219
216
 
@@ -22,22 +22,3 @@ export function str(pattern: string | RegExp, not?: string): Parser<string, Cont
22
22
  : undefined;
23
23
  });
24
24
  }
25
-
26
- export function stropt(pattern: string | RegExp): StrParser;
27
- export function stropt(pattern: string | RegExp): Parser<string, Context<StrParser>, []> {
28
- assert(pattern);
29
- return typeof pattern === 'string'
30
- ? creation(1, false, ({ source }) => {
31
- if (source === '') return;
32
- return source.slice(0, pattern.length) === pattern
33
- ? [[pattern], source.slice(pattern.length)]
34
- : [[''], source];
35
- })
36
- : creation(1, false, ({ source }) => {
37
- if (source === '') return;
38
- const m = source.match(pattern);
39
- return m
40
- ? [[m[0]], source.slice(m[0].length)]
41
- : undefined;
42
- });
43
- }
@@ -2,7 +2,7 @@ import { text } from './text';
2
2
  import { some } from '../../combinator';
3
3
  import { inspect } from '../../debug.test';
4
4
 
5
- describe('Unit: parser/text/text', () => {
5
+ describe('Unit: parser/source/text', () => {
6
6
  describe('text', () => {
7
7
  const parser = (source: string) => some(text)({ source, context: {} });
8
8
 
@@ -3,9 +3,9 @@ import { union, creation, focus } from '../../combinator';
3
3
  import { str } from './str';
4
4
  import { html } from 'typed-dom/dom';
5
5
 
6
- export const delimiter = /[\s\x00-\x7F]|\S[#>]/u;
7
- export const nonWhitespace = /[\S\n]|$/;
8
- export const nonAlphanumeric = /[^0-9A-Za-z]|\S[#>]|$/;
6
+ export const delimiter = /[\s\x00-\x7F()]|\S[#>]/u;
7
+ export const nonWhitespace = /[\S\n]|$/u;
8
+ export const nonAlphanumeric = /[^0-9A-Za-z]|\S[#>]|$/u;
9
9
  const repeat = str(/^(.)\1*/);
10
10
 
11
11
  export const text: TextParser = creation(1, false, ({ source, context }) => {
@@ -14,5 +14,5 @@ export import AnyLineParser = SourceParser.AnyLineParser;
14
14
  export { text, txt, linebreak } from './source/text';
15
15
  export { escsource } from './source/escapable';
16
16
  export { unescsource } from './source/unescapable';
17
- export { str, stropt } from './source/str';
17
+ export { str } from './source/str';
18
18
  export { contentline, emptyline, anyline } from './source/line';
@@ -170,7 +170,6 @@ function trimBlankEnd<T extends HTMLElement | string>(parser: Parser<T>): Parser
170
170
  //}
171
171
  //function trimNodeStart<T extends HTMLElement | string>(nodes: T[]): T[] {
172
172
  // for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes[0], 0);) {
173
- // if (nodes.length === 1 && typeof node === 'object' && node.className === 'indexer') break;
174
173
  // if (typeof node === 'string') {
175
174
  // const pos = node.trimStart().length;
176
175
  // if (pos > 0) {
@@ -178,6 +177,9 @@ function trimBlankEnd<T extends HTMLElement | string>(parser: Parser<T>): Parser
178
177
  // break;
179
178
  // }
180
179
  // }
180
+ // else if (nodes.length === 1 && node.className === 'indexer') {
181
+ // break;
182
+ // }
181
183
  // nodes.shift();
182
184
  // }
183
185
  // return nodes;