securemark 0.279.1 → 0.280.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 (41) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +10 -10
  3. package/dist/index.js +116 -98
  4. package/markdown.d.ts +1 -1
  5. package/package.json +1 -1
  6. package/src/combinator/data/parser/context/delimiter.ts +49 -21
  7. package/src/combinator/data/parser/context/memo.ts +6 -6
  8. package/src/combinator/data/parser/context.ts +23 -7
  9. package/src/parser/api/parse.test.ts +13 -13
  10. package/src/parser/block/extension/table.ts +1 -1
  11. package/src/parser/block.ts +2 -2
  12. package/src/parser/inline/annotation.ts +4 -4
  13. package/src/parser/inline/autolink/account.ts +1 -1
  14. package/src/parser/inline/autolink/url.ts +1 -1
  15. package/src/parser/inline/autolink.ts +2 -2
  16. package/src/parser/inline/bracket.test.ts +3 -2
  17. package/src/parser/inline/bracket.ts +8 -9
  18. package/src/parser/inline/deletion.ts +4 -4
  19. package/src/parser/inline/emphasis.ts +4 -4
  20. package/src/parser/inline/emstrong.ts +4 -4
  21. package/src/parser/inline/extension/index.test.ts +6 -0
  22. package/src/parser/inline/extension/index.ts +11 -11
  23. package/src/parser/inline/extension/placeholder.ts +4 -4
  24. package/src/parser/inline/html.test.ts +1 -1
  25. package/src/parser/inline/html.ts +5 -5
  26. package/src/parser/inline/insertion.ts +4 -4
  27. package/src/parser/inline/link.ts +6 -6
  28. package/src/parser/inline/mark.ts +4 -4
  29. package/src/parser/inline/media.ts +4 -4
  30. package/src/parser/inline/reference.ts +3 -3
  31. package/src/parser/inline/remark.test.ts +1 -0
  32. package/src/parser/inline/remark.ts +4 -4
  33. package/src/parser/inline/ruby.ts +2 -2
  34. package/src/parser/inline/strong.ts +4 -4
  35. package/src/parser/inline/template.ts +7 -4
  36. package/src/parser/inline.test.ts +2 -5
  37. package/src/parser/source/str.ts +0 -19
  38. package/src/parser/source/text.test.ts +1 -1
  39. package/src/parser/source/text.ts +3 -3
  40. package/src/parser/source.ts +1 -1
  41. package/src/parser/visibility.ts +3 -1
@@ -1,5 +1,5 @@
1
1
  import { InsertionParser } from '../inline';
2
- import { union, some, syntax, surround, open, lazy } from '../../combinator';
2
+ import { union, some, syntax, creation, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { str } from '../source';
5
5
  import { Syntax, State } from '../context';
@@ -7,13 +7,13 @@ import { blankWith } from '../visibility';
7
7
  import { unshift } from 'spica/array';
8
8
  import { html, defrag } from 'typed-dom/dom';
9
9
 
10
- export const insertion: InsertionParser = lazy(() => surround(
10
+ export const insertion: InsertionParser = lazy(() => creation(surround(
11
11
  str('++', '+'),
12
- syntax(Syntax.none, 1, 1, State.none,
12
+ syntax(Syntax.none, 1, State.none,
13
13
  some(union([
14
14
  some(inline, blankWith('\n', '++')),
15
15
  open('\n', some(inline, '+'), true),
16
16
  ]))),
17
17
  str('++'), false,
18
18
  ([, bs], rest) => [[html('ins', defrag(bs))], rest],
19
- ([as, bs], rest) => [unshift(as, bs), rest]));
19
+ ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -20,9 +20,9 @@ export const link: LinkParser = lazy(() => validate(['[', '{'], union([
20
20
  textlink,
21
21
  ])));
22
22
 
23
- export const textlink: LinkParser.TextLinkParser = lazy(() =>
23
+ export const textlink: LinkParser.TextLinkParser = lazy(() => creation(10,
24
24
  constraint(State.link, false,
25
- syntax(Syntax.link, 2, 10, State.linkers | State.media,
25
+ syntax(Syntax.link, 2, State.linkers | State.media,
26
26
  bind(reverse(tails([
27
27
  dup(surround(
28
28
  '[',
@@ -36,11 +36,11 @@ export const textlink: LinkParser.TextLinkParser = lazy(() =>
36
36
  assert(content[0] !== '');
37
37
  if (content.length !== 0 && trimNodeEnd(content = defrag(content)).length === 0) return;
38
38
  return [[parse(content, params, context)], rest];
39
- }))));
39
+ })))));
40
40
 
41
- export const medialink: LinkParser.MediaLinkParser = lazy(() =>
41
+ export const medialink: LinkParser.MediaLinkParser = lazy(() => creation(10,
42
42
  constraint(State.link | State.media, false,
43
- syntax(Syntax.link, 2, 10, State.linkers,
43
+ syntax(Syntax.link, 2, State.linkers,
44
44
  bind(reverse(sequence([
45
45
  dup(surround(
46
46
  '[',
@@ -49,7 +49,7 @@ export const medialink: LinkParser.MediaLinkParser = lazy(() =>
49
49
  dup(surround(/^{(?![{}])/, inits([uri, some(option)]), /^[^\S\n]*}/)),
50
50
  ])),
51
51
  ([params, content = []]: [string[], (HTMLElement | string)[]], rest, context) =>
52
- [[parse(defrag(content), params, context)], rest]))));
52
+ [[parse(defrag(content), params, context)], rest])))));
53
53
 
54
54
  export const linemedialink: LinkParser.LineMediaLinkParser = surround(
55
55
  linebreak,
@@ -1,5 +1,5 @@
1
1
  import { MarkParser } from '../inline';
2
- import { union, some, syntax, constraint, surround, open, lazy } from '../../combinator';
2
+ import { union, some, syntax, creation, constraint, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { identity, signature } from './extension/indexee';
5
5
  import { str } from '../source';
@@ -8,10 +8,10 @@ import { Syntax, State } from '../context';
8
8
  import { unshift } from 'spica/array';
9
9
  import { html, define, defrag } from 'typed-dom/dom';
10
10
 
11
- export const mark: MarkParser = lazy(() => surround(
11
+ export const mark: MarkParser = lazy(() => creation(surround(
12
12
  str('==', '='),
13
13
  constraint(State.mark, false,
14
- syntax(Syntax.none, 1, 1, State.none,
14
+ syntax(Syntax.none, 1, State.none,
15
15
  startTight(some(union([
16
16
  some(inline, blankWith('=='), [[/^\\?\n/, 9]]),
17
17
  open(some(inline, '=', [[/^\\?\n/, 9]]), mark),
@@ -24,4 +24,4 @@ export const mark: MarkParser = lazy(() => surround(
24
24
  el.id && html('a', { href: `#${el.id}` }),
25
25
  ], rest];
26
26
  },
27
- ([as, bs], rest) => [unshift(as, bs), rest]));
27
+ ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -18,10 +18,10 @@ const optspec = {
18
18
  } as const;
19
19
  Object.setPrototypeOf(optspec, null);
20
20
 
21
- export const media: MediaParser = lazy(() => validate(['![', '!{'], open(
21
+ export const media: MediaParser = lazy(() => validate(['![', '!{'], creation(10, open(
22
22
  '!',
23
23
  constraint(State.media, false,
24
- syntax(Syntax.media, 2, 10, ~State.link,
24
+ syntax(Syntax.media, 2, ~State.link,
25
25
  bind(verify(fmap(tails([
26
26
  dup(surround(
27
27
  '[',
@@ -60,7 +60,7 @@ export const media: MediaParser = lazy(() => validate(['![', '!{'], open(
60
60
  unsafelink as MediaParser,
61
61
  ([link]) => [define(link, { class: null, target: '_blank' }, [el])])
62
62
  ({ source: `{ ${INSECURE_URI}${params.join('')} }${rest}`, context });
63
- }))))));
63
+ })))))));
64
64
 
65
65
  export const linemedia: MediaParser.LineMediaParser = surround(
66
66
  linebreak,
@@ -71,7 +71,7 @@ const bracket: MediaParser.TextParser.BracketParser = lazy(() => creation(union(
71
71
  surround(str('('), some(union([unsafehtmlentity, bracket, txt]), ')'), str(')'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
72
72
  surround(str('['), some(union([unsafehtmlentity, bracket, txt]), ']'), str(']'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
73
73
  surround(str('{'), some(union([unsafehtmlentity, bracket, txt]), '}'), str('}'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
74
- surround(str('"'), precedence(8, some(union([unsafehtmlentity, txt]), '"')), str('"'), true),
74
+ surround(str('"'), precedence(3, some(union([unsafehtmlentity, txt]), '"')), str('"'), true),
75
75
  ])));
76
76
 
77
77
  const option: MediaParser.ParameterParser.OptionParser = lazy(() => union([
@@ -6,17 +6,17 @@ import { Syntax, State } from '../context';
6
6
  import { blank, trimBlankStart, trimNodeEnd } from '../visibility';
7
7
  import { html, defrag } from 'typed-dom/dom';
8
8
 
9
- export const reference: ReferenceParser = lazy(() => surround(
9
+ export const reference: ReferenceParser = lazy(() => creation(surround(
10
10
  '[[',
11
11
  constraint(State.reference, false,
12
- syntax(Syntax.reference, 6, 1, State.annotation | State.reference | State.media,
12
+ syntax(Syntax.reference, 6, State.annotation | State.reference | State.media,
13
13
  subsequence([
14
14
  abbr,
15
15
  trimBlankStart(some(inline, ']', [[/^\\?\n/, 9], [']', 2], [']]', 6]])),
16
16
  ]))),
17
17
  ']]',
18
18
  false,
19
- ([, ns], rest) => [[html('sup', attributes(ns), [html('span', trimNodeEnd(defrag(ns)))])], rest]));
19
+ ([, ns], rest) => [[html('sup', attributes(ns), [html('span', trimNodeEnd(defrag(ns)))])], rest])));
20
20
 
21
21
  // Chicago-Style
22
22
  const abbr: ReferenceParser.AbbrParser = creation(surround(
@@ -58,6 +58,7 @@ describe('Unit: parser/inline/remark', () => {
58
58
  assert.deepStrictEqual(inspect(parser('[% [ %]')), [['<span class="remark"><input type="checkbox"><span>[% [ %]</span></span>'], '']);
59
59
  assert.deepStrictEqual(inspect(parser('[% \\ a %]')), [['<span class="remark"><input type="checkbox"><span>[% a %]</span></span>'], '']);
60
60
  assert.deepStrictEqual(inspect(parser('[% $-a %]$')), [['<span class="remark"><input type="checkbox"><span>[% <a class="label" data-label="$-a">$-a</a> %]</span></span>'], '$']);
61
+ assert.deepStrictEqual(inspect(parser('[% <bdi> %]')), [['<span class="remark"><input type="checkbox"><span>[% <span class="invalid">&lt;bdi&gt;</span> %]</span></span>'], '']);
61
62
  });
62
63
 
63
64
  });
@@ -1,5 +1,5 @@
1
1
  import { RemarkParser } from '../inline';
2
- import { union, some, syntax, validate, surround, open, close, match, lazy } from '../../combinator';
2
+ import { union, some, syntax, creation, validate, surround, open, close, match, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { text, str } from '../source';
5
5
  import { Syntax, State } from '../context';
@@ -7,13 +7,13 @@ import { memoize } from 'spica/memoize';
7
7
  import { unshift, push } from 'spica/array';
8
8
  import { html, defrag } from 'typed-dom/dom';
9
9
 
10
- export const remark: RemarkParser = lazy(() => validate('[%', syntax(Syntax.none, 4, 1, State.none, match(
10
+ export const remark: RemarkParser = lazy(() => validate('[%', creation(syntax(Syntax.none, 5, State.none, match(
11
11
  /^\[(%+)\s/,
12
12
  memoize(
13
13
  ([, fence]) =>
14
14
  surround(
15
15
  open(str(`[${fence}`), some(text, new RegExp(String.raw`^\s+${fence}\]|^\S`)), true),
16
- some(union([inline]), new RegExp(String.raw`^\s+${fence}\]`), [[new RegExp(String.raw`^\s+${fence}\]`), 4]]),
16
+ some(union([inline]), new RegExp(String.raw`^\s+${fence}\]`), [[new RegExp(String.raw`^\s+${fence}\]`), 5]]),
17
17
  close(some(text, /^\S/), str(`${fence}]`)), true,
18
18
  ([as, bs = [], cs], rest) => [[
19
19
  html('span', { class: 'remark' }, [
@@ -22,4 +22,4 @@ export const remark: RemarkParser = lazy(() => validate('[%', syntax(Syntax.none
22
22
  ]),
23
23
  ], rest],
24
24
  ([as, bs = []], rest) => [unshift(as, bs), rest]),
25
- ([, fence]) => fence.length, {})))));
25
+ ([, fence]) => fence.length, {}))))));
@@ -8,7 +8,7 @@ import { isStartTightNodes } from '../visibility';
8
8
  import { unshift, push } from 'spica/array';
9
9
  import { html, defrag } from 'typed-dom/dom';
10
10
 
11
- export const ruby: RubyParser = lazy(() => validate('[', syntax(Syntax.ruby, 2, 1, State.all, fmap(verify(fmap(
11
+ export const ruby: RubyParser = lazy(() => validate('[', creation(syntax(Syntax.ruby, 2, State.all, fmap(verify(fmap(
12
12
  sequence([
13
13
  surround('[', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ']'),
14
14
  surround('(', str(/^(?:\\[^\n]|[^\\[\](){}"\n])+/), ')'),
@@ -49,7 +49,7 @@ export const ruby: RubyParser = lazy(() => validate('[', syntax(Syntax.ruby, 2,
49
49
  [html('rp', '('), html('rt', rubies.join(' ').trim()), html('rp', ')')]))),
50
50
  ];
51
51
  }
52
- }))));
52
+ })))));
53
53
 
54
54
  const text: RubyParser.TextParser = creation(1, false, ({ source, context }) => {
55
55
  const acc = [''];
@@ -1,5 +1,5 @@
1
1
  import { StrongParser } from '../inline';
2
- import { union, some, syntax, surround, open, lazy } from '../../combinator';
2
+ import { union, some, syntax, creation, surround, open, lazy } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { emstrong } from './emstrong';
5
5
  import { str } from '../source';
@@ -8,9 +8,9 @@ import { startTight, blankWith } from '../visibility';
8
8
  import { unshift } from 'spica/array';
9
9
  import { html, defrag } from 'typed-dom/dom';
10
10
 
11
- export const strong: StrongParser = lazy(() => surround(
11
+ export const strong: StrongParser = lazy(() => creation(surround(
12
12
  str('**', '*'),
13
- syntax(Syntax.none, 1, 1, State.none,
13
+ syntax(Syntax.none, 1, State.none,
14
14
  startTight(some(union([
15
15
  some(inline, blankWith('**'), [[/^\\?\n/, 9]]),
16
16
  open(some(inline, '*', [[/^\\?\n/, 9]]), union([
@@ -20,4 +20,4 @@ export const strong: StrongParser = lazy(() => surround(
20
20
  ])))),
21
21
  str('**'), false,
22
22
  ([, bs], rest) => [[html('strong', defrag(bs))], rest],
23
- ([as, bs], rest) => [unshift(as, bs), rest]));
23
+ ([as, bs], rest) => [unshift(as, bs), rest])));
@@ -5,13 +5,16 @@ import { Syntax, State } from '../context';
5
5
  import { unshift } from 'spica/array';
6
6
  import { html } from 'typed-dom/dom';
7
7
 
8
- export const template: TemplateParser = lazy(() => surround(
9
- '{{', syntax(Syntax.none, 2, 1, State.all, some(union([bracket, escsource]), '}')), '}}', true,
10
- ([, ns = []], rest) => [[html('span', { class: 'template' }, `{{${ns.join('').replace(/\x1B/g, '')}}}`)], rest]));
8
+ export const template: TemplateParser = lazy(() => creation(surround(
9
+ '{{',
10
+ syntax(Syntax.none, 6, State.all, some(union([bracket, escsource]), '}', [['}}', 6]])),
11
+ '}}',
12
+ true,
13
+ ([, ns = []], rest) => [[html('span', { class: 'template' }, `{{${ns.join('').replace(/\x1B/g, '')}}}`)], rest])));
11
14
 
12
15
  const bracket: TemplateParser.BracketParser = lazy(() => creation(union([
13
16
  surround(str('('), some(union([bracket, escsource]), ')'), str(')'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
14
17
  surround(str('['), some(union([bracket, escsource]), ']'), str(']'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
15
18
  surround(str('{'), some(union([bracket, escsource]), '}'), str('}'), true, undefined, ([as, bs = []], rest) => [unshift(as, bs), rest]),
16
- surround(str('"'), precedence(8, some(escsource, /^"|^\\?\n/)), str('"'), true),
19
+ surround(str('"'), precedence(3, some(escsource, /^"|^\\?\n/)), str('"'), true),
17
20
  ])));
@@ -18,6 +18,8 @@ describe('Unit: parser/inline', () => {
18
18
  });
19
19
 
20
20
  it('nest', () => {
21
+ assert.deepStrictEqual(inspect(parser('あ(A)')), [['あ', '(', 'A', ')'], '']);
22
+ assert.deepStrictEqual(inspect(parser('あ(い)')), [['あ', '<span class="paren">(い)</span>'], '']);
21
23
  assert.deepStrictEqual(inspect(parser('+++a+++')), [['+++', 'a', '+++'], '']);
22
24
  assert.deepStrictEqual(inspect(parser('~~~a~~~')), [['~~~', 'a', '~~~'], '']);
23
25
  assert.deepStrictEqual(inspect(parser('===a===')), [['===', 'a', '==='], '']);
@@ -168,11 +170,6 @@ describe('Unit: parser/inline', () => {
168
170
  assert.deepStrictEqual(inspect(parser('[~~a~~]')), [['[', '<del>a</del>', ']'], '']);
169
171
  assert.deepStrictEqual(inspect(parser('[^http://host')), [['[^', '<a class="url" href="http://host" target="_blank">http://host</a>'], '']);
170
172
  assert.deepStrictEqual(inspect(parser('[^a@b')), [['[^', '<a class="email" href="mailto:a@b">a@b</a>'], '']);
171
- assert.deepStrictEqual(inspect(parser('[#a++b\nc++]')), [['[', '<a class="hashtag" href="/hashtags/a">#a</a>', '<ins>b<br>c</ins>', ']'], '']);
172
- assert.deepStrictEqual(inspect(parser('[++a\nb++]{/}')), [['[', '<ins>a<br>b</ins>', ']', '<a class="url" href="/">/</a>'], '']);
173
- assert.deepStrictEqual(inspect(parser('[++a\nb]++')), [['[', '++', 'a', '<br>', 'b', ']', '++'], '']);
174
- assert.deepStrictEqual(inspect(parser('[++[a\nb++]')), [['[', '++', '[', 'a', '<br>', 'b', '++', ']'], '']);
175
- assert.deepStrictEqual(inspect(parser('[[++a\nb++]]')), [['[', '[', '<ins>a<br>b</ins>', ']', ']'], '']);
176
173
  assert.deepStrictEqual(inspect(parser('"[% *"*"*')), [['"', '[%', ' ', '*', '"', '*', '"', '*'], '']);
177
174
  assert.deepStrictEqual(inspect(parser('"[% "*"* %]')), [['"', '<span class="remark"><input type="checkbox"><span>[% "*"* %]</span></span>'], '']);
178
175
  });
@@ -22,22 +22,3 @@ export function str(pattern: string | RegExp, not?: string): Parser<string, Cont
22
22
  : undefined;
23
23
  });
24
24
  }
25
-
26
- export function stropt(pattern: string | RegExp): StrParser;
27
- export function stropt(pattern: string | RegExp): Parser<string, Context<StrParser>, []> {
28
- assert(pattern);
29
- return typeof pattern === 'string'
30
- ? creation(1, false, ({ source }) => {
31
- if (source === '') return;
32
- return source.slice(0, pattern.length) === pattern
33
- ? [[pattern], source.slice(pattern.length)]
34
- : [[''], source];
35
- })
36
- : creation(1, false, ({ source }) => {
37
- if (source === '') return;
38
- const m = source.match(pattern);
39
- return m
40
- ? [[m[0]], source.slice(m[0].length)]
41
- : undefined;
42
- });
43
- }
@@ -2,7 +2,7 @@ import { text } from './text';
2
2
  import { some } from '../../combinator';
3
3
  import { inspect } from '../../debug.test';
4
4
 
5
- describe('Unit: parser/text/text', () => {
5
+ describe('Unit: parser/source/text', () => {
6
6
  describe('text', () => {
7
7
  const parser = (source: string) => some(text)({ source, context: {} });
8
8
 
@@ -3,9 +3,9 @@ import { union, creation, focus } from '../../combinator';
3
3
  import { str } from './str';
4
4
  import { html } from 'typed-dom/dom';
5
5
 
6
- export const delimiter = /[\s\x00-\x7F]|\S[#>]/u;
7
- export const nonWhitespace = /[\S\n]|$/;
8
- export const nonAlphanumeric = /[^0-9A-Za-z]|\S[#>]|$/;
6
+ export const delimiter = /[\s\x00-\x7F()]|\S[#>]/u;
7
+ export const nonWhitespace = /[\S\n]|$/u;
8
+ export const nonAlphanumeric = /[^0-9A-Za-z]|\S[#>]|$/u;
9
9
  const repeat = str(/^(.)\1*/);
10
10
 
11
11
  export const text: TextParser = creation(1, false, ({ source, context }) => {
@@ -14,5 +14,5 @@ export import AnyLineParser = SourceParser.AnyLineParser;
14
14
  export { text, txt, linebreak } from './source/text';
15
15
  export { escsource } from './source/escapable';
16
16
  export { unescsource } from './source/unescapable';
17
- export { str, stropt } from './source/str';
17
+ export { str } from './source/str';
18
18
  export { contentline, emptyline, anyline } from './source/line';
@@ -170,7 +170,6 @@ function trimBlankEnd<T extends HTMLElement | string>(parser: Parser<T>): Parser
170
170
  //}
171
171
  //function trimNodeStart<T extends HTMLElement | string>(nodes: T[]): T[] {
172
172
  // for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes[0], 0);) {
173
- // if (nodes.length === 1 && typeof node === 'object' && node.className === 'indexer') break;
174
173
  // if (typeof node === 'string') {
175
174
  // const pos = node.trimStart().length;
176
175
  // if (pos > 0) {
@@ -178,6 +177,9 @@ function trimBlankEnd<T extends HTMLElement | string>(parser: Parser<T>): Parser
178
177
  // break;
179
178
  // }
180
179
  // }
180
+ // else if (nodes.length === 1 && node.className === 'indexer') {
181
+ // break;
182
+ // }
181
183
  // nodes.shift();
182
184
  // }
183
185
  // return nodes;