securemark 0.257.3 → 0.258.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 (76) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/index.js +1216 -606
  3. package/markdown.d.ts +1 -12
  4. package/package.json +9 -9
  5. package/src/combinator/control/manipulation/convert.ts +8 -4
  6. package/src/combinator/control/manipulation/scope.ts +10 -2
  7. package/src/combinator/data/parser/context/delimiter.ts +70 -0
  8. package/src/combinator/data/parser/context/memo.ts +30 -0
  9. package/src/combinator/{control/manipulation → data/parser}/context.test.ts +9 -9
  10. package/src/combinator/data/parser/context.ts +161 -0
  11. package/src/combinator/data/parser/sequence.test.ts +1 -1
  12. package/src/combinator/data/parser/sequence.ts +1 -1
  13. package/src/combinator/data/parser/some.test.ts +1 -1
  14. package/src/combinator/data/parser/some.ts +14 -37
  15. package/src/combinator/data/parser/subsequence.test.ts +1 -1
  16. package/src/combinator/data/parser/union.test.ts +1 -1
  17. package/src/combinator/data/parser.ts +7 -47
  18. package/src/combinator.ts +1 -2
  19. package/src/parser/api/bind.ts +5 -5
  20. package/src/parser/api/parse.ts +3 -1
  21. package/src/parser/block/blockquote.ts +1 -1
  22. package/src/parser/block/dlist.ts +4 -10
  23. package/src/parser/block/extension/figure.ts +4 -3
  24. package/src/parser/block/extension/table.ts +2 -2
  25. package/src/parser/block/heading.ts +5 -13
  26. package/src/parser/block/ilist.ts +3 -2
  27. package/src/parser/block/olist.ts +10 -7
  28. package/src/parser/block/paragraph.ts +1 -1
  29. package/src/parser/block/reply/cite.ts +1 -1
  30. package/src/parser/block/reply/quote.ts +1 -1
  31. package/src/parser/block/reply.ts +1 -1
  32. package/src/parser/block/sidefence.ts +1 -1
  33. package/src/parser/block/table.ts +9 -9
  34. package/src/parser/block/ulist.ts +4 -3
  35. package/src/parser/block.ts +1 -1
  36. package/src/parser/context.ts +32 -0
  37. package/src/parser/header.ts +1 -1
  38. package/src/parser/inline/annotation.ts +9 -17
  39. package/src/parser/inline/autolink/email.ts +1 -1
  40. package/src/parser/inline/autolink/url.ts +1 -1
  41. package/src/parser/inline/autolink.ts +5 -3
  42. package/src/parser/inline/bracket.ts +16 -15
  43. package/src/parser/inline/code.ts +1 -1
  44. package/src/parser/inline/comment.ts +4 -3
  45. package/src/parser/inline/deletion.ts +5 -4
  46. package/src/parser/inline/emphasis.ts +5 -4
  47. package/src/parser/inline/emstrong.ts +5 -4
  48. package/src/parser/inline/extension/index.ts +7 -14
  49. package/src/parser/inline/extension/indexee.ts +8 -10
  50. package/src/parser/inline/extension/indexer.ts +4 -3
  51. package/src/parser/inline/extension/label.ts +3 -2
  52. package/src/parser/inline/extension/placeholder.ts +5 -4
  53. package/src/parser/inline/html.ts +5 -4
  54. package/src/parser/inline/htmlentity.ts +1 -1
  55. package/src/parser/inline/insertion.ts +5 -4
  56. package/src/parser/inline/link.ts +11 -20
  57. package/src/parser/inline/mark.ts +5 -4
  58. package/src/parser/inline/math.ts +1 -1
  59. package/src/parser/inline/media.ts +8 -7
  60. package/src/parser/inline/reference.ts +10 -16
  61. package/src/parser/inline/ruby.ts +4 -3
  62. package/src/parser/inline/shortmedia.ts +3 -2
  63. package/src/parser/inline/strong.ts +5 -4
  64. package/src/parser/inline/template.test.ts +1 -1
  65. package/src/parser/inline/template.ts +9 -6
  66. package/src/parser/locale.ts +6 -7
  67. package/src/parser/processor/footnote.ts +5 -3
  68. package/src/parser/source/text.ts +1 -1
  69. package/src/parser/util.ts +0 -220
  70. package/src/parser/visibility.ts +205 -0
  71. package/src/util/info.ts +4 -2
  72. package/src/util/quote.ts +12 -15
  73. package/src/util/toc.ts +14 -17
  74. package/webpack.config.js +1 -0
  75. package/src/combinator/control/manipulation/context.ts +0 -70
  76. package/src/combinator/control/manipulation/resource.ts +0 -54
@@ -2,9 +2,10 @@ import { undefined, location } from 'spica/global';
2
2
  import { ParserSettings, Progress } from '../../..';
3
3
  import { MarkdownParser } from '../../../markdown';
4
4
  import { eval } from '../../combinator/data/parser';
5
+ import { segment, validate, MAX_INPUT_SIZE } from '../segment';
5
6
  import { header } from '../header';
6
7
  import { block } from '../block';
7
- import { segment, validate, MAX_INPUT_SIZE } from '../segment';
8
+ import { backtrackable } from '../context';
8
9
  import { normalize } from './normalize';
9
10
  import { headers } from './header';
10
11
  import { figure } from '../processor/figure';
@@ -23,6 +24,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
23
24
  let context: MarkdownParser.Context = {
24
25
  ...settings,
25
26
  host: settings.host ?? new ReadonlyURL(location.pathname, location.origin),
27
+ backtrackable,
26
28
  };
27
29
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
28
30
  assert(!settings.id);
@@ -141,8 +143,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
141
143
 
142
144
  function nearest(index: number): HTMLElement | undefined {
143
145
  let el: HTMLElement | undefined;
144
- let len = 0;
145
- for (let i = 0; i < blocks.length; ++i) {
146
+ for (let i = 0, len = 0; i < blocks.length; ++i) {
146
147
  const block = blocks[i];
147
148
  len += block[0].length;
148
149
  el = block[1][0] ?? el;
@@ -152,8 +153,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
152
153
  }
153
154
 
154
155
  function index(source: HTMLElement): number {
155
- let len = 0;
156
- for (let i = 0; i < blocks.length; ++i) {
156
+ for (let i = 0, len = 0; i < blocks.length; ++i) {
157
157
  const block = blocks[i];
158
158
  if (block[1].includes(source)) return len;
159
159
  len += block[0].length;
@@ -2,9 +2,10 @@ import { location } from 'spica/global';
2
2
  import { ParserOptions } from '../../..';
3
3
  import { MarkdownParser } from '../../../markdown';
4
4
  import { eval } from '../../combinator/data/parser';
5
+ import { segment, validate, MAX_SEGMENT_SIZE } from '../segment';
5
6
  import { header } from '../header';
6
7
  import { block } from '../block';
7
- import { segment, validate, MAX_SEGMENT_SIZE } from '../segment';
8
+ import { backtrackable } from '../context';
8
9
  import { normalize } from './normalize';
9
10
  import { headers } from './header';
10
11
  import { figure } from '../processor/figure';
@@ -29,6 +30,7 @@ export function parse(source: string, opts: Options = {}, context?: MarkdownPars
29
30
  ...context?.resources && {
30
31
  resources: context.resources,
31
32
  },
33
+ backtrackable,
32
34
  };
33
35
  if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
34
36
  const node = frag();
@@ -1,5 +1,5 @@
1
1
  import { BlockquoteParser } from '../block';
2
- import { union, some, block, validate, rewrite, creator, open, convert, lazy, fmap } from '../../combinator';
2
+ import { union, some, creator, block, validate, rewrite, open, convert, lazy, fmap } from '../../combinator';
3
3
  import { autolink } from '../autolink';
4
4
  import { contentline } from '../source';
5
5
  import { parse } from '../api/parse';
@@ -1,23 +1,17 @@
1
1
  import { DListParser } from '../block';
2
- import { union, inits, some, block, line, validate, rewrite, context, creator, open, trimEnd, lazy, fmap } from '../../combinator';
2
+ import { union, inits, some, creator, state, block, line, validate, rewrite, open, trimEnd, lazy, fmap } from '../../combinator';
3
3
  import { inline, indexee, indexer } from '../inline';
4
4
  import { anyline } from '../source';
5
+ import { State } from '../context';
5
6
  import { localize } from '../locale';
6
- import { visualize, trimBlank } from '../util';
7
+ import { visualize, trimBlank } from '../visibility';
7
8
  import { html, defrag } from 'typed-dom/dom';
8
9
  import { push } from 'spica/array';
9
10
 
10
11
  export const dlist: DListParser = lazy(() => block(localize(fmap(validate(
11
12
  /^~[^\S\n]+(?=\S)/,
12
13
  some(inits([
13
- context({ syntax: { inline: {
14
- annotation: false,
15
- reference: false,
16
- index: false,
17
- label: false,
18
- link: false,
19
- media: false,
20
- }}},
14
+ state(State.annotation | State.reference | State.index | State.label | State.link | State.media,
21
15
  some(term)),
22
16
  some(desc),
23
17
  ]))),
@@ -1,6 +1,6 @@
1
1
  import { undefined } from 'spica/global';
2
2
  import { ExtensionParser } from '../../block';
3
- import { union, inits, sequence, some, block, line, fence, rewrite, context, close, match, convert, trimEnd, fallback, fmap } from '../../../combinator';
3
+ import { union, inits, sequence, some, state, block, line, fence, rewrite, close, match, convert, trimEnd, fallback, fmap } from '../../../combinator';
4
4
  import { str, contentline, emptyline } from '../../source';
5
5
  import { label, segment as seg_label } from '../../inline/extension/label';
6
6
  import { ulist } from '../ulist';
@@ -13,8 +13,9 @@ 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
15
  import { inline, media, shortmedia } from '../../inline';
16
+ import { State } from '../../context';
16
17
  import { localize } from '../../locale';
17
- import { visualize, trimBlank } from '../../util';
18
+ import { visualize, trimBlank } from '../../visibility';
18
19
  import { html, defrag } from 'typed-dom/dom';
19
20
  import { memoize } from 'spica/memoize';
20
21
 
@@ -66,7 +67,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
66
67
  ])),
67
68
  emptyline,
68
69
  block(localize(
69
- context({ syntax: { inline: { media: false } } },
70
+ state(State.media,
70
71
  visualize(trimBlank(trimEnd(some(inline))))))),
71
72
  ]),
72
73
  ])),
@@ -2,11 +2,11 @@ import { undefined, BigInt, Array } from 'spica/global';
2
2
  import { max, min, isArray } from 'spica/alias';
3
3
  import { ExtensionParser } from '../../block';
4
4
  import { Tree, eval } from '../../../combinator/data/parser';
5
- import { union, subsequence, inits, some, block, line, validate, fence, rewrite, creator, open, clear, convert, trim, dup, lazy, fmap } from '../../../combinator';
5
+ import { union, subsequence, inits, some, creator, block, line, validate, fence, rewrite, open, clear, convert, trim, dup, lazy, fmap } from '../../../combinator';
6
6
  import { inline } from '../../inline';
7
7
  import { str, anyline, emptyline, contentline } from '../../source';
8
8
  import { localize } from '../../locale';
9
- import { visualize } from '../../util';
9
+ import { visualize } from '../../visibility';
10
10
  import { html, define, defrag } from 'typed-dom/dom';
11
11
  import { unshift, splice } from 'spica/array';
12
12
 
@@ -1,8 +1,9 @@
1
1
  import { HeadingParser } from '../block';
2
- import { union, some, block, line, validate, focus, rewrite, context, open, fmap } from '../../combinator';
2
+ import { union, some, state, block, line, validate, focus, rewrite, open, fmap } from '../../combinator';
3
3
  import { inline, indexee, indexer } from '../inline';
4
4
  import { str } from '../source';
5
- import { visualize, trimBlank } from '../util';
5
+ import { State } from '../context';
6
+ import { visualize, trimBlank } from '../visibility';
6
7
  import { html, defrag } from 'typed-dom/dom';
7
8
 
8
9
  export const segment: HeadingParser.SegmentParser = block(validate('#', focus(
@@ -10,23 +11,14 @@ export const segment: HeadingParser.SegmentParser = block(validate('#', focus(
10
11
  some(line(source => [[source], ''])))));
11
12
 
12
13
  export const heading: HeadingParser = block(rewrite(segment,
13
- context({ syntax: { inline: {
14
- annotation: false,
15
- reference: false,
16
- index: false,
17
- label: false,
18
- link: false,
19
- media: false,
20
- }}},
14
+ state(State.annotation | State.reference | State.index | State.label | State.link | State.media,
21
15
  line(indexee(fmap(union([
22
16
  open(
23
17
  str(/^##+/),
24
18
  visualize(trimBlank(some(union([indexer, inline])))), true),
25
19
  open(
26
20
  str('#'),
27
- context({ syntax: { inline: {
28
- autolink: false,
29
- }}},
21
+ state(State.autolink,
30
22
  visualize(trimBlank(some(union([indexer, inline]))))), true),
31
23
  ]),
32
24
  ([h, ...ns]: [string, ...(HTMLElement | string)[]]) => [
@@ -1,13 +1,14 @@
1
1
  import { IListParser } from '../block';
2
- import { union, inits, some, block, line, validate, indent, context, creator, open, fallback, lazy, fmap } from '../../combinator';
2
+ import { union, inits, some, creator, state, block, line, validate, indent, open, fallback, lazy, fmap } from '../../combinator';
3
3
  import { ulist_, fillFirstLine } from './ulist';
4
4
  import { olist_, invalid } from './olist';
5
5
  import { inline } from '../inline';
6
+ import { State } from '../context';
6
7
  import { html, defrag } from 'typed-dom/dom';
7
8
 
8
9
  export const ilist: IListParser = lazy(() => block(validate(
9
10
  /^[-+*](?=[^\S\n]|\n[^\S\n]*\S)/,
10
- context({ syntax: { inline: { media: false } } },
11
+ state(State.media,
11
12
  ilist_))));
12
13
 
13
14
  export const ilist_: IListParser = lazy(() => block(fmap(validate(
@@ -1,13 +1,15 @@
1
1
  import { undefined } from 'spica/global';
2
2
  import { OListParser } from '../block';
3
- import { union, inits, subsequence, some, block, line, validate, indent, focus, rewrite, context, creator, open, match, fallback, lazy, fmap } from '../../combinator';
3
+ import { union, inits, subsequence, some, creator, state, block, line, validate, indent, focus, rewrite, open, match, fallback, lazy, fmap } from '../../combinator';
4
4
  import { checkbox, ulist_, fillFirstLine } from './ulist';
5
5
  import { ilist_ } from './ilist';
6
6
  import { inline, indexee, indexer } from '../inline';
7
7
  import { contentline } from '../source';
8
- import { trimBlank } from '../util';
8
+ import { State } from '../context';
9
+ import { trimBlank } from '../visibility';
9
10
  import { html, define, defrag } from 'typed-dom/dom';
10
11
  import { memoize } from 'spica/memoize';
12
+ import { duffbk } from 'spica/duff';
11
13
  import { shift } from 'spica/array';
12
14
  import { tuple } from 'spica/tuple';
13
15
 
@@ -21,7 +23,7 @@ export const olist: OListParser = lazy(() => block(validate(
21
23
  /^([0-9]+|[a-z]+|[A-Z]+)(?:-[0-9]+)*\.(?=[^\S\n]|\n[^\S\n]*\S)/.source,
22
24
  /^\(([0-9]+|[a-z]+)\)(?:-[0-9]+)*(?=[^\S\n]|\n[^\S\n]*\S)/.source,
23
25
  ].join('|')),
24
- context({ syntax: { inline: { media: false } } },
26
+ state(State.media,
25
27
  olist_))));
26
28
 
27
29
  export const olist_: OListParser = lazy(() => block(union([
@@ -122,15 +124,16 @@ function format(el: HTMLOListElement, type: string, form: string): HTMLOListElem
122
124
  'data-type': style(type) || undefined,
123
125
  });
124
126
  const marker = el.firstElementChild?.getAttribute('data-marker')!.match(initial(type))?.[0] ?? '';
125
- for (let es = el.children, len = es.length, i = 0; i < len; ++i) {
127
+ const es = el.children;
128
+ duffbk(es.length, i => {
126
129
  const el = es[i];
127
130
  switch (el.getAttribute('data-marker')) {
128
131
  case '':
129
132
  case marker:
130
133
  el.removeAttribute('data-marker');
131
- continue;
134
+ return;
132
135
  }
133
- break;
134
- }
136
+ return false;
137
+ });
135
138
  return el;
136
139
  }
@@ -2,7 +2,7 @@ import { ParagraphParser } from '../block';
2
2
  import { union, some, block, trimEnd, fmap } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { localize } from '../locale';
5
- import { visualize } from '../util';
5
+ import { visualize } from '../visibility';
6
6
  import { html, defrag } from 'typed-dom/dom';
7
7
 
8
8
  export const paragraph: ParagraphParser = block(localize(fmap(
@@ -1,5 +1,5 @@
1
1
  import { ReplyParser } from '../../block';
2
- import { union, tails, line, validate, focus, creator, reverse, fmap } from '../../../combinator';
2
+ import { union, tails, creator, line, validate, focus, reverse, fmap } from '../../../combinator';
3
3
  import { anchor } from '../../inline/autolink/anchor';
4
4
  import { str } from '../../source';
5
5
  import { html, define, defrag } from 'typed-dom/dom';
@@ -1,6 +1,6 @@
1
1
  import { ReplyParser } from '../../block';
2
2
  import { eval } from '../../../combinator/data/parser';
3
- import { union, some, block, line, validate, rewrite, creator, lazy, fmap } from '../../../combinator';
3
+ import { union, some, creator, block, line, validate, rewrite, lazy, fmap } from '../../../combinator';
4
4
  import { math } from '../../inline/math';
5
5
  import { str, anyline } from '../../source';
6
6
  import { autolink } from '../../autolink';
@@ -5,7 +5,7 @@ import { quote, syntax as delimiter } from './reply/quote';
5
5
  import { inline } from '../inline';
6
6
  import { anyline } from '../source';
7
7
  import { localize } from '../locale';
8
- import { visualize } from '../util';
8
+ import { visualize } from '../visibility';
9
9
  import { html, defrag } from 'typed-dom/dom';
10
10
  import { push, pop } from 'spica/array';
11
11
 
@@ -1,5 +1,5 @@
1
1
  import { SidefenceParser } from '../block';
2
- import { union, some, block, focus, rewrite, creator, convert, lazy, fmap } from '../../combinator';
2
+ import { union, some, creator, block, focus, rewrite, convert, lazy, fmap } from '../../combinator';
3
3
  import { autolink } from '../autolink';
4
4
  import { contentline } from '../source';
5
5
  import { html, define, defrag } from 'typed-dom/dom';
@@ -1,9 +1,10 @@
1
1
  import { TableParser } from '../block';
2
- import { union, sequence, some, block, line, validate, focus, rewrite, creator, surround, open, fallback, lazy, fmap } from '../../combinator';
2
+ import { union, sequence, some, creator, block, line, validate, focus, rewrite, surround, open, fallback, lazy, fmap } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { contentline } from '../source';
5
- import { trimNode } from '../util';
5
+ import { trimNode } from '../visibility';
6
6
  import { html, defrag } from 'typed-dom/dom';
7
+ import { duffEach, duffReduce } from 'spica/duff';
7
8
  import { push } from 'spica/array';
8
9
 
9
10
  import RowParser = TableParser.RowParser;
@@ -62,16 +63,15 @@ const data: CellParser.DataParser = creator(fmap(
62
63
  function format(rows: HTMLTableRowElement[]): HTMLTableRowElement[] {
63
64
  const aligns = rows[0].classList.contains('invalid')
64
65
  ? []
65
- : push([], rows.shift()!.children).map(el => el.textContent!);
66
- for (let i = 0, len = rows.length; i < len; ++i) {
67
- const cols = rows[i].children;
68
- for (let i = 0, len = cols.length; i < len; ++i) {
66
+ : duffReduce(rows.shift()!.children, (acc, el) => push(acc, [el.textContent!]), [] as string[]);
67
+ for (let i = 0; i < rows.length; ++i) {
68
+ duffEach(rows[i].children, (col, i) => {
69
69
  if (i > 0 && !aligns[i]) {
70
70
  aligns[i] = aligns[i - 1];
71
71
  }
72
- if (!aligns[i]) continue;
73
- cols[i].setAttribute('align', aligns[i]);
74
- }
72
+ if (!aligns[i]) return;
73
+ col.setAttribute('align', aligns[i]);
74
+ });
75
75
  }
76
76
  return rows;
77
77
  }
@@ -1,15 +1,16 @@
1
1
  import { UListParser } from '../block';
2
- import { union, inits, subsequence, some, block, line, validate, indent, focus, context, creator, open, fallback, lazy, fmap } from '../../combinator';
2
+ import { union, inits, subsequence, some, creator, state, block, line, validate, indent, focus, open, fallback, lazy, fmap } from '../../combinator';
3
3
  import { olist_, invalid } from './olist';
4
4
  import { ilist_ } from './ilist';
5
5
  import { inline, indexer, indexee } from '../inline';
6
- import { trimBlank } from '../util';
6
+ import { State } from '../context';
7
+ import { trimBlank } from '../visibility';
7
8
  import { html, defrag } from 'typed-dom/dom';
8
9
  import { unshift } from 'spica/array';
9
10
 
10
11
  export const ulist: UListParser = lazy(() => block(validate(
11
12
  /^-(?=[^\S\n]|\n[^\S\n]*\S)/,
12
- context({ syntax: { inline: { media: false } } },
13
+ state(State.media,
13
14
  ulist_))));
14
15
 
15
16
  export const ulist_: UListParser = lazy(() => block(fmap(validate(
@@ -36,7 +36,7 @@ export import ReplyParser = BlockParser.ReplyParser;
36
36
  export import ParagraphParser = BlockParser.ParagraphParser;
37
37
 
38
38
  export const block: BlockParser = creator(error(
39
- reset({ resources: { budget: 50 * 1000, recursion: 20 + 1 } },
39
+ reset({ resources: { budget: 50 * 1000, recursion: 20 } },
40
40
  union([
41
41
  emptyline,
42
42
  horizontalrule,
@@ -0,0 +1,32 @@
1
+ export const enum Rule {
2
+ reference = 1 << 12,
3
+ comment = 1 << 11,
4
+ index = 1 << 10,
5
+ placeholder = 1 << 9,
6
+ link = 1 << 8,
7
+ bracket = 1 << 7,
8
+ media = 1 << 6,
9
+ annotation = 1 << 5,
10
+ mathbracket = 1 << 4,
11
+ html = 1 << 3,
12
+ math = 1 << 2,
13
+ autolink = 1 << 1,
14
+ quote = 1 << 0,
15
+ none = 0,
16
+ }
17
+ export const backtrackable = 0
18
+ | Rule.annotation
19
+ | Rule.reference
20
+ | Rule.index
21
+ | Rule.link
22
+ | Rule.media;
23
+
24
+ export const enum State {
25
+ annotation = 1 << 6,
26
+ reference = 1 << 5,
27
+ index = 1 << 4,
28
+ label = 1 << 3,
29
+ link = 1 << 2,
30
+ media = 1 << 1,
31
+ autolink = 1 << 0,
32
+ }
@@ -1,5 +1,5 @@
1
1
  import { MarkdownParser } from '../../markdown';
2
- import { union, inits, some, block, line, validate, focus, rewrite, guard, clear, convert, lazy, fmap } from '../combinator';
2
+ import { union, inits, some, guard, block, line, validate, focus, rewrite, clear, convert, lazy, fmap } from '../combinator';
3
3
  import { segment } from './segment';
4
4
  import { str } from './source';
5
5
  import { normalize } from './api/normalize';
@@ -1,28 +1,20 @@
1
1
  import { undefined } from 'spica/global';
2
2
  import { AnnotationParser } from '../inline';
3
- import { union, some, validate, guard, context, precedence, creator, recursion, surround, lazy } from '../../combinator';
3
+ import { union, some, guard, context, syntax, state, validate, surround, lazy } from '../../combinator';
4
4
  import { inline } from '../inline';
5
5
  import { optimize } from './link';
6
- import { startLoose, trimNode } from '../util';
6
+ import { Rule, State } from '../context';
7
+ import { startLoose, trimNode } from '../visibility';
7
8
  import { html, defrag } from 'typed-dom/dom';
8
9
 
9
- export const annotation: AnnotationParser = lazy(() => creator(recursion(precedence(6, validate('((', surround(
10
+ export const annotation: AnnotationParser = lazy(() => validate('((', syntax(Rule.annotation, 6, surround(
10
11
  '((',
11
- guard(context => context.syntax?.inline?.annotation ?? true,
12
+ guard(context => ~context.state! & State.annotation,
13
+ state(State.annotation | State.media,
12
14
  startLoose(
13
- context({ syntax: { inline: {
14
- annotation: false,
15
- // Redundant
16
- //reference: true,
17
- media: false,
18
- // Redundant
19
- //index: true,
20
- //label: true,
21
- //link: true,
22
- //autolink: true,
23
- }}, delimiters: undefined },
24
- some(union([inline]), ')', [[/^\\?\n/, 9], [')', 2], ['))', 6]])), ')')),
15
+ context({ delimiters: undefined },
16
+ some(union([inline]), ')', [[/^\\?\n/, 9], [')', 2], ['))', 6]])), ')'))),
25
17
  '))',
26
18
  false,
27
19
  ([, ns], rest) => [[html('sup', { class: 'annotation' }, [html('span', trimNode(defrag(ns)))])], rest],
28
- ([, ns, rest], next) => next[0] === ')' ? undefined : optimize('((', ns, rest)))))));
20
+ ([, ns, rest], next) => next[0] === ')' ? undefined : optimize('((', ns, rest)))));
@@ -1,5 +1,5 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { verify, rewrite, creator } from '../../../combinator';
2
+ import { creator, verify, rewrite } from '../../../combinator';
3
3
  import { str } from '../../source';
4
4
  import { html } from 'typed-dom/dom';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { AutolinkParser } from '../../inline';
2
- import { union, some, validate, focus, rewrite, precedence, creator, convert, surround, open, lazy } from '../../../combinator';
2
+ import { union, some, creator, precedence, validate, focus, rewrite, convert, surround, open, lazy } from '../../../combinator';
3
3
  import { textlink } from '../link';
4
4
  import { unescsource } from '../../source';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { AutolinkParser } from '../inline';
2
- import { union, some, validate, guard, fmap } from '../../combinator';
2
+ import { union, some, syntax, guard, validate, fmap } from '../../combinator';
3
3
  import { url } from './autolink/url';
4
4
  import { email } from './autolink/email';
5
5
  import { channel } from './autolink/channel';
@@ -8,11 +8,13 @@ import { hashtag, emoji } from './autolink/hashtag';
8
8
  import { hashnum } from './autolink/hashnum';
9
9
  import { anchor } from './autolink/anchor';
10
10
  import { str } from '../source';
11
+ import { Rule, State } from '../context';
11
12
  import { stringify } from '../util';
12
13
 
13
14
  export const autolink: AutolinkParser = fmap(
14
15
  validate(/^(?:[@#>0-9A-Za-z]|\S#)/,
15
- guard(context => context.syntax?.inline?.autolink ?? true,
16
+ guard(context => ~context.state! & State.autolink,
17
+ syntax(Rule.autolink, 1,
16
18
  some(union([
17
19
  url,
18
20
  email,
@@ -29,5 +31,5 @@ export const autolink: AutolinkParser = fmap(
29
31
  // Escape unmatched hashtag-like strings.
30
32
  str(new RegExp(/^#+(?:[^\p{C}\p{S}\p{P}\s]|emoji|['_])*/u.source.replace('emoji', emoji), 'u')),
31
33
  anchor,
32
- ])))),
34
+ ]))))),
33
35
  ns => ns.length === 1 ? ns : [stringify(ns)]);
@@ -1,30 +1,31 @@
1
1
  import { undefined } from 'spica/global';
2
2
  import { BracketParser } from '../inline';
3
- import { union, some, precedence, creator, surround, lazy } from '../../combinator';
3
+ import { union, some, syntax, surround, lazy } from '../../combinator';
4
4
  import { inline } from '../inline';
5
5
  import { str } from '../source';
6
+ import { Rule } from '../context';
6
7
  import { html, defrag } from 'typed-dom/dom';
7
8
  import { unshift, push } from 'spica/array';
8
9
 
9
10
  const index = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*/;
10
11
 
11
- export const bracket: BracketParser = lazy(() => creator(0, union([
12
- surround(str('('), precedence(2, str(index)), str(')')),
13
- surround(str('('), precedence(2, some(inline, ')', [[')', 2]])), str(')'), true,
12
+ export const bracket: BracketParser = lazy(() => union([
13
+ syntax(Rule.none, 2, surround(str('('), str(index), str(')'))),
14
+ syntax(Rule.bracket, 2, surround(str('('), some(inline, ')', [[')', 2]]), str(')'), true,
14
15
  ([as, bs = [], cs], rest) => [[html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))], rest],
15
- ([as, bs = []], rest) => [unshift([''], unshift(as, bs)), rest]),
16
- surround(str('('), precedence(2, str(new RegExp(index.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)/g, c => c.trimStart() && String.fromCharCode(c.charCodeAt(0) + 0xFEE0))))), str(')')),
17
- surround(str('('), precedence(2, some(inline, ')', [[')', 2]])), str(')'), true,
16
+ ([as, bs = []], rest) => [unshift([''], unshift(as, bs)), rest])),
17
+ syntax(Rule.none, 2, surround(str('('), str(new RegExp(index.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)/g, c => c.trimStart() && String.fromCharCode(c.charCodeAt(0) + 0xFEE0)))), str(')'))),
18
+ syntax(Rule.bracket, 2, surround(str('('), some(inline, ')', [[')', 2]]), str(')'), true,
18
19
  ([as, bs = [], cs], rest) => [[html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))], rest],
19
- ([as, bs = []], rest) => [unshift(as, bs), rest]),
20
- surround(str('['), precedence(2, some(inline, ']', [[']', 2]])), str(']'), true,
20
+ ([as, bs = []], rest) => [unshift(as, bs), rest])),
21
+ syntax(Rule.bracket, 2, surround(str('['), some(inline, ']', [[']', 2]]), str(']'), true,
21
22
  undefined,
22
- ([as, bs = []], rest) => [unshift([''], unshift(as, bs)), rest]),
23
- surround(str('{'), precedence(2, some(inline, '}', [['}', 2]])), str('}'), true,
23
+ ([as, bs = []], rest) => [unshift([''], unshift(as, bs)), rest])),
24
+ syntax(Rule.bracket, 2, surround(str('{'), some(inline, '}', [['}', 2]]), str('}'), true,
24
25
  undefined,
25
- ([as, bs = []], rest) => [unshift(as, bs), rest]),
26
+ ([as, bs = []], rest) => [unshift(as, bs), rest])),
26
27
  // Control media blinking in editing rather than control confusion of pairs of quote marks.
27
- surround(str('"'), precedence(8, some(inline, '"', [['"', 8]])), str('"'), true,
28
+ syntax(Rule.quote, 8, surround(str('"'), some(inline, '"', [['"', 8]]), str('"'), true,
28
29
  undefined,
29
- ([as, bs = []], rest) => [unshift(as, bs), rest]),
30
- ])));
30
+ ([as, bs = []], rest) => [unshift(as, bs), rest])),
31
+ ]));
@@ -1,5 +1,5 @@
1
1
  import { CodeParser } from '../inline';
2
- import { validate, creator, match } from '../../combinator';
2
+ import { creator, validate, match } from '../../combinator';
3
3
  import { html } from 'typed-dom/dom';
4
4
 
5
5
  export const code: CodeParser = creator(validate('`', match(
@@ -1,12 +1,13 @@
1
1
  import { CommentParser } from '../inline';
2
- import { union, some, validate, precedence, creator, surround, open, close, match, lazy } from '../../combinator';
2
+ import { union, some, syntax, validate, surround, open, close, match, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { text, str } from '../source';
5
+ import { Rule } from '../context';
5
6
  import { html, defrag } from 'typed-dom/dom';
6
7
  import { memoize } from 'spica/memoize';
7
8
  import { unshift, push } from 'spica/array';
8
9
 
9
- export const comment: CommentParser = lazy(() => validate('[%', creator(precedence(4, match(
10
+ export const comment: CommentParser = lazy(() => validate('[%', syntax(Rule.none, 4, match(
10
11
  /^\[(%+)\s/,
11
12
  memoize(
12
13
  ([, fence]) =>
@@ -21,4 +22,4 @@ export const comment: CommentParser = lazy(() => validate('[%', creator(preceden
21
22
  ]),
22
23
  ], rest],
23
24
  ([as, bs = []], rest) => [unshift(as, bs), rest]),
24
- ([, fence]) => fence.length, []))))));
25
+ ([, fence]) => fence.length, [])))));
@@ -1,12 +1,13 @@
1
1
  import { DeletionParser } from '../inline';
2
- import { union, some, precedence, creator, surround, open, lazy } from '../../combinator';
2
+ import { union, some, syntax, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
- import { blankWith } from '../util';
5
+ import { Rule } from '../context';
6
+ import { blankWith } from '../visibility';
6
7
  import { html, defrag } from 'typed-dom/dom';
7
8
  import { unshift } from 'spica/array';
8
9
 
9
- export const deletion: DeletionParser = lazy(() => creator(precedence(1, surround(
10
+ export const deletion: DeletionParser = lazy(() => syntax(Rule.none, 1, surround(
10
11
  str('~~'),
11
12
  some(union([
12
13
  some(inline, blankWith('\n', '~~')),
@@ -14,4 +15,4 @@ export const deletion: DeletionParser = lazy(() => creator(precedence(1, surroun
14
15
  ])),
15
16
  str('~~'), false,
16
17
  ([, bs], rest) => [[html('del', defrag(bs))], rest],
17
- ([as, bs], rest) => [unshift(as, bs), rest]))));
18
+ ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -1,14 +1,15 @@
1
1
  import { EmphasisParser } from '../inline';
2
- import { union, some, precedence, creator, surround, open, lazy } from '../../combinator';
2
+ import { union, some, syntax, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { emstrong } from './emstrong';
5
5
  import { strong } from './strong';
6
6
  import { str } from '../source';
7
- import { startTight, blankWith } from '../util';
7
+ import { Rule } from '../context';
8
+ import { startTight, blankWith } from '../visibility';
8
9
  import { html, defrag } from 'typed-dom/dom';
9
10
  import { unshift } from 'spica/array';
10
11
 
11
- export const emphasis: EmphasisParser = lazy(() => creator(precedence(1, surround(
12
+ export const emphasis: EmphasisParser = lazy(() => syntax(Rule.none, 1, surround(
12
13
  str('*'),
13
14
  startTight(some(union([
14
15
  strong,
@@ -21,4 +22,4 @@ export const emphasis: EmphasisParser = lazy(() => creator(precedence(1, surroun
21
22
  ])), '*'),
22
23
  str('*'), false,
23
24
  ([, bs], rest) => [[html('em', defrag(bs))], rest],
24
- ([as, bs], rest) => [unshift(as, bs), rest]))));
25
+ ([as, bs], rest) => [unshift(as, bs), rest])));