securemark 0.283.3 → 0.283.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 +8 -0
- package/dist/index.js +142 -107
- package/markdown.d.ts +16 -8
- package/package.json +1 -1
- package/src/combinator/control/manipulation/surround.ts +4 -4
- package/src/combinator/data/parser/context/delimiter.ts +20 -20
- package/src/combinator/data/parser/context.ts +4 -3
- package/src/parser/block/blockquote.ts +1 -1
- package/src/parser/block/dlist.ts +6 -6
- package/src/parser/block/extension/aside.ts +1 -1
- package/src/parser/block/extension/example.ts +2 -2
- package/src/parser/block/extension/figure.ts +3 -3
- package/src/parser/block/extension/table.ts +5 -5
- package/src/parser/block/heading.ts +6 -6
- package/src/parser/block/ilist.ts +1 -1
- package/src/parser/block/olist.ts +1 -1
- package/src/parser/block/paragraph.ts +3 -3
- package/src/parser/block/reply.ts +2 -2
- package/src/parser/block/sidefence.ts +1 -1
- package/src/parser/block/table.ts +4 -4
- package/src/parser/block/ulist.ts +1 -1
- package/src/parser/block.ts +4 -3
- package/src/parser/context.ts +18 -9
- package/src/parser/inline/annotation.ts +7 -4
- package/src/parser/inline/autolink/account.ts +15 -14
- package/src/parser/inline/autolink/anchor.ts +14 -13
- package/src/parser/inline/autolink/channel.ts +6 -3
- package/src/parser/inline/autolink/email.ts +4 -3
- package/src/parser/inline/autolink/hashnum.ts +11 -9
- package/src/parser/inline/autolink/hashtag.ts +11 -9
- package/src/parser/inline/autolink/url.ts +24 -18
- package/src/parser/inline/autolink.ts +4 -5
- package/src/parser/inline/bracket.ts +6 -6
- package/src/parser/inline/code.ts +1 -1
- package/src/parser/inline/deletion.ts +1 -1
- package/src/parser/inline/emphasis.ts +1 -1
- package/src/parser/inline/emstrong.ts +1 -1
- package/src/parser/inline/extension/index.ts +9 -6
- package/src/parser/inline/extension/indexer.ts +1 -1
- package/src/parser/inline/extension/label.ts +1 -1
- package/src/parser/inline/extension/placeholder.ts +1 -1
- package/src/parser/inline/html.ts +45 -43
- package/src/parser/inline/htmlentity.ts +3 -3
- package/src/parser/inline/insertion.ts +1 -1
- package/src/parser/inline/link.test.ts +7 -2
- package/src/parser/inline/link.ts +11 -15
- package/src/parser/inline/mark.ts +1 -1
- package/src/parser/inline/math.ts +1 -1
- package/src/parser/inline/media.ts +4 -4
- package/src/parser/inline/reference.ts +7 -4
- package/src/parser/inline/remark.ts +4 -4
- package/src/parser/inline/ruby.ts +7 -6
- package/src/parser/inline/shortmedia.ts +1 -1
- package/src/parser/inline/strong.ts +1 -1
- package/src/parser/inline/template.ts +2 -2
- package/src/parser/inline.test.ts +1 -0
- package/src/parser/segment.ts +3 -2
- package/src/parser/source/escapable.ts +2 -2
- package/src/parser/source/str.ts +1 -1
- package/src/parser/source/text.ts +3 -3
- package/src/parser/source/unescapable.ts +4 -2
- package/src/parser/visibility.ts +14 -13
package/markdown.d.ts
CHANGED
|
@@ -603,7 +603,7 @@ export namespace MarkdownParser {
|
|
|
603
603
|
Block<'reply/cite'>,
|
|
604
604
|
Parser<HTMLSpanElement | HTMLBRElement, Context, [
|
|
605
605
|
SourceParser.StrParser,
|
|
606
|
-
Parser<HTMLAnchorElement, Context, [
|
|
606
|
+
Parser<string | HTMLAnchorElement, Context, [
|
|
607
607
|
InlineParser.AutolinkParser.AnchorParser,
|
|
608
608
|
Parser<HTMLAnchorElement, Context, []>,
|
|
609
609
|
Parser<HTMLAnchorElement, Context, []>,
|
|
@@ -1147,8 +1147,9 @@ export namespace MarkdownParser {
|
|
|
1147
1147
|
export interface UrlParser extends
|
|
1148
1148
|
// https://host
|
|
1149
1149
|
Inline<'url'>,
|
|
1150
|
-
Parser<HTMLAnchorElement, Context, [
|
|
1150
|
+
Parser<string | HTMLAnchorElement, Context, [
|
|
1151
1151
|
LinkParser.UnsafeLinkParser,
|
|
1152
|
+
Parser<string, Context, []>,
|
|
1152
1153
|
]> {
|
|
1153
1154
|
}
|
|
1154
1155
|
export namespace UrlParser {
|
|
@@ -1156,7 +1157,10 @@ export namespace MarkdownParser {
|
|
|
1156
1157
|
Inline<'url/lineurl'>,
|
|
1157
1158
|
Parser<string | HTMLElement, Context, [
|
|
1158
1159
|
SourceParser.StrParser,
|
|
1159
|
-
|
|
1160
|
+
Parser<string | HTMLElement, Context, [
|
|
1161
|
+
InlineParser.LinkParser.UnsafeLinkParser,
|
|
1162
|
+
Parser<string, Context, []>,
|
|
1163
|
+
]>,
|
|
1160
1164
|
]> {
|
|
1161
1165
|
}
|
|
1162
1166
|
export interface BracketParser extends
|
|
@@ -1188,7 +1192,7 @@ export namespace MarkdownParser {
|
|
|
1188
1192
|
export interface ChannelParser extends
|
|
1189
1193
|
// @user#tag
|
|
1190
1194
|
Inline<'channel'>,
|
|
1191
|
-
Parser<HTMLAnchorElement, Context, [
|
|
1195
|
+
Parser<string | HTMLAnchorElement, Context, [
|
|
1192
1196
|
InlineParser.AutolinkParser.AccountParser,
|
|
1193
1197
|
InlineParser.AutolinkParser.HashtagParser,
|
|
1194
1198
|
]> {
|
|
@@ -1196,29 +1200,33 @@ export namespace MarkdownParser {
|
|
|
1196
1200
|
export interface AccountParser extends
|
|
1197
1201
|
// @user
|
|
1198
1202
|
Inline<'account'>,
|
|
1199
|
-
Parser<HTMLAnchorElement, Context, [
|
|
1203
|
+
Parser<string | HTMLAnchorElement, Context, [
|
|
1200
1204
|
LinkParser.UnsafeLinkParser,
|
|
1205
|
+
Parser<string, Context, []>,
|
|
1201
1206
|
]> {
|
|
1202
1207
|
}
|
|
1203
1208
|
export interface HashtagParser extends
|
|
1204
1209
|
// #tag
|
|
1205
1210
|
Inline<'hashtag'>,
|
|
1206
|
-
Parser<HTMLAnchorElement, Context, [
|
|
1211
|
+
Parser<string | HTMLAnchorElement, Context, [
|
|
1207
1212
|
LinkParser.UnsafeLinkParser,
|
|
1213
|
+
Parser<string, Context, []>,
|
|
1208
1214
|
]> {
|
|
1209
1215
|
}
|
|
1210
1216
|
export interface HashnumParser extends
|
|
1211
1217
|
// #1
|
|
1212
1218
|
Inline<'hashnum'>,
|
|
1213
|
-
Parser<HTMLAnchorElement, Context, [
|
|
1219
|
+
Parser<string | HTMLAnchorElement, Context, [
|
|
1214
1220
|
LinkParser.UnsafeLinkParser,
|
|
1221
|
+
Parser<string, Context, []>,
|
|
1215
1222
|
]> {
|
|
1216
1223
|
}
|
|
1217
1224
|
export interface AnchorParser extends
|
|
1218
1225
|
// >>1
|
|
1219
1226
|
Inline<'anchor'>,
|
|
1220
|
-
Parser<HTMLAnchorElement, Context, [
|
|
1227
|
+
Parser<string | HTMLAnchorElement, Context, [
|
|
1221
1228
|
LinkParser.UnsafeLinkParser,
|
|
1229
|
+
Parser<string, Context, []>,
|
|
1222
1230
|
]> {
|
|
1223
1231
|
}
|
|
1224
1232
|
}
|
package/package.json
CHANGED
|
@@ -59,10 +59,10 @@ export function surround<T>(
|
|
|
59
59
|
const { logger = {}, offset = 0 } = context;
|
|
60
60
|
for (let i = 0; i < source.length - mr_.length; ++i) {
|
|
61
61
|
if (source[i] !== source[0]) break;
|
|
62
|
-
const
|
|
63
|
-
if (!(
|
|
62
|
+
const pos = source.length + offset - i - 1;
|
|
63
|
+
if (!(pos in logger)) continue;
|
|
64
64
|
assert(log >>> 2);
|
|
65
|
-
if (logger[
|
|
65
|
+
if (logger[pos] & 1 << (log >>> 2)) return;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
const res2 = mr_ !== '' ? parser({ source: mr_, context }) : undefined;
|
|
@@ -77,7 +77,7 @@ export function surround<T>(
|
|
|
77
77
|
if (rest.length === lmr_.length) return;
|
|
78
78
|
if (log & 2 && rr === undefined) {
|
|
79
79
|
const { logger = {}, offset = 0 } = context;
|
|
80
|
-
logger[source.length + offset] |= 1 << (log >>> 2);
|
|
80
|
+
logger[source.length + offset - 1] |= 1 << (log >>> 2);
|
|
81
81
|
}
|
|
82
82
|
return rr
|
|
83
83
|
? f
|
|
@@ -33,7 +33,7 @@ export class Delimiters {
|
|
|
33
33
|
this.signature);
|
|
34
34
|
private readonly registry = memoize<(signature: string) => Delimiter[]>(() => []);
|
|
35
35
|
private readonly delimiters: Delimiter[] = [];
|
|
36
|
-
private readonly
|
|
36
|
+
private readonly stack: number[] = [];
|
|
37
37
|
private readonly states: (readonly number[])[] = [];
|
|
38
38
|
public push(
|
|
39
39
|
delims: readonly {
|
|
@@ -42,14 +42,14 @@ export class Delimiters {
|
|
|
42
42
|
readonly precedence: number;
|
|
43
43
|
}[]
|
|
44
44
|
): void {
|
|
45
|
-
const { registry, delimiters,
|
|
46
|
-
//
|
|
45
|
+
const { registry, delimiters, stack } = this;
|
|
46
|
+
// シグネチャ数以下
|
|
47
47
|
assert(delimiters.length < 100);
|
|
48
48
|
for (let i = 0; i < delims.length; ++i) {
|
|
49
49
|
const { signature, matcher, precedence } = delims[i];
|
|
50
|
-
const
|
|
51
|
-
const index =
|
|
52
|
-
if (
|
|
50
|
+
const memory = registry(signature);
|
|
51
|
+
const index = memory[0]?.index ?? delimiters.length;
|
|
52
|
+
if (memory.length === 0 || precedence > delimiters[index].precedence) {
|
|
53
53
|
const delimiter: Delimiter = {
|
|
54
54
|
index,
|
|
55
55
|
signature,
|
|
@@ -58,34 +58,34 @@ export class Delimiters {
|
|
|
58
58
|
state: true,
|
|
59
59
|
};
|
|
60
60
|
delimiters[index] = delimiter;
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
memory.push(delimiter);
|
|
62
|
+
stack.push(index);
|
|
63
63
|
}
|
|
64
64
|
else {
|
|
65
|
-
|
|
65
|
+
stack.push(-1);
|
|
66
66
|
}
|
|
67
67
|
// 現状各優先順位は固定
|
|
68
|
-
assert(
|
|
68
|
+
assert(memory.length === 1);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
public pop(count: number): void {
|
|
72
72
|
assert(count > 0);
|
|
73
|
-
const { registry, delimiters,
|
|
73
|
+
const { registry, delimiters, stack } = this;
|
|
74
74
|
for (let i = 0; i < count; ++i) {
|
|
75
|
-
assert(this.
|
|
76
|
-
const index =
|
|
75
|
+
assert(this.stack.length > 0);
|
|
76
|
+
const index = stack.pop()!;
|
|
77
77
|
if (index === -1) continue;
|
|
78
|
-
const
|
|
79
|
-
assert(
|
|
80
|
-
if (
|
|
78
|
+
const memory = registry(delimiters[index].signature);
|
|
79
|
+
assert(memory.length > 0);
|
|
80
|
+
if (memory.length === 1) {
|
|
81
81
|
assert(index === delimiters.length - 1);
|
|
82
|
-
assert(
|
|
83
|
-
|
|
82
|
+
assert(memory[0] === delimiters.at(-1));
|
|
83
|
+
memory.pop();
|
|
84
84
|
delimiters.pop();
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
|
-
|
|
88
|
-
delimiters[index] =
|
|
87
|
+
memory.pop();
|
|
88
|
+
delimiters[index] = memory.at(-1)!;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
}
|
|
@@ -96,11 +96,12 @@ export function precedence<T>(precedence: number, parser: Parser<T>): Parser<T>
|
|
|
96
96
|
assert(precedence >= 0);
|
|
97
97
|
return ({ source, context }) => {
|
|
98
98
|
const { delimiters, precedence: p = 0 } = context;
|
|
99
|
-
const shift = precedence > p;
|
|
99
|
+
const shift = delimiters && precedence > p;
|
|
100
100
|
context.precedence = precedence;
|
|
101
|
-
|
|
101
|
+
// デリミタはシフト後に設定しなければならない
|
|
102
|
+
shift && delimiters.shift(precedence);
|
|
102
103
|
const result = parser({ source, context });
|
|
103
|
-
shift && delimiters
|
|
104
|
+
shift && delimiters.unshift();
|
|
104
105
|
context.precedence = p;
|
|
105
106
|
return result;
|
|
106
107
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BlockquoteParser } from '../block';
|
|
2
|
+
import { Recursion } from '../context';
|
|
2
3
|
import { union, some, creation, block, validate, rewrite, open, convert, lazy, fmap } from '../../combinator';
|
|
3
4
|
import { autolink } from '../autolink';
|
|
4
5
|
import { contentline } from '../source';
|
|
5
|
-
import { Recursion } from '../context';
|
|
6
6
|
import { parse } from '../api/parse';
|
|
7
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
8
8
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { DListParser } from '../block';
|
|
2
|
+
import { State } from '../context';
|
|
2
3
|
import { union, inits, some, state, block, line, validate, rewrite, open, lazy, fmap } from '../../combinator';
|
|
3
4
|
import { inline, indexee, indexer, dataindex } from '../inline';
|
|
4
5
|
import { anyline } from '../source';
|
|
5
|
-
import { State } from '../context';
|
|
6
6
|
import { lineable } from '../util';
|
|
7
|
-
import { visualize,
|
|
7
|
+
import { visualize, trimBlank, trimBlankEnd } from '../visibility';
|
|
8
8
|
import { push } from 'spica/array';
|
|
9
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
10
10
|
|
|
@@ -19,17 +19,17 @@ export const dlist: DListParser = lazy(() => block(fmap(validate(
|
|
|
19
19
|
|
|
20
20
|
const term: DListParser.TermParser = line(indexee(fmap(open(
|
|
21
21
|
/^~[^\S\n]+(?=\S)/,
|
|
22
|
-
visualize(
|
|
22
|
+
visualize(trimBlank(some(union([indexer, inline])))),
|
|
23
23
|
true),
|
|
24
|
-
ns => [html('dt', { 'data-index': dataindex(ns) },
|
|
24
|
+
ns => [html('dt', { 'data-index': dataindex(ns) }, defrag(ns))])));
|
|
25
25
|
|
|
26
26
|
const desc: DListParser.DescriptionParser = block(fmap(open(
|
|
27
27
|
/^:[^\S\n]+(?=\S)|/,
|
|
28
28
|
rewrite(
|
|
29
29
|
some(anyline, /^[~:][^\S\n]+\S/),
|
|
30
|
-
visualize(lineable(some(union([inline]))))),
|
|
30
|
+
visualize(trimBlankEnd(lineable(some(union([inline])))))),
|
|
31
31
|
true),
|
|
32
|
-
ns => [html('dd',
|
|
32
|
+
ns => [html('dd', defrag(ns))]),
|
|
33
33
|
false);
|
|
34
34
|
|
|
35
35
|
function fillTrailingDescription(es: HTMLElement[]): HTMLElement[] {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../block';
|
|
2
|
+
import { Recursion } from '../../context';
|
|
2
3
|
import { creation, block, validate, fence, fmap } from '../../../combinator';
|
|
3
4
|
import { identity } from '../../inline/extension/indexee';
|
|
4
|
-
import { Recursion } from '../../context';
|
|
5
5
|
import { parse } from '../../api/parse';
|
|
6
6
|
import { html } from 'typed-dom/dom';
|
|
7
7
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ExtensionParser } from '../../block';
|
|
2
|
+
import { Recursion } from '../../context';
|
|
2
3
|
import { eval } from '../../../combinator/data/parser';
|
|
3
4
|
import { creation, block, validate, fence, fmap } from '../../../combinator';
|
|
4
|
-
import { parse } from '../../api/parse';
|
|
5
5
|
import { mathblock } from '../mathblock';
|
|
6
|
-
import {
|
|
6
|
+
import { parse } from '../../api/parse';
|
|
7
7
|
import { html } from 'typed-dom/dom';
|
|
8
8
|
|
|
9
9
|
const opener = /^(~{3,})(?:example\/(\S+))?(?!\S)([^\n]*)(?:$|\n)/;
|
|
@@ -12,7 +12,7 @@ import { table, segment_ as seg_table } from './table';
|
|
|
12
12
|
import { blockquote, segment as seg_blockquote } from '../blockquote';
|
|
13
13
|
import { placeholder, segment_ as seg_placeholder } from './placeholder';
|
|
14
14
|
import { inline, media, shortmedia } from '../../inline';
|
|
15
|
-
import { visualize,
|
|
15
|
+
import { visualize, trimBlank } from '../../visibility';
|
|
16
16
|
import { memoize } from 'spica/memoize';
|
|
17
17
|
import { html, defrag } from 'typed-dom/dom';
|
|
18
18
|
|
|
@@ -63,7 +63,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
|
|
|
63
63
|
line(shortmedia),
|
|
64
64
|
])),
|
|
65
65
|
emptyline,
|
|
66
|
-
block(visualize(
|
|
66
|
+
block(visualize(trimBlank(some(inline)))),
|
|
67
67
|
]),
|
|
68
68
|
])),
|
|
69
69
|
([label, param, content, ...caption]: [HTMLAnchorElement, string, ...HTMLElement[]]) => [
|
|
@@ -72,7 +72,7 @@ export const figure: FigureParser = block(fallback(rewrite(segment, fmap(
|
|
|
72
72
|
[
|
|
73
73
|
html('figcaption', [
|
|
74
74
|
html('span', { class: 'figindex' }),
|
|
75
|
-
html('span', { class: 'figtext' },
|
|
75
|
+
html('span', { class: 'figtext' }, defrag(caption)),
|
|
76
76
|
]),
|
|
77
77
|
html('div', [content]),
|
|
78
78
|
])
|
|
@@ -5,7 +5,7 @@ import { union, subsequence, inits, some, block, line, validate, fence, rewrite,
|
|
|
5
5
|
import { inline, medialink, media, shortmedia } from '../../inline';
|
|
6
6
|
import { str, anyline, emptyline, contentline } from '../../source';
|
|
7
7
|
import { lineable } from '../../util';
|
|
8
|
-
import { visualize,
|
|
8
|
+
import { visualize, trimBlank, trimBlankEnd } from '../../visibility';
|
|
9
9
|
import { unshift, splice } from 'spica/array';
|
|
10
10
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
11
11
|
|
|
@@ -89,10 +89,10 @@ const head: CellParser.HeadParser = block(fmap(open(
|
|
|
89
89
|
block(surround(/^[^\n]/, medialink, /^\s*$/)),
|
|
90
90
|
block(surround(/^[^\n]/, media, /^\s*$/)),
|
|
91
91
|
block(surround(/^[^\n]/, shortmedia, /^\s*$/)),
|
|
92
|
-
open(/^(?:\s*\n|\s)/, visualize(
|
|
92
|
+
open(/^(?:\s*\n|\s)/, visualize(trimBlank(some(inline))), true),
|
|
93
93
|
])),
|
|
94
94
|
true),
|
|
95
|
-
ns => [html('th', attributes(ns.shift()! as string),
|
|
95
|
+
ns => [html('th', attributes(ns.shift()! as string), defrag(ns))]),
|
|
96
96
|
false);
|
|
97
97
|
|
|
98
98
|
const data: CellParser.DataParser = block(fmap(open(
|
|
@@ -106,10 +106,10 @@ const data: CellParser.DataParser = block(fmap(open(
|
|
|
106
106
|
block(surround(/^[^\n]/, medialink, /^\s*$/)),
|
|
107
107
|
block(surround(/^[^\n]/, media, /^\s*$/)),
|
|
108
108
|
block(surround(/^[^\n]/, shortmedia, /^\s*$/)),
|
|
109
|
-
open(/^(?:\s*\n|\s)/, visualize(lineable(some(inline))), true),
|
|
109
|
+
open(/^(?:\s*\n|\s)/, visualize(trimBlankEnd(lineable(some(inline)))), true),
|
|
110
110
|
])),
|
|
111
111
|
true),
|
|
112
|
-
ns => [html('td', attributes(ns.shift()! as string),
|
|
112
|
+
ns => [html('td', attributes(ns.shift()! as string), defrag(ns))]),
|
|
113
113
|
false);
|
|
114
114
|
|
|
115
115
|
const dataline: CellParser.DatalineParser = line(
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { HeadingParser } from '../block';
|
|
2
|
+
import { State } from '../context';
|
|
2
3
|
import { union, some, state, block, line, validate, focus, rewrite, open, fmap } from '../../combinator';
|
|
3
4
|
import { inline, indexee, indexer, dataindex } from '../inline';
|
|
4
5
|
import { str } from '../source';
|
|
5
|
-
import {
|
|
6
|
-
import { visualize, trimBlankStart, trimNodeEnd } from '../visibility';
|
|
6
|
+
import { visualize, trimBlank } from '../visibility';
|
|
7
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
8
8
|
|
|
9
9
|
export const segment: HeadingParser.SegmentParser = block(validate('#', focus(
|
|
@@ -16,19 +16,19 @@ export const heading: HeadingParser = block(rewrite(segment,
|
|
|
16
16
|
line(indexee(fmap(union([
|
|
17
17
|
open(
|
|
18
18
|
str(/^##+/),
|
|
19
|
-
visualize(
|
|
19
|
+
visualize(trimBlank(some(union([indexer, inline])))), true),
|
|
20
20
|
open(
|
|
21
21
|
str('#'),
|
|
22
22
|
state(State.linkers,
|
|
23
|
-
visualize(
|
|
23
|
+
visualize(trimBlank(some(union([indexer, inline]))))), true),
|
|
24
24
|
]),
|
|
25
25
|
([h, ...ns]: [string, ...(HTMLElement | string)[]]) => [
|
|
26
26
|
h.length <= 6
|
|
27
|
-
? html(`h${h.length as 1}`, { 'data-index': dataindex(ns) },
|
|
27
|
+
? html(`h${h.length as 1}`, { 'data-index': dataindex(ns) }, defrag(ns))
|
|
28
28
|
: html(`h6`, {
|
|
29
29
|
class: 'invalid',
|
|
30
30
|
'data-invalid-syntax': 'heading',
|
|
31
31
|
'data-invalid-type': 'syntax',
|
|
32
32
|
'data-invalid-message': 'Heading level must be up to 6',
|
|
33
|
-
},
|
|
33
|
+
}, defrag(ns))
|
|
34
34
|
]))))));
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { IListParser } from '../block';
|
|
2
|
+
import { Recursion } from '../context';
|
|
2
3
|
import { union, inits, some, creation, block, line, validate, indent, open, trim, fallback, lazy, fmap } from '../../combinator';
|
|
3
4
|
import { ulist_, invalid, fillFirstLine } from './ulist';
|
|
4
5
|
import { olist_ } from './olist';
|
|
5
6
|
import { inline } from '../inline';
|
|
6
|
-
import { Recursion } from '../context';
|
|
7
7
|
import { lineable } from '../util';
|
|
8
8
|
import { visualize, trimBlank } from '../visibility';
|
|
9
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { OListParser } from '../block';
|
|
2
|
+
import { Recursion } from '../context';
|
|
2
3
|
import { union, inits, subsequence, some, creation, block, line, validate, indent, focus, open, match, trim, fallback, lazy, fmap } from '../../combinator';
|
|
3
4
|
import { ulist_, checkbox, invalid, fillFirstLine } from './ulist';
|
|
4
5
|
import { ilist_ } from './ilist';
|
|
5
6
|
import { inline, indexee, indexer, dataindex } from '../inline';
|
|
6
7
|
import { lineable } from '../util';
|
|
7
8
|
import { visualize, trimBlank } from '../visibility';
|
|
8
|
-
import { Recursion } from '../context';
|
|
9
9
|
import { memoize } from 'spica/memoize';
|
|
10
10
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
11
11
|
|
|
@@ -2,9 +2,9 @@ import { ParagraphParser } from '../block';
|
|
|
2
2
|
import { union, some, block, fmap } from '../../combinator';
|
|
3
3
|
import { inline } from '../inline';
|
|
4
4
|
import { lineable } from '../util';
|
|
5
|
-
import { visualize,
|
|
5
|
+
import { visualize, trimBlankEnd } from '../visibility';
|
|
6
6
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
7
|
|
|
8
8
|
export const paragraph: ParagraphParser = block(fmap(
|
|
9
|
-
visualize(lineable(some(union([inline])))),
|
|
10
|
-
ns => [html('p',
|
|
9
|
+
visualize(trimBlankEnd(lineable(some(union([inline]))))),
|
|
10
|
+
ns => [html('p', defrag(ns))]));
|
|
@@ -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 { lineable } from '../util';
|
|
8
|
-
import { visualize,
|
|
8
|
+
import { visualize, trimBlankNodeEnd } from '../visibility';
|
|
9
9
|
import { push } from 'spica/array';
|
|
10
10
|
import { html, defrag } from 'typed-dom/dom';
|
|
11
11
|
|
|
@@ -30,4 +30,4 @@ export const reply: ReplyParser = block(validate('>', fmap(
|
|
|
30
30
|
ns => push(ns, [html('br')])),
|
|
31
31
|
])),
|
|
32
32
|
]),
|
|
33
|
-
ns => [html('p',
|
|
33
|
+
ns => [html('p', trimBlankNodeEnd(defrag(ns)))])));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { SidefenceParser } from '../block';
|
|
2
|
+
import { Recursion } from '../context';
|
|
2
3
|
import { union, some, creation, block, focus, rewrite, convert, lazy, fmap } from '../../combinator';
|
|
3
4
|
import { autolink } from '../autolink';
|
|
4
5
|
import { contentline } from '../source';
|
|
5
|
-
import { Recursion } from '../context';
|
|
6
6
|
import { html, define, defrag } from 'typed-dom/dom';
|
|
7
7
|
|
|
8
8
|
export const sidefence: SidefenceParser = lazy(() => block(fmap(focus(
|
|
@@ -2,7 +2,7 @@ import { TableParser } from '../block';
|
|
|
2
2
|
import { union, sequence, some, block, line, validate, focus, rewrite, surround, open, close, trimStart, fallback, lazy, fmap } from '../../combinator';
|
|
3
3
|
import { inline, media, medialink, shortmedia } from '../inline';
|
|
4
4
|
import { contentline } from '../source';
|
|
5
|
-
import {
|
|
5
|
+
import { trimBlank } from '../visibility';
|
|
6
6
|
import { duffReduce } from 'spica/duff';
|
|
7
7
|
import { push } from 'spica/array';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
@@ -53,17 +53,17 @@ const cell: CellParser = surround(
|
|
|
53
53
|
close(medialink, /^\s*(?=\||$)/),
|
|
54
54
|
close(media, /^\s*(?=\||$)/),
|
|
55
55
|
close(shortmedia, /^\s*(?=\||$)/),
|
|
56
|
-
|
|
56
|
+
trimBlank(some(inline, /^\|/, [[/^[|\\]?\s*$/, 9]])),
|
|
57
57
|
])),
|
|
58
58
|
/^[^|]*/, true);
|
|
59
59
|
|
|
60
60
|
const head: CellParser.HeadParser = fmap(
|
|
61
61
|
cell,
|
|
62
|
-
ns => [html('th',
|
|
62
|
+
ns => [html('th', defrag(ns))]);
|
|
63
63
|
|
|
64
64
|
const data: CellParser.DataParser = fmap(
|
|
65
65
|
cell,
|
|
66
|
-
ns => [html('td',
|
|
66
|
+
ns => [html('td', defrag(ns))]);
|
|
67
67
|
|
|
68
68
|
function format(rows: HTMLTableRowElement[]): HTMLTableRowElement[] {
|
|
69
69
|
const aligns = rows[0].className === 'invalid'
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { UListParser } from '../block';
|
|
2
2
|
import { Parser } from '../../combinator/data/parser';
|
|
3
|
+
import { Recursion } from '../context';
|
|
3
4
|
import { union, inits, subsequence, some, creation, block, line, validate, indent, focus, rewrite, open, trim, fallback, lazy, fmap } from '../../combinator';
|
|
4
5
|
import { olist_ } from './olist';
|
|
5
6
|
import { ilist_ } from './ilist';
|
|
6
7
|
import { inline, indexer, indexee, dataindex } from '../inline';
|
|
7
8
|
import { contentline } from '../source';
|
|
8
|
-
import { Recursion } from '../context';
|
|
9
9
|
import { lineable } from '../util';
|
|
10
10
|
import { visualize, trimBlank } from '../visibility';
|
|
11
11
|
import { unshift } from 'spica/array';
|
package/src/parser/block.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../markdown';
|
|
2
|
+
import { Recursion, Command } from './context';
|
|
2
3
|
import { union, reset, open, fallback, recover } from '../combinator';
|
|
3
4
|
import { emptyline } from './source';
|
|
4
5
|
import { pagebreak } from './block/pagebreak';
|
|
@@ -16,7 +17,6 @@ import { blockquote } from './block/blockquote';
|
|
|
16
17
|
import { mediablock } from './block/mediablock';
|
|
17
18
|
import { reply } from './block/reply';
|
|
18
19
|
import { paragraph } from './block/paragraph';
|
|
19
|
-
import { Recursion } from './context';
|
|
20
20
|
import { rnd0Z } from 'spica/random';
|
|
21
21
|
import { html } from 'typed-dom/dom';
|
|
22
22
|
|
|
@@ -71,8 +71,9 @@ export const block: BlockParser = reset(
|
|
|
71
71
|
])));
|
|
72
72
|
|
|
73
73
|
function error(parser: BlockParser): BlockParser {
|
|
74
|
+
const reg = new RegExp(String.raw`^${Command.Error}.*\n`)
|
|
74
75
|
return recover<BlockParser>(fallback(
|
|
75
|
-
open(
|
|
76
|
+
open(Command.Error, ({ source }) => { throw new Error(source.split('\n', 1)[0]); }),
|
|
76
77
|
parser),
|
|
77
78
|
({ source, context: { id } }, reason) => [[
|
|
78
79
|
html('h1',
|
|
@@ -89,7 +90,7 @@ function error(parser: BlockParser): BlockParser {
|
|
|
89
90
|
translate: 'no',
|
|
90
91
|
},
|
|
91
92
|
source
|
|
92
|
-
.replace(
|
|
93
|
+
.replace(reg, '')
|
|
93
94
|
.slice(0, 1001)
|
|
94
95
|
.replace(/^(.{997}).{4}$/s, '$1...') || undefined),
|
|
95
96
|
], '']);
|
package/src/parser/context.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
export const enum State {
|
|
2
|
-
annotation = 1 <<
|
|
3
|
-
reference = 1 <<
|
|
4
|
-
index = 1 <<
|
|
5
|
-
label = 1 <<
|
|
6
|
-
link = 1 <<
|
|
7
|
-
media = 1 <<
|
|
8
|
-
mark = 1 <<
|
|
9
|
-
autolink = 1 <<
|
|
10
|
-
shortcut = 1 << 0,
|
|
2
|
+
annotation = 1 << 7,
|
|
3
|
+
reference = 1 << 6,
|
|
4
|
+
index = 1 << 5,
|
|
5
|
+
label = 1 << 4,
|
|
6
|
+
link = 1 << 3,
|
|
7
|
+
media = 1 << 2,
|
|
8
|
+
mark = 1 << 1,
|
|
9
|
+
autolink = 1 << 0,
|
|
11
10
|
none = 0,
|
|
12
11
|
all = ~0,
|
|
13
12
|
linkers = 0
|
|
@@ -39,3 +38,13 @@ export const enum Backtrack {
|
|
|
39
38
|
url = 2 << 2,
|
|
40
39
|
bracket = 1 << 2,
|
|
41
40
|
}
|
|
41
|
+
|
|
42
|
+
export const enum Command {
|
|
43
|
+
Error = '\x07',
|
|
44
|
+
Escape = '\x1B',
|
|
45
|
+
Separator = '\x1F',
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const CmdRegExp = {
|
|
49
|
+
Escape: /\x1B/g,
|
|
50
|
+
} as const;
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { AnnotationParser } from '../inline';
|
|
2
|
+
import { State, Recursion, Backtrack } from '../context';
|
|
2
3
|
import { union, some, syntax, creation, constraint, surround, lazy } from '../../combinator';
|
|
3
4
|
import { inline } from '../inline';
|
|
4
|
-
import {
|
|
5
|
-
import { trimBlankStart, trimNodeEnd } from '../visibility';
|
|
5
|
+
import { trimBlankStart, trimBlankNodeEnd } from '../visibility';
|
|
6
6
|
import { html, defrag } from 'typed-dom/dom';
|
|
7
7
|
|
|
8
8
|
export const annotation: AnnotationParser = lazy(() => creation(1, Recursion.ignore, surround(
|
|
9
9
|
'((',
|
|
10
10
|
constraint(State.annotation, false,
|
|
11
11
|
syntax(1, State.annotation | State.media,
|
|
12
|
-
trimBlankStart(some(union([inline]), ')', [[
|
|
12
|
+
trimBlankStart(some(union([inline]), ')', [['\n', 9], [')', 1]])))),
|
|
13
13
|
'))',
|
|
14
14
|
false,
|
|
15
|
-
([, ns], rest) =>
|
|
15
|
+
([, ns], rest) =>
|
|
16
|
+
trimBlankNodeEnd(ns).length > 0
|
|
17
|
+
? [[html('sup', { class: 'annotation' }, [html('span', defrag(ns))])], rest]
|
|
18
|
+
: undefined,
|
|
16
19
|
undefined, 1 | Backtrack.bracket)));
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import { AutolinkParser } from '../../inline';
|
|
2
|
-
import {
|
|
2
|
+
import { State } from '../../context';
|
|
3
|
+
import { union, tails, syntax, constraint, rewrite, open, convert, fmap, lazy } from '../../../combinator';
|
|
3
4
|
import { unsafelink } from '../link';
|
|
4
5
|
import { str } from '../../source';
|
|
5
|
-
import { State } from '../../context';
|
|
6
6
|
import { define } from 'typed-dom/dom';
|
|
7
7
|
|
|
8
8
|
// https://example/@user must be a user page or a redirect page going there.
|
|
9
9
|
|
|
10
|
-
export const account: AutolinkParser.AccountParser = lazy(() =>
|
|
11
|
-
constraint(State.shortcut, false,
|
|
10
|
+
export const account: AutolinkParser.AccountParser = lazy(() => rewrite(
|
|
12
11
|
open(
|
|
13
12
|
'@',
|
|
14
13
|
tails([
|
|
15
14
|
str(/^[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?(?:\.[0-9a-z](?:(?:[0-9a-z]|-(?=[0-9a-z])){0,61}[0-9a-z])?)*\//i),
|
|
16
15
|
str(/^[a-z][0-9a-z]*(?:[-.][0-9a-z]+)*/i),
|
|
17
|
-
]))
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
])),
|
|
17
|
+
union([
|
|
18
|
+
constraint(State.autolink, false, syntax(0, State.autolink, fmap(convert(
|
|
19
|
+
source =>
|
|
20
|
+
`[${source}]{ ${source.includes('/')
|
|
21
|
+
? `https://${source.slice(1).replace('/', '/@')}`
|
|
22
|
+
: `/${source}`
|
|
23
|
+
} }`,
|
|
24
|
+
unsafelink),
|
|
25
|
+
([el]) => [define(el, { class: 'account' })]))),
|
|
26
|
+
({ source }) => [[source], ''],
|
|
27
|
+
])));
|