securemark 0.240.0 → 0.241.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 (89) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/design.md +2 -2
  3. package/dist/securemark.js +1260 -2745
  4. package/gulpfile.js +1 -1
  5. package/index.d.ts +0 -1
  6. package/package-lock.json +285 -160
  7. package/package.json +8 -8
  8. package/src/combinator/control/manipulation/fallback.ts +0 -1
  9. package/src/combinator/control/manipulation/indent.ts +3 -3
  10. package/src/combinator/data/parser/some.ts +28 -6
  11. package/src/combinator/data/parser.ts +21 -16
  12. package/src/debug.test.ts +1 -1
  13. package/src/parser/api/bind.test.ts +1 -1
  14. package/src/parser/api/parse.test.ts +7 -1
  15. package/src/parser/api/parse.ts +1 -1
  16. package/src/parser/block/blockquote.ts +1 -1
  17. package/src/parser/block/codeblock.ts +1 -1
  18. package/src/parser/block/dlist.ts +1 -1
  19. package/src/parser/block/extension/aside.ts +1 -1
  20. package/src/parser/block/extension/example.ts +1 -1
  21. package/src/parser/block/extension/figbase.ts +1 -1
  22. package/src/parser/block/extension/figure.ts +21 -20
  23. package/src/parser/block/extension/message.ts +1 -1
  24. package/src/parser/block/extension/placeholder.ts +1 -1
  25. package/src/parser/block/extension/table.test.ts +1 -1
  26. package/src/parser/block/extension/table.ts +1 -1
  27. package/src/parser/block/heading.ts +1 -1
  28. package/src/parser/block/horizontalrule.ts +1 -1
  29. package/src/parser/block/ilist.ts +1 -1
  30. package/src/parser/block/mathblock.ts +1 -1
  31. package/src/parser/block/olist.ts +8 -8
  32. package/src/parser/block/paragraph.ts +1 -1
  33. package/src/parser/block/reply/cite.ts +1 -1
  34. package/src/parser/block/reply/quote.ts +1 -1
  35. package/src/parser/block/reply.ts +1 -1
  36. package/src/parser/block/table.ts +1 -1
  37. package/src/parser/block/ulist.ts +1 -1
  38. package/src/parser/block.ts +1 -1
  39. package/src/parser/header.ts +1 -1
  40. package/src/parser/inline/annotation.ts +2 -2
  41. package/src/parser/inline/autolink/account.ts +1 -1
  42. package/src/parser/inline/autolink/anchor.ts +1 -1
  43. package/src/parser/inline/autolink/channel.ts +1 -1
  44. package/src/parser/inline/autolink/email.ts +1 -1
  45. package/src/parser/inline/autolink/hashnum.ts +1 -1
  46. package/src/parser/inline/autolink/hashtag.ts +1 -1
  47. package/src/parser/inline/bracket.test.ts +5 -1
  48. package/src/parser/inline/bracket.ts +3 -3
  49. package/src/parser/inline/code.ts +1 -1
  50. package/src/parser/inline/comment.ts +2 -2
  51. package/src/parser/inline/deletion.ts +1 -1
  52. package/src/parser/inline/emphasis.ts +1 -1
  53. package/src/parser/inline/emstrong.ts +1 -1
  54. package/src/parser/inline/extension/index.ts +1 -1
  55. package/src/parser/inline/extension/indexee.ts +1 -1
  56. package/src/parser/inline/extension/indexer.ts +1 -1
  57. package/src/parser/inline/extension/label.ts +1 -1
  58. package/src/parser/inline/extension/placeholder.ts +1 -1
  59. package/src/parser/inline/html.ts +1 -1
  60. package/src/parser/inline/htmlentity.ts +1 -1
  61. package/src/parser/inline/insertion.ts +1 -1
  62. package/src/parser/inline/link.ts +1 -1
  63. package/src/parser/inline/mark.ts +1 -1
  64. package/src/parser/inline/math.ts +1 -1
  65. package/src/parser/inline/media.ts +1 -1
  66. package/src/parser/inline/reference.ts +2 -2
  67. package/src/parser/inline/ruby.ts +1 -1
  68. package/src/parser/inline/strong.ts +1 -1
  69. package/src/parser/inline/template.ts +1 -1
  70. package/src/parser/inline.test.ts +4 -0
  71. package/src/parser/locale.ts +1 -1
  72. package/src/parser/processor/figure.test.ts +1 -1
  73. package/src/parser/processor/figure.ts +1 -1
  74. package/src/parser/processor/footnote.test.ts +1 -1
  75. package/src/parser/processor/footnote.ts +5 -4
  76. package/src/parser/source/text.ts +1 -1
  77. package/src/renderer/render/math.ts +1 -1
  78. package/src/renderer/render/media/audio.ts +1 -1
  79. package/src/renderer/render/media/image.ts +1 -1
  80. package/src/renderer/render/media/pdf.ts +1 -1
  81. package/src/renderer/render/media/twitter.ts +21 -23
  82. package/src/renderer/render/media/video.ts +1 -1
  83. package/src/renderer/render/media/youtube.ts +1 -1
  84. package/src/renderer/render/media.test.ts +1 -1
  85. package/src/util/quote.ts +1 -1
  86. package/src/util/toc.test.ts +1 -1
  87. package/src/util/toc.ts +1 -1
  88. package/src/util.ts +0 -1
  89. package/src/util/sync.ts +0 -57
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.240.0",
3
+ "version": "0.241.0",
4
4
  "description": "Secure markdown renderer working on browsers for user input data.",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/falsandtru/securemark",
@@ -33,12 +33,12 @@
33
33
  "@types/dompurify": "2.3.3",
34
34
  "@types/jquery": "3.5.14",
35
35
  "@types/mathjax": "0.0.37",
36
- "@types/mocha": "9.1.0",
36
+ "@types/mocha": "9.1.1",
37
37
  "@types/power-assert": "1.5.8",
38
38
  "@types/prismjs": "1.26.0",
39
39
  "browserify": "^17.0.0",
40
40
  "browserify-shim": "^3.8.14",
41
- "concurrently": "^7.0.0",
41
+ "concurrently": "^7.1.0",
42
42
  "del": "^6.0.0",
43
43
  "eslint-plugin-redos": "^4.3.0",
44
44
  "gulp": "^4.0.2",
@@ -50,7 +50,7 @@
50
50
  "gulp-mocha": "^8.0.0",
51
51
  "gulp-rename": "^2.0.0",
52
52
  "gulp-unassert": "^2.0.0",
53
- "karma": "^6.3.17",
53
+ "karma": "^6.3.19",
54
54
  "karma-chrome-launcher": "^3.1.1",
55
55
  "karma-coverage-istanbul-instrumenter": "^1.0.4",
56
56
  "karma-coverage-istanbul-reporter": "^3.0.3",
@@ -58,12 +58,12 @@
58
58
  "karma-firefox-launcher": "^2.1.2",
59
59
  "karma-mocha": "^2.0.1",
60
60
  "mocha": "^9.2.2",
61
- "npm-check-updates": "^12.5.4",
61
+ "npm-check-updates": "^12.5.9",
62
62
  "power-assert": "^1.6.1",
63
- "semver": "^7.3.5",
64
- "spica": "0.0.515",
63
+ "semver": "^7.3.7",
64
+ "spica": "0.0.521",
65
65
  "tsify": "^5.0.4",
66
- "typed-dom": "0.0.250",
66
+ "typed-dom": "0.0.253",
67
67
  "typescript": "4.6.3",
68
68
  "vinyl-buffer": "^1.0.1",
69
69
  "vinyl-source-stream": "^2.0.0"
@@ -2,7 +2,6 @@ import { Parser, Tree, Context } from '../../data/parser';
2
2
  import { union } from '../../data/parser/union';
3
3
 
4
4
  export function fallback<P extends Parser<unknown>>(parser: P, otherwise: Parser<Tree<P>, Context<P>>): P;
5
- export function fallback<T, P extends Parser<T>>(parser: P, otherwise: Parser<T, Context<P>>): P;
6
5
  export function fallback<T>(parser: Parser<T>, otherwise: Parser<T>): Parser<T> {
7
6
  return union([parser, otherwise]);
8
7
  }
@@ -5,7 +5,7 @@ import { line } from '../constraint/line';
5
5
  import { bind } from '../monad/bind';
6
6
  import { match } from './match';
7
7
  import { open } from './surround';
8
- import { reduce } from 'spica/memoize';
8
+ import { memoize } from 'spica/memoize';
9
9
  import { join } from 'spica/array';
10
10
 
11
11
  export function indent<P extends Parser<unknown>>(parser: P): P;
@@ -13,10 +13,10 @@ export function indent<T>(parser: Parser<T>): Parser<T> {
13
13
  assert(parser);
14
14
  return bind(match(
15
15
  /^(?=(([ \t])\2*))/,
16
- reduce<string[], Parser<string>, string>(
16
+ memoize(
17
17
  ([, indent]) =>
18
18
  some(line(open(indent, source => [[unline(source)], '']))),
19
- ([, indent]) => indent)),
19
+ ([, indent]) => indent.length * 2 + +(indent[0] === ' '), [])),
20
20
  (nodes, rest, context) => {
21
21
  const result = parser(join(nodes, '\n'), context);
22
22
  return result && exec(result) === ''
@@ -14,14 +14,14 @@ const signature = (pattern: string | RegExp | undefined): string => {
14
14
  }
15
15
  };
16
16
  const matcher = memoize(
17
- (pattern: string | RegExp | undefined): (source: string) => boolean => {
17
+ (pattern: string | RegExp | undefined): (source: string) => true | undefined => {
18
18
  switch (typeof pattern) {
19
19
  case 'undefined':
20
- return () => false;
20
+ return () => undefined;
21
21
  case 'string':
22
- return source => source.slice(0, pattern.length) === pattern;
22
+ return source => source.slice(0, pattern.length) === pattern || undefined;
23
23
  case 'object':
24
- return reduce(source => pattern.test(source));
24
+ return reduce(source => pattern.test(source) || undefined);
25
25
  }
26
26
  },
27
27
  signature);
@@ -42,8 +42,8 @@ export function some<T>(parser: Parser<T>, until?: string | RegExp | number, dee
42
42
  let rest = source;
43
43
  let nodes: T[] | undefined;
44
44
  if (deep && context) {
45
- // bracket > annotation > bracket > reference > bracket > link > media | bracket
46
- // bracket > annotation > bracket > reference > bracket > index > bracket
45
+ // bracket > link > media | bracket
46
+ // bracket > index > bracket
47
47
  context.delimiters ??= new Delimiters();
48
48
  context.delimiters.push(delimiter);
49
49
  }
@@ -69,3 +69,25 @@ export function some<T>(parser: Parser<T>, until?: string | RegExp | number, dee
69
69
  : undefined;
70
70
  };
71
71
  }
72
+
73
+ export function escape<P extends Parser<unknown>>(parser: P, delim: string): P;
74
+ export function escape<T>(parser: Parser<T>, delim: string): Parser<T> {
75
+ assert(parser);
76
+ const delimiter = {
77
+ signature: signature(delim),
78
+ matcher: (source: string) => source.slice(0, delim.length) !== delim && undefined,
79
+ escape: true,
80
+ } as const;
81
+ return (source, context) => {
82
+ if (source === '') return;
83
+ if (context) {
84
+ context.delimiters ??= new Delimiters();
85
+ context.delimiters.push(delimiter);
86
+ }
87
+ const result = parser(source, context);
88
+ if (context.delimiters) {
89
+ context.delimiters.pop();
90
+ }
91
+ return result;
92
+ };
93
+ }
@@ -20,26 +20,31 @@ type ExtractSubTree<D extends Parser<unknown>[]> = ExtractSubParser<D> extends i
20
20
  type ExtractSubParser<D extends Parser<unknown>[]> = D extends (infer P)[] ? P extends Parser<unknown> ? P : never : never;
21
21
 
22
22
  export class Delimiters {
23
- private readonly stack: string[] = [];
24
- private readonly matchers: Record<string, (source: string) => boolean> = {};
25
- public push(delimiter: { readonly signature: string; readonly matcher: (source: string) => boolean; }): void {
26
- const { signature, matcher } = delimiter;
27
- this.stack.push(signature);
28
- this.matchers[signature] ??= matcher;
29
- assert(this.matchers[signature] === matcher);
23
+ private readonly matchers: ((source: string) => boolean | undefined)[] = [];
24
+ private readonly record: Record<string, boolean> = {};
25
+ public push(delimiter: { readonly signature: string; readonly matcher: (source: string) => boolean | undefined; readonly escape?: boolean; }): void {
26
+ const { signature, matcher, escape } = delimiter;
27
+ if (this.record[signature] === !escape) {
28
+ this.matchers.unshift(() => undefined);
29
+ }
30
+ else {
31
+ this.matchers.unshift(matcher);
32
+ this.record[signature] = !escape;
33
+ }
30
34
  }
31
35
  public pop(): void {
32
- assert(this.stack.length > 0);
33
- this.stack.pop();
36
+ assert(this.matchers.length > 0);
37
+ this.matchers.shift();
34
38
  }
35
39
  public match(source: string): boolean {
36
- const { stack, matchers } = this;
37
- const log = {};
38
- for (let i = 0; i < stack.length; ++i) {
39
- const sig = stack[i];
40
- if (sig in log) continue;
41
- if (matchers[sig](source)) return true;
42
- log[sig] = false;
40
+ const { matchers } = this;
41
+ for (let i = 0; i < matchers.length; ++i) {
42
+ switch (matchers[i](source)) {
43
+ case true:
44
+ return true;
45
+ case false:
46
+ return false;
47
+ }
43
48
  }
44
49
  return false;
45
50
  }
package/src/debug.test.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Result, eval, exec } from './combinator/data/parser';
2
- import { html, define } from 'typed-dom';
2
+ import { html, define } from 'typed-dom/dom';
3
3
 
4
4
  export function inspect(result: Result<HTMLElement | string>, until: number | string = Infinity): Result<string> {
5
5
  return result && [
@@ -1,6 +1,6 @@
1
1
  import { ParserSettings, Progress } from '../../..';
2
2
  import { bind } from './bind';
3
- import { frag, html } from 'typed-dom';
3
+ import { frag, html } from 'typed-dom/dom';
4
4
 
5
5
  describe('Unit: parser/api/bind', () => {
6
6
  describe('bind', () => {
@@ -1,5 +1,5 @@
1
1
  import { parse } from './parse';
2
- import { html } from 'typed-dom';
2
+ import { html } from 'typed-dom/dom';
3
3
 
4
4
  describe('Unit: parser/api/parse', () => {
5
5
  describe('parse', () => {
@@ -218,6 +218,12 @@ describe('Unit: parser/api/parse', () => {
218
218
  ['<p>a<span class="linebreak"> </span>b</p>']);
219
219
  });
220
220
 
221
+ it('creation', () => {
222
+ assert.deepStrictEqual(
223
+ [...parse('"[# '.repeat(100)).children].map(el => el.outerHTML),
224
+ [`<p>${'"[# '.repeat(100).trim()}</p>`]);
225
+ });
226
+
221
227
  it('recursion', () => {
222
228
  assert.deepStrictEqual(
223
229
  [...parse('('.repeat(199)).children].map(el => el.outerHTML),
@@ -9,7 +9,7 @@ import { normalize } from './normalize';
9
9
  import { headers } from './header';
10
10
  import { figure } from '../processor/figure';
11
11
  import { footnote } from '../processor/footnote';
12
- import { frag } from 'typed-dom';
12
+ import { frag } from 'typed-dom/dom';
13
13
  import { ReadonlyURL } from 'spica/url';
14
14
 
15
15
  interface Options extends ParserOptions {
@@ -3,7 +3,7 @@ import { union, some, block, validate, rewrite, creator, open, convert, lazy, fm
3
3
  import { autolink } from '../autolink';
4
4
  import { contentline } from '../source';
5
5
  import { parse } from '../api/parse';
6
- import { html, defrag } from 'typed-dom';
6
+ import { html, defrag } from 'typed-dom/dom';
7
7
 
8
8
  export const segment: BlockquoteParser.SegmentParser = block(validate(['!>', '>'], union([
9
9
  validate(/^!?>+(?=[^\S\n]|\n[^\S\n]*\S)/, some(contentline)),
@@ -3,7 +3,7 @@ import { CodeBlockParser } from '../block';
3
3
  import { eval } from '../../combinator/data/parser';
4
4
  import { some, block, validate, fence, clear, fmap } from '../../combinator';
5
5
  import { autolink } from '../autolink';
6
- import { html, defrag } from 'typed-dom';
6
+ import { html, defrag } from 'typed-dom/dom';
7
7
 
8
8
  const opener = /^(`{3,})(?!`)([^\n]*)(?:$|\n)/;
9
9
  const language = /^[0-9a-z]+(?:-[a-z][0-9a-z]*)*$/i;
@@ -4,7 +4,7 @@ import { inline, indexee, indexer } from '../inline';
4
4
  import { anyline } from '../source';
5
5
  import { localize } from '../locale';
6
6
  import { visualize } from '../util';
7
- import { html, defrag } from 'typed-dom';
7
+ import { html, defrag } from 'typed-dom/dom';
8
8
  import { push } from 'spica/array';
9
9
 
10
10
  export const dlist: DListParser = lazy(() => block(localize(fmap(validate(
@@ -2,7 +2,7 @@ import { ExtensionParser } from '../../block';
2
2
  import { block, validate, fence, creator, fmap } from '../../../combinator';
3
3
  import { identity, text } from '../../inline/extension/indexee';
4
4
  import { parse } from '../../api/parse';
5
- import { html } from 'typed-dom';
5
+ import { html } from 'typed-dom/dom';
6
6
 
7
7
  export const aside: ExtensionParser.AsideParser = creator(100, block(validate('~~~', fmap(
8
8
  fence(/^(~{3,})aside(?!\S)([^\n]*)(?:$|\n)/, 300),
@@ -3,7 +3,7 @@ import { eval } from '../../../combinator/data/parser';
3
3
  import { block, validate, fence, creator, fmap } from '../../../combinator';
4
4
  import { parse } from '../../api/parse';
5
5
  import { mathblock } from '../mathblock';
6
- import { html } from 'typed-dom';
6
+ import { html } from 'typed-dom/dom';
7
7
 
8
8
  const opener = /^(~{3,})(?:example\/(\S+)|(?!\S))([^\n]*)(?:$|\n)/;
9
9
 
@@ -1,7 +1,7 @@
1
1
  import { ExtensionParser } from '../../block';
2
2
  import { union, block, line, validate, fmap } from '../../../combinator';
3
3
  import { label } from '../../inline/extension/label';
4
- import { html } from 'typed-dom';
4
+ import { html } from 'typed-dom/dom';
5
5
 
6
6
  export const figbase: ExtensionParser.FigbaseParser = block(fmap(
7
7
  validate(/^\[?\$-(?:[0-9]+\.)*0\]?[^\S\n]*(?!\S|\n[^\S\n]*\S)/,
@@ -15,7 +15,7 @@ import { placeholder, segment_ as seg_placeholder } from './placeholder';
15
15
  import { inline, media, shortmedia } from '../../inline';
16
16
  import { localize } from '../../locale';
17
17
  import { visualize } from '../../util';
18
- import { html, defrag } from 'typed-dom';
18
+ import { html, defrag } from 'typed-dom/dom';
19
19
  import { memoize } from 'spica/memoize';
20
20
  import { unshift } from 'spica/array';
21
21
 
@@ -46,7 +46,7 @@ export const segment: FigureParser.SegmentParser = block(match(
46
46
  ]),
47
47
  ]),
48
48
  closer),
49
- ([, fence]) => fence.length)));
49
+ ([, fence]) => fence.length, [])));
50
50
 
51
51
  export const figure: FigureParser = block(rewrite(segment, fmap(
52
52
  convert(source => source.slice(source.search(/[[$]/), source.trimEnd().lastIndexOf('\n')),
@@ -120,43 +120,44 @@ function attributes(label: string, param: string, content: HTMLElement, caption:
120
120
  'data-invalid-message': 'Invalid argument',
121
121
  } ||
122
122
  group === '$' && (type !== 'math' || caption.length > 0) && {
123
- 'data-invalid-type': 'content',
124
- 'data-invalid-message': '`$` label group can only be used with a math formula with no caption',
123
+ 'data-invalid-type': 'label',
124
+ 'data-invalid-message': '"$" label group must be used to math formulas with no caption',
125
125
  } ||
126
- ['fig', 'figure'].includes(group) && type !== 'media' && {
127
- 'data-invalid-type': 'content',
128
- 'data-invalid-message': '`fig` and `figure` label groups can only be used with media',
126
+ type === 'media' && {} ||
127
+ ['fig', 'figure'].includes(group) && {
128
+ 'data-invalid-type': 'label',
129
+ 'data-invalid-message': '"fig" and "figure" label groups must be used to media',
129
130
  } ||
130
131
  group === 'table' && type !== group && {
131
- 'data-invalid-type': 'content',
132
- 'data-invalid-message': '`table` label group can only be used with a table',
132
+ 'data-invalid-type': 'label',
133
+ 'data-invalid-message': '"table" label group must be used to tables',
133
134
  } ||
134
135
  group === 'list' && type !== group && {
135
- 'data-invalid-type': 'content',
136
- 'data-invalid-message': '`list` label group can only be used with a list',
136
+ 'data-invalid-type': 'label',
137
+ 'data-invalid-message': '"list" label group must be used to lists',
137
138
  } ||
138
139
  group === 'quote' && type !== group && {
139
- 'data-invalid-type': 'content',
140
- 'data-invalid-message': '`quote` label group can only be used with a blockquote',
140
+ 'data-invalid-type': 'label',
141
+ 'data-invalid-message': '"quote" label group must be used to blockquotes',
141
142
  } ||
142
143
  group === 'text' && type !== group && {
143
- 'data-invalid-type': 'content',
144
- 'data-invalid-message': '`text` label group can only be used with a codeblock with no language',
144
+ 'data-invalid-type': 'label',
145
+ 'data-invalid-message': '"text" label group must be used to codeblocks with no language',
145
146
  } ||
146
147
  group === 'code' && type !== group && {
147
- 'data-invalid-type': 'content',
148
- 'data-invalid-message': '`code` label group can only be used with a codeblock',
148
+ 'data-invalid-type': 'label',
149
+ 'data-invalid-message': '"code" label group must be used to codeblocks with any language',
149
150
  } ||
150
151
  group === 'example' && type !== group && {
151
- 'data-invalid-type': 'content',
152
- 'data-invalid-message': '`example` label group can only be used with an example',
152
+ 'data-invalid-type': 'label',
153
+ 'data-invalid-message': '"example" label group must be used to examples',
153
154
  } ||
154
155
  undefined;
155
156
  return {
156
157
  'data-type': type,
157
158
  'data-label': label,
158
159
  'data-group': group,
159
- ...invalid && {
160
+ ...invalid?.['data-invalid-type'] && {
160
161
  class: 'invalid',
161
162
  'data-invalid-syntax': 'figure',
162
163
  ...invalid,
@@ -11,7 +11,7 @@ import { codeblock } from '../codeblock';
11
11
  import { mathblock } from '../mathblock';
12
12
  import { blockquote } from '../blockquote';
13
13
  import { paragraph } from '../paragraph';
14
- import { html } from 'typed-dom';
14
+ import { html } from 'typed-dom/dom';
15
15
  import { unshift, push } from 'spica/array';
16
16
 
17
17
  import MessageParser = ExtensionParser.MessageParser;
@@ -1,6 +1,6 @@
1
1
  import { ExtensionParser } from '../../block';
2
2
  import { block, validate, fence, clear, fmap } from '../../../combinator';
3
- import { html } from 'typed-dom';
3
+ import { html } from 'typed-dom/dom';
4
4
 
5
5
  const opener = /^(~{3,})(?!~)[^\n]*(?:$|\n)/;
6
6
 
@@ -1,7 +1,7 @@
1
1
  import { table } from './table';
2
2
  import { some } from '../../../combinator';
3
3
  import { inspect } from '../../../debug.test';
4
- import { html } from 'typed-dom';
4
+ import { html } from 'typed-dom/dom';
5
5
 
6
6
  describe('Unit: parser/block/extension/table', () => {
7
7
  describe('table', () => {
@@ -7,7 +7,7 @@ import { inline } from '../../inline';
7
7
  import { str, anyline, emptyline, contentline } from '../../source';
8
8
  import { localize } from '../../locale';
9
9
  import { visualize } from '../../util';
10
- import { html, defrag } from 'typed-dom';
10
+ import { html, defrag } from 'typed-dom/dom';
11
11
  import { unshift, splice } from 'spica/array';
12
12
 
13
13
  import TableParser = ExtensionParser.TableParser;
@@ -3,7 +3,7 @@ import { union, some, block, line, validate, focus, rewrite, context, open, trim
3
3
  import { inline, indexee, indexer } from '../inline';
4
4
  import { str } from '../source';
5
5
  import { visualize } from '../util';
6
- import { html, defrag } from 'typed-dom';
6
+ import { html, defrag } from 'typed-dom/dom';
7
7
 
8
8
  export const segment: HeadingParser.SegmentParser = block(validate('#', focus(
9
9
  /^#+[^\S\n]+\S[^\n]*(?:\n#+(?!\S)[^\n]*)*(?:$|\n)/,
@@ -1,6 +1,6 @@
1
1
  import { HorizontalRuleParser } from '../block';
2
2
  import { block, line, focus } from '../../combinator';
3
- import { html } from 'typed-dom';
3
+ import { html } from 'typed-dom/dom';
4
4
 
5
5
  export const horizontalrule: HorizontalRuleParser = block(line(focus(
6
6
  /^-{3,}[^\S\n]*(?:$|\n)/,
@@ -4,7 +4,7 @@ import { ulist_, fillFirstLine } from './ulist';
4
4
  import { olist_ } from './olist';
5
5
  import { inline } from '../inline';
6
6
  import { contentline } from '../source';
7
- import { html, defrag } from 'typed-dom';
7
+ import { html, defrag } from 'typed-dom/dom';
8
8
 
9
9
  export const ilist: IListParser = lazy(() => block(validate(
10
10
  /^[-+*](?=[^\S\n]|\n[^\S\n]*\S)/,
@@ -1,7 +1,7 @@
1
1
  import { undefined } from 'spica/global';
2
2
  import { MathBlockParser } from '../block';
3
3
  import { block, validate, fence, clear, fmap } from '../../combinator';
4
- import { html } from 'typed-dom';
4
+ import { html } from 'typed-dom/dom';
5
5
 
6
6
  const opener = /^(\${2,})(?!\$)([^\n]*)(?:$|\n)/;
7
7
 
@@ -5,7 +5,7 @@ import { checkbox, ulist_, fillFirstLine } from './ulist';
5
5
  import { ilist_ } from './ilist';
6
6
  import { inline, indexee, indexer } from '../inline';
7
7
  import { contentline } from '../source';
8
- import { html, define, defrag } from 'typed-dom';
8
+ import { html, define, defrag } from 'typed-dom/dom';
9
9
  import { memoize } from 'spica/memoize';
10
10
  import { shift } from 'spica/array';
11
11
 
@@ -25,23 +25,23 @@ export const olist: OListParser = lazy(() => block(validate(
25
25
  export const olist_: OListParser = lazy(() => block(union([
26
26
  match(
27
27
  new RegExp(`^(?=${openers['.'].source.replace('?:', '')})`),
28
- memoize(ms => list(type(ms[1]), '.'), ms => type(ms[1]))),
28
+ memoize(ms => list(type(ms[1]), '.'), ms => type(ms[1]).charCodeAt(0) || 0, [])),
29
29
  match(
30
30
  new RegExp(`^(?=${openers['('].source.replace('?:', '')})`),
31
- memoize(ms => list(type(ms[1]), '('), ms => type(ms[1]))),
31
+ memoize(ms => list(type(ms[1]), '('), ms => type(ms[1]).charCodeAt(0) || 0, [])),
32
32
  ])));
33
33
 
34
- const list = (type: string, delim: string): OListParser.ListParser => fmap(
34
+ const list = (type: string, form: string): OListParser.ListParser => fmap(
35
35
  some(creator(union([
36
36
  indexee(fmap(fallback(
37
37
  inits([
38
- line(open(heads[delim], trim(subsequence([checkbox, trimStart(some(union([indexer, inline])))])), true)),
38
+ line(open(heads[form], trim(subsequence([checkbox, trimStart(some(union([indexer, inline])))])), true)),
39
39
  indent(union([ulist_, olist_, ilist_])),
40
40
  ]),
41
41
  invalid),
42
42
  (ns: [string, ...(HTMLElement | string)[]]) => [html('li', { 'data-marker': ns[0] }, defrag(fillFirstLine(shift(ns)[1])))]), true),
43
43
  ]))),
44
- es => [format(html('ol', es), type, delim)]);
44
+ es => [format(html('ol', es), type, form)]);
45
45
 
46
46
  const heads = {
47
47
  '.': focus(
@@ -107,13 +107,13 @@ function initial(type: string): RegExp {
107
107
  }
108
108
  }
109
109
 
110
- function format(el: HTMLOListElement, type: string, delim: string): HTMLOListElement {
110
+ function format(el: HTMLOListElement, type: string, form: string): HTMLOListElement {
111
111
  if (el.firstElementChild?.firstElementChild?.classList.contains('checkbox')) {
112
112
  el.setAttribute('class', 'checklist');
113
113
  }
114
114
  define(el, {
115
115
  type: type || undefined,
116
- 'data-format': delim === '.' ? undefined : 'paren',
116
+ 'data-format': form === '.' ? undefined : 'paren',
117
117
  'data-type': style(type) || undefined,
118
118
  });
119
119
  const marker = el.firstElementChild?.getAttribute('data-marker')!.match(initial(type))?.[0] ?? '';
@@ -3,7 +3,7 @@ import { union, some, block, trim, fmap } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { localize } from '../locale';
5
5
  import { visualize } from '../util';
6
- import { html, defrag } from 'typed-dom';
6
+ import { html, defrag } from 'typed-dom/dom';
7
7
 
8
8
  export const paragraph: ParagraphParser = block(localize(fmap(
9
9
  trim(visualize(some(union([inline])))),
@@ -2,7 +2,7 @@ import { ReplyParser } from '../../block';
2
2
  import { union, tails, line, validate, focus, creator, reverse, fmap } from '../../../combinator';
3
3
  import { anchor } from '../../inline/autolink/anchor';
4
4
  import { str } from '../../source';
5
- import { html, define, defrag } from 'typed-dom';
5
+ import { html, define, defrag } from 'typed-dom/dom';
6
6
 
7
7
  export const cite: ReplyParser.CiteParser = creator(line(fmap(validate(
8
8
  '>>',
@@ -4,7 +4,7 @@ import { union, some, block, line, validate, rewrite, creator, lazy, fmap } from
4
4
  import { math } from '../../inline/math';
5
5
  import { str, anyline } from '../../source';
6
6
  import { autolink } from '../../autolink';
7
- import { html, defrag } from 'typed-dom';
7
+ import { html, defrag } from 'typed-dom/dom';
8
8
 
9
9
  export const syntax = /^>+(?=[^\S\n])|^>(?=[^\s>])|^>+(?=[^\s>])(?![0-9a-z]+(?:-[0-9a-z]+)*(?![0-9A-Za-z@#:]))/;
10
10
 
@@ -6,7 +6,7 @@ import { inline } from '../inline';
6
6
  import { anyline } from '../source';
7
7
  import { localize } from '../locale';
8
8
  import { visualize } from '../util';
9
- import { html, defrag } from 'typed-dom';
9
+ import { html, defrag } from 'typed-dom/dom';
10
10
  import { push, pop } from 'spica/array';
11
11
 
12
12
  /*
@@ -2,7 +2,7 @@ import { TableParser } from '../block';
2
2
  import { union, sequence, some, block, line, validate, focus, rewrite, creator, surround, open, fallback, lazy, fmap } from '../../combinator';
3
3
  import { inline } from '../inline';
4
4
  import { contentline } from '../source';
5
- import { html, defrag } from 'typed-dom';
5
+ import { html, defrag } from 'typed-dom/dom';
6
6
  import { push } from 'spica/array';
7
7
 
8
8
  import RowParser = TableParser.RowParser;
@@ -3,7 +3,7 @@ import { union, inits, subsequence, some, block, line, validate, indent, focus,
3
3
  import { olist_ } from './olist';
4
4
  import { ilist_ } from './ilist';
5
5
  import { inline, indexer, indexee } from '../inline';
6
- import { html, defrag } from 'typed-dom';
6
+ import { html, defrag } from 'typed-dom/dom';
7
7
  import { unshift } from 'spica/array';
8
8
  import { contentline } from '../source';
9
9
 
@@ -15,7 +15,7 @@ import { mathblock } from './block/mathblock';
15
15
  import { extension } from './block/extension';
16
16
  import { reply } from './block/reply';
17
17
  import { paragraph } from './block/paragraph';
18
- import { html } from 'typed-dom';
18
+ import { html } from 'typed-dom/dom';
19
19
  import { rnd0Z } from 'spica/random';
20
20
 
21
21
  export import BlockParser = MarkdownParser.BlockParser;
@@ -3,7 +3,7 @@ import { union, inits, some, block, line, validate, focus, rewrite, guard, clear
3
3
  import { segment } from './segment';
4
4
  import { str } from './source';
5
5
  import { normalize } from './api/normalize';
6
- import { html, defrag } from 'typed-dom';
6
+ import { html, defrag } from 'typed-dom/dom';
7
7
 
8
8
  export const header: MarkdownParser.HeaderParser = lazy(() => validate(
9
9
  /^---+[^\S\v\f\r\n]*\r?\n[^\S\n]*(?=\S)/,
@@ -3,7 +3,7 @@ import { AnnotationParser } from '../inline';
3
3
  import { union, some, validate, guard, context, creator, surround, lazy, fmap } from '../../combinator';
4
4
  import { inline } from '../inline';
5
5
  import { startLoose, trimSpaceStart, trimNodeEnd } from '../util';
6
- import { html, defrag } from 'typed-dom';
6
+ import { html, defrag } from 'typed-dom/dom';
7
7
 
8
8
  export const annotation: AnnotationParser = lazy(() => creator(validate('((', '))', '\n', fmap(surround(
9
9
  '((',
@@ -19,7 +19,7 @@ export const annotation: AnnotationParser = lazy(() => creator(validate('((', ')
19
19
  //label: true,
20
20
  //link: true,
21
21
  //autolink: true,
22
- }}, state: undefined },
22
+ }}, state: undefined, delimiters: undefined },
23
23
  trimSpaceStart(union([some(inline, ')', /^\\?\n/)]))))),
24
24
  '))'),
25
25
  ns => [html('sup', { class: 'annotation' }, trimNodeEnd(defrag(ns)))]))));
@@ -2,7 +2,7 @@ import { AutolinkParser } from '../../inline';
2
2
  import { union, tails, verify, rewrite, context, open, convert, fmap, lazy } from '../../../combinator';
3
3
  import { link } from '../link';
4
4
  import { str } from '../../source';
5
- import { define } from 'typed-dom';
5
+ import { define } from 'typed-dom/dom';
6
6
 
7
7
  // https://example/@user must be a user page or a redirect page going there.
8
8
 
@@ -1,7 +1,7 @@
1
1
  import { AutolinkParser } from '../../inline';
2
2
  import { union, validate, focus, context, convert, fmap, lazy } from '../../../combinator';
3
3
  import { link } from '../link';
4
- import { define } from 'typed-dom';
4
+ import { define } from 'typed-dom/dom';
5
5
 
6
6
  // Timeline(pseudonym): user/tid
7
7
  // Thread(anonymous): cid