securemark 0.293.2 → 0.293.3

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.
@@ -11,14 +11,14 @@ export const math: MathParser = lazy(() => rewrite(
11
11
  union([
12
12
  surround(
13
13
  /\$(?={)/y,
14
- precedence(5, bracket),
14
+ precedence(4, bracket),
15
15
  '$',
16
16
  false, undefined, undefined, [3 | Backtrack.bracket]),
17
17
  surround(
18
18
  /\$(?![\s{}])/y,
19
19
  precedence(2, some(union([
20
20
  some(escsource, /\s?\$|[`"{}\n]/y),
21
- precedence(5, bracket),
21
+ precedence(4, bracket),
22
22
  ]))),
23
23
  /\$(?![-0-9A-Za-z])/y,
24
24
  false, undefined, undefined, [3 | Backtrack.bracket]),
@@ -87,7 +87,8 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
87
87
  el.setAttribute('alt', text);
88
88
  if (!sanitize(el, uri)) return [[el]];
89
89
  assert(!el.matches('.invalid'));
90
- define(el, attributes('media', optspec, params));
90
+ const [attrs, linkparams] = attributes('media', optspec, params);
91
+ define(el, attrs);
91
92
  assert(el.matches('img') || !el.matches('.invalid'));
92
93
  // Awaiting the generic support for attr().
93
94
  if (el.hasAttribute('aspect-ratio')) {
@@ -103,7 +104,7 @@ export const media: MediaParser = lazy(() => constraint(State.media, creation(10
103
104
  context.position = position;
104
105
  return [define(link, { class: null, target: '_blank' }, [el])];
105
106
  })
106
- (subinput(`{ ${INSECURE_URI}${params.join('')} }`, context));
107
+ (subinput(`{ ${INSECURE_URI}${linkparams.join('')} }`, context));
107
108
  })))));
108
109
 
109
110
  const bracket: MediaParser.TextParser.BracketParser = lazy(() => recursion(Recursion.terminal, union([
@@ -17,7 +17,7 @@ describe('Unit: parser/inline/reference', () => {
17
17
  assert.deepStrictEqual(inspect(parser('[[]]]'), ctx), undefined);
18
18
  assert.deepStrictEqual(inspect(parser('[["]]'), ctx), undefined);
19
19
  assert.deepStrictEqual(inspect(parser('[[(]]'), ctx), undefined);
20
- assert.deepStrictEqual(inspect(parser('[[<bdi>]]'), ctx), undefined);
20
+ assert.deepStrictEqual(inspect(parser('[[[%]]'), ctx), undefined);
21
21
  assert.deepStrictEqual(inspect(parser('[[ ]]'), ctx), undefined);
22
22
  assert.deepStrictEqual(inspect(parser('[[ [a'), ctx), undefined);
23
23
  assert.deepStrictEqual(inspect(parser('[[\n]]'), ctx), undefined);
@@ -9,8 +9,8 @@ import { html, defrag } from 'typed-dom/dom';
9
9
 
10
10
  export const remark: RemarkParser = lazy(() => fallback(surround(
11
11
  str(/\[%(?=\s)/y),
12
- precedence(4, recursion(Recursion.inline,
13
- some(union([inline]), /\s%\]/y, [[/\s%\]/y, 4]]))),
12
+ precedence(3, recursion(Recursion.inline,
13
+ some(union([inline]), /\s%\]/y, [[/\s%\]/y, 3]]))),
14
14
  close(text, str(`%]`)), true,
15
15
  ([as, bs = [], cs]) => [[
16
16
  html('span', { class: 'remark' }, [
@@ -34,7 +34,7 @@ const bracket: TemplateParser.BracketParser = lazy(() => union([
34
34
  undefined, () => [[]], [3 | Backtrack.escbracket]),
35
35
  surround(
36
36
  str('"'),
37
- precedence(2, recursion(Recursion.terminal, some(escsource, '"', [['"', 2, false]]))),
37
+ precedence(2, recursion(Recursion.terminal, some(escsource, /["\n]/y, [['"', 2], ['\n', 3]]))),
38
38
  str('"'),
39
39
  true,
40
40
  ([as, bs = [], cs], context) =>
@@ -22,7 +22,7 @@ describe('Unit: parser/inline', () => {
22
22
  it('nest', () => {
23
23
  assert.deepStrictEqual(inspect(parser('あ(A)'), ctx), [['あ', '(', 'A', ')'], '']);
24
24
  assert.deepStrictEqual(inspect(parser('あ(い)'), ctx), [['あ', '<span class="paren">(い)</span>'], '']);
25
- assert.deepStrictEqual(inspect(parser('* a*'), ctx), [['*', ' a', '*'], '']);
25
+ assert.deepStrictEqual(inspect(parser('* a*'), ctx), [['* a', '*'], '']);
26
26
  assert.deepStrictEqual(inspect(parser('** a**'), ctx), [['**', ' a', '**'], '']);
27
27
  assert.deepStrictEqual(inspect(parser('*** a***'), ctx), [['***', ' a', '***'], '']);
28
28
  assert.deepStrictEqual(inspect(parser('**** a****'), ctx), [['****', ' a', '****'], '']);
@@ -82,19 +82,19 @@ describe('Unit: parser/inline', () => {
82
82
  assert.deepStrictEqual(inspect(parser('*++ a ++*'), ctx), [['<em><ins> a </ins></em>'], '']);
83
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
- assert.deepStrictEqual(inspect(parser('*a"\nb*'), ctx), [['*', 'a', '"', '<br>', 'b', '*'], '']);
85
+ assert.deepStrictEqual(inspect(parser('*a"\nb*'), ctx), [['<em>a"<br>b</em>'], '']);
86
86
  assert.deepStrictEqual(inspect(parser('*a"\n"("b*'), ctx), [['<em>a"<br>"("b</em>'], '']);
87
- assert.deepStrictEqual(inspect(parser('"*a\nb*'), ctx), [['"', '<em>a<br>b</em>'], '']);
88
- assert.deepStrictEqual(inspect(parser('"*a\n""b*'), ctx), [['"', '<em>a<br>""b</em>'], '']);
87
+ assert.deepStrictEqual(inspect(parser('"*a\nb*'), ctx), [['"', '*', 'a', '<br>', 'b', '*'], '']);
88
+ assert.deepStrictEqual(inspect(parser('"*a\n""b*'), ctx), [['"', '*', 'a', '<br>', '"', '"', 'b', '*'], '']);
89
89
  assert.deepStrictEqual(inspect(parser('"a\n"*b"c*'), ctx), [['"', 'a', '<br>', '"', '*', 'b', '"', 'c', '*'], '']);
90
- assert.deepStrictEqual(inspect(parser('"*a**b\nc**"("*'), ctx), [['"', '<em>a<strong>b<br>c</strong>"("</em>'], '']);
91
- assert.deepStrictEqual(inspect(parser('<bdi>a"\nb</bdi>'), ctx), [['<bdi>a"<br>b</bdi>'], '']);
92
- assert.deepStrictEqual(inspect(parser('"<bdi>"a\n""b</bdi>"'), ctx), [['"', '<bdi>"a<br>""b</bdi>', '"'], '']);
90
+ assert.deepStrictEqual(inspect(parser('"*a**b\nc**"("*'), ctx), [['"', '*', 'a', '**', 'b', '<br>', 'c', '**', '"', '(', '"', '*'], '']);
91
+ assert.deepStrictEqual(inspect(parser('[% a"\nb %]'), ctx), [['<span class="remark"><input type="checkbox"><span>[% a"<br>b %]</span></span>'], '']);
92
+ assert.deepStrictEqual(inspect(parser('"<bdi>"a\n""b</bdi>"'), ctx), [['"', '<span class="invalid">&lt;bdi&gt;</span>', '"', 'a', '<br>', '"', '"', 'b', '</bdi', '>', '"'], '']);
93
93
  assert.deepStrictEqual(inspect(parser('<bdi>*<bdi>a</bdi>*</bdi>'), ctx), [['<bdi><em><bdi>a</bdi></em></bdi>'], '']);
94
94
  assert.deepStrictEqual(inspect(parser('<bdi>((<bdi>((a))</bdi>))</bdi>'), ctx), [['<bdi><sup class="annotation"><span><bdi><span class="paren">((a))</span></bdi></span></sup></bdi>'], '']);
95
95
  assert.deepStrictEqual(inspect(parser('<bdi>[[<bdi>[[a]]</bdi>]]</bdi>'), ctx), [['<bdi><sup class="reference"><span><bdi>[[a]]</bdi></span></sup></bdi>'], '']);
96
- assert.deepStrictEqual(inspect(parser('<bdi>[#</bdi>]'), ctx), [['<bdi>[#</bdi>', ']'], '']);
97
- assert.deepStrictEqual(inspect(parser('"<bdi>("")</bdi>'), ctx), [['"', '<bdi><span class="paren">("")</span></bdi>'], '']);
96
+ assert.deepStrictEqual(inspect(parser('<bdi>[#</bdi>]'), ctx), [['<span class="invalid">&lt;bdi&gt;[#&lt;/bdi&gt;]</span>'], '']);
97
+ assert.deepStrictEqual(inspect(parser('"<bdi>("")</bdi>'), ctx), [['"', '<span class="invalid">&lt;bdi&gt;(</span>', '"', '"', ')', '</bdi', '>'], '']);
98
98
  assert.deepStrictEqual(inspect(parser('++\na\n++\n~~\nb\n~~\nc'), ctx), [['<ins><br>a</ins>', '<br>', '<del><br>b</del>', '<br>', 'c'], '']);
99
99
  assert.deepStrictEqual(inspect(parser('[@a]'), ctx), [['[', '<a class="account" href="/@a">@a</a>', ']'], '']);
100
100
  assert.deepStrictEqual(inspect(parser('[#1][#2]'), ctx), [['<a class="index" href="#index::1">1</a>', '<a class="index" href="#index::2">2</a>'], '']);
@@ -121,11 +121,11 @@ describe('Unit: parser/inline', () => {
121
121
  assert.deepStrictEqual(inspect(parser('{}'), ctx), [['{', '}'], '']);
122
122
  assert.deepStrictEqual(inspect(parser('{a}'), ctx), [['<a class="url" href="a">a</a>'], '']);
123
123
  assert.deepStrictEqual(inspect(parser('{{a}}'), ctx), [['<span class="template">{{a}}</span>'], '']);
124
- assert.deepStrictEqual(inspect(parser('\r!{}'), ctx), [['!', '{', '}'], '']);
125
- assert.deepStrictEqual(inspect(parser('\r!{a}'), ctx), [['!', '<a class="url" href="a">a</a>'], '']);
126
- assert.deepStrictEqual(inspect(parser('\r!{{a}}'), ctx), [['!', '<span class="template">{{a}}</span>'], '']);
127
- assert.deepStrictEqual(inspect(parser('\r!{{{a}}}'), ctx), [['!', '<span class="template">{{{a}}}</span>'], '']);
128
- assert.deepStrictEqual(inspect(parser('\r!!{a}'), ctx), [['!', '!', '<a class="url" href="a">a</a>'], '']);
124
+ assert.deepStrictEqual(inspect(parser('!{}'), ctx), [['!', '{', '}'], '']);
125
+ assert.deepStrictEqual(inspect(parser('!{a}'), ctx), [['!', '<a class="url" href="a">a</a>'], '']);
126
+ assert.deepStrictEqual(inspect(parser('!{{a}}'), ctx), [['!', '<span class="template">{{a}}</span>'], '']);
127
+ assert.deepStrictEqual(inspect(parser('!{{{a}}}'), ctx), [['!', '<span class="template">{{{a}}}</span>'], '']);
128
+ assert.deepStrictEqual(inspect(parser('!!{a}'), ctx), [['!', '!', '<a class="url" href="a">a</a>'], '']);
129
129
  assert.deepStrictEqual(inspect(parser('${a}'), ctx), [['$', '<a class="url" href="a">a</a>'], '']);
130
130
  assert.deepStrictEqual(inspect(parser('${{a}}'), ctx), [['$', '<span class="template">{{a}}</span>'], '']);
131
131
  assert.deepStrictEqual(inspect(parser('${{{a}}}'), ctx), [['$', '<span class="template">{{{a}}}</span>'], '']);
@@ -167,8 +167,8 @@ describe('Unit: parser/inline', () => {
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
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
- assert.deepStrictEqual(inspect(parser('[#a|<bdi>]</bdi>'), ctx), [['[', '<a class="hashtag" href="/hashtags/a">#a</a>', '|', '<bdi>]</bdi>'], '']);
171
- assert.deepStrictEqual(inspect(parser('[[#a|<bdi>]</bdi>'), ctx), [['[', '[', '<a class="hashtag" href="/hashtags/a">#a</a>', '|', '<bdi>]</bdi>'], '']);
170
+ assert.deepStrictEqual(inspect(parser('[#a|<bdi>]</bdi>'), ctx), [['<a class="index" href="#index::a|&lt;bdi&gt;">a|<span class="invalid">&lt;bdi&gt;</span></a>', '</bdi', '>'], '']);
171
+ assert.deepStrictEqual(inspect(parser('[[#a|<bdi>]</bdi>'), ctx), [['[', '<a class="index" href="#index::a|&lt;bdi&gt;">a|<span class="invalid">&lt;bdi&gt;</span></a>', '</bdi', '>'], '']);
172
172
  });
173
173
 
174
174
  it('uri', () => {
@@ -53,70 +53,69 @@ export const inline: InlineParser = lazy(() => union([
53
53
  input => {
54
54
  const { context: { source, position } } = input;
55
55
  if (position === source.length) return;
56
- switch (source.slice(position, position + 2)) {
57
- case '((':
58
- return annotation(input)
59
- || bracket(input);
60
- case '[[':
61
- return reference(input)
62
- || textlink(input)
63
- || bracket(input);
64
- case '{{':
65
- return template(input)
66
- || bracket(input);
67
- case '[%':
68
- return remark(input)
69
- || textlink(input)
70
- || bracket(input);
71
- case '[#':
72
- case '[$':
73
- case '[:':
74
- case '[^':
75
- case '[|':
76
- return extension(input)
77
- || textlink(input)
78
- || bracket(input);
79
- case '${':
80
- return math(input);
81
- case '++':
82
- return insertion(input);
83
- case '~~':
84
- return deletion(input);
85
- case '==':
86
- return mark(input);
87
- case '//':
88
- return italic(input);
89
- case '**':
90
- return emstrong(input)
91
- || strong(input)
92
- || stars(input);
93
- }
94
56
  switch (source[position]) {
57
+ case '(':
58
+ if (source[position + 1] === '(') return annotation(input) || bracket(input);
59
+ return bracket(input);
95
60
  case '[':
61
+ switch (source[position + 1]) {
62
+ case '[':
63
+ return reference(input)
64
+ || textlink(input)
65
+ || bracket(input);
66
+ case '%':
67
+ return remark(input)
68
+ || textlink(input)
69
+ || bracket(input);
70
+ case '#':
71
+ case '$':
72
+ case ':':
73
+ case '^':
74
+ case '|':
75
+ return extension(input)
76
+ || textlink(input)
77
+ || bracket(input);
78
+ }
96
79
  return textlink(input)
97
80
  || ruby(input)
98
81
  || bracket(input);
99
82
  case '{':
83
+ if (source[position + 1] === '{') return template(input) || bracket(input);
100
84
  return textlink(input)
101
85
  || bracket(input);
86
+ case '"':
87
+ case '(':
88
+ case '[':
89
+ case '{':
90
+ return bracket(input);
102
91
  case '<':
103
92
  return html(input);
104
93
  case '$':
94
+ if (source[position + 1] === '{') return math(input);
105
95
  return extension(input)
106
96
  || math(input);
97
+ case '+':
98
+ if (source[position + 1] === '+') return insertion(input);
99
+ break;
100
+ case '~':
101
+ if (source[position + 1] === '~') return deletion(input);
102
+ break;
103
+ case '=':
104
+ if (source[position + 1] === '=') return mark(input);
105
+ break;
106
+ case '/':
107
+ if (source[position + 1] === '/' && source[position + 2] === '/') return italic(input);
108
+ break;
109
+ case '*':
110
+ return source[position + 1] === '*'
111
+ ? source[position + 2] === '*'
112
+ ? emstrong(input) || stars(input)
113
+ : strong(input) || stars(input)
114
+ : emphasis(input);
107
115
  case '`':
108
116
  return code(input);
109
- case '*':
110
- return emphasis(input)
111
- || stars(input);
112
117
  case '&':
113
118
  return htmlentity(input);
114
- case '(':
115
- case '(':
116
- case '[':
117
- case '{':
118
- case '"':
119
- return bracket(input);
120
119
  }
121
120
  },
122
121
  autolink,
@@ -17,19 +17,19 @@ const parser: SegmentParser = union([
17
17
  input => {
18
18
  const { context: { source, position } } = input;
19
19
  if (position === source.length) return;
20
- switch (source.slice(position, position + 3)) {
21
- case '~~~':
22
- return extension(input);
23
- case '```':
24
- return codeblock(input);
25
- }
26
- switch (source.slice(position, position + 2)) {
27
- case '$$':
28
- return mathblock(input);
29
- case '[$':
30
- return extension(input);
31
- }
32
20
  switch (source[position]) {
21
+ case '`':
22
+ if (source.startsWith('```', position)) return codeblock(input);
23
+ break;
24
+ case '~':
25
+ if (source.startsWith('~~~', position)) return extension(input);
26
+ break;
27
+ case '$':
28
+ if (source[position + 1] === '$') return mathblock(input);
29
+ break;
30
+ case '[':
31
+ if (source[position + 1] === '$') return extension(input);
32
+ break;
33
33
  case '#':
34
34
  return heading(input);
35
35
  case '$':
@@ -41,9 +41,11 @@ export const escsource: EscapableSourceParser = ({ context }) => {
41
41
  nonWhitespace.lastIndex = position + 1;
42
42
  const b = isBlank(source, position);
43
43
  let i = b
44
- ? nonWhitespace.test(source)
45
- ? nonWhitespace.lastIndex - 1
46
- : source.length
44
+ ? source[position + 1] === '\n'
45
+ ? position + 1
46
+ : nonWhitespace.test(source)
47
+ ? nonWhitespace.lastIndex - 1
48
+ : source.length
47
49
  : next(source, position, delimiter);
48
50
  assert(i > position);
49
51
  i -= position;
@@ -3,7 +3,7 @@ import { Command } from '../context';
3
3
  import { union, consume, focus } from '../../combinator';
4
4
  import { html } from 'typed-dom/dom';
5
5
 
6
- export const delimiter = /(?=[\\!@#$&"`\[\](){}<>()[]{}*%|\r\n]|([+~=])\1|\/{3}|\s(?:\\?(?:$|\s)|[$%])|:\/\/)/g;
6
+ //const delimiter = /(?=[\\!@#$&"`\[\](){}<>()[]{}*%|\r\n]|([+~=])\1|\/{3}|\s(?:\\?(?:$|\s)|[$%])|:\/\/)/g;
7
7
  export const nonWhitespace = /[\S\r\n]/g;
8
8
 
9
9
  export const text: TextParser = input => {
@@ -40,10 +40,12 @@ export const text: TextParser = input => {
40
40
  nonWhitespace.lastIndex = position + 1;
41
41
  const b = isBlank(source, position);
42
42
  let i = b
43
- ? nonWhitespace.test(source)
44
- ? nonWhitespace.lastIndex - 1
45
- : source.length
46
- : next(source, position, delimiter);
43
+ ? source[position + 1] === '\n'
44
+ ? position + 1
45
+ : nonWhitespace.test(source)
46
+ ? nonWhitespace.lastIndex - 1
47
+ : source.length
48
+ : next(source, position);
47
49
  assert(i > position);
48
50
  const lineend = 0
49
51
  || b && i === source.length
@@ -70,10 +72,16 @@ export const linebreak: LinebreakParser = focus(/[\r\n]/y, union([
70
72
  text,
71
73
  ])) as LinebreakParser;
72
74
 
73
- export function next(source: string, position: number, delimiter: RegExp): number {
74
- delimiter.lastIndex = position + 1;
75
- delimiter.test(source);
76
- let index = delimiter.lastIndex;
75
+ export function next(source: string, position: number, delimiter?: RegExp): number {
76
+ let index: number;
77
+ if (delimiter) {
78
+ delimiter.lastIndex = position + 1;
79
+ delimiter.test(source);
80
+ index = delimiter.lastIndex;
81
+ }
82
+ else {
83
+ index = seek(source, position);
84
+ }
77
85
  if (index === 0) return source.length;
78
86
  assert(index > position);
79
87
  const char = source[index];
@@ -144,11 +152,6 @@ export function backToEmailHead(source: string, position: number, index: number)
144
152
  return index + offset;
145
153
  }
146
154
 
147
- const blank = /\s(?:$|\s|\\\n)/y;
148
- export function isBlank(source: string, position: number): boolean {
149
- blank.lastIndex = position;
150
- return blank.test(source);
151
- }
152
155
  function isAlphanumeric(char: string): boolean {
153
156
  assert(char.length === 1);
154
157
  if (char < '0' || '\x7F' < char) return false;
@@ -156,3 +159,147 @@ function isAlphanumeric(char: string): boolean {
156
159
  || 'a' <= char && char <= 'z'
157
160
  || 'A' <= char && char <= 'Z';
158
161
  }
162
+
163
+ //const dict = new class {
164
+ // constructor() {
165
+ // [
166
+ // '\\',
167
+ // '!',
168
+ // '@',
169
+ // '#',
170
+ // '$',
171
+ // '&',
172
+ // '"',
173
+ // '`',
174
+ // '[',
175
+ // ']',
176
+ // '(',
177
+ // ')',
178
+ // '{',
179
+ // '}',
180
+ // '<',
181
+ // '>',
182
+ // '(',
183
+ // ')',
184
+ // '[',
185
+ // ']',
186
+ // '{',
187
+ // '}',
188
+ // '*',
189
+ // '%',
190
+ // '|',
191
+ // '\r',
192
+ // '\n',
193
+ // ].forEach(c =>
194
+ // this[c.charCodeAt(0)] = undefined);
195
+ // }
196
+ //};
197
+
198
+ const delimiter = /\s(?:\\?(?:$|\s)|[$%])/y;
199
+
200
+ function seek(source: string, position: number): number {
201
+ for (let i = position + 1; i < source.length; ++i) {
202
+ const fst = source[i];
203
+ //if (fst.charCodeAt(0) in dict) return i;
204
+ switch (fst) {
205
+ case '\\':
206
+ case '!':
207
+ case '@':
208
+ case '#':
209
+ case '$':
210
+ case '&':
211
+ case '"':
212
+ case '`':
213
+ case '[':
214
+ case ']':
215
+ case '(':
216
+ case ')':
217
+ case '{':
218
+ case '}':
219
+ case '<':
220
+ case '>':
221
+ case '(':
222
+ case ')':
223
+ case '[':
224
+ case ']':
225
+ case '{':
226
+ case '}':
227
+ case '*':
228
+ case '%':
229
+ case '|':
230
+ case '\r':
231
+ case '\n':
232
+ return i;
233
+ case '+':
234
+ case '~':
235
+ case '=':
236
+ if (source[i + 1] === fst) return i;
237
+ continue;
238
+ case '/':
239
+ if (source[i + 1] === fst && source[i + 2] === fst) return i;
240
+ continue;
241
+ case ':':
242
+ if (source[i + 1] === '/' && source[i + 2] === '/') return i;
243
+ continue;
244
+ //case ' ':
245
+ //case '\t':
246
+ //case ' ':
247
+ // if (i + 1 === source.length) return i;
248
+ // switch (source[i + 1]) {
249
+ // case ' ':
250
+ // case '\t':
251
+ // case '\r':
252
+ // case '\n':
253
+ // case ' ':
254
+ // case '$':
255
+ // case '%':
256
+ // return i;
257
+ // case '\\':
258
+ // if (i + 2 === source.length) return i;
259
+ // switch (source[i + 2]) {
260
+ // case ' ':
261
+ // case '\t':
262
+ // case '\r':
263
+ // case '\n':
264
+ // case ' ':
265
+ // return i;
266
+ // }
267
+ // }
268
+ // continue;
269
+ default:
270
+ delimiter.lastIndex = i;
271
+ if (delimiter.test(source)) return i;
272
+ continue;
273
+ }
274
+ assert(false);
275
+ }
276
+ return source.length;
277
+ }
278
+
279
+ const blank = /\s(?:$|\s|\\\n)/y;
280
+ export function isBlank(source: string, position: number): boolean {
281
+ blank.lastIndex = position;
282
+ return blank.test(source);
283
+ assert(position < source.length);
284
+ if (!isWhitespace(source[position])) return false;
285
+ if (position + 1 === source.length) return true;
286
+ const snd = source[position + 1];
287
+ if (isWhitespace(snd)) return true;
288
+ if (position + 2 === source.length) return false;
289
+ if (snd === '\\' && source[position + 2] === '\n') return true;
290
+ return false;
291
+ }
292
+ const whitespace = /\s/;
293
+ export function isWhitespace(char: string): boolean {
294
+ whitespace;
295
+ switch (char) {
296
+ case ' ':
297
+ case '\t':
298
+ case '\r':
299
+ case '\n':
300
+ case ' ':
301
+ return true
302
+ default:
303
+ return false;
304
+ }
305
+ }
@@ -30,9 +30,11 @@ export const unescsource: UnescapableSourceParser = ({ context }) => {
30
30
  nonWhitespace.lastIndex = position + 1;
31
31
  const b = isBlank(source, position);
32
32
  let i = b
33
- ? nonWhitespace.test(source)
34
- ? nonWhitespace.lastIndex - 1
35
- : source.length
33
+ ? source[position + 1] === '\n'
34
+ ? position + 1
35
+ : nonWhitespace.test(source)
36
+ ? nonWhitespace.lastIndex - 1
37
+ : source.length
36
38
  : next(source, position, delimiter);
37
39
  assert(i > position);
38
40
  i -= position;