securemark 0.257.0 → 0.257.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 (35) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +21 -8
  3. package/dist/index.js +94 -102
  4. package/markdown.d.ts +21 -22
  5. package/package.json +1 -1
  6. package/src/combinator/data/parser/inits.ts +1 -1
  7. package/src/combinator/data/parser/sequence.ts +1 -1
  8. package/src/debug.test.ts +1 -1
  9. package/src/parser/block/table.test.ts +5 -0
  10. package/src/parser/block/table.ts +6 -5
  11. package/src/parser/inline/annotation.test.ts +6 -5
  12. package/src/parser/inline/annotation.ts +5 -4
  13. package/src/parser/inline/autolink/account.ts +3 -7
  14. package/src/parser/inline/autolink/anchor.ts +3 -7
  15. package/src/parser/inline/autolink/hashnum.ts +3 -7
  16. package/src/parser/inline/autolink/hashtag.ts +3 -7
  17. package/src/parser/inline/autolink/url.test.ts +1 -0
  18. package/src/parser/inline/autolink/url.ts +4 -5
  19. package/src/parser/inline/bracket.test.ts +3 -1
  20. package/src/parser/inline/bracket.ts +6 -6
  21. package/src/parser/inline/comment.test.ts +1 -0
  22. package/src/parser/inline/deletion.ts +1 -1
  23. package/src/parser/inline/extension/index.ts +2 -2
  24. package/src/parser/inline/extension/placeholder.ts +2 -2
  25. package/src/parser/inline/insertion.ts +1 -1
  26. package/src/parser/inline/link.ts +55 -14
  27. package/src/parser/inline/mark.ts +1 -1
  28. package/src/parser/inline/math.ts +8 -9
  29. package/src/parser/inline/media.ts +5 -5
  30. package/src/parser/inline/reference.test.ts +6 -5
  31. package/src/parser/inline/reference.ts +7 -15
  32. package/src/parser/inline/template.ts +1 -1
  33. package/src/parser/inline.test.ts +5 -3
  34. package/src/parser/inline.ts +1 -0
  35. package/src/parser/util.ts +18 -18
@@ -1,20 +1,19 @@
1
1
  import { MathParser } from '../inline';
2
- import { union, some, validate, rewrite, precedence, creator, surround, lazy } from '../../combinator';
3
- import { escsource, str } from '../source';
2
+ import { union, some, validate, focus, rewrite, precedence, creator, surround, lazy } from '../../combinator';
3
+ import { escsource, unescsource } from '../source';
4
4
  import { html } from 'typed-dom/dom';
5
5
 
6
- const syntax = /^(?:[ ([](?!\$)|\\[\\{}$]?|[!#%&')\x2A-\x5A\]^_\x61-\x7A|~])+/;
7
6
  const forbiddenCommand = /\\(?:begin|tiny|huge|large)(?![a-z])/i;
8
7
 
9
- export const math: MathParser = lazy(() => validate('$', creator(precedence(7, rewrite(
8
+ export const math: MathParser = lazy(() => validate('$', creator(rewrite(
10
9
  union([
11
- surround('$', bracket, '$'),
10
+ surround('$', precedence(6, bracket), '$'),
12
11
  surround(
13
12
  /^\$(?![\s{}])/,
14
- some(union([
13
+ precedence(3, some(union([
15
14
  bracket,
16
- str(syntax),
17
- ])),
15
+ focus(/^(?:[ ([](?!\$)|\\[\\{}$]?|[!#%&')\x2A-\x5A\]^_\x61-\x7A|~])+/, some(unescsource)),
16
+ ]))),
18
17
  /^\$(?![0-9A-Za-z])/),
19
18
  ]),
20
19
  (source, { caches: { math: cache } = {} }) => [[
@@ -30,7 +29,7 @@ export const math: MathParser = lazy(() => validate('$', creator(precedence(7, r
30
29
  'data-invalid-message': `"${source.match(forbiddenCommand)![0]}" command is forbidden`,
31
30
  },
32
31
  source)
33
- ], ''])))));
32
+ ], '']))));
34
33
 
35
34
  const bracket: MathParser.BracketParser = lazy(() => creator(surround(
36
35
  '{',
@@ -1,13 +1,13 @@
1
1
  import { undefined, location } from 'spica/global';
2
2
  import { MediaParser } from '../inline';
3
3
  import { union, inits, tails, some, validate, verify, guard, precedence, creator, surround, open, dup, lazy, fmap, bind } from '../../combinator';
4
- import { link, uri, option as linkoption, resolve } from './link';
4
+ import { textlink, uri, option as linkoption, resolve } from './link';
5
5
  import { attributes } from './html';
6
6
  import { unsafehtmlentity } from './htmlentity';
7
7
  import { txt, str } from '../source';
8
8
  import { html, define } from 'typed-dom/dom';
9
9
  import { ReadonlyURL } from 'spica/url';
10
- import { unshift, push } from 'spica/array';
10
+ import { unshift, shift, push } from 'spica/array';
11
11
 
12
12
  const optspec = {
13
13
  'width': [],
@@ -17,7 +17,7 @@ const optspec = {
17
17
  } as const;
18
18
  Object.setPrototypeOf(optspec, null);
19
19
 
20
- export const media: MediaParser = lazy(() => validate(['![', '!{'], creator(10, precedence(3, bind(verify(fmap(open(
20
+ export const media: MediaParser = lazy(() => validate(['![', '!{'], creator(10, precedence(2, bind(verify(fmap(open(
21
21
  '!',
22
22
  guard(context => context.syntax?.inline?.media ?? true,
23
23
  tails([
@@ -28,7 +28,7 @@ export const media: MediaParser = lazy(() => validate(['![', '!{'], creator(10,
28
28
  true)),
29
29
  dup(surround(/^{(?![{}])/, inits([uri, some(option)]), /^[^\S\n]*}/)),
30
30
  ]))),
31
- ([as, bs]) => bs ? [[as.join('').trim() || as.join('')], bs] : [[''], as]),
31
+ ([as, bs]) => bs ? [[as.join('').trim() || as.join('')], shift(bs)[1]] : [[''], shift(as)[1]]),
32
32
  ([[text]]) => text === '' || text.trim() !== ''),
33
33
  ([[text], params], rest, context) => {
34
34
  assert(text === text.trim());
@@ -54,7 +54,7 @@ export const media: MediaParser = lazy(() => validate(['![', '!{'], creator(10,
54
54
  }
55
55
  if (context.syntax?.inline?.link === false || cache && cache.tagName !== 'IMG') return [[el], rest];
56
56
  return fmap(
57
- link as MediaParser,
57
+ textlink as MediaParser,
58
58
  ([link]) => [define(link, { target: '_blank' }, [el])])
59
59
  (`{ ${INSECURE_URI}${params.join('')} }${rest}`, context);
60
60
  })))));
@@ -14,14 +14,15 @@ describe('Unit: parser/inline/reference', () => {
14
14
  assert.deepStrictEqual(inspect(parser('[[]]')), undefined);
15
15
  assert.deepStrictEqual(inspect(parser('[[]]]')), undefined);
16
16
  assert.deepStrictEqual(inspect(parser('[[ ]]')), undefined);
17
+ assert.deepStrictEqual(inspect(parser('[[ [a')), [['', '[['], ' [a']);
17
18
  assert.deepStrictEqual(inspect(parser('[[\n]]')), undefined);
18
19
  assert.deepStrictEqual(inspect(parser('[[\na]]')), undefined);
19
20
  assert.deepStrictEqual(inspect(parser('[[\\\na]]')), undefined);
20
- assert.deepStrictEqual(inspect(parser('[[a\n]]')), [['[['], 'a\n]]']);
21
- assert.deepStrictEqual(inspect(parser('[[a\\\n]]')), [['[['], 'a\\\n]]']);
22
- assert.deepStrictEqual(inspect(parser('[[a\nb]]')), [['[['], 'a\nb]]']);
23
- assert.deepStrictEqual(inspect(parser('[[a\\\nb]]')), [['[['], 'a\\\nb]]']);
24
- assert.deepStrictEqual(inspect(parser('[[*a\nb*]]')), [['[['], '*a\nb*]]']);
21
+ assert.deepStrictEqual(inspect(parser('[[a\n]]')), [['', '[['], 'a\n]]']);
22
+ assert.deepStrictEqual(inspect(parser('[[a\\\n]]')), [['', '[['], 'a\\\n]]']);
23
+ assert.deepStrictEqual(inspect(parser('[[a\nb]]')), [['', '[['], 'a\nb]]']);
24
+ assert.deepStrictEqual(inspect(parser('[[a\\\nb]]')), [['', '[['], 'a\\\nb]]']);
25
+ assert.deepStrictEqual(inspect(parser('[[*a\nb*]]')), [['', '[['], '*a\nb*]]']);
25
26
  assert.deepStrictEqual(inspect(parser('[[\\]]')), undefined);
26
27
  assert.deepStrictEqual(inspect(parser('[[a]b]]')), undefined);
27
28
  assert.deepStrictEqual(inspect(parser('[[[a]]')), undefined);
@@ -1,15 +1,16 @@
1
1
  import { undefined } from 'spica/global';
2
2
  import { ReferenceParser } from '../inline';
3
- import { Result } from '../../combinator/data/parser';
4
3
  import { union, subsequence, some, validate, guard, context, precedence, creator, recursion, surround, open, lazy, bind } from '../../combinator';
5
4
  import { inline } from '../inline';
5
+ import { optimize } from './link';
6
6
  import { str, stropt } from '../source';
7
- import { regBlankStart, trimBlankStart, trimNodeEnd, stringify } from '../util';
7
+ import { regBlankStart, startLoose, trimNode, stringify } from '../util';
8
8
  import { html, defrag } from 'typed-dom/dom';
9
9
 
10
10
  export const reference: ReferenceParser = lazy(() => validate('[[', creator(recursion(precedence(6, surround(
11
11
  '[[',
12
12
  guard(context => context.syntax?.inline?.reference ?? true,
13
+ startLoose(
13
14
  context({ syntax: { inline: {
14
15
  annotation: false,
15
16
  reference: false,
@@ -22,12 +23,12 @@ export const reference: ReferenceParser = lazy(() => validate('[[', creator(recu
22
23
  }}, delimiters: undefined },
23
24
  subsequence([
24
25
  abbr,
25
- open(stropt(/^(?=\^)/), some(inline, ']', [[/^\\?\n/, 9], [']', 3], [']]', 6]])),
26
- trimBlankStart(some(inline, ']', [[/^\\?\n/, 9], [']', 3], [']]', 6]])),
27
- ]))),
26
+ open(stropt(/^(?=\^)/), some(inline, ']', [[/^\\?\n/, 9], [']', 2], [']]', 6]])),
27
+ some(inline, ']', [[/^\\?\n/, 9], [']', 2], [']]', 6]]),
28
+ ])), ']')),
28
29
  ']]',
29
30
  false,
30
- ([, ns], rest) => [[html('sup', attributes(ns), [html('span', trimNodeEnd(defrag(ns)))])], rest],
31
+ ([, ns], rest) => [[html('sup', attributes(ns), [html('span', trimNode(defrag(ns)))])], rest],
31
32
  ([, ns, rest], next) => next[0] === ']' ? undefined : optimize('[[', ns, rest)))))));
32
33
 
33
34
  const abbr: ReferenceParser.AbbrParser = creator(bind(surround(
@@ -51,12 +52,3 @@ function attributes(ns: (string | HTMLElement)[]): Record<string, string | undef
51
52
  }
52
53
  : { class: 'reference' };
53
54
  }
54
-
55
- export function optimize(opener: string, ns: readonly (string | HTMLElement)[], rest: string): Result<string> {
56
- let count = 0;
57
- for (let i = 0; i < ns.length - 1; i += 2) {
58
- if (ns[i] !== '' || ns[i + 1] !== opener[0]) break;
59
- ++count;
60
- }
61
- return [[opener[0].repeat(opener.length + count)], rest.slice(count)];
62
- }
@@ -5,7 +5,7 @@ import { escsource, str } from '../source';
5
5
  import { html } from 'typed-dom/dom';
6
6
  import { unshift } from 'spica/array';
7
7
 
8
- export const template: TemplateParser = lazy(() => creator(precedence(3, rewrite(
8
+ export const template: TemplateParser = lazy(() => creator(precedence(2, rewrite(
9
9
  surround('{{', some(union([bracket, escsource]), '}'), '}}', true),
10
10
  source => [[html('span', { class: 'template' }, source.replace(/\x1B/g, ''))], '']))));
11
11
 
@@ -143,18 +143,20 @@ describe('Unit: parser/inline', () => {
143
143
  assert.deepStrictEqual(inspect(parser('Di$ney Micro$oft')), [['Di', '$', 'ney', ' ', 'Micro', '$', 'oft'], '']);
144
144
  assert.deepStrictEqual(inspect(parser('Di$ney, Micro$oft')), [['Di', '$', 'ney', ',', ' ', 'Micro', '$', 'oft'], '']);
145
145
  assert.deepStrictEqual(inspect(parser('(((a))')), [['', '(', '<sup class="annotation"><span>a</span></sup>'], '']);
146
- assert.deepStrictEqual(inspect(parser('((((a))')), [['((', '<sup class="annotation"><span>a</span></sup>'], '']);
146
+ assert.deepStrictEqual(inspect(parser('((((a))')), [['', '((', '<sup class="annotation"><span>a</span></sup>'], '']);
147
147
  assert.deepStrictEqual(inspect(parser('((((a))))')), [['<sup class="annotation"><span><span class="paren">((a))</span></span></sup>'], '']);
148
148
  assert.deepStrictEqual(inspect(parser('((<bdi>))')), [['<sup class="annotation"><span><span class="invalid">&lt;bdi&gt;</span></span></sup>'], '']);
149
+ assert.deepStrictEqual(inspect(parser('((${))}$')), [['', '((', '<span class="math" translate="no" data-src="${))}$">${))}$</span>'], '']);
149
150
  assert.deepStrictEqual(inspect(parser('"((""))')), [['"', '<sup class="annotation"><span>""</span></sup>'], '']);
150
151
  assert.deepStrictEqual(inspect(parser('[[[a]]')), [['', '[', '<sup class="reference"><span>a</span></sup>'], '']);
151
- assert.deepStrictEqual(inspect(parser('[[[[a]]')), [['[[', '<sup class="reference"><span>a</span></sup>'], '']);
152
+ assert.deepStrictEqual(inspect(parser('[[[[a]]')), [['', '[[', '<sup class="reference"><span>a</span></sup>'], '']);
152
153
  assert.deepStrictEqual(inspect(parser('[[[[a]]]]')), [['<sup class="reference"><span>[[a]]</span></sup>'], '']);
153
154
  assert.deepStrictEqual(inspect(parser('[[[$-1]]]')), [['<sup class="reference"><span><a class="label" data-label="$-1">$-1</a></span></sup>'], '']);
154
155
  assert.deepStrictEqual(inspect(parser('[[[]{a}]]')), [['<sup class="reference"><span><a href="a">a</a></span></sup>'], '']);
155
156
  assert.deepStrictEqual(inspect(parser('[[[a]{b}]]')), [['<sup class="reference"><span><a href="b">a</a></span></sup>'], '']);
156
157
  assert.deepStrictEqual(inspect(parser('[(([a]{#}))]{#}')), [['<a href="#"><span class="paren">(<span class="paren">([a]{#})</span>)</span></a>'], '']);
157
158
  assert.deepStrictEqual(inspect(parser('[[<bdi>]]')), [['<sup class="reference"><span><span class="invalid">&lt;bdi&gt;</span></span></sup>'], '']);
159
+ assert.deepStrictEqual(inspect(parser('[[${]]}$')), [['', '[[', '<span class="math" translate="no" data-src="${]]}$">${]]}$</span>'], '']);
158
160
  assert.deepStrictEqual(inspect(parser('"[[""]]')), [['"', '<sup class="reference"><span>""</span></sup>'], '']);
159
161
  assert.deepStrictEqual(inspect(parser('[[a](b)]{c}')), [['<a href="c"><ruby>a<rp>(</rp><rt>b</rt><rp>)</rp></ruby></a>'], '']);
160
162
  assert.deepStrictEqual(inspect(parser('<http://host>')), [['<', '<a href="http://host" target="_blank">http://host</a>', '>'], '']);
@@ -165,7 +167,7 @@ describe('Unit: parser/inline', () => {
165
167
  assert.deepStrictEqual(inspect(parser('[^a@b')), [['[^', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
166
168
  assert.deepStrictEqual(inspect(parser('[#a*b\nc*]')), [['[', '<a href="/hashtags/a" class="hashtag">#a</a>', '<em>b<br>c</em>', ']'], '']);
167
169
  assert.deepStrictEqual(inspect(parser('[*a\nb*]{/}')), [['[', '<em>a<br>b</em>', ']', '<a href="/">/</a>'], '']);
168
- assert.deepStrictEqual(inspect(parser('[[*a\nb*]]')), [['[[', '<em>a<br>b</em>', ']', ']'], '']);
170
+ assert.deepStrictEqual(inspect(parser('[[*a\nb*]]')), [['', '[[', '<em>a<br>b</em>', ']', ']'], '']);
169
171
  assert.deepStrictEqual(inspect(parser('"[% *"*"*')), [['"', '[%', ' ', '*', '"', '*', '"', '*'], '']);
170
172
  assert.deepStrictEqual(inspect(parser('"[% "*"* %]')), [['"', '[%', ' ', '"', '*', '"', '*', ' ', '%', ']'], '']);
171
173
  });
@@ -34,6 +34,7 @@ export import MathParser = InlineParser.MathParser;
34
34
  export import ExtensionParser = InlineParser.ExtensionParser;
35
35
  export import RubyParser = InlineParser.RubyParser;
36
36
  export import LinkParser = InlineParser.LinkParser;
37
+ export import TextLinkParser = InlineParser.TextLinkParser;
37
38
  export import HTMLParser = InlineParser.HTMLParser;
38
39
  export import InsertionParser = InlineParser.InsertionParser;
39
40
  export import DeletionParser = InlineParser.DeletionParser;
@@ -182,24 +182,24 @@ export function trimBlankEnd<T extends HTMLElement | string>(parser: Parser<T>):
182
182
  parser,
183
183
  trimNodeEnd);
184
184
  }
185
- //export function trimNode(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
186
- // return trimNodeStart(trimNodeEnd(nodes));
187
- //}
188
- //function trimNodeStart(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
189
- // for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes[0], 0);) {
190
- // if (nodes.length === 1 && typeof node === 'object' && node.className === 'indexer') break;
191
- // if (typeof node === 'string') {
192
- // const pos = node.length - node.trimStart().length;
193
- // if (pos > 0) {
194
- // nodes[0] = node.slice(pos);
195
- // break;
196
- // }
197
- // }
198
- // nodes.shift();
199
- // }
200
- // return nodes;
201
- //}
202
- export function trimNodeEnd<T extends HTMLElement | string>(nodes: T[]): T[] {
185
+ export function trimNode<T extends HTMLElement | string>(nodes: T[]): T[] {
186
+ return trimNodeStart(trimNodeEnd(nodes));
187
+ }
188
+ function trimNodeStart<T extends HTMLElement | string>(nodes: T[]): T[] {
189
+ for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes[0], 0);) {
190
+ if (nodes.length === 1 && typeof node === 'object' && node.className === 'indexer') break;
191
+ if (typeof node === 'string') {
192
+ const pos = node.trimStart().length;
193
+ if (pos > 0) {
194
+ nodes[0] = node.slice(-pos) as T;
195
+ break;
196
+ }
197
+ }
198
+ nodes.shift();
199
+ }
200
+ return nodes;
201
+ }
202
+ function trimNodeEnd<T extends HTMLElement | string>(nodes: T[]): T[] {
203
203
  const skip = nodes.length > 0 &&
204
204
  typeof nodes[nodes.length - 1] === 'object' &&
205
205
  nodes[nodes.length - 1]['className'] === 'indexer'