securemark 0.293.1 → 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.
Files changed (36) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +7 -10
  3. package/dist/index.js +329 -150
  4. package/package.json +1 -1
  5. package/src/combinator/control/manipulation/indent.test.ts +6 -1
  6. package/src/combinator/control/manipulation/indent.ts +1 -1
  7. package/src/combinator/control/manipulation/scope.ts +3 -4
  8. package/src/combinator/control/manipulation/surround.ts +2 -1
  9. package/src/combinator/data/parser/context/delimiter.ts +7 -12
  10. package/src/combinator/data/parser/some.ts +4 -8
  11. package/src/parser/api/parse.test.ts +2 -2
  12. package/src/parser/block/olist.test.ts +8 -6
  13. package/src/parser/block/olist.ts +2 -2
  14. package/src/parser/block/sidefence.ts +2 -2
  15. package/src/parser/block/table.ts +2 -2
  16. package/src/parser/block.ts +38 -36
  17. package/src/parser/inline/annotation.test.ts +1 -1
  18. package/src/parser/inline/autolink/url.test.ts +5 -5
  19. package/src/parser/inline/bracket.test.ts +6 -4
  20. package/src/parser/inline/bracket.ts +114 -88
  21. package/src/parser/inline/html.ts +24 -13
  22. package/src/parser/inline/italic.test.ts +9 -9
  23. package/src/parser/inline/link.ts +1 -1
  24. package/src/parser/inline/mark.test.ts +5 -5
  25. package/src/parser/inline/math.ts +2 -2
  26. package/src/parser/inline/media.ts +3 -2
  27. package/src/parser/inline/reference.test.ts +1 -1
  28. package/src/parser/inline/remark.ts +2 -2
  29. package/src/parser/inline/template.ts +1 -1
  30. package/src/parser/inline.test.ts +24 -23
  31. package/src/parser/inline.ts +46 -47
  32. package/src/parser/segment.ts +12 -12
  33. package/src/parser/source/escapable.test.ts +1 -1
  34. package/src/parser/source/escapable.ts +7 -4
  35. package/src/parser/source/text.ts +162 -25
  36. package/src/parser/source/unescapable.ts +5 -3
@@ -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 '$':
@@ -15,7 +15,7 @@ describe('Unit: parser/source/escsource', () => {
15
15
  it('basic', () => {
16
16
  assert.deepStrictEqual(inspect(parser('a'), ctx), [['a'], '']);
17
17
  assert.deepStrictEqual(inspect(parser('ab'), ctx), [['ab'], '']);
18
- assert.deepStrictEqual(inspect(parser('09あいAZaz'), ctx), [['09', 'あいAZaz'], '']);
18
+ assert.deepStrictEqual(inspect(parser('09あいAZaz'), ctx), [['09あいAZaz'], '']);
19
19
  });
20
20
 
21
21
  it('space', () => {
@@ -2,9 +2,10 @@ import { EscapableSourceParser } from '../source';
2
2
  import { Command } from '../context';
3
3
  import { consume } from '../../combinator';
4
4
  import { nonWhitespace, isBlank, next } from './text';
5
- import { delimiter } from './unescapable';
6
5
  import { html } from 'typed-dom/dom';
7
6
 
7
+ const delimiter = /(?=[\\$"`\[\](){}\r\n]|\s(?:\$)|:\/\/)/g;
8
+
8
9
  export const escsource: EscapableSourceParser = ({ context }) => {
9
10
  const { source, position } = context;
10
11
  if (position === source.length) return;
@@ -40,9 +41,11 @@ export const escsource: EscapableSourceParser = ({ context }) => {
40
41
  nonWhitespace.lastIndex = position + 1;
41
42
  const b = isBlank(source, position);
42
43
  let i = b
43
- ? nonWhitespace.test(source)
44
- ? nonWhitespace.lastIndex - 1
45
- : source.length
44
+ ? source[position + 1] === '\n'
45
+ ? position + 1
46
+ : nonWhitespace.test(source)
47
+ ? nonWhitespace.lastIndex - 1
48
+ : source.length
46
49
  : next(source, position, delimiter);
47
50
  assert(i > position);
48
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 = /(?=[\\!@#$&"`\[\](){}<>()[]{}*%|+~=/]|\s(?:\\?(?:$|\s)|[$*%|]|([+~=])\1)|\/{3}|:\/\/|\n)/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];
@@ -85,16 +93,6 @@ export function next(source: string, position: number, delimiter: RegExp): numbe
85
93
  index = backToEmailHead(source, position, index);
86
94
  break;
87
95
  }
88
- if (index > position + 1) switch (char) {
89
- case '*':
90
- case '+':
91
- case '~':
92
- case '=':
93
- case '/':
94
- case '%':
95
- case '|':
96
- index -= /\s/.test(source[index - 1]) ? 1 : 0;
97
- }
98
96
  assert(index > position);
99
97
  return index;
100
98
  }
@@ -154,15 +152,154 @@ export function backToEmailHead(source: string, position: number, index: number)
154
152
  return index + offset;
155
153
  }
156
154
 
157
- const blank = /\s(?:$|\s|\\\n)/y;
158
- export function isBlank(source: string, position: number): boolean {
159
- blank.lastIndex = position;
160
- return blank.test(source);
161
- }
162
- export function isAlphanumeric(char: string): boolean {
155
+ function isAlphanumeric(char: string): boolean {
163
156
  assert(char.length === 1);
164
157
  if (char < '0' || '\x7F' < char) return false;
165
158
  return '0' <= char && char <= '9'
166
159
  || 'a' <= char && char <= 'z'
167
160
  || 'A' <= char && char <= 'Z';
168
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;