securemark 0.292.0 → 0.293.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 (119) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/index.js +395 -287
  3. package/markdown.d.ts +22 -39
  4. package/package.json +1 -1
  5. package/src/combinator/control/constraint/contract.ts +6 -15
  6. package/src/combinator/control/manipulation/clear.ts +3 -4
  7. package/src/combinator/control/manipulation/fence.ts +3 -1
  8. package/src/combinator/control/manipulation/indent.ts +5 -11
  9. package/src/combinator/control/manipulation/match.ts +3 -2
  10. package/src/combinator/control/manipulation/recovery.ts +1 -1
  11. package/src/combinator/control/manipulation/scope.ts +3 -10
  12. package/src/combinator/control/manipulation/surround.ts +4 -24
  13. package/src/combinator/data/parser/context/delimiter.ts +10 -9
  14. package/src/combinator/data/parser/context.ts +31 -0
  15. package/src/combinator/data/parser/inits.ts +1 -1
  16. package/src/combinator/data/parser/sequence.ts +1 -1
  17. package/src/combinator/data/parser/some.test.ts +1 -1
  18. package/src/combinator/data/parser/some.ts +4 -5
  19. package/src/combinator/data/parser.ts +0 -1
  20. package/src/parser/api/parse.test.ts +16 -8
  21. package/src/parser/api/parse.ts +1 -2
  22. package/src/parser/autolink.test.ts +7 -7
  23. package/src/parser/autolink.ts +2 -4
  24. package/src/parser/block/blockquote.test.ts +1 -1
  25. package/src/parser/block/blockquote.ts +6 -6
  26. package/src/parser/block/codeblock.ts +1 -1
  27. package/src/parser/block/dlist.test.ts +1 -1
  28. package/src/parser/block/dlist.ts +6 -6
  29. package/src/parser/block/extension/aside.ts +1 -1
  30. package/src/parser/block/extension/example.ts +1 -1
  31. package/src/parser/block/extension/fig.ts +3 -3
  32. package/src/parser/block/extension/figbase.ts +1 -1
  33. package/src/parser/block/extension/figure.ts +4 -4
  34. package/src/parser/block/extension/message.ts +1 -1
  35. package/src/parser/block/extension/placeholder.ts +1 -1
  36. package/src/parser/block/extension/table.test.ts +1 -1
  37. package/src/parser/block/extension/table.ts +15 -15
  38. package/src/parser/block/extension.ts +2 -2
  39. package/src/parser/block/heading.test.ts +1 -1
  40. package/src/parser/block/heading.ts +2 -2
  41. package/src/parser/block/ilist.test.ts +3 -3
  42. package/src/parser/block/ilist.ts +4 -4
  43. package/src/parser/block/mathblock.ts +1 -1
  44. package/src/parser/block/mediablock.ts +1 -1
  45. package/src/parser/block/olist.test.ts +16 -14
  46. package/src/parser/block/olist.ts +12 -12
  47. package/src/parser/block/pagebreak.ts +1 -1
  48. package/src/parser/block/paragraph.test.ts +2 -2
  49. package/src/parser/block/paragraph.ts +2 -2
  50. package/src/parser/block/reply/cite.ts +4 -4
  51. package/src/parser/block/reply/quote.ts +5 -4
  52. package/src/parser/block/reply.ts +3 -3
  53. package/src/parser/block/sidefence.ts +3 -3
  54. package/src/parser/block/table.ts +10 -10
  55. package/src/parser/block/ulist.test.ts +8 -7
  56. package/src/parser/block/ulist.ts +6 -6
  57. package/src/parser/block.ts +48 -15
  58. package/src/parser/header.ts +3 -3
  59. package/src/parser/inline/autolink/account.test.ts +8 -7
  60. package/src/parser/inline/autolink/account.ts +11 -8
  61. package/src/parser/inline/autolink/anchor.test.ts +1 -1
  62. package/src/parser/inline/autolink/anchor.ts +21 -17
  63. package/src/parser/inline/autolink/channel.test.ts +8 -8
  64. package/src/parser/inline/autolink/channel.ts +40 -15
  65. package/src/parser/inline/autolink/email.test.ts +15 -15
  66. package/src/parser/inline/autolink/email.ts +5 -7
  67. package/src/parser/inline/autolink/hashnum.test.ts +4 -9
  68. package/src/parser/inline/autolink/hashnum.ts +8 -4
  69. package/src/parser/inline/autolink/hashtag.test.ts +9 -10
  70. package/src/parser/inline/autolink/hashtag.ts +9 -6
  71. package/src/parser/inline/autolink/url.test.ts +72 -74
  72. package/src/parser/inline/autolink/url.ts +19 -23
  73. package/src/parser/inline/autolink.ts +21 -24
  74. package/src/parser/inline/bracket.ts +3 -3
  75. package/src/parser/inline/code.ts +2 -2
  76. package/src/parser/inline/deletion.test.ts +2 -2
  77. package/src/parser/inline/deletion.ts +1 -1
  78. package/src/parser/inline/emphasis.test.ts +5 -5
  79. package/src/parser/inline/emphasis.ts +2 -7
  80. package/src/parser/inline/emstrong.test.ts +14 -14
  81. package/src/parser/inline/emstrong.ts +4 -16
  82. package/src/parser/inline/extension/index.test.ts +5 -3
  83. package/src/parser/inline/extension/index.ts +4 -7
  84. package/src/parser/inline/extension/indexer.test.ts +1 -1
  85. package/src/parser/inline/extension/indexer.ts +3 -3
  86. package/src/parser/inline/extension/label.ts +1 -1
  87. package/src/parser/inline/extension/placeholder.ts +1 -1
  88. package/src/parser/inline/html.test.ts +2 -2
  89. package/src/parser/inline/html.ts +14 -14
  90. package/src/parser/inline/htmlentity.ts +1 -1
  91. package/src/parser/inline/insertion.test.ts +2 -2
  92. package/src/parser/inline/insertion.ts +1 -1
  93. package/src/parser/inline/italic.test.ts +5 -5
  94. package/src/parser/inline/italic.ts +1 -1
  95. package/src/parser/inline/link.ts +15 -15
  96. package/src/parser/inline/mark.test.ts +5 -5
  97. package/src/parser/inline/mark.ts +1 -1
  98. package/src/parser/inline/math.test.ts +6 -6
  99. package/src/parser/inline/math.ts +7 -11
  100. package/src/parser/inline/media.ts +9 -9
  101. package/src/parser/inline/reference.test.ts +4 -4
  102. package/src/parser/inline/reference.ts +4 -4
  103. package/src/parser/inline/remark.test.ts +7 -7
  104. package/src/parser/inline/remark.ts +2 -2
  105. package/src/parser/inline/ruby.ts +3 -1
  106. package/src/parser/inline/shortmedia.ts +6 -9
  107. package/src/parser/inline/strong.test.ts +5 -5
  108. package/src/parser/inline/strong.ts +2 -7
  109. package/src/parser/inline.test.ts +13 -11
  110. package/src/parser/source/escapable.test.ts +6 -6
  111. package/src/parser/source/escapable.ts +29 -5
  112. package/src/parser/source/line.ts +28 -4
  113. package/src/parser/source/str.ts +5 -27
  114. package/src/parser/source/text.test.ts +27 -27
  115. package/src/parser/source/text.ts +58 -6
  116. package/src/parser/source/unescapable.test.ts +6 -6
  117. package/src/parser/source/unescapable.ts +27 -3
  118. package/src/parser/util.ts +3 -3
  119. package/src/parser/visibility.ts +14 -9
@@ -5,7 +5,7 @@ import { union, inits, tails, some, creation, recursion, precedence, constraint,
5
5
  import { unsafelink, uri, option as linkoption, resolve, decode } from './link';
6
6
  import { attributes } from './html';
7
7
  import { unsafehtmlentity } from './htmlentity';
8
- import { txt, linebreak, str } from '../source';
8
+ import { txt, str } from '../source';
9
9
  import { invalid } from '../util';
10
10
  import { ReadonlyURL } from 'spica/url';
11
11
  import { unshift, push } from 'spica/array';
@@ -19,7 +19,7 @@ const optspec = {
19
19
  } as const;
20
20
  Object.setPrototypeOf(optspec, null);
21
21
 
22
- export const media: MediaParser = lazy(() => constraint(State.media, validate(['![', '!{'], creation(10, open(
22
+ export const media: MediaParser = lazy(() => constraint(State.media, validate(/![[{]/y, creation(10, open(
23
23
  '!',
24
24
  bind(verify(fmap(tails([
25
25
  dup(surround(
@@ -38,9 +38,9 @@ export const media: MediaParser = lazy(() => constraint(State.media, validate(['
38
38
  undefined,
39
39
  [3 | Backtrack.escbracket])),
40
40
  dup(surround(
41
- /^{(?![{}])/,
41
+ /{(?![{}])/y,
42
42
  inits([uri, some(option)]),
43
- /^[^\S\n]*}/,
43
+ /[^\S\n]*}/y,
44
44
  false,
45
45
  undefined,
46
46
  ([as, bs], context) => {
@@ -107,9 +107,9 @@ export const media: MediaParser = lazy(() => constraint(State.media, validate(['
107
107
  }))))));
108
108
 
109
109
  export const linemedia: MediaParser.LineMediaParser = surround(
110
- linebreak,
110
+ /(?<=^|[\r\n])/y,
111
111
  union([media]),
112
- /^(?=[^\S\n]*(?:$|\n))/);
112
+ /(?=[^\S\n]*(?:$|\n))/y);
113
113
 
114
114
  const bracket: MediaParser.TextParser.BracketParser = lazy(() => recursion(Recursion.terminal, union([
115
115
  surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'), true,
@@ -124,9 +124,9 @@ const bracket: MediaParser.TextParser.BracketParser = lazy(() => recursion(Recur
124
124
 
125
125
  const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
126
126
  surround(
127
- open(/^[^\S\n]+/, str(/^[1-9][0-9]*/)),
128
- str(/^[x:]/),
129
- str(/^[1-9][0-9]*(?=[^\S\n]|})/),
127
+ open(/[^\S\n]+/y, str(/[1-9][0-9]*/y)),
128
+ str(/[x:]/y),
129
+ str(/[1-9][0-9]*(?=[^\S\n]|})/y),
130
130
  false,
131
131
  ([[a], [b], [c]]) => [
132
132
  b === 'x'
@@ -69,7 +69,7 @@ describe('Unit: parser/inline/reference', () => {
69
69
  assert.deepStrictEqual(inspect(parser('[[^A ]]'), ctx), [['<sup class="reference" data-abbr="A"><span></span></sup>'], '']);
70
70
  assert.deepStrictEqual(inspect(parser('[[^A ]]'), ctx), [['<sup class="invalid"><span>^A</span></sup>'], '']);
71
71
  assert.deepStrictEqual(inspect(parser('[[^A B]]'), ctx), [['<sup class="reference" data-abbr="A B"><span></span></sup>'], '']);
72
- assert.deepStrictEqual(inspect(parser('[[^A B]]'), ctx), [['<sup class="invalid"><span>^A B</span></sup>'], '']);
72
+ assert.deepStrictEqual(inspect(parser('[[^A B]]'), ctx), [['<sup class="invalid"><span>^A B</span></sup>'], '']);
73
73
  assert.deepStrictEqual(inspect(parser('[[^A|]]'), ctx), [['<sup class="reference" data-abbr="A"><span></span></sup>'], '']);
74
74
  assert.deepStrictEqual(inspect(parser('[[^A,|]]'), ctx), [['<sup class="reference" data-abbr="A,"><span></span></sup>'], '']);
75
75
  assert.deepStrictEqual(inspect(parser('[[^A |]]'), ctx), [['<sup class="reference" data-abbr="A"><span></span></sup>'], '']);
@@ -77,11 +77,11 @@ describe('Unit: parser/inline/reference', () => {
77
77
  assert.deepStrictEqual(inspect(parser('[[^A|b]]'), ctx), [['<sup class="reference" data-abbr="A"><span>b</span></sup>'], '']);
78
78
  assert.deepStrictEqual(inspect(parser('[[^A|b ]]'), ctx), [['<sup class="reference" data-abbr="A"><span>b</span></sup>'], '']);
79
79
  assert.deepStrictEqual(inspect(parser('[[^A|b ]]'), ctx), [['<sup class="reference" data-abbr="A"><span>b</span></sup>'], '']);
80
- assert.deepStrictEqual(inspect(parser('[[^A|<wbr>]]'), ctx), [['<sup class="reference" data-abbr="A"><span></span></sup>'], '']);
81
- assert.deepStrictEqual(inspect(parser('[[^A|<wbr>b]]'), ctx), [['<sup class="reference" data-abbr="A"><span>b</span></sup>'], '']);
82
80
  assert.deepStrictEqual(inspect(parser('[[^A| ]]'), ctx), [['<sup class="reference" data-abbr="A"><span></span></sup>'], '']);
83
81
  assert.deepStrictEqual(inspect(parser('[[^A| b]]'), ctx), [['<sup class="reference" data-abbr="A"><span>b</span></sup>'], '']);
84
- assert.deepStrictEqual(inspect(parser('[[^A| ]]'), ctx), [['<sup class="reference" data-abbr="A"><span></span></sup>'], '']);
82
+ assert.deepStrictEqual(inspect(parser('[[^A| ]]'), ctx), undefined);
83
+ assert.deepStrictEqual(inspect(parser('[[^A|<wbr>]]'), ctx), undefined);
84
+ assert.deepStrictEqual(inspect(parser('[[^A|<wbr>b]]'), ctx), [['<sup class="reference" data-abbr="A"><span>b</span></sup>'], '']);
85
85
  assert.deepStrictEqual(inspect(parser('[[^A|^]]'), ctx), [['<sup class="reference" data-abbr="A"><span>^</span></sup>'], '']);
86
86
  assert.deepStrictEqual(inspect(parser('[[^A|^B]]'), ctx), [['<sup class="reference" data-abbr="A"><span>^B</span></sup>'], '']);
87
87
  assert.deepStrictEqual(inspect(parser('[[^1]]'), ctx), [['<sup class="invalid"><span>^1</span></sup>'], '']);
@@ -5,7 +5,7 @@ import { union, subsequence, some, precedence, state, constraint, surround, isBa
5
5
  import { inline } from '../inline';
6
6
  import { textlink } from './link';
7
7
  import { str } from '../source';
8
- import { blank, trimBlankStart, trimBlankNodeEnd } from '../visibility';
8
+ import { trimBlankStart, trimBlankNodeEnd } from '../visibility';
9
9
  import { html, defrag } from 'typed-dom/dom';
10
10
  import { unshift, push } from 'spica/array';
11
11
  import { invalid } from '../util';
@@ -93,13 +93,13 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
93
93
  // Chicago-Style
94
94
  const abbr: ReferenceParser.AbbrParser = surround(
95
95
  str('^'),
96
- union([str(/^(?=[A-Z])(?:[0-9A-Za-z]'?|(?:[-.:]|\.?\??,? ?)(?!['\-.:?, ]))+/)]),
97
- /^\|?(?=]])|^\|/,
96
+ union([str(/(?=[A-Z])(?:[0-9A-Za-z]'?|(?:[-.:]|\.?\??,? ?)(?!['\-.:?, ]))+/y)]),
97
+ /\|?(?=]])|\|/y,
98
98
  true,
99
99
  ([, ns], context) => {
100
100
  const { source, position, range = 0 } = context;
101
101
  if (!ns) return [['', source.slice(position - range, source[position - 1] === '|' ? position - 1 : position)]];
102
- context.position += source.slice(position).match(blank.start)?.[0].length ?? 0;
102
+ context.position += source[position] === ' ' ? 1 : 0;
103
103
  return [[Command.Separator, ns[0].trimEnd()]];
104
104
  },
105
105
  (_, context) => {
@@ -15,16 +15,16 @@ describe('Unit: parser/inline/remark', () => {
15
15
  assert.deepStrictEqual(inspect(parser('[%[%'), ctx), undefined);
16
16
  assert.deepStrictEqual(inspect(parser('[%a%]'), ctx), undefined);
17
17
  assert.deepStrictEqual(inspect(parser('[%a b%]'), ctx), undefined);
18
- assert.deepStrictEqual(inspect(parser('[% '), ctx), [['[%', ' '], '']);
19
- assert.deepStrictEqual(inspect(parser('[% \n a'), ctx), [['[%', ' ', '<br>', ' ', 'a'], '']);
18
+ assert.deepStrictEqual(inspect(parser('[% '), ctx), [['[%'], '']);
19
+ assert.deepStrictEqual(inspect(parser('[% \n a'), ctx), [['[%', '<br>', ' ', 'a'], '']);
20
20
  assert.deepStrictEqual(inspect(parser('[%%]'), ctx), undefined);
21
21
  assert.deepStrictEqual(inspect(parser('[% [%'), ctx), [['[%', ' ', '[', '%'], '']);
22
- assert.deepStrictEqual(inspect(parser('[% [% '), ctx), [['[%', ' ', '[%', ' '], '']);
22
+ assert.deepStrictEqual(inspect(parser('[% [% '), ctx), [['[%', ' ', '[%'], '']);
23
23
  assert.deepStrictEqual(inspect(parser('[% [% a'), ctx), [['[%', ' ', '[%', ' ', 'a'], '']);
24
24
  assert.deepStrictEqual(inspect(parser('[% [% a %]'), ctx), [['[%', ' ', '<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], '']);
25
25
  assert.deepStrictEqual(inspect(parser('[% a[%'), ctx), [['[%', ' ', 'a', '[', '%'], '']);
26
26
  assert.deepStrictEqual(inspect(parser('[% a [%'), ctx), [['[%', ' ', 'a', ' ', '[', '%'], '']);
27
- assert.deepStrictEqual(inspect(parser('[% a [% '), ctx), [['[%', ' ', 'a', ' ', '[%', ' '], '']);
27
+ assert.deepStrictEqual(inspect(parser('[% a [% '), ctx), [['[%', ' ', 'a', ' ', '[%'], '']);
28
28
  assert.deepStrictEqual(inspect(parser('[% a [% b'), ctx), [['[%', ' ', 'a', ' ', '[%', ' ', 'b'], '']);
29
29
  assert.deepStrictEqual(inspect(parser('[% a [%% b'), ctx), [['[%', ' ', 'a', ' ', '[%%', ' ', 'b'], '']);
30
30
  assert.deepStrictEqual(inspect(parser('[%% a [% b'), ctx), [['[%%', ' ', 'a', ' ', '[%', ' ', 'b'], '']);
@@ -40,10 +40,10 @@ describe('Unit: parser/inline/remark', () => {
40
40
 
41
41
  it('basic', () => {
42
42
  assert.deepStrictEqual(inspect(parser('[% %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% %]</span></span>'], '']);
43
- assert.deepStrictEqual(inspect(parser('[% %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% %]</span></span>'], '']);
44
- assert.deepStrictEqual(inspect(parser('[% %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% %]</span></span>'], '']);
43
+ assert.deepStrictEqual(inspect(parser('[% %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% %]</span></span>'], '']);
44
+ assert.deepStrictEqual(inspect(parser('[% %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% %]</span></span>'], '']);
45
45
  assert.deepStrictEqual(inspect(parser('[% a %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], '']);
46
- assert.deepStrictEqual(inspect(parser('[% a %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], '']);
46
+ assert.deepStrictEqual(inspect(parser('[% a %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], '']);
47
47
  assert.deepStrictEqual(inspect(parser('[% a b %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a b %]</span></span>'], '']);
48
48
  assert.deepStrictEqual(inspect(parser('[% a\nb %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a<br>b %]</span></span>'], '']);
49
49
  assert.deepStrictEqual(inspect(parser('[% a %] %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], ' %]']);
@@ -8,13 +8,13 @@ import { unshift, push } from 'spica/array';
8
8
  import { html, defrag } from 'typed-dom/dom';
9
9
 
10
10
  export const remark: RemarkParser = lazy(() => match(
11
- /^\[(%+)\s/,
11
+ /\[(%+)\s/y,
12
12
  memoize(
13
13
  ([, fence]) =>
14
14
  surround(
15
15
  str(`[${fence}`),
16
16
  precedence(4, recursion(Recursion.inline,
17
- some(union([inline]), new RegExp(String.raw`^\s+${fence}\]`), [[new RegExp(String.raw`^\s+${fence}\]`), 4]]))),
17
+ some(union([inline]), new RegExp(String.raw`\s+${fence}\]`, 'y'), [[new RegExp(String.raw`\s+${fence}\]`, 'y'), 4]]))),
18
18
  close(some(text, '%'), str(`${fence}]`)), true,
19
19
  ([as, bs = [], cs]) => [[
20
20
  html('span', { class: 'remark' }, [
@@ -67,8 +67,9 @@ const text: RubyParser.TextParser = input => {
67
67
  const { source } = context;
68
68
  const acc = [''];
69
69
  let state = false;
70
+ context.sequential = true;
70
71
  for (let { position } = context; position < source.length; position = context.position) {
71
- if (!/^(?:\\[^\n]|[^\\[\](){}<>"`$#:^|\n])/.test(source.slice(position, position + 2))) break;
72
+ if (!/(?:\\[^\n]|[^\\[\](){}<>"`$#:^|\n])/y.test(source.slice(position, position + 2))) break;
72
73
  assert(source[position] !== '\n');
73
74
  switch (source[position]) {
74
75
  case '&': {
@@ -91,6 +92,7 @@ const text: RubyParser.TextParser = input => {
91
92
  }
92
93
  }
93
94
  }
95
+ context.sequential = false;
94
96
  state ||= acc.at(-1)!.trimStart() !== '';
95
97
  return state
96
98
  ? [acc]
@@ -3,7 +3,6 @@ import { State } from '../context';
3
3
  import { union, constraint, focus, rewrite, open, convert } from '../../combinator';
4
4
  import { url } from './autolink/url';
5
5
  import { media } from './media';
6
- import { linebreak } from '../source';
7
6
 
8
7
  export const shortmedia: ShortMediaParser = constraint(State.media, rewrite(
9
8
  open('!', url),
@@ -12,11 +11,9 @@ export const shortmedia: ShortMediaParser = constraint(State.media, rewrite(
12
11
  union([media]),
13
12
  false)));
14
13
 
15
- export const lineshortmedia: ShortMediaParser.LineShortMediaParser = open(
16
- linebreak,
17
- focus(
18
- /^!https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/,
19
- convert(
20
- source => `!{ ${source.slice(1)} }`,
21
- union([media]),
22
- false)));
14
+ export const lineshortmedia: ShortMediaParser.LineShortMediaParser = focus(
15
+ /(?<=^|[\r\n])!?https?:\/\/\S+(?=[^\S\n]*(?:$|\n))/y,
16
+ convert(
17
+ source => `!{ ${source.slice(1)} }`,
18
+ union([media]),
19
+ false));
@@ -11,11 +11,11 @@ describe('Unit: parser/inline/strong', () => {
11
11
  it('invalid', () => {
12
12
  assert.deepStrictEqual(inspect(parser('**'), ctx), undefined);
13
13
  assert.deepStrictEqual(inspect(parser('**a'), ctx), [['**', 'a'], '']);
14
- assert.deepStrictEqual(inspect(parser('**a **'), ctx), [['**', 'a'], ' **']);
15
- assert.deepStrictEqual(inspect(parser('**a **'), ctx), [['**', 'a', ' '], ' **']);
16
- assert.deepStrictEqual(inspect(parser('**a\n**'), ctx), [['**', 'a'], '\n**']);
17
- assert.deepStrictEqual(inspect(parser('**a\\ **'), ctx), [['**', 'a'], '\\ **']);
18
- assert.deepStrictEqual(inspect(parser('**a\\\n**'), ctx), [['**', 'a'], '\\\n**']);
14
+ assert.deepStrictEqual(inspect(parser('**a **'), ctx), [['**', 'a', ' ', '**'], '']);
15
+ assert.deepStrictEqual(inspect(parser('**a **'), ctx), [['**', 'a', ' ', '**'], '']);
16
+ assert.deepStrictEqual(inspect(parser('**a\n**'), ctx), [['**', 'a', '<br>', '**'], '']);
17
+ assert.deepStrictEqual(inspect(parser('**a\\ **'), ctx), [['**', 'a', ' ', '**'], '']);
18
+ assert.deepStrictEqual(inspect(parser('**a\\\n**'), ctx), [['**', 'a', '<br>', '**'], '']);
19
19
  assert.deepStrictEqual(inspect(parser('**a*'), ctx), [['**', 'a'], '*']);
20
20
  assert.deepStrictEqual(inspect(parser('**a*b**'), ctx), [['**', 'a', '<em>b</em>'], '*']);
21
21
  assert.deepStrictEqual(inspect(parser('** **'), ctx), undefined);
@@ -2,7 +2,6 @@ import { StrongParser } from '../inline';
2
2
  import { Recursion } from '../context';
3
3
  import { union, some, recursion, precedence, surround, open, lazy } from '../../combinator';
4
4
  import { inline } from '../inline';
5
- import { emstrong } from './emstrong';
6
5
  import { emphasis } from './emphasis';
7
6
  import { str } from '../source';
8
7
  import { tightStart, blankWith } from '../visibility';
@@ -10,16 +9,12 @@ import { unshift } from 'spica/array';
10
9
  import { html, defrag } from 'typed-dom/dom';
11
10
 
12
11
  export const strong: StrongParser = lazy(() => surround(
13
- str('**', '*'),
12
+ str(/\*\*(?!\*)/y),
14
13
  precedence(0, recursion(Recursion.inline,
15
14
  tightStart(some(union([
16
15
  emphasis,
17
16
  some(inline, blankWith('*')),
18
- open(some(inline, '*'), union([
19
- emstrong,
20
- strong,
21
- emphasis,
22
- ])),
17
+ open(some(inline, '*'), inline),
23
18
  ]))))),
24
19
  str('**'), false,
25
20
  ([, bs]) => [[html('strong', defrag(bs))]],
@@ -80,7 +80,7 @@ describe('Unit: parser/inline', () => {
80
80
  assert.deepStrictEqual(inspect(parser('*a((b))*'), ctx), [['<em>a<sup class="annotation"><span>b</span></sup></em>'], '']);
81
81
  assert.deepStrictEqual(inspect(parser('*++ ++*'), ctx), [['<em><ins> </ins></em>'], '']);
82
82
  assert.deepStrictEqual(inspect(parser('*++ a ++*'), ctx), [['<em><ins> a </ins></em>'], '']);
83
- assert.deepStrictEqual(inspect(parser('*++ a ++*'), ctx), [['<em><ins> a </ins></em>'], '']);
83
+ assert.deepStrictEqual(inspect(parser('*++ a ++*'), ctx), [['<em><ins> a </ins></em>'], '']);
84
84
  assert.deepStrictEqual(inspect(parser('*<bdi>`a`</bdi>*'), ctx), [['<em><bdi><code data-src="`a`">a</code></bdi></em>'], '']);
85
85
  assert.deepStrictEqual(inspect(parser('*a"\nb*'), ctx), [['*', 'a', '"', '<br>', 'b', '*'], '']);
86
86
  assert.deepStrictEqual(inspect(parser('*a"\n"("b*'), ctx), [['<em>a"<br>"("b</em>'], '']);
@@ -166,7 +166,7 @@ describe('Unit: parser/inline', () => {
166
166
  assert.deepStrictEqual(inspect(parser('"[% "*"* %]'), ctx), [['"', '<span class="remark"><input type="checkbox"><span>[% "*"* %]</span></span>'], '']);
167
167
  assert.deepStrictEqual(inspect(parser('"{{""}}'), ctx), [['"', '{', '{', '"', '"', '}', '}'], '']);
168
168
  assert.deepStrictEqual(inspect(parser('[#http://host/(<bdi>)]</bdi>'), ctx), [['<a class="index" href="#index::http://host/(&lt;bdi&gt;)">http://host/(&lt;bdi&gt;)</a>', '<', '/', 'bdi', '>'], '']);
169
- assert.deepStrictEqual(inspect(parser('[#@a/http://host/(<bdi>)]</bdi>'), ctx), [[ '[', '#@a/http', ':', '/', '/', 'host', '/', '(', '<bdi>)]</bdi>' ], '']);
169
+ assert.deepStrictEqual(inspect(parser('[#@a/http://host/(<bdi>)]</bdi>'), ctx), [['<a class="index" href="#index::@a/http://host/(&lt;bdi&gt;)">@a/http://host/(&lt;bdi&gt;)</a>', '<', '/', 'bdi', '>'], '']);
170
170
  assert.deepStrictEqual(inspect(parser('[#a|<bdi>]</bdi>'), ctx), [['[', '<a class="hashtag" href="/hashtags/a">#a</a>', '|', '<bdi>]</bdi>'], '']);
171
171
  assert.deepStrictEqual(inspect(parser('[[#a|<bdi>]</bdi>'), ctx), [['[', '[', '<a class="hashtag" href="/hashtags/a">#a</a>', '|', '<bdi>]</bdi>'], '']);
172
172
  });
@@ -209,6 +209,7 @@ describe('Unit: parser/inline', () => {
209
209
 
210
210
  it('account', () => {
211
211
  assert.deepStrictEqual(inspect(parser('@a'), ctx), [['<a class="account" href="/@a">@a</a>'], '']);
212
+ assert.deepStrictEqual(inspect(parser('@http://host'), ctx), [['@http', ':', '/', '/', 'host'], '']);
212
213
  assert.deepStrictEqual(inspect(parser('_@a'), ctx), [['_', '<a class="account" href="/@a">@a</a>'], '']);
213
214
  assert.deepStrictEqual(inspect(parser('_@a_'), ctx), [['_', '<a class="account" href="/@a">@a</a>', '_'], '']);
214
215
  assert.deepStrictEqual(inspect(parser('*@a*'), ctx), [['<em><a class="account" href="/@a">@a</a></em>'], '']);
@@ -217,21 +218,22 @@ describe('Unit: parser/inline', () => {
217
218
  });
218
219
 
219
220
  it('hashtag', () => {
220
- assert.deepStrictEqual(inspect(parser('#a#'), ctx), [['#a#'], '']);
221
- assert.deepStrictEqual(inspect(parser('#a#b'), ctx), [['#a#b'], '']);
221
+ assert.deepStrictEqual(inspect(parser('#a#'), ctx), [['#a', '#'], '']);
222
+ assert.deepStrictEqual(inspect(parser('#a#b'), ctx), [['#a', '#', 'b'], '']);
222
223
  assert.deepStrictEqual(inspect(parser('#a'), ctx), [['<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
224
+ assert.deepStrictEqual(inspect(parser('#http://host'), ctx), [['#http', ':', '/', '/', 'host'], '']);
223
225
  assert.deepStrictEqual(inspect(parser('#a\nb\n#c\n[#d]'), ctx), [['<a class="hashtag" href="/hashtags/a">#a</a>', '<br>', 'b', '<br>', '<a class="hashtag" href="/hashtags/c">#c</a>', '<br>', '<a class="index" href="#index::d">d</a>'], '']);
224
226
  assert.deepStrictEqual(inspect(parser('##a'), ctx), [['##a'], '']);
225
227
  assert.deepStrictEqual(inspect(parser('_#a'), ctx), [['_', '<a class="hashtag" href="/hashtags/a">#a</a>'], '']);
226
228
  assert.deepStrictEqual(inspect(parser('_#a_'), ctx), [['_', '<a class="hashtag" href="/hashtags/a">#a</a>', '_'], '']);
227
229
  assert.deepStrictEqual(inspect(parser('_#a_b'), ctx), [['_', '<a class="hashtag" href="/hashtags/a_b">#a_b</a>'], '']);
228
230
  assert.deepStrictEqual(inspect(parser('_#a_b_'), ctx), [['_', '<a class="hashtag" href="/hashtags/a_b">#a_b</a>', '_'], '']);
229
- assert.deepStrictEqual(inspect(parser('a#b'), ctx), [['a#b'], '']);
230
- assert.deepStrictEqual(inspect(parser('0a#b'), ctx), [['0a#b'], '']);
231
- assert.deepStrictEqual(inspect(parser('あ#b'), ctx), [['あ#b'], '']);
232
- assert.deepStrictEqual(inspect(parser('あい#b'), ctx), [['', 'い#b'], '']);
233
- assert.deepStrictEqual(inspect(parser('0aあ#b'), ctx), [['0aあ#b'], '']);
234
- assert.deepStrictEqual(inspect(parser('0aあい#b'), ctx), [['0a', '', 'い#b'], '']);
231
+ assert.deepStrictEqual(inspect(parser('a#b'), ctx), [['a', '#', 'b'], '']);
232
+ assert.deepStrictEqual(inspect(parser('0a#b'), ctx), [['0a', '#', 'b'], '']);
233
+ assert.deepStrictEqual(inspect(parser('あ#b'), ctx), [['あ', '#', 'b'], '']);
234
+ assert.deepStrictEqual(inspect(parser('あい#b'), ctx), [['あい', '#', 'b'], '']);
235
+ assert.deepStrictEqual(inspect(parser('0aあ#b'), ctx), [['0a', 'あ', '#', 'b'], '']);
236
+ assert.deepStrictEqual(inspect(parser('0aあい#b'), ctx), [['0a', 'あい', '#', 'b'], '']);
235
237
  assert.deepStrictEqual(inspect(parser('「#あ」'), ctx), [['「', '<a class="hashtag" href="/hashtags/あ">#あ</a>', '」'], '']);
236
238
  assert.deepStrictEqual(inspect(parser('a\n#b'), ctx), [['a', '<br>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
237
239
  assert.deepStrictEqual(inspect(parser('a\\\n#b'), ctx), [['a', '<br>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
@@ -245,7 +247,7 @@ describe('Unit: parser/inline', () => {
245
247
  it('hashnum', () => {
246
248
  assert.deepStrictEqual(inspect(parser('#1'), ctx), [['<a class="hashnum">#1</a>'], '']);
247
249
  assert.deepStrictEqual(inspect(parser(`#1'`), ctx), [[`<a class="hashnum">#1</a>`, `'`], '']);
248
- assert.deepStrictEqual(inspect(parser('#1234567890@a'), ctx), [['#1234567890@a'], '']);
250
+ assert.deepStrictEqual(inspect(parser('#1234567890@a'), ctx), [['#1234567890', '@', 'a'], '']);
249
251
  assert.deepStrictEqual(inspect(parser('_#1'), ctx), [['_', '<a class="hashnum">#1</a>'], '']);
250
252
  assert.deepStrictEqual(inspect(parser('_#1_'), ctx), [['_', '<a class="hashnum">#1</a>', '_'], '']);
251
253
  assert.deepStrictEqual(inspect(parser('_#1_0'), ctx), [['_', '<a class="hashtag" href="/hashtags/1_0">#1_0</a>'], '']);
@@ -14,17 +14,17 @@ describe('Unit: parser/source/escsource', () => {
14
14
 
15
15
  it('basic', () => {
16
16
  assert.deepStrictEqual(inspect(parser('a'), ctx), [['a'], '']);
17
- assert.deepStrictEqual(inspect(parser('ab'), ctx), [['a', 'b'], '']);
18
- assert.deepStrictEqual(inspect(parser('09あいAZaz'), ctx), [['0', '9', '', 'い', 'A', 'Z', 'a', 'z'], '']);
17
+ assert.deepStrictEqual(inspect(parser('ab'), ctx), [['ab'], '']);
18
+ assert.deepStrictEqual(inspect(parser('09あいAZaz'), ctx), [['09', 'あい', 'AZaz'], '']);
19
19
  });
20
20
 
21
21
  it('space', () => {
22
22
  assert.deepStrictEqual(inspect(parser(' '), ctx), [[' '], '']);
23
- assert.deepStrictEqual(inspect(parser(' '), ctx), [[' ', ' '], '']);
24
- assert.deepStrictEqual(inspect(parser(' '), ctx), [[' ', ' ', ' '], '']);
23
+ assert.deepStrictEqual(inspect(parser(' '), ctx), [[' '], '']);
24
+ assert.deepStrictEqual(inspect(parser(' '), ctx), [[' '], '']);
25
25
  assert.deepStrictEqual(inspect(parser(' \n'), ctx), [[' ', '<br>'], '']);
26
- assert.deepStrictEqual(inspect(parser(' \n'), ctx), [[' ', ' ', '<br>'], '']);
27
- assert.deepStrictEqual(inspect(parser(' \n'), ctx), [[' ', ' ', ' ', '<br>'], '']);
26
+ assert.deepStrictEqual(inspect(parser(' \n'), ctx), [[' ', '<br>'], '']);
27
+ assert.deepStrictEqual(inspect(parser(' \n'), ctx), [[' ', '<br>'], '']);
28
28
  });
29
29
 
30
30
  it('linebreak', () => {
@@ -1,14 +1,16 @@
1
1
  import { EscapableSourceParser } from '../source';
2
2
  import { Command } from '../context';
3
3
  import { consume } from '../../combinator';
4
+ import { nonWhitespace, nonAlphanumeric, ASCII, isBlank, isAlphanumeric, isASCII } from './text';
4
5
  import { html } from 'typed-dom/dom';
5
6
 
6
7
  export const escsource: EscapableSourceParser = ({ context }) => {
7
8
  const { source, position } = context;
8
9
  if (position === source.length) return;
10
+ const char = source[position];
9
11
  consume(1, context);
10
12
  context.position += 1;
11
- switch (source[position]) {
13
+ switch (char) {
12
14
  case '\r':
13
15
  assert(!source.includes('\r', position + 1));
14
16
  consume(-1, context);
@@ -20,9 +22,9 @@ export const escsource: EscapableSourceParser = ({ context }) => {
20
22
  case '\\':
21
23
  switch (source[position + 1]) {
22
24
  case undefined:
23
- return [[source[position]]];
25
+ return [[char]];
24
26
  case '\n':
25
- return [[source[position]]];
27
+ return [[char]];
26
28
  default:
27
29
  consume(1, context);
28
30
  context.position += 1;
@@ -32,7 +34,29 @@ export const escsource: EscapableSourceParser = ({ context }) => {
32
34
  context.linebreak ||= source.length - position;
33
35
  return [[html('br')]];
34
36
  default:
35
- assert(source[position] !== '\n');
36
- return [[source[position]]];
37
+ assert(char !== '\n');
38
+ if (context.sequential) return [[char]];
39
+ nonAlphanumeric.lastIndex = position + 1;
40
+ nonWhitespace.lastIndex = position + 1;
41
+ ASCII.lastIndex = position + 1;
42
+ const b = isBlank(source, position);
43
+ let i = b
44
+ ? nonWhitespace.test(source)
45
+ ? nonWhitespace.lastIndex - 1
46
+ : source.length
47
+ : isAlphanumeric(char)
48
+ ? nonAlphanumeric.test(source)
49
+ ? nonAlphanumeric.lastIndex - 1
50
+ : source.length
51
+ : !isASCII(char)
52
+ ? ASCII.test(source)
53
+ ? ASCII.lastIndex - 1
54
+ : source.length
55
+ : position + 1;
56
+ assert(i > position);
57
+ i -= position;
58
+ consume(i - 1, context);
59
+ context.position += i - 1;
60
+ return [[source.slice(position, context.position)]];
37
61
  }
38
62
  };
@@ -1,6 +1,30 @@
1
1
  import { AnyLineParser, EmptyLineParser, ContentLineParser } from '../source';
2
- import { line, isBlank } from '../../combinator';
3
2
 
4
- export const anyline: AnyLineParser = line(() => [[]]);
5
- export const emptyline: EmptyLineParser = line(({ context: { source } }) => isBlank(source) ? [[]] : undefined);
6
- export const contentline: ContentLineParser = line(({ context: { source } }) => !isBlank(source) ? [[]] : undefined);
3
+ export const anyline: AnyLineParser = input => {
4
+ const { context } = input;
5
+ const { source, position } = context;
6
+ context.position = source.indexOf('\n', position) + 1 || source.length;
7
+ return [[]];
8
+ };
9
+ const regEmptyline = /[^\S\n]*(?:$|\n)/y;
10
+ export const emptyline: EmptyLineParser = input => {
11
+ const { context } = input;
12
+ const { source, position } = context;
13
+ regEmptyline.lastIndex = position;
14
+ regEmptyline.test(source);
15
+ const i = regEmptyline.lastIndex;
16
+ if (i === 0) return;
17
+ context.position = i;
18
+ return [[]];
19
+ };
20
+ const regContentline = /[^\S\n]*\S[^\n]*(?:$|\n)/y;
21
+ export const contentline: ContentLineParser = input => {
22
+ const { context } = input;
23
+ const { source, position } = context;
24
+ regContentline.lastIndex = position;
25
+ regContentline.test(source);
26
+ const i = regContentline.lastIndex;
27
+ if (i === 0) return;
28
+ context.position = i;
29
+ return [[]];
30
+ }
@@ -1,32 +1,10 @@
1
1
  import { StrParser } from '../source';
2
- import { Parser, Context } from '../../combinator/data/parser';
3
- import { consume } from '../../combinator';
2
+ import { Parser } from '../../combinator/data/parser';
3
+ import { matcher } from '../../combinator';
4
4
 
5
- export function str(pattern: string | RegExp, not?: string): StrParser;
6
- export function str(pattern: string | RegExp, not?: string): Parser<string, Context<StrParser>, []> {
7
- assert(pattern);
8
- const count = typeof pattern === 'object'
9
- ? /[^^\\*+][*+]/.test(pattern.source)
10
- : false;
11
- return typeof pattern === 'string'
12
- ? ({ context }) => {
13
- const { source, position } = context;
14
- if (position === source.length) return;
15
- if (!source.startsWith(pattern, position)) return;
16
- if (not && source.startsWith(not, position + pattern.length)) return;
17
- context.position += pattern.length;
18
- return [[pattern]];
19
- }
20
- : ({ context }) => {
21
- const { source, position } = context;
22
- if (position === source.length) return;
23
- const m = source.slice(position).match(pattern);
24
- if (m === null) return;
25
- count && consume(m[0].length, context);
26
- if (not && source.slice(position + m[0].length, position + m[0].length + not.length) === not) return;
27
- context.position += m[0].length;
28
- return [[m[0]]];
29
- };
5
+ export function str(pattern: string | RegExp): StrParser;
6
+ export function str(pattern: string | RegExp): Parser<string> {
7
+ return matcher(pattern, true);
30
8
  }
31
9
 
32
10
  export function strs(pattern: string): StrParser;
@@ -14,8 +14,8 @@ describe('Unit: parser/source/text', () => {
14
14
 
15
15
  it('basic', () => {
16
16
  assert.deepStrictEqual(inspect(parser('a'), ctx), [['a'], '']);
17
- assert.deepStrictEqual(inspect(parser('ab'), ctx), [['a', 'b'], '']);
18
- assert.deepStrictEqual(inspect(parser('09あいAZaz'), ctx), [['0', '9', '', 'い', 'A', 'Z', 'a', 'z'], '']);
17
+ assert.deepStrictEqual(inspect(parser('ab'), ctx), [['ab'], '']);
18
+ assert.deepStrictEqual(inspect(parser('09あいAZaz'), ctx), [['09', 'あい', 'AZaz'], '']);
19
19
  assert.deepStrictEqual(inspect(parser('a\nb'), ctx), [['a', '<br>', 'b'], '']);
20
20
  });
21
21
 
@@ -34,41 +34,41 @@ describe('Unit: parser/source/text', () => {
34
34
  });
35
35
 
36
36
  it('space', () => {
37
- assert.deepStrictEqual(inspect(parser(' '), ctx), [[' '], '']);
38
- assert.deepStrictEqual(inspect(parser(' '), ctx), [[' ', ' '], '']);
39
- assert.deepStrictEqual(inspect(parser(' '), ctx), [[' ', ' ', ' '], '']);
40
- assert.deepStrictEqual(inspect(parser(' \n'), ctx), [[' ', '<br>'], '']);
41
- assert.deepStrictEqual(inspect(parser(' \n'), ctx), [[' ', ' ', '<br>'], '']);
42
- assert.deepStrictEqual(inspect(parser(' \\\n'), ctx), [[' ', '<br>'], '']);
43
- assert.deepStrictEqual(inspect(parser(' \\\n'), ctx), [[' ', ' ', '<br>'], '']);
37
+ assert.deepStrictEqual(inspect(parser(' '), ctx), [[], '']);
38
+ assert.deepStrictEqual(inspect(parser(' '), ctx), [[], '']);
39
+ assert.deepStrictEqual(inspect(parser(' '), ctx), [[], '']);
40
+ assert.deepStrictEqual(inspect(parser(' \n'), ctx), [['<br>'], '']);
41
+ assert.deepStrictEqual(inspect(parser(' \n'), ctx), [['<br>'], '']);
42
+ assert.deepStrictEqual(inspect(parser(' \\\n'), ctx), [['<br>'], '']);
43
+ assert.deepStrictEqual(inspect(parser(' \\\n'), ctx), [['<br>'], '']);
44
44
  assert.deepStrictEqual(inspect(parser(' a'), ctx), [[' ', 'a'], '']);
45
45
  assert.deepStrictEqual(inspect(parser(' a'), ctx), [[' ', ' ', 'a'], '']);
46
- assert.deepStrictEqual(inspect(parser(' a'), ctx), [[' ', ' ', ' ', 'a'], '']);
47
- assert.deepStrictEqual(inspect(parser('a '), ctx), [['a', ' '], '']);
48
- assert.deepStrictEqual(inspect(parser('a '), ctx), [['a', ' ', ' '], '']);
49
- assert.deepStrictEqual(inspect(parser('a \n'), ctx), [['a', ' ', '<br>'], '']);
50
- assert.deepStrictEqual(inspect(parser('a \n'), ctx), [['a', ' ', ' ', '<br>'], '']);
51
- assert.deepStrictEqual(inspect(parser('a \\\n'), ctx), [['a', ' ', '<br>'], '']);
52
- assert.deepStrictEqual(inspect(parser('a \\\n'), ctx), [['a', ' ', ' ', '<br>'], '']);
46
+ assert.deepStrictEqual(inspect(parser(' a'), ctx), [[' ', ' ', 'a'], '']);
47
+ assert.deepStrictEqual(inspect(parser('a '), ctx), [['a'], '']);
48
+ assert.deepStrictEqual(inspect(parser('a '), ctx), [['a'], '']);
49
+ assert.deepStrictEqual(inspect(parser('a \n'), ctx), [['a', '<br>'], '']);
50
+ assert.deepStrictEqual(inspect(parser('a \n'), ctx), [['a', '<br>'], '']);
51
+ assert.deepStrictEqual(inspect(parser('a \\\n'), ctx), [['a', '<br>'], '']);
52
+ assert.deepStrictEqual(inspect(parser('a \\\n'), ctx), [['a', '<br>'], '']);
53
53
  assert.deepStrictEqual(inspect(parser('a b'), ctx), [['a', ' ', 'b'], '']);
54
- assert.deepStrictEqual(inspect(parser('a b'), ctx), [['a', ' ', ' ', 'b'], '']);
55
- assert.deepStrictEqual(inspect(parser('a b'), ctx), [['a', ' ', ' ', ' ', 'b'], '']);
54
+ assert.deepStrictEqual(inspect(parser('a b'), ctx), [['a', ' ', 'b'], '']);
55
+ assert.deepStrictEqual(inspect(parser('a b'), ctx), [['a', ' ', 'b'], '']);
56
56
  });
57
57
 
58
58
  it('hardbreak', () => {
59
59
  assert.deepStrictEqual(inspect(parser('\n'), ctx), [['<br>'], '']);
60
- assert.deepStrictEqual(inspect(parser('\n '), ctx), [['<br>', ' '], '']);
61
- assert.deepStrictEqual(inspect(parser(' \n'), ctx), [[' ', '<br>'], '']);
60
+ assert.deepStrictEqual(inspect(parser('\n '), ctx), [['<br>'], '']);
61
+ assert.deepStrictEqual(inspect(parser(' \n'), ctx), [['<br>'], '']);
62
62
  assert.deepStrictEqual(inspect(parser('\n\n'), ctx), [['<br>', '<br>'], '']);
63
- assert.deepStrictEqual(inspect(parser(' \n\n'), ctx), [[' ', '<br>', '<br>'], '']);
64
- assert.deepStrictEqual(inspect(parser('\n \n'), ctx), [['<br>', ' ', '<br>'], '']);
65
- assert.deepStrictEqual(inspect(parser('\n\n '), ctx), [['<br>', '<br>', ' '], '']);
63
+ assert.deepStrictEqual(inspect(parser(' \n\n'), ctx), [['<br>', '<br>'], '']);
64
+ assert.deepStrictEqual(inspect(parser('\n \n'), ctx), [['<br>', '<br>'], '']);
65
+ assert.deepStrictEqual(inspect(parser('\n\n '), ctx), [['<br>', '<br>'], '']);
66
66
  assert.deepStrictEqual(inspect(parser('。\n'), ctx), [['。', '<br>'], '']);
67
67
  });
68
68
 
69
69
  it('softbreak', () => {
70
70
  assert.deepStrictEqual(inspect(parser('\\\n'), ctx), [['<br>'], '']);
71
- assert.deepStrictEqual(inspect(parser('\\\n '), ctx), [['<br>', ' '], '']);
71
+ assert.deepStrictEqual(inspect(parser('\\\n '), ctx), [['<br>'], '']);
72
72
  assert.deepStrictEqual(inspect(parser('\\\na'), ctx), [['<br>', 'a'], '']);
73
73
  assert.deepStrictEqual(inspect(parser('a\\\n'), ctx), [['a', '<br>'], '']);
74
74
  assert.deepStrictEqual(inspect(parser('a\\\nb\\\n'), ctx), [['a', '<br>', 'b', '<br>'], '']);
@@ -84,7 +84,7 @@ describe('Unit: parser/source/text', () => {
84
84
  assert.deepStrictEqual(inspect(parser('0@0'), ctx), [['0', '@', '0'], '']);
85
85
  assert.deepStrictEqual(inspect(parser('a@0'), ctx), [['a', '@', '0'], '']);
86
86
  assert.deepStrictEqual(inspect(parser('A@0'), ctx), [['A', '@', '0'], '']);
87
- assert.deepStrictEqual(inspect(parser('aA@0'), ctx), [['a', 'A', '@', '0'], '']);
87
+ assert.deepStrictEqual(inspect(parser('aA@0'), ctx), [['aA', '@', '0'], '']);
88
88
  assert.deepStrictEqual(inspect(parser(' @0'), ctx), [[' ', '@', '0'], '']);
89
89
  assert.deepStrictEqual(inspect(parser('@@0'), ctx), [['@', '@', '0'], '']);
90
90
  });
@@ -98,7 +98,7 @@ describe('Unit: parser/source/text', () => {
98
98
  assert.deepStrictEqual(inspect(parser('0#0'), ctx), [['0', '#', '0'], '']);
99
99
  assert.deepStrictEqual(inspect(parser('a#0'), ctx), [['a', '#', '0'], '']);
100
100
  assert.deepStrictEqual(inspect(parser('A#0'), ctx), [['A', '#', '0'], '']);
101
- assert.deepStrictEqual(inspect(parser('aA#0'), ctx), [['a', 'A', '#', '0'], '']);
101
+ assert.deepStrictEqual(inspect(parser('aA#0'), ctx), [['aA', '#', '0'], '']);
102
102
  assert.deepStrictEqual(inspect(parser(' #0'), ctx), [[' ', '#', '0'], '']);
103
103
  assert.deepStrictEqual(inspect(parser('##0'), ctx), [['#', '#', '0'], '']);
104
104
  });
@@ -112,7 +112,7 @@ describe('Unit: parser/source/text', () => {
112
112
  assert.deepStrictEqual(inspect(parser('0>>0'), ctx), [['0', '>', '>', '0'], '']);
113
113
  assert.deepStrictEqual(inspect(parser('a>>0'), ctx), [['a', '>', '>', '0'], '']);
114
114
  assert.deepStrictEqual(inspect(parser('A>>0'), ctx), [['A', '>', '>', '0'], '']);
115
- assert.deepStrictEqual(inspect(parser('aA>>0'), ctx), [['a', 'A', '>', '>', '0'], '']);
115
+ assert.deepStrictEqual(inspect(parser('aA>>0'), ctx), [['aA', '>', '>', '0'], '']);
116
116
  assert.deepStrictEqual(inspect(parser(' >>0'), ctx), [[' ', '>', '>', '0'], '']);
117
117
  assert.deepStrictEqual(inspect(parser('>>>>0'), ctx), [['>', '>', '>', '>', '0'], '']);
118
118
  });