securemark 0.294.4 → 0.294.5
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 +140 -89
- package/package.json +3 -3
- package/src/combinator/control/manipulation/fence.ts +2 -0
- package/src/combinator/control/manipulation/indent.ts +1 -1
- package/src/combinator/control/manipulation/match.ts +11 -8
- package/src/parser/api/parse.test.ts +3 -3
- package/src/parser/block/blockquote.test.ts +3 -9
- package/src/parser/block/blockquote.ts +4 -4
- package/src/parser/block/dlist.ts +4 -4
- package/src/parser/block/extension/example.ts +1 -3
- package/src/parser/block/extension/fig.test.ts +0 -1
- package/src/parser/block/extension/fig.ts +6 -6
- package/src/parser/block/extension/figbase.ts +1 -1
- package/src/parser/block/extension/figure.test.ts +1 -1
- package/src/parser/block/extension/figure.ts +6 -6
- package/src/parser/block/extension/message.ts +1 -1
- package/src/parser/block/extension/table.ts +4 -4
- package/src/parser/block/heading.ts +4 -4
- package/src/parser/block/reply/cite.ts +1 -1
- package/src/parser/block/reply/quote.ts +2 -2
- package/src/parser/block/sidefence.test.ts +1 -3
- package/src/parser/block/sidefence.ts +4 -4
- package/src/parser/block/table.ts +2 -2
- package/src/parser/block.ts +1 -1
- package/src/parser/header.ts +3 -3
- package/src/parser/inline/autolink/account.ts +5 -7
- package/src/parser/inline/autolink/channel.ts +15 -15
- package/src/parser/inline/autolink/hashtag.ts +10 -8
- package/src/parser/inline/code.ts +12 -18
- package/src/parser/inline/deletion.ts +3 -3
- package/src/parser/inline/emstrong.ts +3 -3
- package/src/parser/inline/extension/indexer.ts +1 -1
- package/src/parser/inline/html.ts +1 -1
- package/src/parser/inline/insertion.ts +3 -3
- package/src/parser/inline/italic.ts +3 -3
- package/src/parser/inline/link.ts +3 -3
- package/src/parser/inline/mark.ts +3 -3
- package/src/parser/inline/remark.ts +3 -3
- package/src/parser/inline.ts +2 -0
- package/src/parser/source/text.ts +8 -4
- package/src/parser/util.ts +1 -1
- package/src/parser/visibility.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AutolinkParser } from '../../inline';
|
|
2
2
|
import { State, Backtrack } from '../../context';
|
|
3
3
|
import { List, Data } from '../../../combinator/data/parser';
|
|
4
|
-
import { union, state, constraint, verify, rewrite,
|
|
4
|
+
import { union, state, constraint, verify, rewrite, surround, convert, fmap, lazy } from '../../../combinator';
|
|
5
5
|
import { unsafelink } from '../link';
|
|
6
6
|
import { str } from '../../source';
|
|
7
7
|
import { define } from 'typed-dom/dom';
|
|
@@ -12,17 +12,19 @@ import { define } from 'typed-dom/dom';
|
|
|
12
12
|
export const emoji = String.raw`\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F`;
|
|
13
13
|
|
|
14
14
|
export const hashtag: AutolinkParser.HashtagParser = lazy(() => rewrite(
|
|
15
|
-
|
|
15
|
+
verify(surround(
|
|
16
16
|
new RegExp([
|
|
17
17
|
/(?<![^\p{C}\p{S}\p{P}\s]|emoji)#/yiu.source,
|
|
18
18
|
].join('').replace(/emoji/g, emoji), 'yu'),
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
([
|
|
24
|
-
|
|
19
|
+
str(new RegExp([
|
|
20
|
+
/(?!['_])(?:[^\p{C}\p{S}\p{P}\s]|emoji|'(?=[0-9A-Za-z])|_(?=[^\p{C}\p{S}\p{P}\s]|emoji))+/yu.source,
|
|
21
|
+
].join('').replace(/emoji/g, emoji), 'yu')),
|
|
22
|
+
str(new RegExp([
|
|
23
|
+
/(?![0-9a-z@#]|>>|:\S|[^\p{C}\p{S}\p{P}\s]|emoji)/yu.source,
|
|
24
|
+
].join('').replace(/emoji/g, emoji), 'yu')),
|
|
25
|
+
false, undefined, undefined,
|
|
25
26
|
[3 | Backtrack.autolink]),
|
|
27
|
+
([{ value }]) => !/^[0-9]{1,4}$|^[0-9]{5}/.test(value)),
|
|
26
28
|
constraint(State.autolink, state(State.autolink, fmap(convert(
|
|
27
29
|
source => `[${source}]{ ${`/hashtags/${source.slice(1)}`} }`,
|
|
28
30
|
union([unsafelink]),
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
import { CodeParser } from '../inline';
|
|
2
2
|
import { List, Data } from '../../combinator/data/parser';
|
|
3
|
-
import {
|
|
4
|
-
import { Backtrack } from '../context';
|
|
3
|
+
import { match } from '../../combinator';
|
|
5
4
|
import { invalid } from '../util';
|
|
6
5
|
import { html } from 'typed-dom/dom';
|
|
7
6
|
|
|
8
|
-
export const code: CodeParser =
|
|
9
|
-
/(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
? new List([new Data(html('code', {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}, whole))])
|
|
20
|
-
: new List([new Data(opener)]),
|
|
21
|
-
true),
|
|
22
|
-
false,
|
|
23
|
-
[3 | Backtrack.bracket]);
|
|
7
|
+
export const code: CodeParser = match(
|
|
8
|
+
/(`+)(?!`)([^\n]*?)(?:((?<!`)\1(?!`))|(?=$|\n))/y,
|
|
9
|
+
([whole, opener, body, closer]) => () =>
|
|
10
|
+
closer
|
|
11
|
+
? new List([new Data(html('code', { 'data-src': whole }, format(body)))])
|
|
12
|
+
: body
|
|
13
|
+
? new List([new Data(html('code', {
|
|
14
|
+
class: 'invalid',
|
|
15
|
+
...invalid('code', 'syntax', `Missing the closing symbol "${opener}"`)
|
|
16
|
+
}, whole))])
|
|
17
|
+
: new List([new Data(opener)]));
|
|
24
18
|
|
|
25
19
|
function format(text: string): string {
|
|
26
20
|
return text.length > 2
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { DeletionParser } from '../inline';
|
|
2
2
|
import { Recursion, Command } from '../context';
|
|
3
3
|
import { List, Data } from '../../combinator/data/parser';
|
|
4
|
-
import { union, some, recursion, precedence,
|
|
4
|
+
import { union, some, recursion, precedence, surround, open, lazy } from '../../combinator';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { blankWith } from '../visibility';
|
|
7
7
|
import { unwrap, repeat } from '../util';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
|
-
export const deletion: DeletionParser = lazy(() =>
|
|
10
|
+
export const deletion: DeletionParser = lazy(() =>
|
|
11
11
|
precedence(0, repeat('~~', surround(
|
|
12
12
|
'',
|
|
13
13
|
recursion(Recursion.inline,
|
|
@@ -18,4 +18,4 @@ export const deletion: DeletionParser = lazy(() => validate('~~',
|
|
|
18
18
|
'~~', false,
|
|
19
19
|
([, bs], { buffer }) => buffer!.import(bs),
|
|
20
20
|
([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
|
|
21
|
-
nodes => new List([new Data(html('del', defrag(unwrap(nodes))))]))))
|
|
21
|
+
nodes => new List([new Data(html('del', defrag(unwrap(nodes))))]))));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EmStrongParser, EmphasisParser, StrongParser } from '../inline';
|
|
2
2
|
import { Recursion, Command } from '../context';
|
|
3
3
|
import { Result, List, Data, Node, Context, IntermediateParser } from '../../combinator/data/parser';
|
|
4
|
-
import { union, some, recursion, precedence,
|
|
4
|
+
import { union, some, recursion, precedence, surround, open, lazy, bind } from '../../combinator';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { strong } from './strong';
|
|
7
7
|
import { emphasis } from './emphasis';
|
|
@@ -24,7 +24,7 @@ const subemphasis: IntermediateParser<EmphasisParser> = lazy(() => some(union([
|
|
|
24
24
|
// 開閉が明示的でない構文は開閉の不明確な記号による再帰的適用を行わず
|
|
25
25
|
// 可能な限り早く閉じるよう解析しなければならない。
|
|
26
26
|
// このため終端記号の後ろを見て終端を中止し同じ構文を再帰的に適用してはならない。
|
|
27
|
-
export const emstrong: EmStrongParser = lazy(() =>
|
|
27
|
+
export const emstrong: EmStrongParser = lazy(() =>
|
|
28
28
|
precedence(0, repeat('***', surround(
|
|
29
29
|
'',
|
|
30
30
|
recursion(Recursion.inline,
|
|
@@ -142,7 +142,7 @@ export const emstrong: EmStrongParser = lazy(() => validate('***',
|
|
|
142
142
|
nodes = prepend('*'.repeat(prefix - postfix), nodes);
|
|
143
143
|
}
|
|
144
144
|
return nodes;
|
|
145
|
-
})))
|
|
145
|
+
})));
|
|
146
146
|
|
|
147
147
|
function prepend<N>(prefix: string, nodes: List<Data<N>>): List<Data<N>> {
|
|
148
148
|
if (typeof nodes.head?.value === 'string') {
|
|
@@ -11,7 +11,7 @@ import { html } from 'typed-dom/dom';
|
|
|
11
11
|
// 継続的編集において最も簡便となる。
|
|
12
12
|
|
|
13
13
|
export const indexer: ExtensionParser.IndexerParser = surround(
|
|
14
|
-
|
|
14
|
+
/ \[(?=\|\S)/y,
|
|
15
15
|
union([
|
|
16
16
|
signature,
|
|
17
17
|
focus(/\|(?=\])/y, () => new List([new Data(html('span', { class: 'indexer', 'data-index': '' }))])),
|
|
@@ -32,7 +32,7 @@ export const html: HTMLParser = lazy(() => validate(/<[a-z]+(?=[ >])/yi,
|
|
|
32
32
|
([as, bs = new List()], context) =>
|
|
33
33
|
new List([new Data(elem(as.head!.value.slice(1), false, [...unwrap(as.import(bs))], new List(), new List(), context))])),
|
|
34
34
|
match(
|
|
35
|
-
new RegExp(String.raw`<(${TAGS.join('|')})(?=[
|
|
35
|
+
new RegExp(String.raw`<(${TAGS.join('|')})(?=[ >])`, 'y'),
|
|
36
36
|
memoize(
|
|
37
37
|
([, tag]) =>
|
|
38
38
|
surround<HTMLParser.TagParser, string>(
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { InsertionParser } from '../inline';
|
|
2
2
|
import { Recursion, Command } from '../context';
|
|
3
3
|
import { List, Data } from '../../combinator/data/parser';
|
|
4
|
-
import { union, some, recursion, precedence,
|
|
4
|
+
import { union, some, recursion, precedence, surround, open, lazy } from '../../combinator';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { blankWith } from '../visibility';
|
|
7
7
|
import { unwrap, repeat } from '../util';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
|
-
export const insertion: InsertionParser = lazy(() =>
|
|
10
|
+
export const insertion: InsertionParser = lazy(() =>
|
|
11
11
|
precedence(0, repeat('++', surround(
|
|
12
12
|
'',
|
|
13
13
|
recursion(Recursion.inline,
|
|
@@ -18,4 +18,4 @@ export const insertion: InsertionParser = lazy(() => validate('++',
|
|
|
18
18
|
'++', false,
|
|
19
19
|
([, bs], { buffer }) => buffer!.import(bs),
|
|
20
20
|
([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
|
|
21
|
-
nodes => new List([new Data(html('ins', defrag(unwrap(nodes))))]))))
|
|
21
|
+
nodes => new List([new Data(html('ins', defrag(unwrap(nodes))))]))));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ItalicParser } from '../inline';
|
|
2
2
|
import { Recursion, Command } from '../context';
|
|
3
3
|
import { List, Data } from '../../combinator/data/parser';
|
|
4
|
-
import { union, some, recursion, precedence,
|
|
4
|
+
import { union, some, recursion, precedence, surround, open, lazy } from '../../combinator';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { tightStart, blankWith } from '../visibility';
|
|
7
7
|
import { unwrap, repeat } from '../util';
|
|
@@ -10,7 +10,7 @@ import { html, defrag } from 'typed-dom/dom';
|
|
|
10
10
|
// 可読性のため実際にはオブリーク体を指定する。
|
|
11
11
|
// 斜体は単語に使うとかえって見づらく読み飛ばしやすくなるため使わないべきであり
|
|
12
12
|
// ある程度の長さのある文に使うのが望ましい。
|
|
13
|
-
export const italic: ItalicParser = lazy(() =>
|
|
13
|
+
export const italic: ItalicParser = lazy(() =>
|
|
14
14
|
precedence(0, repeat('///', surround(
|
|
15
15
|
'',
|
|
16
16
|
recursion(Recursion.inline,
|
|
@@ -21,4 +21,4 @@ export const italic: ItalicParser = lazy(() => validate('///',
|
|
|
21
21
|
'///', false,
|
|
22
22
|
([, bs], { buffer }) => buffer!.import(bs),
|
|
23
23
|
([, bs], { buffer }) => bs && buffer!.import(bs).push(new Data(Command.Cancel)) && buffer!),
|
|
24
|
-
nodes => new List([new Data(html('i', defrag(unwrap(nodes))))]))))
|
|
24
|
+
nodes => new List([new Data(html('i', defrag(unwrap(nodes))))]))));
|
|
@@ -2,7 +2,7 @@ import { MarkdownParser } from '../../../markdown';
|
|
|
2
2
|
import { LinkParser } from '../inline';
|
|
3
3
|
import { State, Backtrack, Command } from '../context';
|
|
4
4
|
import { List, Data } from '../../combinator/data/parser';
|
|
5
|
-
import { union, inits, tails, sequence, subsequence, some, creation, precedence, state, constraint,
|
|
5
|
+
import { union, inits, tails, sequence, subsequence, some, creation, precedence, state, constraint, surround, open, setBacktrack, dup, reverse, lazy, fmap, bind } from '../../combinator';
|
|
6
6
|
import { inline, media, shortmedia } from '../inline';
|
|
7
7
|
import { attributes } from './html';
|
|
8
8
|
import { unescsource, str } from '../source';
|
|
@@ -75,7 +75,7 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
|
|
|
75
75
|
return new List([new Data(parse(content, params as List<Data<string>>, context))]);
|
|
76
76
|
}))))));
|
|
77
77
|
|
|
78
|
-
export const medialink: LinkParser.MediaLinkParser = lazy(() => constraint(State.link | State.media,
|
|
78
|
+
export const medialink: LinkParser.MediaLinkParser = lazy(() => constraint(State.link | State.media, creation(10,
|
|
79
79
|
state(State.linkers,
|
|
80
80
|
bind(sequence([
|
|
81
81
|
dup(surround(
|
|
@@ -85,7 +85,7 @@ export const medialink: LinkParser.MediaLinkParser = lazy(() => constraint(State
|
|
|
85
85
|
dup(surround(/{(?![{}])/y, inits([uri, some(option)]), / ?}/y)),
|
|
86
86
|
]),
|
|
87
87
|
([{ value: content }, { value: params }], context) =>
|
|
88
|
-
new List([new Data(parse(content, params as List<Data<string>>, context))]))))))
|
|
88
|
+
new List([new Data(parse(content, params as List<Data<string>>, context))]))))));
|
|
89
89
|
|
|
90
90
|
export const unsafelink: LinkParser.UnsafeLinkParser = lazy(() =>
|
|
91
91
|
creation(10,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { MarkParser } from '../inline';
|
|
2
2
|
import { State, Recursion, Command } from '../context';
|
|
3
3
|
import { List, Data } from '../../combinator/data/parser';
|
|
4
|
-
import { union, some, recursion, precedence, state, constraint,
|
|
4
|
+
import { union, some, recursion, precedence, state, constraint, surround, open, lazy } from '../../combinator';
|
|
5
5
|
import { inline } from '../inline';
|
|
6
6
|
import { identity, signature } from './extension/indexee';
|
|
7
7
|
import { tightStart, blankWith } from '../visibility';
|
|
8
8
|
import { unwrap, repeat } from '../util';
|
|
9
9
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
10
10
|
|
|
11
|
-
export const mark: MarkParser = lazy(() => constraint(State.linkers & ~State.mark,
|
|
11
|
+
export const mark: MarkParser = lazy(() => constraint(State.linkers & ~State.mark,
|
|
12
12
|
precedence(0, state(State.mark, repeat('==', surround(
|
|
13
13
|
'',
|
|
14
14
|
recursion(Recursion.inline,
|
|
@@ -25,4 +25,4 @@ export const mark: MarkParser = lazy(() => constraint(State.linkers & ~State.mar
|
|
|
25
25
|
return el.id
|
|
26
26
|
? new List([new Data(el), new Data(html('a', { href: `#${el.id}` }))])
|
|
27
27
|
: new List([new Data(el)]);
|
|
28
|
-
})))))
|
|
28
|
+
})))));
|
|
@@ -8,9 +8,9 @@ import { unwrap, invalid } from '../util';
|
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
9
9
|
|
|
10
10
|
export const remark: RemarkParser = lazy(() => fallback(surround(
|
|
11
|
-
str(/\[%(
|
|
11
|
+
str(/\[%(?=[ \n])/y),
|
|
12
12
|
precedence(3, recursion(Recursion.inline,
|
|
13
|
-
some(union([inline]),
|
|
13
|
+
some(union([inline]), /[ \n]%\]/y, [[/[ \n]%\]/y, 3]]))),
|
|
14
14
|
close(text, str(`%]`)), true,
|
|
15
15
|
([as, bs = new List(), cs]) => new List([
|
|
16
16
|
new Data(html('span', { class: 'remark' }, [
|
|
@@ -19,6 +19,6 @@ export const remark: RemarkParser = lazy(() => fallback(surround(
|
|
|
19
19
|
])),
|
|
20
20
|
]),
|
|
21
21
|
([as, bs]) => bs && as.import(bs as List<Data<string>>)),
|
|
22
|
-
focus(/\[%+(
|
|
22
|
+
focus(/\[%+(?=[ \n])/y, ({ context: { source } }) => new List([
|
|
23
23
|
new Data(html('span', { class: 'invalid', ...invalid('remark', 'syntax', 'Invalid start symbol') }, source))
|
|
24
24
|
]))));
|
package/src/parser/inline.ts
CHANGED
|
@@ -66,6 +66,7 @@ export const inline: InlineParser = lazy(() => union([
|
|
|
66
66
|
case '%':
|
|
67
67
|
return remark(input)
|
|
68
68
|
|| textlink(input)
|
|
69
|
+
|| ruby(input)
|
|
69
70
|
|| bracket(input);
|
|
70
71
|
case '#':
|
|
71
72
|
case '$':
|
|
@@ -74,6 +75,7 @@ export const inline: InlineParser = lazy(() => union([
|
|
|
74
75
|
case '|':
|
|
75
76
|
return extension(input)
|
|
76
77
|
|| textlink(input)
|
|
78
|
+
|| ruby(input)
|
|
77
79
|
|| bracket(input);
|
|
78
80
|
}
|
|
79
81
|
return textlink(input)
|
|
@@ -103,7 +103,6 @@ export function next(source: string, position: number, delimiter?: RegExp): numb
|
|
|
103
103
|
const char = source[index];
|
|
104
104
|
switch (char) {
|
|
105
105
|
case '$':
|
|
106
|
-
case '%':
|
|
107
106
|
case '*':
|
|
108
107
|
case '+':
|
|
109
108
|
case '~':
|
|
@@ -111,10 +110,15 @@ export function next(source: string, position: number, delimiter?: RegExp): numb
|
|
|
111
110
|
case '/':
|
|
112
111
|
index = backToWhitespace(source, position, index);
|
|
113
112
|
break;
|
|
113
|
+
case '%':
|
|
114
|
+
index += index - 1 > position && source.startsWith(' %]', index - 1)
|
|
115
|
+
? -1
|
|
116
|
+
: 0;
|
|
117
|
+
break;
|
|
114
118
|
case '[':
|
|
115
|
-
index
|
|
116
|
-
?
|
|
117
|
-
:
|
|
119
|
+
index += index - 1 > position && source.startsWith(' [|', index - 1)
|
|
120
|
+
? -1
|
|
121
|
+
: 0;
|
|
118
122
|
break;
|
|
119
123
|
case ':':
|
|
120
124
|
index = source.startsWith('//', index + 1)
|
package/src/parser/util.ts
CHANGED
|
@@ -28,7 +28,7 @@ export function repeat<N extends HTMLElement | string>(symbol: string, parser: P
|
|
|
28
28
|
return failsafe(input => {
|
|
29
29
|
const { context } = input;
|
|
30
30
|
const { source, position } = context;
|
|
31
|
-
|
|
31
|
+
if (!source.startsWith(symbol, context.position)) return;
|
|
32
32
|
let nodes = new List<Data<N>>();
|
|
33
33
|
let i = symbol.length;
|
|
34
34
|
for (; source[context.position + i] === source[context.position];) ++i;
|
package/src/parser/visibility.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { invisibleHTMLEntityNames } from './api/normalize';
|
|
|
8
8
|
export namespace blank {
|
|
9
9
|
export const line = new RegExp(
|
|
10
10
|
// TODO: 行全体をエスケープ
|
|
11
|
-
/^(
|
|
11
|
+
/^(\\?[^\S\r\n]|&IHN;|<wbr ?>|\\$)+$/mg.source
|
|
12
12
|
.replace('IHN', `(?:${invisibleHTMLEntityNames.join('|')})`),
|
|
13
13
|
'gm');
|
|
14
14
|
export const start = new RegExp(
|