securemark 0.294.11 → 0.295.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/design.md +5 -5
- package/dist/index.js +122 -112
- package/package.json +1 -1
- package/src/combinator/control/constraint/block.ts +1 -1
- package/src/combinator/control/constraint/contract.ts +5 -6
- package/src/combinator/control/constraint/line.ts +1 -2
- package/src/combinator/control/manipulation/convert.ts +1 -1
- package/src/combinator/control/manipulation/fallback.ts +1 -1
- package/src/combinator/control/manipulation/indent.ts +2 -2
- package/src/combinator/control/manipulation/lazy.ts +1 -1
- package/src/combinator/control/manipulation/match.ts +2 -5
- package/src/combinator/control/manipulation/recovery.ts +1 -1
- package/src/combinator/control/manipulation/reverse.ts +1 -1
- package/src/combinator/control/manipulation/scope.ts +3 -7
- package/src/combinator/control/manipulation/surround.ts +51 -62
- package/src/combinator/control/monad/bind.ts +7 -12
- package/src/combinator/control/monad/fmap.ts +4 -4
- package/src/combinator/data/parser/context.ts +12 -12
- package/src/combinator/data/parser/inits.ts +3 -6
- package/src/combinator/data/parser/sequence.ts +3 -6
- package/src/combinator/data/parser/some.ts +2 -2
- package/src/combinator/data/parser/subsequence.ts +1 -1
- package/src/combinator/data/parser/tails.ts +1 -1
- package/src/combinator/data/parser/union.ts +1 -1
- package/src/combinator/data/parser.ts +10 -9
- package/src/parser/context.ts +6 -6
- package/src/parser/inline/autolink/account.ts +1 -1
- package/src/parser/inline/autolink/url.ts +4 -5
- package/src/parser/inline/bracket.ts +27 -18
- package/src/parser/inline/extension/indexee.ts +1 -1
- package/src/parser/inline/link.ts +3 -3
- package/src/parser/inline/media.ts +1 -1
- package/src/parser/inline/reference.ts +8 -8
- package/src/parser/inline/ruby.ts +2 -2
- package/src/parser/visibility.ts +2 -2
|
@@ -3,8 +3,8 @@ import { Delimiters } from './context/delimiter';
|
|
|
3
3
|
|
|
4
4
|
type DelimiterOption = readonly [delimiter: string | RegExp, precedence: number];
|
|
5
5
|
|
|
6
|
-
export function some<P extends Parser
|
|
7
|
-
export function some<P extends Parser
|
|
6
|
+
export function some<P extends Parser>(parser: P, limit?: number): P;
|
|
7
|
+
export function some<P extends Parser>(parser: P, end?: string | RegExp, delimiters?: readonly DelimiterOption[], limit?: number): P;
|
|
8
8
|
export function some<N>(parser: Parser<N>, end?: string | RegExp | number, delimiters: readonly DelimiterOption[] = [], limit = -1): Parser<N> {
|
|
9
9
|
if (typeof end === 'number') return some(parser, undefined, delimiters, end);
|
|
10
10
|
assert(parser);
|
|
@@ -2,7 +2,7 @@ import { Parser, List, Data, Ctx, Node, Context, SubParsers, SubNode } from '../
|
|
|
2
2
|
import { union } from './union';
|
|
3
3
|
import { inits } from './inits';
|
|
4
4
|
|
|
5
|
-
export function subsequence<P extends Parser
|
|
5
|
+
export function subsequence<P extends Parser>(parsers: SubParsers<P>, resume?: (nodes: List<Data<SubNode<P>>>) => boolean): SubNode<P> extends Node<P> ? P : Parser<SubNode<P>, Context<P>, SubParsers<P>>;
|
|
6
6
|
export function subsequence<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: List<Data<N>>) => boolean): Parser<N, Ctx, D> {
|
|
7
7
|
assert(parsers.every(f => f));
|
|
8
8
|
return union(
|
|
@@ -2,7 +2,7 @@ import { Parser, List, Data, Ctx, Node, Context, SubParsers, SubNode } from '../
|
|
|
2
2
|
import { union } from './union';
|
|
3
3
|
import { sequence } from './sequence';
|
|
4
4
|
|
|
5
|
-
export function tails<P extends Parser
|
|
5
|
+
export function tails<P extends Parser>(parsers: SubParsers<P>, resume?: (nodes: List<Data<SubNode<P>>>) => boolean): SubNode<P> extends Node<P> ? P : Parser<SubNode<P>, Context<P>, SubParsers<P>>;
|
|
6
6
|
export function tails<N, D extends Parser<N>[]>(parsers: D, resume?: (nodes: List<Data<N>>) => boolean): Parser<N, Ctx, D> {
|
|
7
7
|
return union(parsers.map((_, i) => sequence(parsers.slice(i), resume)) as D);
|
|
8
8
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Parser, Ctx, Node, Context, SubParsers, SubNode } from '../parser';
|
|
2
2
|
|
|
3
|
-
export function union<P extends Parser
|
|
3
|
+
export function union<P extends Parser>(parsers: SubParsers<P>): SubNode<P> extends Node<P> ? P : Parser<SubNode<P>, Context<P>, SubParsers<P>>;
|
|
4
4
|
export function union<N, D extends Parser<N>[]>(parsers: D): Parser<N, Ctx, D> {
|
|
5
5
|
assert(parsers.every(f => f));
|
|
6
6
|
switch (parsers.length) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { List } from './data';
|
|
2
2
|
import { Delimiters } from './parser/context/delimiter';
|
|
3
3
|
|
|
4
|
-
export type Parser<N, C extends Ctx = Ctx, D extends Parser<unknown, C>[] = any>
|
|
4
|
+
export type Parser<N = unknown, C extends Ctx = Ctx, D extends Parser<unknown, C>[] = any>
|
|
5
5
|
= (input: Input<C>) => Result<N, C, D>;
|
|
6
6
|
export interface Input<C extends Ctx = Ctx> {
|
|
7
7
|
readonly context: C;
|
|
@@ -35,6 +35,7 @@ export interface CtxOptions {
|
|
|
35
35
|
// 最大セグメントサイズ10KB内で探索コストが平均実行性能を圧迫するほど大きくなるとは考えにくいが
|
|
36
36
|
// 探索コストを減らすにはバックトラック位置数が規定数を超えた場合一定区間ごとに探索木を分割する方法が考えられる。
|
|
37
37
|
// 10KBの入力すべてを保持する探索木を1024文字ごとに分割するために必要なテーブルサイズは64bit*98=784byteとなる。
|
|
38
|
+
// 128文字ごとでもテーブルサイズは入力全体の1%未満であるため無視でき16文字ごとでさえ6.25%に過ぎない。
|
|
38
39
|
// 探索木のポインタによるオーバーヘッドを考慮すれば一定サイズ以上ではテーブルのほうが効率的となる。
|
|
39
40
|
// 区間別テーブルは固定サイズであるためプールして再使用できる。
|
|
40
41
|
// 従って分割時のデータ構造は区間ごとに探索木を動的に生成しデータ数に応じてテーブルに移行するのが最も効率的である。
|
|
@@ -64,13 +65,13 @@ export interface CtxOptions {
|
|
|
64
65
|
linebreak?: number;
|
|
65
66
|
range?: number;
|
|
66
67
|
}
|
|
67
|
-
export type Node<P extends Parser
|
|
68
|
-
export type SubParsers<P extends Parser
|
|
69
|
-
export type Context<P extends Parser
|
|
70
|
-
export type SubNode<P extends Parser
|
|
71
|
-
export type IntermediateParser<P extends Parser
|
|
72
|
-
type ExtractSubNode<D extends Parser
|
|
73
|
-
type ExtractSubParser<D extends Parser
|
|
68
|
+
export type Node<P extends Parser> = P extends Parser<infer N> ? N : never;
|
|
69
|
+
export type SubParsers<P extends Parser> = P extends Parser<unknown, Ctx, infer D> ? D : never;
|
|
70
|
+
export type Context<P extends Parser> = P extends Parser<unknown, infer C> ? C : never;
|
|
71
|
+
export type SubNode<P extends Parser> = ExtractSubNode<SubParsers<P>>;
|
|
72
|
+
export type IntermediateParser<P extends Parser> = Parser<SubNode<P>, Context<P>, SubParsers<P>>;
|
|
73
|
+
type ExtractSubNode<D extends Parser[]> = ExtractSubParser<D> extends infer N ? N extends Parser<infer U> ? U : never : never;
|
|
74
|
+
type ExtractSubParser<D extends Parser[]> = D extends (infer P)[] ? P extends Parser ? P : never : never;
|
|
74
75
|
|
|
75
76
|
export function input<C extends CtxOptions>(source: string, context: C): Input<C & Ctx> {
|
|
76
77
|
// @ts-expect-error
|
|
@@ -95,7 +96,7 @@ export function subinput<C extends Ctx>(source: string, context: C): Input<C> {
|
|
|
95
96
|
};
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
export function failsafe<P extends Parser
|
|
99
|
+
export function failsafe<P extends Parser>(parser: P): P;
|
|
99
100
|
export function failsafe<N>(parser: Parser<N>): Parser<N> {
|
|
100
101
|
assert(parser);
|
|
101
102
|
return input => {
|
package/src/parser/context.ts
CHANGED
|
@@ -29,14 +29,14 @@ export const enum Recursion {
|
|
|
29
29
|
|
|
30
30
|
export const enum Backtrack {
|
|
31
31
|
// 構文
|
|
32
|
-
doublebracket = 1 <<
|
|
33
|
-
link = 1 <<
|
|
34
|
-
ruby = 1 <<
|
|
32
|
+
doublebracket = 1 << 7,
|
|
33
|
+
link = 1 << 6,
|
|
34
|
+
ruby = 1 << 5,
|
|
35
35
|
// 特殊構造
|
|
36
|
-
escapable = 1 <<
|
|
37
|
-
unescapable = 1 <<
|
|
36
|
+
escapable = 1 << 4,
|
|
37
|
+
unescapable = 1 << 3,
|
|
38
38
|
// 共通構造
|
|
39
|
-
common =
|
|
39
|
+
common = 1 << 2,
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export const enum Command {
|
|
@@ -47,7 +47,7 @@ export const account: AutolinkParser.AccountParser = lazy(() => constraint(State
|
|
|
47
47
|
([[{ value: host }, { value: account }]], context) => {
|
|
48
48
|
if (context.source[context.position] === '#') {
|
|
49
49
|
assert(context.source[context.position - context.range!] === '@');
|
|
50
|
-
return void setBacktrack(context,
|
|
50
|
+
return void setBacktrack(context, 2 | Backtrack.unescapable, context.position - context.range!);
|
|
51
51
|
}
|
|
52
52
|
return new List([
|
|
53
53
|
new Data(define(
|
|
@@ -27,19 +27,18 @@ export const lineurl: AutolinkParser.UrlParser.LineUrlParser = lazy(() => focus(
|
|
|
27
27
|
str('!'),
|
|
28
28
|
union([
|
|
29
29
|
constraint(State.autolink, state(State.autolink, ({ context }) => {
|
|
30
|
-
const { source, position
|
|
31
|
-
context.position -=
|
|
32
|
-
context.position += range;
|
|
30
|
+
const { source, position } = context;
|
|
31
|
+
context.position -= source[0] === '!' ? 1 : 0;
|
|
33
32
|
return new List([
|
|
34
33
|
new Data(parse(
|
|
35
34
|
new List(),
|
|
36
|
-
new List([new Data(source.slice(position
|
|
35
|
+
new List([new Data(source.slice(position))]),
|
|
37
36
|
context))
|
|
38
37
|
]);
|
|
39
38
|
})),
|
|
40
39
|
str(/[^:]+/y),
|
|
41
40
|
]),
|
|
42
|
-
])
|
|
41
|
+
])));
|
|
43
42
|
|
|
44
43
|
const bracket: AutolinkParser.UrlParser.BracketParser = lazy(() => union([
|
|
45
44
|
surround(str('('), recursion(Recursion.terminal, some(union([bracket, unescsource]), ')')), str(')'),
|
|
@@ -38,22 +38,32 @@ const p1 = lazy(() => surround(
|
|
|
38
38
|
str('('),
|
|
39
39
|
precedence(1, recursion(Recursion.bracket, some(inline, ')', [[')', 1]]))),
|
|
40
40
|
str(')'),
|
|
41
|
-
true,
|
|
42
|
-
[
|
|
43
|
-
|
|
41
|
+
true, [],
|
|
42
|
+
([as, bs = new List(), cs], context) => {
|
|
43
|
+
const { source, position, range = 0 } = context;
|
|
44
|
+
const head = position - range;
|
|
45
|
+
if (context.linebreak !== 0 || source[position - 2] !== ')' || source[head + 1] !== '(') {
|
|
46
|
+
setBacktrack(context, 2 | Backtrack.doublebracket, head);
|
|
47
|
+
}
|
|
44
48
|
const str = source.slice(position - range + 1, position - 1);
|
|
45
49
|
return indexA.test(str)
|
|
46
50
|
? new List([new Data(as.head!.value), new Data(str), new Data(cs.head!.value)])
|
|
47
51
|
: new List([new Data(html('span', { class: 'paren' }, defrag(unwrap(as.import(bs as List<Data<string>>).import(cs)))))]);
|
|
48
52
|
},
|
|
49
|
-
([as, bs = new List()]) =>
|
|
53
|
+
([as, bs = new List()], context) => {
|
|
54
|
+
const { source, position, range = 0 } = context;
|
|
55
|
+
const head = position - range;
|
|
56
|
+
if (context.linebreak !== 0 || source[head + 1] !== '(') {
|
|
57
|
+
setBacktrack(context, 2 | Backtrack.doublebracket, head);
|
|
58
|
+
}
|
|
59
|
+
return as.import(bs as List<Data<string>>);
|
|
60
|
+
}));
|
|
50
61
|
|
|
51
62
|
const p2 = lazy(() => surround(
|
|
52
63
|
str('('),
|
|
53
64
|
precedence(1, recursion(Recursion.bracket, some(inline, ')', [[')', 1]]))),
|
|
54
65
|
str(')'),
|
|
55
|
-
true,
|
|
56
|
-
[2 | Backtrack.common],
|
|
66
|
+
true, [],
|
|
57
67
|
([as, bs = [], cs], { source, position, range = 0 }) => {
|
|
58
68
|
const str = source.slice(position - range + 1, position - 1);
|
|
59
69
|
return indexF.test(str)
|
|
@@ -72,20 +82,23 @@ const s1 = lazy(() => surround(
|
|
|
72
82
|
if (context.state! & State.link) {
|
|
73
83
|
const { source, position, range = 0 } = context;
|
|
74
84
|
const head = position - range;
|
|
85
|
+
if (context.linebreak !== 0 || source[position - 2] !== ']' || source[head + 1] !== '[') {
|
|
86
|
+
setBacktrack(context, 2 | Backtrack.doublebracket, head);
|
|
87
|
+
}
|
|
75
88
|
if (context.linebreak !== 0) {
|
|
76
|
-
setBacktrack(context,
|
|
89
|
+
setBacktrack(context, 2 | Backtrack.doublebracket | Backtrack.link | Backtrack.ruby, head);
|
|
77
90
|
}
|
|
78
91
|
else if (source[position] !== '{') {
|
|
79
|
-
setBacktrack(context,
|
|
92
|
+
setBacktrack(context, 2 | Backtrack.link, head);
|
|
80
93
|
}
|
|
81
94
|
else {
|
|
82
95
|
context.state! ^= State.link;
|
|
83
|
-
const result = !isBacktrack(context,
|
|
96
|
+
const result = !isBacktrack(context, 1 | Backtrack.link)
|
|
84
97
|
? textlink({ context })
|
|
85
98
|
: undefined;
|
|
86
99
|
context.position = position;
|
|
87
100
|
if (!result) {
|
|
88
|
-
setBacktrack(context,
|
|
101
|
+
setBacktrack(context, 2 | Backtrack.link, head);
|
|
89
102
|
}
|
|
90
103
|
context.state! ^= State.link;
|
|
91
104
|
context.range = range;
|
|
@@ -99,8 +112,7 @@ const s2 = lazy(() => surround(
|
|
|
99
112
|
str('['),
|
|
100
113
|
precedence(1, recursion(Recursion.bracket, some(inline, ']', [[']', 1]]))),
|
|
101
114
|
str(']'),
|
|
102
|
-
true,
|
|
103
|
-
[2 | Backtrack.common],
|
|
115
|
+
true, [],
|
|
104
116
|
undefined,
|
|
105
117
|
([as, bs = new List()]) => as.import(bs as List<Data<string>>)));
|
|
106
118
|
|
|
@@ -108,8 +120,7 @@ const c1 = lazy(() => surround(
|
|
|
108
120
|
str('{'),
|
|
109
121
|
precedence(1, recursion(Recursion.bracket, some(inline, '}', [['}', 1]]))),
|
|
110
122
|
str('}'),
|
|
111
|
-
true,
|
|
112
|
-
[2 | Backtrack.common],
|
|
123
|
+
true, [],
|
|
113
124
|
undefined,
|
|
114
125
|
([as, bs = new List()]) => as.import(bs as List<Data<string>>)));
|
|
115
126
|
|
|
@@ -117,8 +128,7 @@ const c2 = lazy(() => surround(
|
|
|
117
128
|
str('{'),
|
|
118
129
|
precedence(1, recursion(Recursion.bracket, some(inline, '}', [['}', 1]]))),
|
|
119
130
|
str('}'),
|
|
120
|
-
true,
|
|
121
|
-
[2 | Backtrack.common],
|
|
131
|
+
true, [],
|
|
122
132
|
undefined,
|
|
123
133
|
([as, bs = new List()]) => as.import(bs as List<Data<string>>)));
|
|
124
134
|
|
|
@@ -127,7 +137,6 @@ const d1 = lazy(() => surround(
|
|
|
127
137
|
// 改行の優先度を構文ごとに変える場合シグネチャの優先度対応が必要
|
|
128
138
|
precedence(2, recursion(Recursion.bracket, some(inline, /["\n]/y, [['"', 2], ['\n', 3]]))),
|
|
129
139
|
str('"'),
|
|
130
|
-
true,
|
|
131
|
-
[2 | Backtrack.common],
|
|
140
|
+
true, [],
|
|
132
141
|
undefined,
|
|
133
142
|
([as, bs = new List()]) => as.import(bs as List<Data<string>>)));
|
|
@@ -3,7 +3,7 @@ import { Parser, List, Data } from '../../../combinator/data/parser';
|
|
|
3
3
|
import { fmap } from '../../../combinator';
|
|
4
4
|
import { define } from 'typed-dom/dom';
|
|
5
5
|
|
|
6
|
-
export function indexee<P extends Parser<
|
|
6
|
+
export function indexee<P extends Parser<HTMLElement, MarkdownParser.Context>>(parser: P): P;
|
|
7
7
|
export function indexee(parser: Parser<HTMLElement, MarkdownParser.Context>): Parser<HTMLElement> {
|
|
8
8
|
return fmap(parser, (ns, { id }) =>
|
|
9
9
|
ns.length === 1
|
|
@@ -24,11 +24,11 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
24
24
|
trimBlankStart(some(union([inline]), ']', [[']', 1]])),
|
|
25
25
|
']',
|
|
26
26
|
true,
|
|
27
|
-
[3 | Backtrack.common
|
|
27
|
+
[3 | Backtrack.common | Backtrack.link, 2 | Backtrack.ruby],
|
|
28
28
|
([, ns = new List()], context) => {
|
|
29
29
|
if (context.linebreak !== 0) {
|
|
30
30
|
const head = context.position - context.range!;
|
|
31
|
-
return void setBacktrack(context,
|
|
31
|
+
return void setBacktrack(context, 2 | Backtrack.link | Backtrack.ruby, head);
|
|
32
32
|
}
|
|
33
33
|
return ns.push(new Data(Command.Separator)) && ns;
|
|
34
34
|
})),
|
|
@@ -48,7 +48,7 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
48
48
|
content.pop();
|
|
49
49
|
if (params === undefined) {
|
|
50
50
|
const head = context.position - context.range!;
|
|
51
|
-
return void setBacktrack(context,
|
|
51
|
+
return void setBacktrack(context, 2 | Backtrack.link, head);
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
else {
|
|
@@ -34,7 +34,7 @@ export const media: MediaParser = lazy(() => constraint(State.media, open(
|
|
|
34
34
|
([, ns = new List()], context) => {
|
|
35
35
|
if (context.linebreak !== 0) {
|
|
36
36
|
const head = context.position - context.range!;
|
|
37
|
-
return void setBacktrack(context,
|
|
37
|
+
return void setBacktrack(context, 2 | Backtrack.link | Backtrack.ruby, head);
|
|
38
38
|
}
|
|
39
39
|
return ns;
|
|
40
40
|
})),
|
|
@@ -26,7 +26,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
26
26
|
}
|
|
27
27
|
else {
|
|
28
28
|
const head = position - range;
|
|
29
|
-
setBacktrack(context,
|
|
29
|
+
setBacktrack(context, 2 | Backtrack.link, head, 2);
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
([as, bs], context) => {
|
|
@@ -34,10 +34,10 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
34
34
|
const { source, position, range = 0, linebreak = 0, state = 0 } = context;
|
|
35
35
|
const head = position - range;
|
|
36
36
|
if (source[position] !== ']') {
|
|
37
|
-
setBacktrack(context,
|
|
37
|
+
setBacktrack(context, 2 | Backtrack.common, head, 2);
|
|
38
38
|
}
|
|
39
39
|
else if (linebreak !== 0) {
|
|
40
|
-
setBacktrack(context,
|
|
40
|
+
setBacktrack(context, 2 | Backtrack.link | Backtrack.ruby, head, 2);
|
|
41
41
|
}
|
|
42
42
|
else {
|
|
43
43
|
assert(source[position] === ']');
|
|
@@ -47,22 +47,22 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
47
47
|
context.position += 1;
|
|
48
48
|
let result: ReturnType<typeof textlink>;
|
|
49
49
|
if (source[context.position] !== '{') {
|
|
50
|
-
setBacktrack(context,
|
|
50
|
+
setBacktrack(context, 2 | Backtrack.link, head + 1);
|
|
51
51
|
result = new List();
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
result = !isBacktrack(context,
|
|
54
|
+
result = !isBacktrack(context, 1 | Backtrack.link)
|
|
55
55
|
? textlink({ context })
|
|
56
56
|
: undefined;
|
|
57
57
|
context.range = range;
|
|
58
58
|
if (!result) {
|
|
59
|
-
setBacktrack(context,
|
|
59
|
+
setBacktrack(context, 2 | Backtrack.link, head + 1);
|
|
60
60
|
result = new List();
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
assert(result);
|
|
64
64
|
if (context.position === source.length) {
|
|
65
|
-
setBacktrack(context,
|
|
65
|
+
setBacktrack(context, 2 | Backtrack.link, head);
|
|
66
66
|
}
|
|
67
67
|
else {
|
|
68
68
|
assert(state ^ State.link);
|
|
@@ -74,7 +74,7 @@ export const reference: ReferenceParser = lazy(() => constraint(State.reference,
|
|
|
74
74
|
([, cs = new List(), ds]) =>
|
|
75
75
|
cs.import(ds),
|
|
76
76
|
([, cs = new List()]) => {
|
|
77
|
-
setBacktrack(context,
|
|
77
|
+
setBacktrack(context, 2 | Backtrack.link, head);
|
|
78
78
|
return cs;
|
|
79
79
|
})
|
|
80
80
|
({ context });
|
|
@@ -21,12 +21,12 @@ export const ruby: RubyParser = lazy(() => bind(
|
|
|
21
21
|
dup(surround(
|
|
22
22
|
'(', text, ')',
|
|
23
23
|
false,
|
|
24
|
-
[
|
|
24
|
+
[3 | Backtrack.ruby])),
|
|
25
25
|
]),
|
|
26
26
|
([{ value: texts }, { value: rubies = undefined } = {}], context) => {
|
|
27
27
|
if (rubies === undefined) {
|
|
28
28
|
const head = context.position - context.range!;
|
|
29
|
-
return void setBacktrack(context,
|
|
29
|
+
return void setBacktrack(context, 2 | Backtrack.ruby, head);
|
|
30
30
|
}
|
|
31
31
|
switch (true) {
|
|
32
32
|
case texts.length >= rubies.length:
|
package/src/parser/visibility.ts
CHANGED
|
@@ -50,7 +50,7 @@ export function blankWith(starts: '' | '\n', delimiter?: string | RegExp): RegEx
|
|
|
50
50
|
// return isTightStart({ source: source.replace(blank.start, ''), context }, except);
|
|
51
51
|
//}, ({ source }, except = '') => `${source}${Command.Separator}${except}`);
|
|
52
52
|
|
|
53
|
-
export function tightStart<P extends Parser
|
|
53
|
+
export function tightStart<P extends Parser>(parser: P, except?: string): P;
|
|
54
54
|
export function tightStart<N>(parser: Parser<N>, except?: string): Parser<N> {
|
|
55
55
|
return input =>
|
|
56
56
|
isTightStart(input, except)
|
|
@@ -140,7 +140,7 @@ export function trimBlank<P extends Parser<HTMLElement | string>>(parser: P): P;
|
|
|
140
140
|
export function trimBlank<N extends HTMLElement | string>(parser: Parser<N>): Parser<N> {
|
|
141
141
|
return trimBlankStart(trimBlankEnd(parser));
|
|
142
142
|
}
|
|
143
|
-
export function trimBlankStart<P extends Parser
|
|
143
|
+
export function trimBlankStart<P extends Parser>(parser: P): P;
|
|
144
144
|
export function trimBlankStart<N>(parser: Parser<N>): Parser<N> {
|
|
145
145
|
return failsafe(input => {
|
|
146
146
|
const { context } = input;
|