securemark 0.263.1 → 0.265.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 (59) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/index.js +1218 -3058
  3. package/markdown.d.ts +1 -1
  4. package/package.json +18 -18
  5. package/src/combinator/data/parser/context.ts +3 -2
  6. package/src/combinator/data/parser/some.ts +2 -1
  7. package/src/parser/api/bind.test.ts +1 -1
  8. package/src/parser/api/normalize.ts +1 -1
  9. package/src/parser/api/parse.test.ts +3 -3
  10. package/src/parser/block/blockquote.test.ts +3 -3
  11. package/src/parser/block/blockquote.ts +1 -1
  12. package/src/parser/block/dlist.ts +2 -3
  13. package/src/parser/block/extension/aside.ts +0 -2
  14. package/src/parser/block/extension/example.test.ts +1 -1
  15. package/src/parser/block/extension/fig.ts +2 -1
  16. package/src/parser/block/extension/figure.test.ts +2 -2
  17. package/src/parser/block/extension/figure.ts +2 -3
  18. package/src/parser/block/extension/table.ts +2 -3
  19. package/src/parser/block/heading.test.ts +1 -1
  20. package/src/parser/block/olist.test.ts +27 -25
  21. package/src/parser/block/paragraph.test.ts +1 -1
  22. package/src/parser/block/paragraph.ts +2 -3
  23. package/src/parser/block/reply.ts +2 -3
  24. package/src/parser/block/sidefence.ts +1 -1
  25. package/src/parser/block/ulist.test.ts +23 -23
  26. package/src/parser/context.ts +15 -19
  27. package/src/parser/inline/annotation.ts +1 -1
  28. package/src/parser/inline/bracket.test.ts +1 -1
  29. package/src/parser/inline/bracket.ts +1 -1
  30. package/src/parser/inline/deletion.test.ts +2 -2
  31. package/src/parser/inline/emphasis.test.ts +2 -2
  32. package/src/parser/inline/emphasis.ts +2 -2
  33. package/src/parser/inline/extension/index.test.ts +28 -32
  34. package/src/parser/inline/extension/index.ts +1 -1
  35. package/src/parser/inline/extension/indexee.ts +23 -15
  36. package/src/parser/inline/extension/placeholder.test.ts +10 -12
  37. package/src/parser/inline/extension/placeholder.ts +7 -7
  38. package/src/parser/inline/html.test.ts +1 -1
  39. package/src/parser/inline/html.ts +2 -2
  40. package/src/parser/inline/insertion.test.ts +2 -2
  41. package/src/parser/inline/link.test.ts +32 -27
  42. package/src/parser/inline/link.ts +52 -56
  43. package/src/parser/inline/mark.test.ts +11 -11
  44. package/src/parser/inline/mark.ts +12 -6
  45. package/src/parser/inline/strong.test.ts +2 -2
  46. package/src/parser/inline/strong.ts +2 -2
  47. package/src/parser/inline.test.ts +11 -9
  48. package/src/parser/processor/figure.ts +0 -2
  49. package/src/parser/processor/footnote.ts +0 -4
  50. package/src/parser/source/escapable.test.ts +1 -1
  51. package/src/parser/source/escapable.ts +7 -1
  52. package/src/parser/source/text.test.ts +24 -35
  53. package/src/parser/source/text.ts +2 -15
  54. package/src/parser/visibility.ts +1 -6
  55. package/src/util/toc.ts +0 -2
  56. package/src/parser/locale/ja.test.ts +0 -14
  57. package/src/parser/locale/ja.ts +0 -3
  58. package/src/parser/locale.test.ts +0 -26
  59. package/src/parser/locale.ts +0 -61
@@ -20,33 +20,33 @@ describe('Unit: parser/inline/link', () => {
20
20
  });
21
21
 
22
22
  it('fishing', () => {
23
- assert.deepStrictEqual(inspect(parser('[http://host]{http://evil}')), undefined);
24
- assert.deepStrictEqual(inspect(parser('[\\http://host]{http://evil}')), undefined);
25
- assert.deepStrictEqual(inspect(parser('[https://host]{http://host}')), undefined);
26
- assert.deepStrictEqual(inspect(parser('[[]{http://host}.com]{http://host}')), undefined);
27
- assert.deepStrictEqual(inspect(parser('[[]{http://host/a}b]{http://host/ab}')), undefined);
23
+ assert.deepStrictEqual(inspect(parser('[http://host]{http://evil}')), [['<a class="invalid">http://host</a>'], '']);
24
+ assert.deepStrictEqual(inspect(parser('[\\http://host]{http://evil}')), [['<a class="invalid">http://host</a>'], '']);
25
+ assert.deepStrictEqual(inspect(parser('[https://host]{http://host}')), [['<a class="invalid">https://host</a>'], '']);
26
+ assert.deepStrictEqual(inspect(parser('[[]{http://host}.com]{http://host}')), [['<a class="invalid">[]{http://host}.com</a>'], '']);
27
+ assert.deepStrictEqual(inspect(parser('[[]{http://host/a}b]{http://host/ab}')), [['<a class="invalid">[]{http://host/a}b</a>'], '']);
28
28
  assert.deepStrictEqual(inspect(parser('{http%73://host}')), [['<a class="url" href="http%73://host">http%73://host</a>'], '']);
29
29
  assert.deepStrictEqual(inspect(parser('{http://a%C3%A1}')), [['<a class="url" href="http://a%C3%A1" target="_blank">http://a%C3%A1</a>'], '']);
30
- assert.deepStrictEqual(inspect(parser('[http://á]{http://evil}')), undefined);
31
- assert.deepStrictEqual(inspect(parser('[xxx://á]{http://evil}')), undefined);
32
- assert.deepStrictEqual(inspect(parser('[mailto:á]{http://evil}')), undefined);
33
- assert.deepStrictEqual(inspect(parser('[file:///]{http://evil}')), undefined);
34
- assert.deepStrictEqual(inspect(parser('[.http://á]{http://evil}')), undefined);
35
- assert.deepStrictEqual(inspect(parser('[0987654321]{tel:1234567890}')), undefined);
36
- assert.deepStrictEqual(inspect(parser('[1234567890-]{tel:1234567890}')), undefined);
37
- assert.deepStrictEqual(inspect(parser('[-1234567890]{tel:1234567890}')), undefined);
38
- assert.deepStrictEqual(inspect(parser('[123456789a]{tel:1234567890}')), undefined);
39
- assert.deepStrictEqual(inspect(parser('[1234567890]{tel:ttel:1234567890}')), undefined);
40
- //assert.deepStrictEqual(inspect(parser('[#a]{b}')), undefined);
41
- //assert.deepStrictEqual(inspect(parser('[\\#a]{b}')), undefined);
42
- //assert.deepStrictEqual(inspect(parser('[c #a]{b}')), undefined);
43
- //assert.deepStrictEqual(inspect(parser('[c \\#a]{b}')), undefined);
44
- //assert.deepStrictEqual(inspect(parser('[]{#a}')), [['<a class="link" href="#a">#a</a>'], '']);
45
- //assert.deepStrictEqual(inspect(parser('[@a]{b}')), undefined);
46
- //assert.deepStrictEqual(inspect(parser('[\\@a]{b}')), undefined);
47
- //assert.deepStrictEqual(inspect(parser('[c @a]{b}')), undefined);
48
- //assert.deepStrictEqual(inspect(parser('[c \\@a]{b}')), undefined);
49
- //assert.deepStrictEqual(inspect(parser('[]{@a}')), [['<a class="link" href="@a">@a</a>'], '']);
30
+ assert.deepStrictEqual(inspect(parser('[http://á]{http://evil}')), [['<a class="invalid">http://á</a>'], '']);
31
+ assert.deepStrictEqual(inspect(parser('[xxx://á]{http://evil}')), [['<a class="invalid">xxx://á</a>'], '']);
32
+ assert.deepStrictEqual(inspect(parser('[mailto:á]{http://evil}')), [['<a class="invalid">mailto:á</a>'], '']);
33
+ assert.deepStrictEqual(inspect(parser('[file:///]{http://evil}')), [['<a class="invalid">file:///</a>'], '']);
34
+ assert.deepStrictEqual(inspect(parser('[.http://á]{http://evil}')), [['<a class="invalid">.http://á</a>'], '']);
35
+ assert.deepStrictEqual(inspect(parser('[0987654321]{tel:1234567890}')), [['<a class="invalid">0987654321</a>'], '']);
36
+ assert.deepStrictEqual(inspect(parser('[1234567890-]{tel:1234567890}')), [['<a class="invalid">1234567890-</a>'], '']);
37
+ assert.deepStrictEqual(inspect(parser('[-1234567890]{tel:1234567890}')), [['<a class="invalid">-1234567890</a>'], '']);
38
+ assert.deepStrictEqual(inspect(parser('[123456789a]{tel:1234567890}')), [['<a class="invalid">123456789a</a>'], '']);
39
+ assert.deepStrictEqual(inspect(parser('[1234567890]{tel:ttel:1234567890}')), [['<a class="invalid">1234567890</a>'], '']);
40
+ //assert.deepStrictEqual(inspect(parser('[#a]{b}')), [['<a class="link" href="b">#a</a>'], '']);
41
+ //assert.deepStrictEqual(inspect(parser('[\\#a]{b}')), [['<a class="link" href="b">#a</a>'], '']);
42
+ //assert.deepStrictEqual(inspect(parser('[c #a]{b}')), [['<a class="link" href="b">c #a</a>'], '']);
43
+ //assert.deepStrictEqual(inspect(parser('[c \\#a]{b}')), [['<a class="link" href="b">c #a</a>'], '']);
44
+ //assert.deepStrictEqual(inspect(parser('[]{#a}')), [['<a class="url" href="#a">#a</a>'], '']);
45
+ //assert.deepStrictEqual(inspect(parser('[@a]{b}')), [['<a class="link" href="b">@a</a>'], '']);
46
+ //assert.deepStrictEqual(inspect(parser('[\\@a]{b}')), [['<a class="link" href="b">@a</a>'], '']);
47
+ //assert.deepStrictEqual(inspect(parser('[c @a]{b}')), [['<a class="link" href="b">c @a</a>'], '']);
48
+ //assert.deepStrictEqual(inspect(parser('[c \\@a]{b}')), [['<a class="link" href="b">c @a</a>'], '']);
49
+ //assert.deepStrictEqual(inspect(parser('[]{@a}')), [['<a class="url" href="@a">@a</a>'], '']);
50
50
  });
51
51
 
52
52
  it('invalid', () => {
@@ -79,7 +79,7 @@ describe('Unit: parser/inline/link', () => {
79
79
  assert.deepStrictEqual(inspect(parser('[a\\\nb]{b}')), undefined);
80
80
  assert.deepStrictEqual(inspect(parser('[<wbr>]{b}')), undefined);
81
81
  assert.deepStrictEqual(inspect(parser('[*a\nb*]{/}')), undefined);
82
- assert.deepStrictEqual(inspect(parser('[http://host]{http://host}')), undefined);
82
+ assert.deepStrictEqual(inspect(parser('[http://host]{http://host}')), [['<a class="invalid">http://host</a>'], '']);
83
83
  assert.deepStrictEqual(inspect(parser('[]{ttp://host}')), [['<a class="invalid">ttp://host</a>'], '']);
84
84
  //assert.deepStrictEqual(inspect(parser('[]{http://[::ffff:0:0%1]}')), [['<a class="invalid">http://[::ffff:0:0%1]</a>'], '']);
85
85
  //assert.deepStrictEqual(inspect(parser('[]{http://[::ffff:0:0/96]}')), [['<a class="invalid">http://[::ffff:0:0/96]</a>'], '']);
@@ -145,6 +145,7 @@ describe('Unit: parser/inline/link', () => {
145
145
  assert.deepStrictEqual(inspect(parser('{tel:+1234567890}')), [[`<a class="tel" href="tel:+1234567890">tel:+1234567890</a>`], '']);
146
146
  assert.deepStrictEqual(inspect(parser('{tel:+12-345-67-890}')), [[`<a class="tel" href="tel:+12-345-67-890">tel:+12-345-67-890</a>`], '']);
147
147
  assert.deepStrictEqual(inspect(parser('[1234567890]{tel:1234567890}')), [[`<a class="tel" href="tel:1234567890">1234567890</a>`], '']);
148
+ assert.deepStrictEqual(inspect(parser('[1234567890]{tel:12-3456-7890}')), [[`<a class="tel" href="tel:12-3456-7890">1234567890</a>`], '']);
148
149
  assert.deepStrictEqual(inspect(parser('[12-3456-7890]{tel:1234567890}')), [[`<a class="tel" href="tel:1234567890">12-3456-7890</a>`], '']);
149
150
  assert.deepStrictEqual(inspect(parser('[+12-34567-890]{tel:+12-345-67890}')), [[`<a class="tel" href="tel:+12-345-67890">+12-34567-890</a>`], '']);
150
151
  });
@@ -170,7 +171,11 @@ describe('Unit: parser/inline/link', () => {
170
171
  assert.deepStrictEqual(inspect(parser('[((a))]{b}')), [['<a class="link" href="b"><span class="paren">((a))</span></a>'], '']);
171
172
  assert.deepStrictEqual(inspect(parser('[[[a]]]{b}')), [['<a class="link" href="b">[[a]]</a>'], '']);
172
173
  assert.deepStrictEqual(inspect(parser('[!http://host]{/}')), [['<a class="link" href="/" target="_blank"><img class="media" data-src="http://host" alt=""></a>'], '']);
173
- assert.deepStrictEqual(inspect(parser('[_a_]{b}')), [['<a class="link" href="b"><em>a</em></a>'], '']);
174
+ assert.deepStrictEqual(inspect(parser('[#a]{b}')), [['<a class="link" href="b">#a</a>'], '']);
175
+ assert.deepStrictEqual(inspect(parser('[@a]{b}')), [['<a class="link" href="b">@a</a>'], '']);
176
+ assert.deepStrictEqual(inspect(parser('[@a@b]{c}')), [['<a class="link" href="c">@a@b</a>'], '']);
177
+ assert.deepStrictEqual(inspect(parser('[a@b]{c}')), [['<a class="link" href="c">a@b</a>'], '']);
178
+ assert.deepStrictEqual(inspect(parser('[*a*]{b}')), [['<a class="link" href="b"><strong>a</strong></a>'], '']);
174
179
  });
175
180
 
176
181
  it('external', () => {
@@ -1,10 +1,9 @@
1
1
  import { MarkdownParser } from '../../../markdown';
2
2
  import { LinkParser } from '../inline';
3
- import { Result, eval, exec } from '../../combinator/data/parser';
4
- import { union, inits, tails, sequence, some, constraint, syntax, creation, precedence, state, validate, surround, open, dup, reverse, lazy, fmap, bind } from '../../combinator';
3
+ import { Result } from '../../combinator/data/parser';
4
+ import { union, inits, tails, sequence, some, constraint, syntax, creation, precedence, validate, surround, open, dup, reverse, lazy, fmap, bind } from '../../combinator';
5
5
  import { inline, media, shortmedia } from '../inline';
6
6
  import { attributes } from './html';
7
- import { autolink as autolink_ } from '../autolink';
8
7
  import { unescsource, str } from '../source';
9
8
  import { Syntax, State } from '../context';
10
9
  import { trimNode } from '../visibility';
@@ -74,8 +73,6 @@ export const option: LinkParser.ParameterParser.OptionParser = union([
74
73
  fmap(str(/^[^\S\n]+[^\s{}]+/), opt => [` \\${opt.slice(1)}`]),
75
74
  ]);
76
75
 
77
- const autolink = state(State.autolink, false, state(State.shortcut, autolink_));
78
-
79
76
  function parse(
80
77
  content: (string | HTMLElement)[],
81
78
  params: string[],
@@ -85,38 +82,15 @@ function parse(
85
82
  assert(params.length > 0);
86
83
  assert(params.every(p => typeof p === 'string'));
87
84
  if (content.length !== 0 && trimNode(content).length === 0) return;
88
- content = defrag(content);
89
- for (let source = stringify(content); source;) {
90
- if (/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i.test(source)) return;
91
- const result = autolink({ source, context });
92
- if (typeof eval(result, [])[0] === 'object') return;
93
- source = exec(result, '');
94
- }
95
85
  const INSECURE_URI = params.shift()!;
96
86
  assert(INSECURE_URI === INSECURE_URI.trim());
97
87
  assert(!INSECURE_URI.match(/\s/));
98
88
  const uri = new ReadonlyURL(
99
89
  resolve(INSECURE_URI, context.host ?? location, context.url ?? context.host ?? location),
100
90
  context.host?.href || location.href);
101
- switch (uri.protocol) {
102
- case 'tel:': {
103
- const tel = content.length === 0
104
- ? INSECURE_URI
105
- : content[0];
106
- const pattern = /^(?:tel:)?(?:\+(?!0))?\d+(?:-\d+)*$/i;
107
- if (content.length <= 1 &&
108
- typeof tel === 'string' &&
109
- pattern.test(tel) &&
110
- pattern.test(INSECURE_URI) &&
111
- tel.replace(/[^+\d]/g, '') === INSECURE_URI.replace(/[^+\d]/g, '')) {
112
- break;
113
- }
114
- return;
115
- }
116
- }
117
91
  const el = elem(
118
92
  INSECURE_URI,
119
- content,
93
+ defrag(content),
120
94
  uri,
121
95
  context.host?.origin || location.origin);
122
96
  if (el.className === 'invalid') return [[el], rest];
@@ -135,35 +109,57 @@ function elem(
135
109
  case 'http:':
136
110
  case 'https:':
137
111
  assert(uri.host);
138
- if (INSECURE_URI.slice(0, 2) === '^/' &&
139
- /\/\.\.?(?:\/|$)/.test(INSECURE_URI.slice(0, INSECURE_URI.search(/[?#]|$/)))) {
140
- type = 'argument';
141
- message = 'Dot-segments cannot be used in subresource paths';
142
- break;
112
+ switch (true) {
113
+ case /[a-z][0-9]*:\/{0,2}\S/i.test(stringify(content)):
114
+ type = 'content';
115
+ message = 'URI must not be contained';
116
+ break;
117
+ case INSECURE_URI.slice(0, 2) === '^/'
118
+ && /\/\.\.?(?:\/|$)/.test(INSECURE_URI.slice(0, INSECURE_URI.search(/[?#]|$/))):
119
+ type = 'argument';
120
+ message = 'Dot-segments cannot be used in subresource paths';
121
+ break;
122
+ default:
123
+ return html('a',
124
+ {
125
+ class: content.length === 0 ? 'url' : 'link',
126
+ href: uri.source,
127
+ target: undefined
128
+ || uri.origin !== origin
129
+ || typeof content[0] === 'object' && content[0].classList.contains('media')
130
+ ? '_blank'
131
+ : undefined,
132
+ },
133
+ content.length === 0
134
+ ? decode(INSECURE_URI)
135
+ : content);
143
136
  }
144
- return html('a',
145
- {
146
- class: content.length === 0 ? 'url' : 'link',
147
- href: uri.source,
148
- target: undefined
149
- || uri.origin !== origin
150
- || typeof content[0] === 'object' && content[0].classList.contains('media')
151
- ? '_blank'
152
- : undefined,
153
- },
154
- content.length === 0
155
- ? decode(INSECURE_URI)
156
- : content);
137
+ break;
157
138
  case 'tel:':
158
139
  assert(content.length <= 1);
159
- return html('a',
160
- {
161
- class: 'tel',
162
- href: uri.source,
163
- },
164
- content.length === 0
165
- ? [INSECURE_URI]
166
- : content);
140
+ const tel = content.length === 0
141
+ ? INSECURE_URI
142
+ : content[0];
143
+ const pattern = /^(?:tel:)?(?:\+(?!0))?\d+(?:-\d+)*$/i;
144
+ switch (true) {
145
+ case content.length <= 1
146
+ && pattern.test(INSECURE_URI)
147
+ && typeof tel === 'string'
148
+ && pattern.test(tel)
149
+ && tel.replace(/[^+\d]/g, '') === INSECURE_URI.replace(/[^+\d]/g, ''):
150
+ return html('a',
151
+ {
152
+ class: 'tel',
153
+ href: uri.source,
154
+ },
155
+ content.length === 0
156
+ ? [INSECURE_URI]
157
+ : content);
158
+ default:
159
+ type = 'content';
160
+ message = 'Invalid content';
161
+ }
162
+ break;
167
163
  }
168
164
  return html('a',
169
165
  {
@@ -204,7 +200,7 @@ function decode(uri: string): string {
204
200
  const origin = uri.match(/^[a-z](?:[-.](?=\w)|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i)?.[0] ?? '';
205
201
  try {
206
202
  let path = decodeURI(uri.slice(origin.length));
207
- if (!origin && /^[a-z](?:[-.](?=\w)|[0-9a-z])*:(?:\/{0,2}[^/?#\s]+|\/\/(?=[/]))/i.test(path)) {
203
+ if (!origin && /^[a-z](?:[-.](?=\w)|[0-9a-z])*:\/{0,2}\S/i.test(path)) {
208
204
  path = uri.slice(origin.length);
209
205
  }
210
206
  uri = origin + path;
@@ -15,8 +15,10 @@ describe('Unit: parser/inline/mark', () => {
15
15
  assert.deepStrictEqual(inspect(parser('==a ==')), [['==', 'a'], ' ==']);
16
16
  assert.deepStrictEqual(inspect(parser('==a ==')), [['==', 'a', ' '], ' ==']);
17
17
  assert.deepStrictEqual(inspect(parser('==a\n==')), [['==', 'a'], '\n==']);
18
+ assert.deepStrictEqual(inspect(parser('==a\nb==')), [['==', 'a'], '\nb==']);
18
19
  assert.deepStrictEqual(inspect(parser('==a\\ ==')), [['==', 'a'], '\\ ==']);
19
20
  assert.deepStrictEqual(inspect(parser('==a\\\n==')), [['==', 'a'], '\\\n==']);
21
+ assert.deepStrictEqual(inspect(parser('==a\\\nb==')), [['==', 'a'], '\\\nb==']);
20
22
  assert.deepStrictEqual(inspect(parser('== ==')), undefined);
21
23
  assert.deepStrictEqual(inspect(parser('== a==')), undefined);
22
24
  assert.deepStrictEqual(inspect(parser('== a ==')), undefined);
@@ -27,20 +29,18 @@ describe('Unit: parser/inline/mark', () => {
27
29
  });
28
30
 
29
31
  it('basic', () => {
30
- assert.deepStrictEqual(inspect(parser('==a==')), [['<mark>a</mark>'], '']);
31
- assert.deepStrictEqual(inspect(parser('==a=b==')), [['<mark>a=b</mark>'], '']);
32
- assert.deepStrictEqual(inspect(parser('==a\nb==')), [['<mark>a<br>b</mark>'], '']);
33
- assert.deepStrictEqual(inspect(parser('==a\\\nb==')), [['<mark>a<span class="linebreak"> </span>b</mark>'], '']);
34
- assert.deepStrictEqual(inspect(parser('==\\===')), [['<mark>=</mark>'], '']);
35
- assert.deepStrictEqual(inspect(parser('==a===')), [['<mark>a</mark>'], '=']);
32
+ assert.deepStrictEqual(inspect(parser('==a==')), [['<mark id="mark:a">a</mark>', '<a href="#mark:a"></a>'], '']);
33
+ assert.deepStrictEqual(inspect(parser('==a=b==')), [['<mark id="mark:a=b">a=b</mark>', '<a href="#mark:a=b"></a>'], '']);
34
+ assert.deepStrictEqual(inspect(parser('==\\===')), [['<mark id="mark:=">=</mark>', '<a href="#mark:="></a>'], '']);
35
+ assert.deepStrictEqual(inspect(parser('==a===')), [['<mark id="mark:a">a</mark>', '<a href="#mark:a"></a>'], '=']);
36
36
  });
37
37
 
38
38
  it('nest', () => {
39
- assert.deepStrictEqual(inspect(parser('==a ==b====')), [['<mark>a <mark>b</mark></mark>'], '']);
40
- assert.deepStrictEqual(inspect(parser('==a\\ ==b====')), [['<mark>a <mark>b</mark></mark>'], '']);
41
- assert.deepStrictEqual(inspect(parser('==a&Tab;==b====')), [['<mark>a\t<mark>b</mark></mark>'], '']);
42
- assert.deepStrictEqual(inspect(parser('==a<wbr>==b====')), [['<mark>a<wbr><mark>b</mark></mark>'], '']);
43
- assert.deepStrictEqual(inspect(parser('==_==a==_==')), [['<mark><em><mark>a</mark></em></mark>'], '']);
39
+ assert.deepStrictEqual(inspect(parser('==a ==b====')), [['<mark id="mark:a_b">a <mark id="mark:b">b</mark><a href="#mark:b"></a></mark>', '<a href="#mark:a_b"></a>'], '']);
40
+ assert.deepStrictEqual(inspect(parser('==a\\ ==b====')), [['<mark id="mark:a_b">a <mark id="mark:b">b</mark><a href="#mark:b"></a></mark>', '<a href="#mark:a_b"></a>'], '']);
41
+ assert.deepStrictEqual(inspect(parser('==a&Tab;==b====')), [['<mark id="mark:a_b">a\t<mark id="mark:b">b</mark><a href="#mark:b"></a></mark>', '<a href="#mark:a_b"></a>'], '']);
42
+ assert.deepStrictEqual(inspect(parser('==a<wbr>==b====')), [['<mark id="mark:ab">a<wbr><mark id="mark:b">b</mark><a href="#mark:b"></a></mark>', '<a href="#mark:ab"></a>'], '']);
43
+ assert.deepStrictEqual(inspect(parser('==_==a==_==')), [['<mark id="mark:a"><em><mark id="mark:a">a</mark><a href="#mark:a"></a></em></mark>', '<a href="#mark:a"></a>'], '']);
44
44
  });
45
45
 
46
46
  });
@@ -1,19 +1,25 @@
1
1
  import { MarkParser } from '../inline';
2
- import { union, some, syntax, surround, open, lazy } from '../../combinator';
2
+ import { union, some, syntax, constraint, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
+ import { identity, text } from './extension/indexee';
4
5
  import { str } from '../source';
5
6
  import { startTight, blankWith } from '../visibility';
6
7
  import { Syntax, State } from '../context';
7
8
  import { unshift } from 'spica/array';
8
- import { html, defrag } from 'typed-dom/dom';
9
+ import { html, define, defrag } from 'typed-dom/dom';
9
10
 
10
11
  export const mark: MarkParser = lazy(() => surround(
11
12
  str('==', '='),
13
+ constraint(State.mark, false,
12
14
  syntax(Syntax.none, 1, 1, State.none,
13
15
  startTight(some(union([
14
- some(inline, blankWith('==')),
15
- open(some(inline, '='), mark),
16
- ])))),
16
+ some(inline, blankWith('=='), [[/^\\?\n/, 9]]),
17
+ open(some(inline, '=', [[/^\\?\n/, 9]]), mark),
18
+ ]))))),
17
19
  str('=='), false,
18
- ([, bs], rest) => [[html('mark', defrag(bs))], rest],
20
+ ([, bs], rest, { id }) => {
21
+ const el = html('mark', defrag(bs));
22
+ define(el, { id: id !== '' && identity(text(el), 'mark') || undefined });
23
+ return [[el, html('a', { href: el.id ? `#${el.id}` : undefined })], rest];
24
+ },
19
25
  ([as, bs], rest) => [unshift(as, bs), rest]));
@@ -12,8 +12,10 @@ describe('Unit: parser/inline/strong', () => {
12
12
  assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a'], ' *']);
13
13
  assert.deepStrictEqual(inspect(parser('*a *')), [['*', 'a', ' '], ' *']);
14
14
  assert.deepStrictEqual(inspect(parser('*a\n*')), [['*', 'a'], '\n*']);
15
+ assert.deepStrictEqual(inspect(parser('*a\nb*')), [['*', 'a'], '\nb*']);
15
16
  assert.deepStrictEqual(inspect(parser('*a\\ *')), [['*', 'a'], '\\ *']);
16
17
  assert.deepStrictEqual(inspect(parser('*a\\\n*')), [['*', 'a'], '\\\n*']);
18
+ assert.deepStrictEqual(inspect(parser('*a\\\nb*')), [['*', 'a'], '\\\nb*']);
17
19
  assert.deepStrictEqual(inspect(parser('* *')), undefined);
18
20
  assert.deepStrictEqual(inspect(parser('* a*')), undefined);
19
21
  assert.deepStrictEqual(inspect(parser('* a *')), undefined);
@@ -28,8 +30,6 @@ describe('Unit: parser/inline/strong', () => {
28
30
  it('basic', () => {
29
31
  assert.deepStrictEqual(inspect(parser('*a*')), [['<strong>a</strong>'], '']);
30
32
  assert.deepStrictEqual(inspect(parser('*ab*')), [['<strong>ab</strong>'], '']);
31
- assert.deepStrictEqual(inspect(parser('*a\nb*')), [['<strong>a<br>b</strong>'], '']);
32
- assert.deepStrictEqual(inspect(parser('*a\\\nb*')), [['<strong>a<span class="linebreak"> </span>b</strong>'], '']);
33
33
  });
34
34
 
35
35
  it('nest', () => {
@@ -11,8 +11,8 @@ export const strong: StrongParser = lazy(() => surround(
11
11
  str('*', '*'),
12
12
  syntax(Syntax.none, 1, 1, State.none,
13
13
  startTight(some(union([
14
- some(inline, blankWith('*')),
15
- open(some(inline, '*'), strong),
14
+ some(inline, blankWith('*'), [[/^\\?\n/, 9]]),
15
+ open(some(inline, '*', [[/^\\?\n/, 9]]), strong),
16
16
  ])))),
17
17
  str('*'), false,
18
18
  ([, bs], rest) => [[html('strong', defrag(bs))], rest],
@@ -29,6 +29,7 @@ describe('Unit: parser/inline', () => {
29
29
  assert.deepStrictEqual(inspect(parser('*[*]')), [['*', '[', '*', ']'], '']);
30
30
  assert.deepStrictEqual(inspect(parser('*<*>')), [['<strong>&lt;</strong>', '>'], '']);
31
31
  assert.deepStrictEqual(inspect(parser('*a((b))*')), [['<strong>a<sup class="annotation"><span>b</span></sup></strong>'], '']);
32
+ assert.deepStrictEqual(inspect(parser('++\na\n++\n~~\nb\n~~\nc')), [['<ins><br>a</ins>', '<br>', '<del><br>b</del>', '<br>', 'c'], '']);
32
33
  assert.deepStrictEqual(inspect(parser('``a`')), [['``', 'a', '`'], '']);
33
34
  assert.deepStrictEqual(inspect(parser('[@a]')), [['[', '<a class="account" href="/@a">@a</a>', ']'], '']);
34
35
  assert.deepStrictEqual(inspect(parser('[#1][#2]')), [['<a class="index" href="#index:1">1</a>', '<a class="index" href="#index:2">2</a>'], '']);
@@ -46,12 +47,12 @@ describe('Unit: parser/inline', () => {
46
47
  assert.deepStrictEqual(inspect(parser('[[#-1]a](b)')), [['[', '<a class="index" href="#index:-1">-1</a>', 'a', ']', '(', 'b', ')'], '']);
47
48
  assert.deepStrictEqual(inspect(parser('[#a]{b}')), [['<a class="index" href="#index:a">a</a>', '<a class="url" href="b">b</a>'], '']);
48
49
  assert.deepStrictEqual(inspect(parser('[@a]{b}')), [['<a class="link" href="b">@a</a>'], '']);
49
- assert.deepStrictEqual(inspect(parser('[http://host]{http://evil}')), [['[', '<a class="url" href="http://host" target="_blank">http://host</a>', ']', '<a class="url" href="http://evil" target="_blank">http://evil</a>'], '']);
50
- assert.deepStrictEqual(inspect(parser('[http://host]{http://host}')), [['[', '<a class="url" href="http://host" target="_blank">http://host</a>', ']', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
50
+ assert.deepStrictEqual(inspect(parser('[http://host]{http://evil}')), [['<a class="invalid">http://host</a>'], '']);
51
+ assert.deepStrictEqual(inspect(parser('[http://host]{http://host}')), [['<a class="invalid">http://host</a>'], '']);
51
52
  assert.deepStrictEqual(inspect(parser('[]{{a}}')), [['[', ']', '<span class="template">{{a}}</span>'], '']);
52
53
  assert.deepStrictEqual(inspect(parser('![]{{a}}')), [['!', '[', ']', '<span class="template">{{a}}</span>'], '']);
53
54
  assert.deepStrictEqual(inspect(parser('[\n]{a}')), [['[', '<br>', ']', '<a class="url" href="a">a</a>'], '']);
54
- assert.deepStrictEqual(inspect(parser('[\\\n]{a}')), [['[', '<span class="linebreak"> </span>', ']', '<a class="url" href="a">a</a>'], '']);
55
+ assert.deepStrictEqual(inspect(parser('[\\\n]{a}')), [['[', '<br>', ']', '<a class="url" href="a">a</a>'], '']);
55
56
  assert.deepStrictEqual(inspect(parser('{}')), [['{', '}'], '']);
56
57
  assert.deepStrictEqual(inspect(parser('{a}')), [['<a class="url" href="a">a</a>'], '']);
57
58
  assert.deepStrictEqual(inspect(parser('{{a}}')), [['<span class="template">{{a}}</span>'], '']);
@@ -81,6 +82,7 @@ describe('Unit: parser/inline', () => {
81
82
  assert.deepStrictEqual(inspect(parser('[[<bdi>]]')), [['<sup class="reference"><span><span class="invalid">&lt;bdi&gt;</span></span></sup>'], '']);
82
83
  assert.deepStrictEqual(inspect(parser('[[${]]}$')), [['', '[', '', '[', '<span class="math" translate="no" data-src="${]]}$">${]]}$</span>'], '']);
83
84
  assert.deepStrictEqual(inspect(parser('"[[""]]')), [['"', '<sup class="reference"><span>""</span></sup>'], '']);
85
+ assert.deepStrictEqual(inspect(parser('[==a==]{b}')), [['<a class="link" href="b">==a==</a>'], '']);
84
86
  assert.deepStrictEqual(inspect(parser('[[a](b)]{c}')), [['<a class="link" href="c"><ruby>a<rp>(</rp><rt>b</rt><rp>)</rp></ruby></a>'], '']);
85
87
  assert.deepStrictEqual(inspect(parser('[[[[[[[{a}')), [['', '[', '', '[', '', '[', '', '[', '', '[', '', '[', '', '[', '<a class="url" href="a">a</a>'], '']);
86
88
  assert.deepStrictEqual(inspect(parser('<http://host>')), [['<', '<a class="url" href="http://host" target="_blank">http://host</a>', '>'], '']);
@@ -89,11 +91,11 @@ describe('Unit: parser/inline', () => {
89
91
  assert.deepStrictEqual(inspect(parser('[~~a~~]')), [['[', '<del>a</del>', ']'], '']);
90
92
  assert.deepStrictEqual(inspect(parser('[^http://host')), [['[^', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
91
93
  assert.deepStrictEqual(inspect(parser('[^a@b')), [['[^', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
92
- assert.deepStrictEqual(inspect(parser('[#a*b\nc*]')), [['[', '<a class="hashtag" href="/hashtags/a">#a</a>', '<strong>b<br>c</strong>', ']'], '']);
93
- assert.deepStrictEqual(inspect(parser('[*a\nb*]{/}')), [['[', '<strong>a<br>b</strong>', ']', '<a class="url" href="/">/</a>'], '']);
94
- assert.deepStrictEqual(inspect(parser('[*a\nb]*')), [['[', '*', 'a', '<br>', 'b', ']', '*'], '']);
95
- assert.deepStrictEqual(inspect(parser('[*[a\nb*]')), [['', '[', '*', '[', 'a', '<br>', 'b', '*', ']'], '']);
96
- assert.deepStrictEqual(inspect(parser('[[*a\nb*]]')), [['[', '[', '<strong>a<br>b</strong>', ']', ']'], '']);
94
+ assert.deepStrictEqual(inspect(parser('[#a++b\nc++]')), [['[', '<a class="hashtag" href="/hashtags/a">#a</a>', '<ins>b<br>c</ins>', ']'], '']);
95
+ assert.deepStrictEqual(inspect(parser('[++a\nb++]{/}')), [['[', '<ins>a<br>b</ins>', ']', '<a class="url" href="/">/</a>'], '']);
96
+ assert.deepStrictEqual(inspect(parser('[++a\nb]++')), [['[', '++', 'a', '<br>', 'b', ']', '++'], '']);
97
+ assert.deepStrictEqual(inspect(parser('[++[a\nb++]')), [['', '[', '++', '[', 'a', '<br>', 'b', '++', ']'], '']);
98
+ assert.deepStrictEqual(inspect(parser('[[++a\nb++]]')), [['[', '[', '<ins>a<br>b</ins>', ']', ']'], '']);
97
99
  assert.deepStrictEqual(inspect(parser('"[% *"*"*')), [['"', '[%', ' ', '*', '"', '*', '"', '*'], '']);
98
100
  assert.deepStrictEqual(inspect(parser('"[% "*"* %]')), [['"', '[%', ' ', '"', '*', '"', '*', ' ', '%', ']'], '']);
99
101
  });
@@ -158,7 +160,7 @@ describe('Unit: parser/inline', () => {
158
160
  assert.deepStrictEqual(inspect(parser('0aあい#b')), [['0a', 'あ', 'い#b'], '']);
159
161
  assert.deepStrictEqual(inspect(parser('「#あ」')), [['「', '<a class="hashtag" href="/hashtags/あ">#あ</a>', '」'], '']);
160
162
  assert.deepStrictEqual(inspect(parser('a\n#b')), [['a', '<br>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
161
- assert.deepStrictEqual(inspect(parser('a\\\n#b')), [['a', '<span class="linebreak"> </span>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
163
+ assert.deepStrictEqual(inspect(parser('a\\\n#b')), [['a', '<br>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
162
164
  assert.deepStrictEqual(inspect(parser('_a_#b')), [['<em>a</em>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
163
165
  assert.deepStrictEqual(inspect(parser('*a*#b')), [['<strong>a</strong>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
164
166
  assert.deepStrictEqual(inspect(parser('((a))#b')), [['<sup class="annotation"><span>a</span></sup>', '<a class="hashtag" href="/hashtags/b">#b</a>'], '']);
@@ -18,8 +18,6 @@ export function* figure(
18
18
  let base = '0';
19
19
  let bases: readonly string[] = base.split('.');
20
20
  let index: readonly string[] = bases;
21
- // Bug: Firefox
22
- //for (let defs = target.querySelectorAll(':scope > figure[data-label], :scope > h1, :scope > h2'), len = defs.length, i = 0; i < len; ++i) {
23
21
  for (
24
22
  let defs = target.querySelectorAll('figure[data-label], h1, h2'),
25
23
  len = defs.length, i = 0; i < len; ++i) {
@@ -8,8 +8,6 @@ export function* footnote(
8
8
  opts: { readonly id?: string; } = {},
9
9
  bottom: Node | null = null,
10
10
  ): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
11
- // Bug: Firefox
12
- //target.querySelectorAll(`:scope > .annotations`).forEach(el => el.remove());
13
11
  for (let es = target.querySelectorAll(`.annotations`),
14
12
  len = es.length, i = 0; i < len; ++i) {
15
13
  const el = es[i];
@@ -40,8 +38,6 @@ function build(
40
38
  const defs = new Map<string, HTMLLIElement>();
41
39
  const buffer = new MultiQueue<string, HTMLElement>();
42
40
  const titles = new Map<string, string>();
43
- // Bug: Firefox
44
- //const splitters = push([], target.querySelectorAll(`:scope > :is(${splitter ?? '_'})`));
45
41
  const splitters: Element[] = [];
46
42
  for (let es = target.querySelectorAll(splitter ?? '_'),
47
43
  len = es.length, i = 0; i < len; ++i) {
@@ -39,7 +39,7 @@ describe('Unit: parser/source/escsource', () => {
39
39
  assert.deepStrictEqual(inspect(parser('\\a')), [['\\a'], '']);
40
40
  assert.deepStrictEqual(inspect(parser('\\$')), [['\\$'], '']);
41
41
  assert.deepStrictEqual(inspect(parser('\\ ')), [['\\ '], '']);
42
- assert.deepStrictEqual(inspect(parser('\\\n')), [['\\\n'], '']);
42
+ assert.deepStrictEqual(inspect(parser('\\\n')), [['\\', '\n'], '']);
43
43
  });
44
44
 
45
45
  });
@@ -15,7 +15,13 @@ export const escsource: EscapableSourceParser = creation(1, false, ({ source })
15
15
  case '\x1B':
16
16
  return [[source.slice(1, 2)], source.slice(2)];
17
17
  case '\\':
18
- return [[source.slice(0, 2)], source.slice(2)];
18
+ switch (source[1]) {
19
+ case undefined:
20
+ case '\n':
21
+ return [[source[0]], source.slice(1)];
22
+ default:
23
+ return [[source.slice(0, 2)], source.slice(2)];
24
+ }
19
25
  default:
20
26
  const b = source[0] !== '\n' && source[0].trimStart() === '';
21
27
  const i = b
@@ -18,14 +18,28 @@ describe('Unit: parser/text/text', () => {
18
18
  assert.deepStrictEqual(inspect(parser('a\nb')), [['a', '<br>', 'b'], '']);
19
19
  });
20
20
 
21
+ it('escape', () => {
22
+ assert.deepStrictEqual(inspect(parser('\\')), [[], '']);
23
+ assert.deepStrictEqual(inspect(parser('\\\\')), [['\\'], '']);
24
+ assert.deepStrictEqual(inspect(parser('\\\\\\')), [['\\'], '']);
25
+ assert.deepStrictEqual(inspect(parser('\\\\\\\\')), [['\\', '\\'], '']);
26
+ assert.deepStrictEqual(inspect(parser('\\ ')), [[' '], '']);
27
+ assert.deepStrictEqual(inspect(parser('\\_')), [['_'], '']);
28
+ assert.deepStrictEqual(inspect(parser('\\0')), [['0'], '']);
29
+ assert.deepStrictEqual(inspect(parser('\\a')), [['a'], '']);
30
+ assert.deepStrictEqual(inspect(parser('\\\\a')), [['\\', 'a'], '']);
31
+ assert.deepStrictEqual(inspect(parser('\\ ')), [[' '], '']);
32
+ assert.deepStrictEqual(inspect(parser('\\。')), [['。'], '']);
33
+ });
34
+
21
35
  it('space', () => {
22
36
  assert.deepStrictEqual(inspect(parser(' ')), [[], '']);
23
37
  assert.deepStrictEqual(inspect(parser(' ')), [[], '']);
24
38
  assert.deepStrictEqual(inspect(parser(' ')), [[], '']);
25
39
  assert.deepStrictEqual(inspect(parser(' \n')), [['<br>'], '']);
26
40
  assert.deepStrictEqual(inspect(parser(' \n')), [['<br>'], '']);
27
- assert.deepStrictEqual(inspect(parser(' \\\n')), [['<span class="linebreak"> </span>'], '']);
28
- assert.deepStrictEqual(inspect(parser(' \\\n')), [['<span class="linebreak"> </span>'], '']);
41
+ assert.deepStrictEqual(inspect(parser(' \\\n')), [['<br>'], '']);
42
+ assert.deepStrictEqual(inspect(parser(' \\\n')), [['<br>'], '']);
29
43
  assert.deepStrictEqual(inspect(parser(' a')), [[' ', 'a'], '']);
30
44
  assert.deepStrictEqual(inspect(parser(' a')), [[' ', ' ', 'a'], '']);
31
45
  assert.deepStrictEqual(inspect(parser(' a')), [[' ', ' ', 'a'], '']);
@@ -33,8 +47,8 @@ describe('Unit: parser/text/text', () => {
33
47
  assert.deepStrictEqual(inspect(parser('a ')), [['a'], '']);
34
48
  assert.deepStrictEqual(inspect(parser('a \n')), [['a', '<br>'], '']);
35
49
  assert.deepStrictEqual(inspect(parser('a \n')), [['a', '<br>'], '']);
36
- assert.deepStrictEqual(inspect(parser('a \\\n')), [['a', '<span class="linebreak"> </span>'], '']);
37
- assert.deepStrictEqual(inspect(parser('a \\\n')), [['a', '<span class="linebreak"> </span>'], '']);
50
+ assert.deepStrictEqual(inspect(parser('a \\\n')), [['a', '<br>'], '']);
51
+ assert.deepStrictEqual(inspect(parser('a \\\n')), [['a', '<br>'], '']);
38
52
  assert.deepStrictEqual(inspect(parser('a b')), [['a', ' ', 'b'], '']);
39
53
  assert.deepStrictEqual(inspect(parser('a b')), [['a', ' ', ' ', 'b'], '']);
40
54
  assert.deepStrictEqual(inspect(parser('a b')), [['a', ' ', ' ', 'b'], '']);
@@ -51,27 +65,13 @@ describe('Unit: parser/text/text', () => {
51
65
  assert.deepStrictEqual(inspect(parser('。\n')), [['。', '<br>'], '']);
52
66
  });
53
67
 
54
- it('\\', () => {
55
- assert.deepStrictEqual(inspect(parser('\\')), [[], '']);
56
- assert.deepStrictEqual(inspect(parser('\\\\')), [['\\'], '']);
57
- assert.deepStrictEqual(inspect(parser('\\\\\\')), [['\\'], '']);
58
- assert.deepStrictEqual(inspect(parser('\\\\\\\\')), [['\\', '\\'], '']);
59
- assert.deepStrictEqual(inspect(parser('\\ ')), [[' '], '']);
60
- assert.deepStrictEqual(inspect(parser('\\_')), [['_'], '']);
61
- assert.deepStrictEqual(inspect(parser('\\0')), [['0'], '']);
62
- assert.deepStrictEqual(inspect(parser('\\a')), [['a'], '']);
63
- assert.deepStrictEqual(inspect(parser('\\\\a')), [['\\', 'a'], '']);
64
- assert.deepStrictEqual(inspect(parser('\\ ')), [[' '], '']);
65
- assert.deepStrictEqual(inspect(parser('\\。')), [['。'], '']);
66
- });
67
-
68
68
  it('softbreak', () => {
69
- assert.deepStrictEqual(inspect(parser('\\\n')), [['<span class="linebreak"> </span>'], '']);
70
- assert.deepStrictEqual(inspect(parser('\\\n ')), [['<span class="linebreak"> </span>'], '']);
71
- assert.deepStrictEqual(inspect(parser('\\\na')), [['<span class="linebreak"> </span>', 'a'], '']);
72
- assert.deepStrictEqual(inspect(parser('a\\\n')), [['a', '<span class="linebreak"> </span>'], '']);
73
- assert.deepStrictEqual(inspect(parser('a\\\nb\\\n')), [['a', '<span class="linebreak"> </span>', 'b', '<span class="linebreak"> </span>'], '']);
74
- assert.deepStrictEqual(inspect(parser('\\\\\\\n')), [['\\', '<span class="linebreak"> </span>'], '']);
69
+ assert.deepStrictEqual(inspect(parser('\\\n')), [['<br>'], '']);
70
+ assert.deepStrictEqual(inspect(parser('\\\n ')), [['<br>'], '']);
71
+ assert.deepStrictEqual(inspect(parser('\\\na')), [['<br>', 'a'], '']);
72
+ assert.deepStrictEqual(inspect(parser('a\\\n')), [['a', '<br>'], '']);
73
+ assert.deepStrictEqual(inspect(parser('a\\\nb\\\n')), [['a', '<br>', 'b', '<br>'], '']);
74
+ assert.deepStrictEqual(inspect(parser('\\\\\\\n')), [['\\', '<br>'], '']);
75
75
  });
76
76
 
77
77
  it('account', () => {
@@ -116,17 +116,6 @@ describe('Unit: parser/text/text', () => {
116
116
  assert.deepStrictEqual(inspect(parser('>>>>0')), [['>', '>', '>', '>', '0'], '']);
117
117
  });
118
118
 
119
- it('localize', () => {
120
- assert.deepStrictEqual(inspect(parser('a\\\n0')), [['a', '<span class="linebreak"> </span>', '0'], '']);
121
- assert.deepStrictEqual(inspect(parser('あ\\\n0')), [['あ', '<span class="linebreak"></span>', '0'], '']);
122
- assert.deepStrictEqual(inspect(parser('ア\\\n0')), [['ア', '<span class="linebreak"></span>', '0'], '']);
123
- assert.deepStrictEqual(inspect(parser('亜\\\n0')), [['亜', '<span class="linebreak"></span>', '0'], '']);
124
- assert.deepStrictEqual(inspect(parser('、\\\n0')), [['、', '<span class="linebreak"></span>', '0'], '']);
125
- assert.deepStrictEqual(inspect(parser('。\\\n0')), [['。', '<span class="linebreak"></span>', '0'], '']);
126
- assert.deepStrictEqual(inspect(parser('!?\\\n0')), [['!', '?', '<span class="linebreak"></span>', '0'], '']);
127
- assert.deepStrictEqual(inspect(parser('\\あ\\\n0')), [['あ', '<span class="linebreak"></span>', '0'], '']);
128
- });
129
-
130
119
  });
131
120
 
132
121
  });