securemark 0.257.3 → 0.258.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.
- package/CHANGELOG.md +4 -0
- package/dist/index.js +1216 -606
- package/markdown.d.ts +1 -12
- package/package.json +9 -9
- package/src/combinator/control/manipulation/convert.ts +8 -4
- package/src/combinator/control/manipulation/scope.ts +10 -2
- package/src/combinator/data/parser/context/delimiter.ts +70 -0
- package/src/combinator/data/parser/context/memo.ts +30 -0
- package/src/combinator/{control/manipulation → data/parser}/context.test.ts +9 -9
- package/src/combinator/data/parser/context.ts +161 -0
- package/src/combinator/data/parser/sequence.test.ts +1 -1
- package/src/combinator/data/parser/sequence.ts +1 -1
- package/src/combinator/data/parser/some.test.ts +1 -1
- package/src/combinator/data/parser/some.ts +14 -37
- package/src/combinator/data/parser/subsequence.test.ts +1 -1
- package/src/combinator/data/parser/union.test.ts +1 -1
- package/src/combinator/data/parser.ts +7 -47
- package/src/combinator.ts +1 -2
- package/src/parser/api/bind.ts +5 -5
- package/src/parser/api/parse.ts +3 -1
- package/src/parser/block/blockquote.ts +1 -1
- package/src/parser/block/dlist.ts +4 -10
- package/src/parser/block/extension/figure.ts +4 -3
- package/src/parser/block/extension/table.ts +2 -2
- package/src/parser/block/heading.ts +5 -13
- package/src/parser/block/ilist.ts +3 -2
- package/src/parser/block/olist.ts +10 -7
- package/src/parser/block/paragraph.ts +1 -1
- package/src/parser/block/reply/cite.ts +1 -1
- package/src/parser/block/reply/quote.ts +1 -1
- package/src/parser/block/reply.ts +1 -1
- package/src/parser/block/sidefence.ts +1 -1
- package/src/parser/block/table.ts +9 -9
- package/src/parser/block/ulist.ts +4 -3
- package/src/parser/block.ts +1 -1
- package/src/parser/context.ts +32 -0
- package/src/parser/header.ts +1 -1
- package/src/parser/inline/annotation.ts +9 -17
- package/src/parser/inline/autolink/email.ts +1 -1
- package/src/parser/inline/autolink/url.ts +1 -1
- package/src/parser/inline/autolink.ts +5 -3
- package/src/parser/inline/bracket.ts +16 -15
- package/src/parser/inline/code.ts +1 -1
- package/src/parser/inline/comment.ts +4 -3
- package/src/parser/inline/deletion.ts +5 -4
- package/src/parser/inline/emphasis.ts +5 -4
- package/src/parser/inline/emstrong.ts +5 -4
- package/src/parser/inline/extension/index.ts +7 -14
- package/src/parser/inline/extension/indexee.ts +8 -10
- package/src/parser/inline/extension/indexer.ts +4 -3
- package/src/parser/inline/extension/label.ts +3 -2
- package/src/parser/inline/extension/placeholder.ts +5 -4
- package/src/parser/inline/html.ts +5 -4
- package/src/parser/inline/htmlentity.ts +1 -1
- package/src/parser/inline/insertion.ts +5 -4
- package/src/parser/inline/link.ts +11 -20
- package/src/parser/inline/mark.ts +5 -4
- package/src/parser/inline/math.ts +1 -1
- package/src/parser/inline/media.ts +8 -7
- package/src/parser/inline/reference.ts +10 -16
- package/src/parser/inline/ruby.ts +4 -3
- package/src/parser/inline/shortmedia.ts +3 -2
- package/src/parser/inline/strong.ts +5 -4
- package/src/parser/inline/template.test.ts +1 -1
- package/src/parser/inline/template.ts +9 -6
- package/src/parser/locale.ts +6 -7
- package/src/parser/processor/footnote.ts +5 -3
- package/src/parser/source/text.ts +1 -1
- package/src/parser/util.ts +0 -220
- package/src/parser/visibility.ts +205 -0
- package/src/util/info.ts +4 -2
- package/src/util/quote.ts +12 -15
- package/src/util/toc.ts +14 -17
- package/webpack.config.js +1 -0
- package/src/combinator/control/manipulation/context.ts +0 -70
- package/src/combinator/control/manipulation/resource.ts +0 -54
package/src/parser/api/bind.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { undefined, location } from 'spica/global';
|
|
|
2
2
|
import { ParserSettings, Progress } from '../../..';
|
|
3
3
|
import { MarkdownParser } from '../../../markdown';
|
|
4
4
|
import { eval } from '../../combinator/data/parser';
|
|
5
|
+
import { segment, validate, MAX_INPUT_SIZE } from '../segment';
|
|
5
6
|
import { header } from '../header';
|
|
6
7
|
import { block } from '../block';
|
|
7
|
-
import {
|
|
8
|
+
import { backtrackable } from '../context';
|
|
8
9
|
import { normalize } from './normalize';
|
|
9
10
|
import { headers } from './header';
|
|
10
11
|
import { figure } from '../processor/figure';
|
|
@@ -23,6 +24,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
|
|
|
23
24
|
let context: MarkdownParser.Context = {
|
|
24
25
|
...settings,
|
|
25
26
|
host: settings.host ?? new ReadonlyURL(location.pathname, location.origin),
|
|
27
|
+
backtrackable,
|
|
26
28
|
};
|
|
27
29
|
if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
|
|
28
30
|
assert(!settings.id);
|
|
@@ -141,8 +143,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
|
|
|
141
143
|
|
|
142
144
|
function nearest(index: number): HTMLElement | undefined {
|
|
143
145
|
let el: HTMLElement | undefined;
|
|
144
|
-
let len = 0;
|
|
145
|
-
for (let i = 0; i < blocks.length; ++i) {
|
|
146
|
+
for (let i = 0, len = 0; i < blocks.length; ++i) {
|
|
146
147
|
const block = blocks[i];
|
|
147
148
|
len += block[0].length;
|
|
148
149
|
el = block[1][0] ?? el;
|
|
@@ -152,8 +153,7 @@ export function bind(target: DocumentFragment | HTMLElement | ShadowRoot, settin
|
|
|
152
153
|
}
|
|
153
154
|
|
|
154
155
|
function index(source: HTMLElement): number {
|
|
155
|
-
let len = 0;
|
|
156
|
-
for (let i = 0; i < blocks.length; ++i) {
|
|
156
|
+
for (let i = 0, len = 0; i < blocks.length; ++i) {
|
|
157
157
|
const block = blocks[i];
|
|
158
158
|
if (block[1].includes(source)) return len;
|
|
159
159
|
len += block[0].length;
|
package/src/parser/api/parse.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { location } from 'spica/global';
|
|
|
2
2
|
import { ParserOptions } from '../../..';
|
|
3
3
|
import { MarkdownParser } from '../../../markdown';
|
|
4
4
|
import { eval } from '../../combinator/data/parser';
|
|
5
|
+
import { segment, validate, MAX_SEGMENT_SIZE } from '../segment';
|
|
5
6
|
import { header } from '../header';
|
|
6
7
|
import { block } from '../block';
|
|
7
|
-
import {
|
|
8
|
+
import { backtrackable } from '../context';
|
|
8
9
|
import { normalize } from './normalize';
|
|
9
10
|
import { headers } from './header';
|
|
10
11
|
import { figure } from '../processor/figure';
|
|
@@ -29,6 +30,7 @@ export function parse(source: string, opts: Options = {}, context?: MarkdownPars
|
|
|
29
30
|
...context?.resources && {
|
|
30
31
|
resources: context.resources,
|
|
31
32
|
},
|
|
33
|
+
backtrackable,
|
|
32
34
|
};
|
|
33
35
|
if (context.host?.origin === 'null') throw new Error(`Invalid host: ${context.host.href}`);
|
|
34
36
|
const node = frag();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BlockquoteParser } from '../block';
|
|
2
|
-
import { union, some, block, validate, rewrite,
|
|
2
|
+
import { union, some, creator, block, validate, rewrite, open, convert, lazy, fmap } from '../../combinator';
|
|
3
3
|
import { autolink } from '../autolink';
|
|
4
4
|
import { contentline } from '../source';
|
|
5
5
|
import { parse } from '../api/parse';
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
import { DListParser } from '../block';
|
|
2
|
-
import { union, inits, some, block, line, validate, rewrite,
|
|
2
|
+
import { union, inits, some, creator, state, block, line, validate, rewrite, open, trimEnd, lazy, fmap } from '../../combinator';
|
|
3
3
|
import { inline, indexee, indexer } from '../inline';
|
|
4
4
|
import { anyline } from '../source';
|
|
5
|
+
import { State } from '../context';
|
|
5
6
|
import { localize } from '../locale';
|
|
6
|
-
import { visualize, trimBlank } from '../
|
|
7
|
+
import { visualize, trimBlank } from '../visibility';
|
|
7
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
8
9
|
import { push } from 'spica/array';
|
|
9
10
|
|
|
10
11
|
export const dlist: DListParser = lazy(() => block(localize(fmap(validate(
|
|
11
12
|
/^~[^\S\n]+(?=\S)/,
|
|
12
13
|
some(inits([
|
|
13
|
-
|
|
14
|
-
annotation: false,
|
|
15
|
-
reference: false,
|
|
16
|
-
index: false,
|
|
17
|
-
label: false,
|
|
18
|
-
link: false,
|
|
19
|
-
media: false,
|
|
20
|
-
}}},
|
|
14
|
+
state(State.annotation | State.reference | State.index | State.label | State.link | State.media,
|
|
21
15
|
some(term)),
|
|
22
16
|
some(desc),
|
|
23
17
|
]))),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { ExtensionParser } from '../../block';
|
|
3
|
-
import { union, inits, sequence, some, block, line, fence, rewrite,
|
|
3
|
+
import { union, inits, sequence, some, state, block, line, fence, rewrite, close, match, convert, trimEnd, fallback, fmap } from '../../../combinator';
|
|
4
4
|
import { str, contentline, emptyline } from '../../source';
|
|
5
5
|
import { label, segment as seg_label } from '../../inline/extension/label';
|
|
6
6
|
import { ulist } from '../ulist';
|
|
@@ -13,8 +13,9 @@ import { table, segment_ as seg_table } from './table';
|
|
|
13
13
|
import { blockquote, segment as seg_blockquote } from '../blockquote';
|
|
14
14
|
import { placeholder, segment_ as seg_placeholder } from './placeholder';
|
|
15
15
|
import { inline, media, shortmedia } from '../../inline';
|
|
16
|
+
import { State } from '../../context';
|
|
16
17
|
import { localize } from '../../locale';
|
|
17
|
-
import { visualize, trimBlank } from '../../
|
|
18
|
+
import { visualize, trimBlank } from '../../visibility';
|
|
18
19
|
import { html, defrag } from 'typed-dom/dom';
|
|
19
20
|
import { memoize } from 'spica/memoize';
|
|
20
21
|
|
|
@@ -66,7 +67,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
|
|
|
66
67
|
])),
|
|
67
68
|
emptyline,
|
|
68
69
|
block(localize(
|
|
69
|
-
|
|
70
|
+
state(State.media,
|
|
70
71
|
visualize(trimBlank(trimEnd(some(inline))))))),
|
|
71
72
|
]),
|
|
72
73
|
])),
|
|
@@ -2,11 +2,11 @@ import { undefined, BigInt, Array } from 'spica/global';
|
|
|
2
2
|
import { max, min, isArray } from 'spica/alias';
|
|
3
3
|
import { ExtensionParser } from '../../block';
|
|
4
4
|
import { Tree, eval } from '../../../combinator/data/parser';
|
|
5
|
-
import { union, subsequence, inits, some, block, line, validate, fence, rewrite,
|
|
5
|
+
import { union, subsequence, inits, some, creator, block, line, validate, fence, rewrite, open, clear, convert, trim, dup, lazy, fmap } from '../../../combinator';
|
|
6
6
|
import { inline } from '../../inline';
|
|
7
7
|
import { str, anyline, emptyline, contentline } from '../../source';
|
|
8
8
|
import { localize } from '../../locale';
|
|
9
|
-
import { visualize } from '../../
|
|
9
|
+
import { visualize } from '../../visibility';
|
|
10
10
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
11
11
|
import { unshift, splice } from 'spica/array';
|
|
12
12
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { HeadingParser } from '../block';
|
|
2
|
-
import { union, some, block, line, validate, focus, rewrite,
|
|
2
|
+
import { union, some, state, block, line, validate, focus, rewrite, open, fmap } from '../../combinator';
|
|
3
3
|
import { inline, indexee, indexer } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
-
import {
|
|
5
|
+
import { State } from '../context';
|
|
6
|
+
import { visualize, trimBlank } from '../visibility';
|
|
6
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
8
|
|
|
8
9
|
export const segment: HeadingParser.SegmentParser = block(validate('#', focus(
|
|
@@ -10,23 +11,14 @@ export const segment: HeadingParser.SegmentParser = block(validate('#', focus(
|
|
|
10
11
|
some(line(source => [[source], ''])))));
|
|
11
12
|
|
|
12
13
|
export const heading: HeadingParser = block(rewrite(segment,
|
|
13
|
-
|
|
14
|
-
annotation: false,
|
|
15
|
-
reference: false,
|
|
16
|
-
index: false,
|
|
17
|
-
label: false,
|
|
18
|
-
link: false,
|
|
19
|
-
media: false,
|
|
20
|
-
}}},
|
|
14
|
+
state(State.annotation | State.reference | State.index | State.label | State.link | State.media,
|
|
21
15
|
line(indexee(fmap(union([
|
|
22
16
|
open(
|
|
23
17
|
str(/^##+/),
|
|
24
18
|
visualize(trimBlank(some(union([indexer, inline])))), true),
|
|
25
19
|
open(
|
|
26
20
|
str('#'),
|
|
27
|
-
|
|
28
|
-
autolink: false,
|
|
29
|
-
}}},
|
|
21
|
+
state(State.autolink,
|
|
30
22
|
visualize(trimBlank(some(union([indexer, inline]))))), true),
|
|
31
23
|
]),
|
|
32
24
|
([h, ...ns]: [string, ...(HTMLElement | string)[]]) => [
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { IListParser } from '../block';
|
|
2
|
-
import { union, inits, some, block, line, validate, indent,
|
|
2
|
+
import { union, inits, some, creator, state, block, line, validate, indent, open, fallback, lazy, fmap } from '../../combinator';
|
|
3
3
|
import { ulist_, fillFirstLine } from './ulist';
|
|
4
4
|
import { olist_, invalid } from './olist';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
|
+
import { State } from '../context';
|
|
6
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
8
|
|
|
8
9
|
export const ilist: IListParser = lazy(() => block(validate(
|
|
9
10
|
/^[-+*](?=[^\S\n]|\n[^\S\n]*\S)/,
|
|
10
|
-
|
|
11
|
+
state(State.media,
|
|
11
12
|
ilist_))));
|
|
12
13
|
|
|
13
14
|
export const ilist_: IListParser = lazy(() => block(fmap(validate(
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { OListParser } from '../block';
|
|
3
|
-
import { union, inits, subsequence, some, block, line, validate, indent, focus, rewrite,
|
|
3
|
+
import { union, inits, subsequence, some, creator, state, block, line, validate, indent, focus, rewrite, open, match, fallback, lazy, fmap } from '../../combinator';
|
|
4
4
|
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 {
|
|
8
|
+
import { State } from '../context';
|
|
9
|
+
import { trimBlank } from '../visibility';
|
|
9
10
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
10
11
|
import { memoize } from 'spica/memoize';
|
|
12
|
+
import { duffbk } from 'spica/duff';
|
|
11
13
|
import { shift } from 'spica/array';
|
|
12
14
|
import { tuple } from 'spica/tuple';
|
|
13
15
|
|
|
@@ -21,7 +23,7 @@ export const olist: OListParser = lazy(() => block(validate(
|
|
|
21
23
|
/^([0-9]+|[a-z]+|[A-Z]+)(?:-[0-9]+)*\.(?=[^\S\n]|\n[^\S\n]*\S)/.source,
|
|
22
24
|
/^\(([0-9]+|[a-z]+)\)(?:-[0-9]+)*(?=[^\S\n]|\n[^\S\n]*\S)/.source,
|
|
23
25
|
].join('|')),
|
|
24
|
-
|
|
26
|
+
state(State.media,
|
|
25
27
|
olist_))));
|
|
26
28
|
|
|
27
29
|
export const olist_: OListParser = lazy(() => block(union([
|
|
@@ -122,15 +124,16 @@ function format(el: HTMLOListElement, type: string, form: string): HTMLOListElem
|
|
|
122
124
|
'data-type': style(type) || undefined,
|
|
123
125
|
});
|
|
124
126
|
const marker = el.firstElementChild?.getAttribute('data-marker')!.match(initial(type))?.[0] ?? '';
|
|
125
|
-
|
|
127
|
+
const es = el.children;
|
|
128
|
+
duffbk(es.length, i => {
|
|
126
129
|
const el = es[i];
|
|
127
130
|
switch (el.getAttribute('data-marker')) {
|
|
128
131
|
case '':
|
|
129
132
|
case marker:
|
|
130
133
|
el.removeAttribute('data-marker');
|
|
131
|
-
|
|
134
|
+
return;
|
|
132
135
|
}
|
|
133
|
-
|
|
134
|
-
}
|
|
136
|
+
return false;
|
|
137
|
+
});
|
|
135
138
|
return el;
|
|
136
139
|
}
|
|
@@ -2,7 +2,7 @@ import { ParagraphParser } from '../block';
|
|
|
2
2
|
import { union, some, block, trimEnd, fmap } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { localize } from '../locale';
|
|
5
|
-
import { visualize } from '../
|
|
5
|
+
import { visualize } from '../visibility';
|
|
6
6
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
7
|
|
|
8
8
|
export const paragraph: ParagraphParser = block(localize(fmap(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReplyParser } from '../../block';
|
|
2
|
-
import { union, tails, line, validate, focus,
|
|
2
|
+
import { union, tails, creator, line, validate, focus, reverse, fmap } from '../../../combinator';
|
|
3
3
|
import { anchor } from '../../inline/autolink/anchor';
|
|
4
4
|
import { str } from '../../source';
|
|
5
5
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReplyParser } from '../../block';
|
|
2
2
|
import { eval } from '../../../combinator/data/parser';
|
|
3
|
-
import { union, some, block, line, validate, rewrite,
|
|
3
|
+
import { union, some, creator, block, line, validate, rewrite, lazy, fmap } from '../../../combinator';
|
|
4
4
|
import { math } from '../../inline/math';
|
|
5
5
|
import { str, anyline } from '../../source';
|
|
6
6
|
import { autolink } from '../../autolink';
|
|
@@ -5,7 +5,7 @@ import { quote, syntax as delimiter } from './reply/quote';
|
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { anyline } from '../source';
|
|
7
7
|
import { localize } from '../locale';
|
|
8
|
-
import { visualize } from '../
|
|
8
|
+
import { visualize } from '../visibility';
|
|
9
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
10
10
|
import { push, pop } from 'spica/array';
|
|
11
11
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SidefenceParser } from '../block';
|
|
2
|
-
import { union, some, block, focus, rewrite,
|
|
2
|
+
import { union, some, creator, block, focus, rewrite, convert, lazy, fmap } from '../../combinator';
|
|
3
3
|
import { autolink } from '../autolink';
|
|
4
4
|
import { contentline } from '../source';
|
|
5
5
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { TableParser } from '../block';
|
|
2
|
-
import { union, sequence, some, block, line, validate, focus, rewrite,
|
|
2
|
+
import { union, sequence, some, creator, block, line, validate, focus, rewrite, surround, open, fallback, lazy, fmap } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { contentline } from '../source';
|
|
5
|
-
import { trimNode } from '../
|
|
5
|
+
import { trimNode } from '../visibility';
|
|
6
6
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
|
+
import { duffEach, duffReduce } from 'spica/duff';
|
|
7
8
|
import { push } from 'spica/array';
|
|
8
9
|
|
|
9
10
|
import RowParser = TableParser.RowParser;
|
|
@@ -62,16 +63,15 @@ const data: CellParser.DataParser = creator(fmap(
|
|
|
62
63
|
function format(rows: HTMLTableRowElement[]): HTMLTableRowElement[] {
|
|
63
64
|
const aligns = rows[0].classList.contains('invalid')
|
|
64
65
|
? []
|
|
65
|
-
:
|
|
66
|
-
for (let i = 0
|
|
67
|
-
|
|
68
|
-
for (let i = 0, len = cols.length; i < len; ++i) {
|
|
66
|
+
: duffReduce(rows.shift()!.children, (acc, el) => push(acc, [el.textContent!]), [] as string[]);
|
|
67
|
+
for (let i = 0; i < rows.length; ++i) {
|
|
68
|
+
duffEach(rows[i].children, (col, i) => {
|
|
69
69
|
if (i > 0 && !aligns[i]) {
|
|
70
70
|
aligns[i] = aligns[i - 1];
|
|
71
71
|
}
|
|
72
|
-
if (!aligns[i])
|
|
73
|
-
|
|
74
|
-
}
|
|
72
|
+
if (!aligns[i]) return;
|
|
73
|
+
col.setAttribute('align', aligns[i]);
|
|
74
|
+
});
|
|
75
75
|
}
|
|
76
76
|
return rows;
|
|
77
77
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { UListParser } from '../block';
|
|
2
|
-
import { union, inits, subsequence, some, block, line, validate, indent, focus,
|
|
2
|
+
import { union, inits, subsequence, some, creator, state, block, line, validate, indent, focus, open, fallback, lazy, fmap } from '../../combinator';
|
|
3
3
|
import { olist_, invalid } from './olist';
|
|
4
4
|
import { ilist_ } from './ilist';
|
|
5
5
|
import { inline, indexer, indexee } from '../inline';
|
|
6
|
-
import {
|
|
6
|
+
import { State } from '../context';
|
|
7
|
+
import { trimBlank } from '../visibility';
|
|
7
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
8
9
|
import { unshift } from 'spica/array';
|
|
9
10
|
|
|
10
11
|
export const ulist: UListParser = lazy(() => block(validate(
|
|
11
12
|
/^-(?=[^\S\n]|\n[^\S\n]*\S)/,
|
|
12
|
-
|
|
13
|
+
state(State.media,
|
|
13
14
|
ulist_))));
|
|
14
15
|
|
|
15
16
|
export const ulist_: UListParser = lazy(() => block(fmap(validate(
|
package/src/parser/block.ts
CHANGED
|
@@ -36,7 +36,7 @@ export import ReplyParser = BlockParser.ReplyParser;
|
|
|
36
36
|
export import ParagraphParser = BlockParser.ParagraphParser;
|
|
37
37
|
|
|
38
38
|
export const block: BlockParser = creator(error(
|
|
39
|
-
reset({ resources: { budget: 50 * 1000, recursion: 20
|
|
39
|
+
reset({ resources: { budget: 50 * 1000, recursion: 20 } },
|
|
40
40
|
union([
|
|
41
41
|
emptyline,
|
|
42
42
|
horizontalrule,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const enum Rule {
|
|
2
|
+
reference = 1 << 12,
|
|
3
|
+
comment = 1 << 11,
|
|
4
|
+
index = 1 << 10,
|
|
5
|
+
placeholder = 1 << 9,
|
|
6
|
+
link = 1 << 8,
|
|
7
|
+
bracket = 1 << 7,
|
|
8
|
+
media = 1 << 6,
|
|
9
|
+
annotation = 1 << 5,
|
|
10
|
+
mathbracket = 1 << 4,
|
|
11
|
+
html = 1 << 3,
|
|
12
|
+
math = 1 << 2,
|
|
13
|
+
autolink = 1 << 1,
|
|
14
|
+
quote = 1 << 0,
|
|
15
|
+
none = 0,
|
|
16
|
+
}
|
|
17
|
+
export const backtrackable = 0
|
|
18
|
+
| Rule.annotation
|
|
19
|
+
| Rule.reference
|
|
20
|
+
| Rule.index
|
|
21
|
+
| Rule.link
|
|
22
|
+
| Rule.media;
|
|
23
|
+
|
|
24
|
+
export const enum State {
|
|
25
|
+
annotation = 1 << 6,
|
|
26
|
+
reference = 1 << 5,
|
|
27
|
+
index = 1 << 4,
|
|
28
|
+
label = 1 << 3,
|
|
29
|
+
link = 1 << 2,
|
|
30
|
+
media = 1 << 1,
|
|
31
|
+
autolink = 1 << 0,
|
|
32
|
+
}
|
package/src/parser/header.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../markdown';
|
|
2
|
-
import { union, inits, some, block, line, validate, focus, rewrite,
|
|
2
|
+
import { union, inits, some, guard, block, line, validate, focus, rewrite, clear, convert, lazy, fmap } from '../combinator';
|
|
3
3
|
import { segment } from './segment';
|
|
4
4
|
import { str } from './source';
|
|
5
5
|
import { normalize } from './api/normalize';
|
|
@@ -1,28 +1,20 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { AnnotationParser } from '../inline';
|
|
3
|
-
import { union, some,
|
|
3
|
+
import { union, some, guard, context, syntax, state, validate, surround, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { optimize } from './link';
|
|
6
|
-
import {
|
|
6
|
+
import { Rule, State } from '../context';
|
|
7
|
+
import { startLoose, trimNode } from '../visibility';
|
|
7
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
8
9
|
|
|
9
|
-
export const annotation: AnnotationParser = lazy(() =>
|
|
10
|
+
export const annotation: AnnotationParser = lazy(() => validate('((', syntax(Rule.annotation, 6, surround(
|
|
10
11
|
'((',
|
|
11
|
-
guard(context => context.
|
|
12
|
+
guard(context => ~context.state! & State.annotation,
|
|
13
|
+
state(State.annotation | State.media,
|
|
12
14
|
startLoose(
|
|
13
|
-
context({
|
|
14
|
-
|
|
15
|
-
// Redundant
|
|
16
|
-
//reference: true,
|
|
17
|
-
media: false,
|
|
18
|
-
// Redundant
|
|
19
|
-
//index: true,
|
|
20
|
-
//label: true,
|
|
21
|
-
//link: true,
|
|
22
|
-
//autolink: true,
|
|
23
|
-
}}, delimiters: undefined },
|
|
24
|
-
some(union([inline]), ')', [[/^\\?\n/, 9], [')', 2], ['))', 6]])), ')')),
|
|
15
|
+
context({ delimiters: undefined },
|
|
16
|
+
some(union([inline]), ')', [[/^\\?\n/, 9], [')', 2], ['))', 6]])), ')'))),
|
|
25
17
|
'))',
|
|
26
18
|
false,
|
|
27
19
|
([, ns], rest) => [[html('sup', { class: 'annotation' }, [html('span', trimNode(defrag(ns)))])], rest],
|
|
28
|
-
([, ns, rest], next) => next[0] === ')' ? undefined : optimize('((', ns, rest)))))
|
|
20
|
+
([, ns, rest], next) => next[0] === ')' ? undefined : optimize('((', ns, rest)))));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AutolinkParser } from '../../inline';
|
|
2
|
-
import { union, some,
|
|
2
|
+
import { union, some, creator, precedence, validate, focus, rewrite, convert, surround, open, lazy } from '../../../combinator';
|
|
3
3
|
import { textlink } from '../link';
|
|
4
4
|
import { unescsource } from '../../source';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AutolinkParser } from '../inline';
|
|
2
|
-
import { union, some,
|
|
2
|
+
import { union, some, syntax, guard, validate, fmap } from '../../combinator';
|
|
3
3
|
import { url } from './autolink/url';
|
|
4
4
|
import { email } from './autolink/email';
|
|
5
5
|
import { channel } from './autolink/channel';
|
|
@@ -8,11 +8,13 @@ import { hashtag, emoji } from './autolink/hashtag';
|
|
|
8
8
|
import { hashnum } from './autolink/hashnum';
|
|
9
9
|
import { anchor } from './autolink/anchor';
|
|
10
10
|
import { str } from '../source';
|
|
11
|
+
import { Rule, State } from '../context';
|
|
11
12
|
import { stringify } from '../util';
|
|
12
13
|
|
|
13
14
|
export const autolink: AutolinkParser = fmap(
|
|
14
15
|
validate(/^(?:[@#>0-9A-Za-z]|\S#)/,
|
|
15
|
-
guard(context => context.
|
|
16
|
+
guard(context => ~context.state! & State.autolink,
|
|
17
|
+
syntax(Rule.autolink, 1,
|
|
16
18
|
some(union([
|
|
17
19
|
url,
|
|
18
20
|
email,
|
|
@@ -29,5 +31,5 @@ export const autolink: AutolinkParser = fmap(
|
|
|
29
31
|
// Escape unmatched hashtag-like strings.
|
|
30
32
|
str(new RegExp(/^#+(?:[^\p{C}\p{S}\p{P}\s]|emoji|['_])*/u.source.replace('emoji', emoji), 'u')),
|
|
31
33
|
anchor,
|
|
32
|
-
])))),
|
|
34
|
+
]))))),
|
|
33
35
|
ns => ns.length === 1 ? ns : [stringify(ns)]);
|
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { BracketParser } from '../inline';
|
|
3
|
-
import { union, some,
|
|
3
|
+
import { union, some, syntax, surround, lazy } from '../../combinator';
|
|
4
4
|
import { inline } from '../inline';
|
|
5
5
|
import { str } from '../source';
|
|
6
|
+
import { Rule } from '../context';
|
|
6
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
8
|
import { unshift, push } from 'spica/array';
|
|
8
9
|
|
|
9
10
|
const index = /^[0-9A-Za-z]+(?:(?:[.-]|, )[0-9A-Za-z]+)*/;
|
|
10
11
|
|
|
11
|
-
export const bracket: BracketParser = lazy(() =>
|
|
12
|
-
surround(str('('),
|
|
13
|
-
surround(str('('),
|
|
12
|
+
export const bracket: BracketParser = lazy(() => union([
|
|
13
|
+
syntax(Rule.none, 2, surround(str('('), str(index), str(')'))),
|
|
14
|
+
syntax(Rule.bracket, 2, surround(str('('), some(inline, ')', [[')', 2]]), str(')'), true,
|
|
14
15
|
([as, bs = [], cs], rest) => [[html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))], rest],
|
|
15
|
-
([as, bs = []], rest) => [unshift([''], unshift(as, bs)), rest]),
|
|
16
|
-
surround(str('('),
|
|
17
|
-
surround(str('('),
|
|
16
|
+
([as, bs = []], rest) => [unshift([''], unshift(as, bs)), rest])),
|
|
17
|
+
syntax(Rule.none, 2, surround(str('('), str(new RegExp(index.source.replace(', ', '[,、]').replace(/[09AZaz.]|\-(?!\w)/g, c => c.trimStart() && String.fromCharCode(c.charCodeAt(0) + 0xFEE0)))), str(')'))),
|
|
18
|
+
syntax(Rule.bracket, 2, surround(str('('), some(inline, ')', [[')', 2]]), str(')'), true,
|
|
18
19
|
([as, bs = [], cs], rest) => [[html('span', { class: 'paren' }, defrag(push(unshift(as, bs), cs)))], rest],
|
|
19
|
-
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
20
|
-
surround(str('['),
|
|
20
|
+
([as, bs = []], rest) => [unshift(as, bs), rest])),
|
|
21
|
+
syntax(Rule.bracket, 2, surround(str('['), some(inline, ']', [[']', 2]]), str(']'), true,
|
|
21
22
|
undefined,
|
|
22
|
-
([as, bs = []], rest) => [unshift([''], unshift(as, bs)), rest]),
|
|
23
|
-
surround(str('{'),
|
|
23
|
+
([as, bs = []], rest) => [unshift([''], unshift(as, bs)), rest])),
|
|
24
|
+
syntax(Rule.bracket, 2, surround(str('{'), some(inline, '}', [['}', 2]]), str('}'), true,
|
|
24
25
|
undefined,
|
|
25
|
-
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
26
|
+
([as, bs = []], rest) => [unshift(as, bs), rest])),
|
|
26
27
|
// Control media blinking in editing rather than control confusion of pairs of quote marks.
|
|
27
|
-
surround(str('"'),
|
|
28
|
+
syntax(Rule.quote, 8, surround(str('"'), some(inline, '"', [['"', 8]]), str('"'), true,
|
|
28
29
|
undefined,
|
|
29
|
-
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
30
|
-
]))
|
|
30
|
+
([as, bs = []], rest) => [unshift(as, bs), rest])),
|
|
31
|
+
]));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CodeParser } from '../inline';
|
|
2
|
-
import {
|
|
2
|
+
import { creator, validate, match } from '../../combinator';
|
|
3
3
|
import { html } from 'typed-dom/dom';
|
|
4
4
|
|
|
5
5
|
export const code: CodeParser = creator(validate('`', match(
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { CommentParser } from '../inline';
|
|
2
|
-
import { union, some,
|
|
2
|
+
import { union, some, syntax, validate, surround, open, close, match, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { text, str } from '../source';
|
|
5
|
+
import { Rule } from '../context';
|
|
5
6
|
import { html, defrag } from 'typed-dom/dom';
|
|
6
7
|
import { memoize } from 'spica/memoize';
|
|
7
8
|
import { unshift, push } from 'spica/array';
|
|
8
9
|
|
|
9
|
-
export const comment: CommentParser = lazy(() => validate('[%',
|
|
10
|
+
export const comment: CommentParser = lazy(() => validate('[%', syntax(Rule.none, 4, match(
|
|
10
11
|
/^\[(%+)\s/,
|
|
11
12
|
memoize(
|
|
12
13
|
([, fence]) =>
|
|
@@ -21,4 +22,4 @@ export const comment: CommentParser = lazy(() => validate('[%', creator(preceden
|
|
|
21
22
|
]),
|
|
22
23
|
], rest],
|
|
23
24
|
([as, bs = []], rest) => [unshift(as, bs), rest]),
|
|
24
|
-
([, fence]) => fence.length, [])))))
|
|
25
|
+
([, fence]) => fence.length, [])))));
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { DeletionParser } from '../inline';
|
|
2
|
-
import { union, some,
|
|
2
|
+
import { union, some, syntax, surround, open, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { str } from '../source';
|
|
5
|
-
import {
|
|
5
|
+
import { Rule } from '../context';
|
|
6
|
+
import { blankWith } from '../visibility';
|
|
6
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
8
|
import { unshift } from 'spica/array';
|
|
8
9
|
|
|
9
|
-
export const deletion: DeletionParser = lazy(() =>
|
|
10
|
+
export const deletion: DeletionParser = lazy(() => syntax(Rule.none, 1, surround(
|
|
10
11
|
str('~~'),
|
|
11
12
|
some(union([
|
|
12
13
|
some(inline, blankWith('\n', '~~')),
|
|
@@ -14,4 +15,4 @@ export const deletion: DeletionParser = lazy(() => creator(precedence(1, surroun
|
|
|
14
15
|
])),
|
|
15
16
|
str('~~'), false,
|
|
16
17
|
([, bs], rest) => [[html('del', defrag(bs))], rest],
|
|
17
|
-
([as, bs], rest) => [unshift(as, bs), rest])))
|
|
18
|
+
([as, bs], rest) => [unshift(as, bs), rest])));
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { EmphasisParser } from '../inline';
|
|
2
|
-
import { union, some,
|
|
2
|
+
import { union, some, syntax, surround, open, lazy } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { emstrong } from './emstrong';
|
|
5
5
|
import { strong } from './strong';
|
|
6
6
|
import { str } from '../source';
|
|
7
|
-
import {
|
|
7
|
+
import { Rule } from '../context';
|
|
8
|
+
import { startTight, blankWith } from '../visibility';
|
|
8
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
10
|
import { unshift } from 'spica/array';
|
|
10
11
|
|
|
11
|
-
export const emphasis: EmphasisParser = lazy(() =>
|
|
12
|
+
export const emphasis: EmphasisParser = lazy(() => syntax(Rule.none, 1, surround(
|
|
12
13
|
str('*'),
|
|
13
14
|
startTight(some(union([
|
|
14
15
|
strong,
|
|
@@ -21,4 +22,4 @@ export const emphasis: EmphasisParser = lazy(() => creator(precedence(1, surroun
|
|
|
21
22
|
])), '*'),
|
|
22
23
|
str('*'), false,
|
|
23
24
|
([, bs], rest) => [[html('em', defrag(bs))], rest],
|
|
24
|
-
([as, bs], rest) => [unshift(as, bs), rest])))
|
|
25
|
+
([as, bs], rest) => [unshift(as, bs), rest])));
|