securemark 0.294.6 → 0.294.8

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 (62) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/index.js +226 -216
  3. package/markdown.d.ts +13 -36
  4. package/package.json +1 -1
  5. package/src/combinator/control/constraint/block.ts +2 -2
  6. package/src/combinator/control/constraint/line.ts +7 -5
  7. package/src/combinator/control/manipulation/convert.ts +2 -1
  8. package/src/combinator/control/manipulation/fence.ts +4 -4
  9. package/src/combinator/control/manipulation/indent.ts +3 -5
  10. package/src/combinator/control/manipulation/surround.ts +47 -18
  11. package/src/combinator/data/parser/some.ts +1 -1
  12. package/src/combinator/data/parser/union.ts +6 -2
  13. package/src/parser/api/bind.test.ts +0 -1
  14. package/src/parser/api/normalize.test.ts +5 -8
  15. package/src/parser/api/normalize.ts +11 -11
  16. package/src/parser/api/parse.test.ts +3 -3
  17. package/src/parser/autolink.ts +1 -2
  18. package/src/parser/block/extension/fig.ts +4 -1
  19. package/src/parser/block/heading.ts +12 -2
  20. package/src/parser/block/reply/quote.ts +1 -2
  21. package/src/parser/block/ulist.ts +1 -1
  22. package/src/parser/block.ts +0 -4
  23. package/src/parser/header.ts +28 -40
  24. package/src/parser/inline/annotation.ts +2 -3
  25. package/src/parser/inline/autolink/account.ts +47 -17
  26. package/src/parser/inline/autolink/anchor.test.ts +0 -1
  27. package/src/parser/inline/autolink/anchor.ts +15 -15
  28. package/src/parser/inline/autolink/email.test.ts +1 -1
  29. package/src/parser/inline/autolink/email.ts +10 -11
  30. package/src/parser/inline/autolink/hashnum.ts +17 -14
  31. package/src/parser/inline/autolink/hashtag.ts +23 -19
  32. package/src/parser/inline/autolink/url.ts +24 -19
  33. package/src/parser/inline/autolink.ts +36 -25
  34. package/src/parser/inline/bracket.ts +14 -14
  35. package/src/parser/inline/deletion.ts +2 -1
  36. package/src/parser/inline/emphasis.ts +2 -1
  37. package/src/parser/inline/emstrong.ts +2 -1
  38. package/src/parser/inline/extension/index.ts +4 -4
  39. package/src/parser/inline/extension/indexer.ts +1 -1
  40. package/src/parser/inline/extension/label.ts +1 -1
  41. package/src/parser/inline/extension/placeholder.ts +4 -3
  42. package/src/parser/inline/html.ts +5 -5
  43. package/src/parser/inline/htmlentity.ts +3 -3
  44. package/src/parser/inline/insertion.ts +2 -1
  45. package/src/parser/inline/italic.ts +2 -1
  46. package/src/parser/inline/link.ts +7 -20
  47. package/src/parser/inline/mark.ts +2 -1
  48. package/src/parser/inline/math.ts +4 -2
  49. package/src/parser/inline/media.ts +24 -25
  50. package/src/parser/inline/reference.ts +4 -4
  51. package/src/parser/inline/remark.ts +2 -1
  52. package/src/parser/inline/ruby.ts +3 -4
  53. package/src/parser/inline/strong.ts +2 -1
  54. package/src/parser/inline/template.ts +10 -10
  55. package/src/parser/inline.ts +2 -1
  56. package/src/parser/segment.ts +2 -2
  57. package/src/parser/source/escapable.ts +3 -4
  58. package/src/parser/source/line.ts +3 -1
  59. package/src/parser/source/text.ts +8 -13
  60. package/src/parser/source/unescapable.ts +2 -4
  61. package/src/parser/source.ts +1 -2
  62. package/src/parser/inline/autolink/channel.ts +0 -44
@@ -22,12 +22,12 @@ export const index: IndexParser = lazy(() => constraint(State.index, fmap(indexe
22
22
  ]), ']', [[']', 1]])))),
23
23
  str(']'),
24
24
  false,
25
+ [3 | Backtrack.bracket],
25
26
  ([, bs], context) =>
26
27
  context.linebreak === 0 && trimBlankNodeEnd(bs).length > 0
27
28
  ? new List([new Data(html('a', { 'data-index': dataindex(bs) }, defrag(unwrap(bs))))])
28
29
  : undefined,
29
- undefined,
30
- [3 | Backtrack.bracket])),
30
+ undefined)),
31
31
  ns => {
32
32
  if (ns.length === 1) {
33
33
  const el = ns.head!.value as HTMLElement;
@@ -54,14 +54,14 @@ export const signature: IndexParser.SignatureParser = lazy(() => validate('|', s
54
54
  ]), ']'),
55
55
  /(?=])/y,
56
56
  false,
57
+ [3 | Backtrack.bracket],
57
58
  ([, ns], context) => {
58
59
  const index = identity('index', undefined, ns.foldl((acc, { value }) => acc + value, ''))?.slice(7);
59
60
  return index && context.linebreak === 0
60
61
  ? new List([new Data(html('span', { class: 'indexer', 'data-index': index }))])
61
62
  : undefined;
62
63
  },
63
- ([as, bs]) => bs && as.import(bs),
64
- [3 | Backtrack.bracket])));
64
+ ([as, bs]) => bs && as.import(bs))));
65
65
 
66
66
  export function dataindex(nodes: List<Data<string | HTMLElement>>): string | undefined {
67
67
  let node = nodes.last;
@@ -16,4 +16,4 @@ export const indexer: ExtensionParser.IndexerParser = surround(
16
16
  signature,
17
17
  focus(/\|(?=\])/y, () => new List([new Data(html('span', { class: 'indexer', 'data-index': '' }))])),
18
18
  ]),
19
- /\]\s*$/y);
19
+ /\][^\S\n]*(?:$|\n)/y);
@@ -14,7 +14,7 @@ export const segment: ExtensionParser.LabelParser.SegmentParser = clear(union([
14
14
 
15
15
  export const label: ExtensionParser.LabelParser = constraint(State.label, fmap(
16
16
  union([
17
- surround('[', body, ']', false, undefined, undefined, [1 | Backtrack.bracket, 1]),
17
+ surround('[', body, ']', false, [1 | Backtrack.bracket, 1]),
18
18
  body,
19
19
  ]),
20
20
  ([{ value }]) => new List([
@@ -17,7 +17,9 @@ export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => surroun
17
17
  str(/\[[:^|]/y),
18
18
  precedence(1, recursion(Recursion.inline,
19
19
  tightStart(some(union([inline]), ']', [[']', 1]])))),
20
- str(']'), false,
20
+ str(']'),
21
+ false,
22
+ [3 | Backtrack.bracket],
21
23
  (_, context) => new List([
22
24
  new Data(html('span',
23
25
  {
@@ -26,5 +28,4 @@ export const placeholder: ExtensionParser.PlaceholderParser = lazy(() => surroun
26
28
  },
27
29
  context.source.slice(context.position - context.range!, context.position)))
28
30
  ]),
29
- ([as, bs]) => bs && as.import(bs as List<Data<string>>),
30
- [3 | Backtrack.bracket]));
31
+ ([as, bs]) => bs && as.import(bs as List<Data<string>>)));
@@ -23,10 +23,10 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
23
23
  union([
24
24
  surround(
25
25
  // https://html.spec.whatwg.org/multipage/syntax.html#void-elements
26
- str(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[ >])/yi),
26
+ str(/<(?:area|base|br|col|embed|hr|img|input|link|meta|source|track|wbr)(?=[ >])/y),
27
27
  some(union([attribute])),
28
28
  open(str(/ ?/y), str('>'), true),
29
- true,
29
+ true, [],
30
30
  ([as, bs = new List(), cs], context) =>
31
31
  new List([new Data(elem(as.head!.value.slice(1), false, [...unwrap(as.import(bs).import(cs))], new List(), new List(), context))]),
32
32
  ([as, bs = new List()], context) =>
@@ -38,7 +38,7 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
38
38
  surround<HTMLParser.TagParser, string>(
39
39
  surround(
40
40
  str(`<${tag}`), some(attribute), open(str(/ ?/y), str('>'), true),
41
- true,
41
+ true, [],
42
42
  ([as, bs = new List(), cs]) => as.import(bs).import(cs),
43
43
  ([as, bs = new List()]) => as.import(bs)),
44
44
  // 不可視のHTML構造が可視構造を変化させるべきでない。
@@ -51,7 +51,7 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
51
51
  open('\n', some(inline, `</${tag}>`), true),
52
52
  ])))),
53
53
  str(`</${tag}>`),
54
- true,
54
+ true, [],
55
55
  ([as, bs = new List(), cs], context) =>
56
56
  new List([new Data(elem(tag, true, [...unwrap(as)], bs, cs, context))]),
57
57
  ([as, bs = new List()], context) =>
@@ -63,7 +63,7 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
63
63
  str(/<[a-z]+(?=[ >])/yi),
64
64
  some(union([attribute])),
65
65
  open(str(/ ?/y), str('>'), true),
66
- true,
66
+ true, [],
67
67
  ([as, bs = new List(), cs], context) =>
68
68
  new List([new Data(elem(as.head!.value.slice(1), false, [...unwrap(as.import(bs).import(cs))], new List(), new List(), context))]),
69
69
  ([as, bs = new List()], context) =>
@@ -9,11 +9,11 @@ import { html } from 'typed-dom/dom';
9
9
  export const unsafehtmlentity: UnsafeHTMLEntityParser = surround(
10
10
  str('&'), str(/[0-9A-Za-z]+/y), str(';'),
11
11
  false,
12
+ [3 | Backtrack.bracket],
12
13
  ([as, bs, cs]) =>
13
14
  new List([new Data(parser(as.head!.value + bs.head!.value + cs.head!.value))]),
14
15
  ([as, bs]) =>
15
- new List([new Data(as.head!.value + (bs?.head?.value ?? ''))]),
16
- [3 | Backtrack.bracket]);
16
+ new List([new Data(as.head!.value + (bs?.head?.value ?? ''))]));
17
17
 
18
18
  export const htmlentity: HTMLEntityParser = fmap(
19
19
  union([unsafehtmlentity]),
@@ -23,7 +23,7 @@ export const htmlentity: HTMLEntityParser = fmap(
23
23
  : new Data(html('span', {
24
24
  class: 'invalid',
25
25
  ...invalid('htmlentity', 'syntax', 'Invalid HTML entity'),
26
- }, value))
26
+ }, value))
27
27
  ]));
28
28
 
29
29
  const parser = (el => (entity: string): string => {
@@ -15,7 +15,8 @@ export const insertion: InsertionParser = lazy(() =>
15
15
  some(inline, blankWith('\n', '++')),
16
16
  open('\n', some(inline, '+'), true),
17
17
  ]))),
18
- '++', false,
18
+ '++',
19
+ false, [],
19
20
  ([, bs], { buffer }) => buffer!.import(bs),
20
21
  ([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
21
22
  nodes => new List([new Data(html('ins', defrag(unwrap(nodes))))]))));
@@ -18,7 +18,8 @@ export const italic: ItalicParser = lazy(() =>
18
18
  some(inline, blankWith('///')),
19
19
  open(some(inline, '/'), inline),
20
20
  ])))),
21
- '///', false,
21
+ '///',
22
+ false, [],
22
23
  ([, bs], { buffer }) => buffer!.import(bs),
23
24
  ([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
24
25
  nodes => new List([new Data(html('i', defrag(unwrap(nodes))))]))));
@@ -2,10 +2,10 @@ import { MarkdownParser } from '../../../markdown';
2
2
  import { LinkParser } from '../inline';
3
3
  import { State, Backtrack, Command } from '../context';
4
4
  import { List, Data } from '../../combinator/data/parser';
5
- import { union, inits, tails, sequence, subsequence, some, creation, precedence, state, constraint, surround, open, setBacktrack, dup, reverse, lazy, fmap, bind } from '../../combinator';
5
+ import { union, inits, sequence, subsequence, some, creation, precedence, state, constraint, surround, open, setBacktrack, dup, lazy, fmap, bind } from '../../combinator';
6
6
  import { inline, media, shortmedia } from '../inline';
7
7
  import { attributes } from './html';
8
- import { unescsource, str } from '../source';
8
+ import { str } from '../source';
9
9
  import { trimBlankStart, trimBlankNodeEnd } from '../visibility';
10
10
  import { unwrap, invalid, stringify } from '../util';
11
11
  import { ReadonlyURL } from 'spica/url';
@@ -24,12 +24,11 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
24
24
  trimBlankStart(some(union([inline]), ']', [[']', 1]])),
25
25
  ']',
26
26
  true,
27
+ [3 | Backtrack.bracket, 3 | Backtrack.link, 2 | Backtrack.ruby],
27
28
  ([, ns = new List()], context) =>
28
29
  context.linebreak === 0
29
30
  ? ns.push(new Data(Command.Separator)) && ns
30
- : undefined,
31
- undefined,
32
- [3 | Backtrack.bracket, 3 | Backtrack.link, 2 | Backtrack.ruby])),
31
+ : undefined)),
33
32
  // `{ `と`{`で個別にバックトラックが発生し+1nされる。
34
33
  // 自己再帰的にパースしてもオプションの不要なパースによる計算量の増加により相殺される。
35
34
  dup(surround(
@@ -37,14 +36,14 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
37
36
  inits([uri, some(option)]),
38
37
  / ?}/y,
39
38
  false,
39
+ [3 | Backtrack.link],
40
40
  undefined,
41
41
  ([as, bs], context) => {
42
42
  if (!bs) return;
43
43
  const head = context.position - context.range!;
44
44
  setBacktrack(context, [2 | Backtrack.link], head);
45
45
  return as.import(bs).push(new Data(Command.Cancel)) && as;
46
- },
47
- [3 | Backtrack.link])),
46
+ })),
48
47
  ]),
49
48
  ([{ value: content }, { value: params = undefined } = {}], context) => {
50
49
  if (content.last!.value === Command.Separator) {
@@ -87,18 +86,6 @@ export const medialink: LinkParser.MediaLinkParser = lazy(() => constraint(State
87
86
  ([{ value: content }, { value: params }], context) =>
88
87
  new List([new Data(parse(content, params as List<Data<string>>, context))]))))));
89
88
 
90
- export const unsafelink: LinkParser.UnsafeLinkParser = lazy(() =>
91
- creation(10,
92
- bind(reverse(tails([
93
- dup(surround(
94
- '[',
95
- some(union([unescsource]), ']'),
96
- ']')),
97
- dup(surround(/{(?![{}])/y, inits([uri, some(option)]), / ?}/y)),
98
- ])),
99
- ([{ value: params }, { value: content } = new Data(new List<Data<string>>())], context) =>
100
- new List([new Data(parse(content, params, context))]))));
101
-
102
89
  export const uri: LinkParser.ParameterParser.UriParser = union([
103
90
  open(/ /y, str(/\S+/y)),
104
91
  str(/[^\s{}]+/y),
@@ -110,7 +97,7 @@ export const option: LinkParser.ParameterParser.OptionParser = union([
110
97
  str(/ [^\s{}]+/y),
111
98
  ]);
112
99
 
113
- function parse(
100
+ export function parse(
114
101
  content: List<Data<string | HTMLElement>>,
115
102
  params: List<Data<string>>,
116
103
  context: MarkdownParser.Context,
@@ -16,7 +16,8 @@ export const mark: MarkParser = lazy(() => constraint(State.linkers & ~State.mar
16
16
  some(inline, blankWith('==')),
17
17
  open(some(inline, '='), inline),
18
18
  ])))),
19
- '==', false,
19
+ '==',
20
+ false, [],
20
21
  ([, bs], { buffer }) => buffer!.import(bs),
21
22
  ([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
22
23
  (nodes, { id }) => {
@@ -14,7 +14,8 @@ export const math: MathParser = lazy(() => rewrite(
14
14
  /\$(?={)/y,
15
15
  precedence(4, bracket),
16
16
  '$',
17
- false, undefined, undefined, [3 | Backtrack.bracket]),
17
+ false,
18
+ [3 | Backtrack.bracket]),
18
19
  surround(
19
20
  /\$(?![\s{}])/y,
20
21
  precedence(2, some(union([
@@ -22,7 +23,8 @@ export const math: MathParser = lazy(() => rewrite(
22
23
  precedence(4, bracket),
23
24
  ]))),
24
25
  /\$(?![-0-9A-Za-z])/y,
25
- false, undefined, undefined, [3 | Backtrack.bracket]),
26
+ false,
27
+ [3 | Backtrack.bracket]),
26
28
  ]),
27
29
  ({ context: { source, caches: { math: cache } = {} } }) => new List([
28
30
  new Data(cache?.get(source)?.cloneNode(true) ||
@@ -1,8 +1,8 @@
1
1
  import { MediaParser } from '../inline';
2
2
  import { State, Recursion, Backtrack, Command } from '../context';
3
- import { List, Data, subinput } from '../../combinator/data/parser';
3
+ import { List, Data } from '../../combinator/data/parser';
4
4
  import { union, inits, tails, some, creation, recursion, precedence, constraint, surround, open, setBacktrack, dup, lazy, fmap, bind } from '../../combinator';
5
- import { unsafelink, uri, option as linkoption, resolve, decode } from './link';
5
+ import { uri, option as linkoption, resolve, decode, parse } from './link';
6
6
  import { attributes } from './html';
7
7
  import { unsafehtmlentity } from './htmlentity';
8
8
  import { txt, str } from '../source';
@@ -30,25 +30,24 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
30
30
  ]), ']')),
31
31
  ']',
32
32
  true,
33
+ [3 | Backtrack.escbracket],
33
34
  ([, ns = new List()], context) =>
34
35
  context.linebreak === 0
35
36
  ? ns
36
- : undefined,
37
- undefined,
38
- [3 | Backtrack.escbracket])),
37
+ : undefined)),
39
38
  dup(surround(
40
39
  /{(?![{}])/y,
41
40
  inits([uri, some(option)]),
42
41
  / ?}/y,
43
42
  false,
43
+ [3 | Backtrack.link],
44
44
  undefined,
45
45
  ([as, bs], context) => {
46
46
  if (!bs) return;
47
47
  const head = context.position - context.range!;
48
48
  setBacktrack(context, [2 | Backtrack.link], head);
49
49
  return as.import(bs).push(new Data(Command.Cancel)) && as;
50
- },
51
- [3 | Backtrack.link])),
50
+ })),
52
51
  ]),
53
52
  nodes =>
54
53
  nodes.length === 1
@@ -98,26 +97,26 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
98
97
  }
99
98
  if (context.state! & State.link) return new List([new Data(el)]);
100
99
  if (cache && cache.tagName !== 'IMG') return new List([new Data(el)]);
101
- const { source, position } = context;
102
- return fmap(
103
- unsafelink as MediaParser,
104
- ([{ value }]) => {
105
- context.source = source;
106
- context.position = position;
107
- return new List([new Data(define(value, { class: null, target: '_blank' }, [el]))]);
108
- })
109
- (subinput(`{ ${INSECURE_URI}${linkparams.join('')} }`, context));
100
+ return new List([new Data(define(
101
+ parse(
102
+ new List(),
103
+ linkparams.reduce(
104
+ (acc, p) => acc.push(new Data(p)) && acc,
105
+ new List([new Data(INSECURE_URI)])),
106
+ context),
107
+ { class: null, target: '_blank' }, [el]))
108
+ ]);
110
109
  })))));
111
110
 
112
111
  const bracket: MediaParser.TextParser.BracketParser = lazy(() => recursion(Recursion.terminal, union([
113
- surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'), true,
114
- undefined, () => new List(), [3 | Backtrack.escbracket]),
115
- surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'), true,
116
- undefined, () => new List(), [3 | Backtrack.escbracket]),
117
- surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'), true,
118
- undefined, () => new List(), [3 | Backtrack.escbracket]),
119
- surround(str('"'), precedence(2, some(union([unsafehtmlentity, txt]), '"')), str('"'), true,
120
- undefined, () => new List(), [3 | Backtrack.escbracket]),
112
+ surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'),
113
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
114
+ surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'),
115
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
116
+ surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'),
117
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
118
+ surround(str('"'), precedence(2, some(union([unsafehtmlentity, txt]), '"')), str('"'),
119
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
121
120
  ])));
122
121
 
123
122
  const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
@@ -125,7 +124,7 @@ const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
125
124
  open(/ /y, str(/[1-9][0-9]*/y)),
126
125
  str(/[x:]/y),
127
126
  str(/[1-9][0-9]*(?=[ }])/y),
128
- false,
127
+ false, [],
129
128
  ([[{ value: a }], [{ value: b }], [{ value: c }]]) =>
130
129
  b === 'x'
131
130
  ? new List([new Data(`width="${a}"`), new Data(`height="${c}"`)])
@@ -18,6 +18,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
18
18
  ]))),
19
19
  ']]',
20
20
  false,
21
+ [1 | Backtrack.bracket, 3 | Backtrack.doublebracket],
21
22
  ([, ns], context) => {
22
23
  const { position, range = 0, linebreak = 0 } = context;
23
24
  if (linebreak === 0) {
@@ -69,7 +70,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
69
70
  '',
70
71
  some(inline, ']', [[']', 1]]),
71
72
  str(']'),
72
- true,
73
+ true, [],
73
74
  ([, cs = new List(), ds]) =>
74
75
  cs.import(ds),
75
76
  ([, cs = new List()]) => {
@@ -86,15 +87,14 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
86
87
  return state & State.annotation
87
88
  ? as.import(bs as List<Data<string>>)
88
89
  : undefined;
89
- },
90
- [1 | Backtrack.bracket, 3 | Backtrack.doublebracket])));
90
+ })));
91
91
 
92
92
  // Chicago-Style
93
93
  const abbr: ReferenceParser.AbbrParser = surround(
94
94
  str('^'),
95
95
  union([str(/(?=[A-Z])(?:[0-9A-Za-z]'?|(?:[-.:]|\.?\??,? ?)(?!['\-.:?, ]))+/y)]),
96
96
  /\|?(?=]])|\|/y,
97
- true,
97
+ true, [],
98
98
  ([, ns], context) => {
99
99
  const { source, position, range = 0 } = context;
100
100
  if (!ns) return new List([new Data(''), new Data(source.slice(position - range, source[position - 1] === '|' ? position - 1 : position))]);
@@ -11,7 +11,8 @@ export const remark: RemarkParser = lazy(() => fallback(surround(
11
11
  str(/\[%(?=[ \n])/y),
12
12
  precedence(3, recursion(Recursion.inline,
13
13
  some(union([inline]), /[ \n]%\]/y, [[/[ \n]%\]/y, 3]]))),
14
- close(text, str(`%]`)), true,
14
+ close(text, str(`%]`)),
15
+ true, [],
15
16
  ([as, bs = new List(), cs]) => new List([
16
17
  new Data(html('span', { class: 'remark' }, [
17
18
  html('input', { type: 'checkbox' }),
@@ -13,15 +13,14 @@ export const ruby: RubyParser = lazy(() => bind(
13
13
  dup(surround(
14
14
  '[', text, ']',
15
15
  false,
16
+ [1 | Backtrack.bracket, 3 | Backtrack.ruby],
16
17
  ([, ns]) => {
17
18
  ns && ns.last?.value === '' && ns.pop();
18
19
  return isTightNodeStart(ns) ? ns : undefined;
19
- },
20
- undefined,
21
- [1 | Backtrack.bracket, 3 | Backtrack.ruby])),
20
+ })),
22
21
  dup(surround(
23
22
  '(', text, ')',
24
- false, undefined, undefined,
23
+ false,
25
24
  [1 | Backtrack.bracket, 3 | Backtrack.ruby])),
26
25
  ]),
27
26
  ([{ value: texts }, { value: rubies = undefined } = {}], context) => {
@@ -17,6 +17,7 @@ export const strong: StrongParser = lazy(() => surround(
17
17
  some(inline, blankWith('*')),
18
18
  open(some(inline, '*'), inline),
19
19
  ]))))),
20
- str('**'), false,
20
+ str('**'),
21
+ false, [],
21
22
  ([, bs]) => new List([new Data(html('strong', defrag(unwrap(bs))))]),
22
23
  ([as, bs]) => bs && as.import(bs as List<Data<string>>)));
@@ -12,6 +12,7 @@ export const template: TemplateParser = lazy(() => surround(
12
12
  some(union([bracket, escsource]), '}')),
13
13
  str('}}'),
14
14
  true,
15
+ [3 | Backtrack.doublebracket, 3 | Backtrack.escbracket],
15
16
  ([as, bs = new List(), cs]) => new List([
16
17
  new Data(html('span', { class: 'template' }, defrag(unwrap(as.import(bs as List<Data<string>>).import(cs)))))
17
18
  ]),
@@ -23,25 +24,24 @@ export const template: TemplateParser = lazy(() => surround(
23
24
  ...invalid('template', 'syntax', `Missing the closing symbol "}}"`),
24
25
  },
25
26
  context.source.slice(context.position - context.range!, context.position)))
26
- ]),
27
- [3 | Backtrack.doublebracket, 3 | Backtrack.escbracket]));
27
+ ])));
28
28
 
29
29
  const bracket: TemplateParser.BracketParser = lazy(() => union([
30
- surround(str('('), recursion(Recursion.terminal, some(union([bracket, escsource]), ')')), str(')'), true,
31
- undefined, () => new List(), [3 | Backtrack.escbracket]),
32
- surround(str('['), recursion(Recursion.terminal, some(union([bracket, escsource]), ']')), str(']'), true,
33
- undefined, () => new List(), [3 | Backtrack.escbracket]),
34
- surround(str('{'), recursion(Recursion.terminal, some(union([bracket, escsource]), '}')), str('}'), true,
35
- undefined, () => new List(), [3 | Backtrack.escbracket]),
30
+ surround(str('('), recursion(Recursion.terminal, some(union([bracket, escsource]), ')')), str(')'),
31
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
32
+ surround(str('['), recursion(Recursion.terminal, some(union([bracket, escsource]), ']')), str(']'),
33
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
34
+ surround(str('{'), recursion(Recursion.terminal, some(union([bracket, escsource]), '}')), str('}'),
35
+ true, [3 | Backtrack.escbracket], undefined, () => new List()),
36
36
  surround(
37
37
  str('"'),
38
38
  precedence(2, recursion(Recursion.terminal, some(escsource, /["\n]/y, [['"', 2], ['\n', 3]]))),
39
39
  str('"'),
40
40
  true,
41
+ [3 | Backtrack.escbracket],
41
42
  ([as, bs = new List(), cs], context) =>
42
43
  context.linebreak === 0
43
44
  ? as.import(bs as List<Data<string>>).import(cs)
44
45
  : (context.position -= 1, as.import(bs as List<Data<string>>)),
45
- ([as, bs]) => bs && as.import(bs as List<Data<string>>),
46
- [3 | Backtrack.escbracket]),
46
+ ([as, bs]) => bs && as.import(bs as List<Data<string>>)),
47
47
  ]));
@@ -5,6 +5,7 @@ import { reference } from './inline/reference';
5
5
  import { template } from './inline/template';
6
6
  import { remark } from './inline/remark';
7
7
  import { extension } from './inline/extension';
8
+ import { label } from './inline/extension/label';
8
9
  import { textlink } from './inline/link';
9
10
  import { ruby } from './inline/ruby';
10
11
  import { html } from './inline/html';
@@ -94,7 +95,7 @@ export const inline: InlineParser = lazy(() => union([
94
95
  return html(input);
95
96
  case '$':
96
97
  if (source[position + 1] === '{') return math(input);
97
- return extension(input)
98
+ return label(input)
98
99
  || math(input);
99
100
  case '+':
100
101
  if (source[position + 1] === '+') return insertion(input);
@@ -13,6 +13,7 @@ export const MAX_SEGMENT_SIZE = 100_000; // 100,000 bytes (Max value size of FDB
13
13
  export const MAX_INPUT_SIZE = MAX_SEGMENT_SIZE * 10;
14
14
 
15
15
  const parser: SegmentParser = union([
16
+ some(emptyline),
16
17
  input => {
17
18
  const { context: { source, position } } = input;
18
19
  if (position === source.length) return;
@@ -35,8 +36,7 @@ const parser: SegmentParser = union([
35
36
  return extension(input);
36
37
  }
37
38
  },
38
- some(contentline, MAX_SEGMENT_SIZE + 1),
39
- some(emptyline, MAX_SEGMENT_SIZE + 1),
39
+ some(contentline),
40
40
  ]) as any;
41
41
 
42
42
  export function* segment(source: string): Generator<string, undefined, undefined> {
@@ -14,10 +14,6 @@ export const escsource: EscapableSourceParser = ({ context }) => {
14
14
  consume(1, context);
15
15
  context.position += 1;
16
16
  switch (char) {
17
- case '\r':
18
- assert(!source.includes('\r', position + 1));
19
- consume(-1, context);
20
- return new List();
21
17
  case Command.Escape:
22
18
  consume(1, context);
23
19
  context.position += 1;
@@ -33,6 +29,9 @@ export const escsource: EscapableSourceParser = ({ context }) => {
33
29
  context.position += 1;
34
30
  return new List([new Data(source.slice(position, position + 2))]);
35
31
  }
32
+ case '\r':
33
+ consume(-1, context);
34
+ return new List();
36
35
  case '\n':
37
36
  context.linebreak ||= source.length - position;
38
37
  return new List([new Data(html('br'))]);
@@ -8,6 +8,7 @@ export const anyline: AnyLineParser = input => {
8
8
  context.position = source.indexOf('\n', position) + 1 || source.length;
9
9
  return new List();
10
10
  };
11
+
11
12
  const regEmptyline = /[^\S\n]*(?:$|\n)/y;
12
13
  export const emptyline: EmptyLineParser = input => {
13
14
  const { context } = input;
@@ -21,6 +22,7 @@ export const emptyline: EmptyLineParser = input => {
21
22
  context.position = i;
22
23
  return new List();
23
24
  };
25
+
24
26
  const regContentline = /[^\S\n]*\S[^\n]*(?:$|\n)/y;
25
27
  export const contentline: ContentLineParser = input => {
26
28
  const { context } = input;
@@ -33,4 +35,4 @@ export const contentline: ContentLineParser = input => {
33
35
  if (i === 0) return;
34
36
  context.position = i;
35
37
  return new List();
36
- }
38
+ };
@@ -1,7 +1,7 @@
1
- import { TextParser, TxtParser, LinebreakParser } from '../source';
1
+ import { TextParser, TxtParser } from '../source';
2
2
  import { Command } from '../context';
3
3
  import { List, Data } from '../../combinator/data/parser';
4
- import { union, consume, focus } from '../../combinator';
4
+ import { union, consume } from '../../combinator';
5
5
  import { html } from 'typed-dom/dom';
6
6
 
7
7
  //const delimiter = /(?=[\\!@#$&"`\[\](){}<>()[]{}*%|\r\n]|([+~=])\1|\/{3}|\s(?:\\?(?:$|\s)|[$%])|:\/\/)/g;
@@ -15,10 +15,6 @@ export const text: TextParser = input => {
15
15
  consume(1, context);
16
16
  context.position += 1;
17
17
  switch (char) {
18
- case '\r':
19
- assert(!source.includes('\r', position + 1));
20
- consume(-1, context);
21
- return new List();
22
18
  case Command.Escape:
23
19
  case '\\':
24
20
  switch (source[position + 1]) {
@@ -32,6 +28,9 @@ export const text: TextParser = input => {
32
28
  context.position += 1;
33
29
  return new List([new Data(source.slice(position + 1, context.position))]);
34
30
  }
31
+ case '\r':
32
+ consume(-1, context);
33
+ return new List();
35
34
  case '\n':
36
35
  context.linebreak ||= source.length - position;
37
36
  return new List([new Data(html('br'))]);
@@ -64,10 +63,6 @@ export const txt: TxtParser = union([
64
63
  text,
65
64
  ]) as TxtParser;
66
65
 
67
- export const linebreak: LinebreakParser = focus(/[\r\n]/y, union([
68
- text,
69
- ])) as LinebreakParser;
70
-
71
66
  export function canSkip(source: string, position: number): boolean {
72
67
  assert(position < source.length);
73
68
  if (!isWhitespace(source[position], false)) return false;
@@ -185,12 +180,12 @@ export function backToEmailHead(source: string, position: number, index: number)
185
180
  ? delim
186
181
  : index;
187
182
  }
188
- function isAlphanumeric(char: string): boolean {
183
+ export function isAlphanumeric(char: string): boolean {
189
184
  assert(char.length === 1);
190
185
  if (char < '0' || '\x7F' < char) return false;
191
186
  return '0' <= char && char <= '9'
192
- || 'a' <= char && char <= 'z'
193
- || 'A' <= char && char <= 'Z';
187
+ || 'A' <= char && char <= 'Z'
188
+ || 'a' <= char && char <= 'z';
194
189
  }
195
190
 
196
191
  //const dict = new class {
@@ -14,14 +14,12 @@ export const unescsource: UnescapableSourceParser = ({ context }) => {
14
14
  consume(1, context);
15
15
  context.position += 1;
16
16
  switch (char) {
17
- case '\r':
18
- assert(!source.includes('\r', position + 1));
19
- consume(-1, context);
20
- return new List();
21
17
  case Command.Escape:
22
18
  consume(1, context);
23
19
  context.position += 1;
24
20
  return new List([new Data(source.slice(position + 1, position + 2))]);
21
+ case '\r':
22
+ return new List();
25
23
  case '\n':
26
24
  context.linebreak ||= source.length - position;
27
25
  return new List([new Data(html('br'))]);
@@ -3,7 +3,6 @@ import { MarkdownParser } from '../../markdown';
3
3
  import SourceParser = MarkdownParser.SourceParser;
4
4
  export import TextParser = SourceParser.TextParser;
5
5
  export import TxtParser = SourceParser.TxtParser;
6
- export import LinebreakParser = SourceParser.LinebreakParser;
7
6
  export import EscapableSourceParser = SourceParser.EscapableSourceParser;
8
7
  export import UnescapableSourceParser = SourceParser.UnescapableSourceParser;
9
8
  export import StrParser = SourceParser.StrParser;
@@ -11,7 +10,7 @@ export import ContentLineParser = SourceParser.ContentLineParser;
11
10
  export import EmptyLineParser = SourceParser.EmptyLineParser;
12
11
  export import AnyLineParser = SourceParser.AnyLineParser;
13
12
 
14
- export { text, txt, linebreak } from './source/text';
13
+ export { text, txt } from './source/text';
15
14
  export { escsource } from './source/escapable';
16
15
  export { unescsource } from './source/unescapable';
17
16
  export { str, strs } from './source/str';