securemark 0.283.4 → 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 +4 -0
- package/dist/index.js +76 -55
- package/package.json +1 -1
- 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 +10 -0
- package/src/parser/inline/annotation.ts +7 -4
- package/src/parser/inline/autolink/account.ts +1 -1
- package/src/parser/inline/autolink/anchor.ts +1 -1
- package/src/parser/inline/autolink/channel.ts +1 -1
- package/src/parser/inline/autolink/email.ts +1 -1
- package/src/parser/inline/autolink/hashnum.ts +1 -1
- package/src/parser/inline/autolink/hashtag.ts +1 -1
- package/src/parser/inline/autolink/url.ts +1 -1
- package/src/parser/inline/autolink.ts +1 -1
- 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 +1 -1
- 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 +5 -10
- 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 +1 -1
- package/src/parser/inline/ruby.ts +3 -3
- 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/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
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { MediaParser } from '../inline';
|
|
2
|
+
import { State, Recursion, Backtrack, Command, CmdRegExp } from '../context';
|
|
2
3
|
import { union, inits, tails, some, syntax, creation, precedence, constraint, validate, verify, surround, open, dup, lazy, fmap, bind } from '../../combinator';
|
|
3
4
|
import { unsafelink, uri, option as linkoption, resolve } from './link';
|
|
4
5
|
import { attributes } from './html';
|
|
5
6
|
import { unsafehtmlentity } from './htmlentity';
|
|
6
7
|
import { txt, linebreak, str } from '../source';
|
|
7
|
-
import { State, Recursion, Backtrack } from '../context';
|
|
8
8
|
import { markInvalid } from '../util';
|
|
9
9
|
import { ReadonlyURL } from 'spica/url';
|
|
10
10
|
import { unshift, push } from 'spica/array';
|
|
@@ -25,7 +25,7 @@ export const media: MediaParser = lazy(() => validate(['![', '!{'], creation(1,
|
|
|
25
25
|
bind(verify(fmap(tails([
|
|
26
26
|
dup(surround(
|
|
27
27
|
'[',
|
|
28
|
-
some(union([unsafehtmlentity, bracket, txt]), ']', [[
|
|
28
|
+
some(union([unsafehtmlentity, bracket, txt]), ']', [['\n', 9]]),
|
|
29
29
|
']',
|
|
30
30
|
true, undefined, undefined, 1 | Backtrack.media)),
|
|
31
31
|
dup(surround(
|
|
@@ -105,8 +105,8 @@ function sanitize(target: HTMLElement, uri: ReadonlyURL, alt: string): boolean {
|
|
|
105
105
|
markInvalid(target, 'media', 'argument', 'Invalid protocol');
|
|
106
106
|
return false;
|
|
107
107
|
}
|
|
108
|
-
if (alt.includes(
|
|
109
|
-
define(target, { alt: target.getAttribute('alt')?.replace(
|
|
108
|
+
if (alt.includes(Command.Escape)) {
|
|
109
|
+
define(target, { alt: target.getAttribute('alt')?.replace(CmdRegExp.Escape, '') });
|
|
110
110
|
markInvalid(target, 'media', 'content',
|
|
111
111
|
`Cannot use invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)![0]}"`);
|
|
112
112
|
return false;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ReferenceParser } from '../inline';
|
|
2
|
+
import { State, Recursion, Backtrack } from '../context';
|
|
2
3
|
import { union, subsequence, some, syntax, creation, constraint, surround, lazy } from '../../combinator';
|
|
3
4
|
import { inline } from '../inline';
|
|
4
5
|
import { str } from '../source';
|
|
5
|
-
import {
|
|
6
|
-
import { blank, trimBlankStart, trimNodeEnd } from '../visibility';
|
|
6
|
+
import { blank, trimBlankStart, trimBlankNodeEnd } from '../visibility';
|
|
7
7
|
import { html, defrag } from 'typed-dom/dom';
|
|
8
8
|
|
|
9
9
|
export const reference: ReferenceParser = lazy(() => creation(1, Recursion.ignore, surround(
|
|
@@ -12,11 +12,14 @@ export const reference: ReferenceParser = lazy(() => creation(1, Recursion.ignor
|
|
|
12
12
|
syntax(1, State.annotation | State.reference | State.media,
|
|
13
13
|
subsequence([
|
|
14
14
|
abbr,
|
|
15
|
-
trimBlankStart(some(inline, ']', [[
|
|
15
|
+
trimBlankStart(some(inline, ']', [['\n', 9], [']', 1]])),
|
|
16
16
|
]))),
|
|
17
17
|
']]',
|
|
18
18
|
false,
|
|
19
|
-
([, ns], rest) =>
|
|
19
|
+
([, ns], rest) =>
|
|
20
|
+
trimBlankNodeEnd(ns).length > 0
|
|
21
|
+
? [[html('sup', attributes(ns), [html('span', defrag(ns))])], rest]
|
|
22
|
+
: undefined,
|
|
20
23
|
undefined, 1 | Backtrack.bracket)));
|
|
21
24
|
|
|
22
25
|
// Chicago-Style
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { RemarkParser } from '../inline';
|
|
2
|
+
import { State, Recursion } from '../context';
|
|
2
3
|
import { union, some, syntax, creation, validate, surround, open, close, match, lazy } from '../../combinator';
|
|
3
4
|
import { inline } from '../inline';
|
|
4
5
|
import { text, str } from '../source';
|
|
5
|
-
import { State, Recursion } from '../context';
|
|
6
6
|
import { memoize } from 'spica/memoize';
|
|
7
7
|
import { unshift, push } from 'spica/array';
|
|
8
8
|
import { html, defrag } from 'typed-dom/dom';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { RubyParser } from '../inline';
|
|
2
|
+
import { State, Recursion, Backtrack, Command, CmdRegExp } from '../context';
|
|
2
3
|
import { eval, exec } from '../../combinator/data/parser';
|
|
3
4
|
import { sequence, syntax, creation, validate, surround, lazy, fmap, bind } from '../../combinator';
|
|
4
5
|
import { unsafehtmlentity } from './htmlentity';
|
|
5
6
|
import { text as txt, str } from '../source';
|
|
6
|
-
import { State, Recursion, Backtrack } from '../context';
|
|
7
7
|
import { isStartTightNodes } from '../visibility';
|
|
8
8
|
import { unshift, push } from 'spica/array';
|
|
9
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
@@ -91,8 +91,8 @@ function attributes(texts: string[], rubies: string[]): Record<string, string> {
|
|
|
91
91
|
let attrs: Record<string, string> | undefined;
|
|
92
92
|
for (const ss of [texts, rubies]) {
|
|
93
93
|
for (let i = 0; i < ss.length; ++i) {
|
|
94
|
-
if (!ss[i].includes(
|
|
95
|
-
ss[i] = ss[i].replace(
|
|
94
|
+
if (!ss[i].includes(Command.Escape)) continue;
|
|
95
|
+
ss[i] = ss[i].replace(CmdRegExp.Escape, '');
|
|
96
96
|
attrs ??= {
|
|
97
97
|
class: 'invalid',
|
|
98
98
|
'data-invalid-syntax': 'ruby',
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ShortMediaParser } from '../inline';
|
|
2
|
+
import { State } from '../context';
|
|
2
3
|
import { union, constraint, focus, rewrite, open, convert } from '../../combinator';
|
|
3
4
|
import { url } from './autolink/url';
|
|
4
5
|
import { media } from './media';
|
|
5
6
|
import { linebreak } from '../source';
|
|
6
|
-
import { State } from '../context';
|
|
7
7
|
|
|
8
8
|
export const shortmedia: ShortMediaParser = rewrite(
|
|
9
9
|
constraint(State.media, false,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { StrongParser } from '../inline';
|
|
2
|
+
import { State, Recursion } from '../context';
|
|
2
3
|
import { union, some, syntax, creation, surround, open, lazy } from '../../combinator';
|
|
3
4
|
import { inline } from '../inline';
|
|
4
5
|
import { emstrong } from './emstrong';
|
|
5
6
|
import { str } from '../source';
|
|
6
|
-
import { State, Recursion } from '../context';
|
|
7
7
|
import { startTight, blankWith } from '../visibility';
|
|
8
8
|
import { unshift } from 'spica/array';
|
|
9
9
|
import { html, defrag } from 'typed-dom/dom';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TemplateParser } from '../inline';
|
|
2
|
+
import { State, Recursion, Backtrack } from '../context';
|
|
2
3
|
import { union, some, syntax, creation, precedence, surround, lazy } from '../../combinator';
|
|
3
4
|
import { escsource, str } from '../source';
|
|
4
|
-
import { State, Recursion, Backtrack } from '../context';
|
|
5
5
|
import { unshift } from 'spica/array';
|
|
6
6
|
import { html } from 'typed-dom/dom';
|
|
7
7
|
|
|
@@ -10,7 +10,7 @@ export const template: TemplateParser = lazy(() => creation(1, Recursion.ignore,
|
|
|
10
10
|
syntax(1, State.all, some(union([bracket, escsource]), '}')),
|
|
11
11
|
'}}',
|
|
12
12
|
true,
|
|
13
|
-
([, ns = []], rest) => [[html('span', { class: 'template' }, `{{${ns.join('')
|
|
13
|
+
([, ns = []], rest) => [[html('span', { class: 'template' }, `{{${ns.join('')}}}`)], rest],
|
|
14
14
|
undefined, 3 | Backtrack.template)));
|
|
15
15
|
|
|
16
16
|
const bracket: TemplateParser.BracketParser = lazy(() => creation(0, Recursion.terminal, union([
|
package/src/parser/segment.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../markdown';
|
|
2
|
+
import { Command } from './context';
|
|
2
3
|
import { eval, exec } from '../combinator/data/parser';
|
|
3
4
|
import { union, some } from '../combinator';
|
|
4
5
|
import { segment as heading } from './block/heading';
|
|
@@ -22,7 +23,7 @@ const parser: SegmentParser = union([
|
|
|
22
23
|
]);
|
|
23
24
|
|
|
24
25
|
export function* segment(source: string): Generator<string, undefined, undefined> {
|
|
25
|
-
if (!validate(source, MAX_INPUT_SIZE)) return yield
|
|
26
|
+
if (!validate(source, MAX_INPUT_SIZE)) return yield `${Command.Error}Too large input over ${MAX_INPUT_SIZE.toLocaleString('en')} bytes.\n${source.slice(0, 1001)}`;
|
|
26
27
|
assert(source.length < Number.MAX_SAFE_INTEGER);
|
|
27
28
|
while (source !== '') {
|
|
28
29
|
const result = parser({ source, context: {} })!;
|
|
@@ -35,7 +36,7 @@ export function* segment(source: string): Generator<string, undefined, undefined
|
|
|
35
36
|
const seg = segs[i];
|
|
36
37
|
validate(seg, MAX_SEGMENT_SIZE)
|
|
37
38
|
? yield seg
|
|
38
|
-
: yield
|
|
39
|
+
: yield `${Command.Error}Too large segment over ${MAX_SEGMENT_SIZE.toLocaleString('en')} bytes.\n${seg}`
|
|
39
40
|
}
|
|
40
41
|
source = rest;
|
|
41
42
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EscapableSourceParser } from '../source';
|
|
2
|
+
import { Recursion, Command } from '../context';
|
|
2
3
|
import { creation } from '../../combinator';
|
|
3
4
|
import { nonWhitespace } from './text';
|
|
4
|
-
import { Recursion } from '../context';
|
|
5
5
|
|
|
6
6
|
const delimiter = /[\s\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]/;
|
|
7
7
|
|
|
@@ -17,7 +17,7 @@ export const escsource: EscapableSourceParser = creation(1, Recursion.ignore, ({
|
|
|
17
17
|
assert(!source.includes('\r', 1));
|
|
18
18
|
context.resources && ++context.resources.clock;
|
|
19
19
|
return [[], source.slice(1)];
|
|
20
|
-
case
|
|
20
|
+
case Command.Escape:
|
|
21
21
|
return [[source.slice(1, 2)], source.slice(2)];
|
|
22
22
|
case '\\':
|
|
23
23
|
switch (source[1]) {
|
package/src/parser/source/str.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { StrParser } from '../source';
|
|
2
|
+
import { Recursion } from '../context';
|
|
2
3
|
import { Parser, Context } from '../../combinator/data/parser';
|
|
3
4
|
import { creation } from '../../combinator';
|
|
4
|
-
import { Recursion } from '../context';
|
|
5
5
|
|
|
6
6
|
export function str(pattern: string | RegExp, not?: string): StrParser;
|
|
7
7
|
export function str(pattern: string | RegExp, not?: string): Parser<string, Context<StrParser>, []> {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TextParser, TxtParser, LinebreakParser } from '../source';
|
|
2
|
+
import { Recursion, Command } from '../context';
|
|
2
3
|
import { union, creation, focus } from '../../combinator';
|
|
3
4
|
import { str } from './str';
|
|
4
|
-
import { Recursion } from '../context';
|
|
5
5
|
import { html } from 'typed-dom/dom';
|
|
6
6
|
|
|
7
7
|
export const delimiter = /[\s\x00-\x7F()[]{}“”‘’「」『』]|\S[#>]/u;
|
|
@@ -21,12 +21,12 @@ export const text: TextParser = creation(1, Recursion.ignore, ({ source, context
|
|
|
21
21
|
assert(!source.includes('\r', 1));
|
|
22
22
|
context.resources && ++context.resources.clock;
|
|
23
23
|
return [[], source.slice(1)];
|
|
24
|
-
case
|
|
24
|
+
case Command.Escape:
|
|
25
25
|
case '\\':
|
|
26
26
|
switch (source[1]) {
|
|
27
27
|
case undefined:
|
|
28
28
|
case '\n':
|
|
29
|
-
assert(source[0] !==
|
|
29
|
+
assert(source[0] !== Command.Escape);
|
|
30
30
|
return [[], source.slice(1)];
|
|
31
31
|
default:
|
|
32
32
|
return [[source.slice(1, 2)], source.slice(2)];
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { UnescapableSourceParser } from '../source';
|
|
2
|
+
import { Recursion, Command } from '../context';
|
|
2
3
|
import { creation } from '../../combinator';
|
|
3
4
|
import { delimiter, nonWhitespace, nonAlphanumeric, isAlphanumeric } from './text';
|
|
4
|
-
import { Recursion } from '../context';
|
|
5
5
|
|
|
6
6
|
export const unescsource: UnescapableSourceParser = creation(1, Recursion.ignore, ({ source, context }) => {
|
|
7
|
-
assert(source[0] !== '\x1B');
|
|
8
7
|
if (source === '') return;
|
|
9
8
|
const i = source.search(delimiter);
|
|
10
9
|
switch (i) {
|
|
@@ -16,6 +15,9 @@ export const unescsource: UnescapableSourceParser = creation(1, Recursion.ignore
|
|
|
16
15
|
assert(!source.includes('\r', 1));
|
|
17
16
|
context.resources && ++context.resources.clock;
|
|
18
17
|
return [[], source.slice(1)];
|
|
18
|
+
case Command.Escape:
|
|
19
|
+
assert(source[0] !== Command.Escape);
|
|
20
|
+
return [[source.slice(1, 2)], source.slice(2)];
|
|
19
21
|
}
|
|
20
22
|
const b = source[0] !== '\n' && source[0].trimStart() === '';
|
|
21
23
|
const i = b || isAlphanumeric(source[0])
|
package/src/parser/visibility.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MarkdownParser } from '../../markdown';
|
|
2
|
+
import { Command } from './context';
|
|
2
3
|
import { Parser, Input, eval } from '../combinator/data/parser';
|
|
3
4
|
import { union, some, verify, convert, fmap } from '../combinator';
|
|
4
5
|
import { unsafehtmlentity } from './inline/htmlentity';
|
|
@@ -21,7 +22,7 @@ export function visualize<P extends Parser<HTMLElement | string>>(parser: P): P;
|
|
|
21
22
|
export function visualize<T extends HTMLElement | string>(parser: Parser<T>): Parser<T> {
|
|
22
23
|
return union([
|
|
23
24
|
convert(
|
|
24
|
-
source => source.replace(blank.line, line => line.replace(/[\\&<]/g,
|
|
25
|
+
source => source.replace(blank.line, line => line.replace(/[\\&<]/g, `${Command.Escape}$&`)),
|
|
25
26
|
verify(parser, (ns, rest) => !rest && hasVisible(ns))),
|
|
26
27
|
some(union([linebreak, unescsource])),
|
|
27
28
|
]);
|
|
@@ -64,7 +65,7 @@ export function blankWith(starting: '' | '\n', delimiter?: string | RegExp): Reg
|
|
|
64
65
|
//}
|
|
65
66
|
//const isStartLoose = reduce(({ source, context }: Input<MarkdownParser.Context>, except?: string): boolean => {
|
|
66
67
|
// return isStartTight({ source: source.replace(blank.start, ''), context }, except);
|
|
67
|
-
//}, ({ source }, except = '') => `${source}
|
|
68
|
+
//}, ({ source }, except = '') => `${source}${Command.Separator}${except}`);
|
|
68
69
|
|
|
69
70
|
export function startTight<P extends Parser<unknown>>(parser: P, except?: string): P;
|
|
70
71
|
export function startTight<T>(parser: Parser<T>, except?: string): Parser<T> {
|
|
@@ -103,7 +104,7 @@ const isStartTight = reduce(({ source, context }: Input<MarkdownParser.Context>,
|
|
|
103
104
|
default:
|
|
104
105
|
return source[0].trimStart() !== '';
|
|
105
106
|
}
|
|
106
|
-
}, ({ source }, except = '') => `${source}
|
|
107
|
+
}, ({ source }, except = '') => `${source}${Command.Separator}${except}`);
|
|
107
108
|
|
|
108
109
|
export function isStartLooseNodes(nodes: readonly (HTMLElement | string)[]): boolean {
|
|
109
110
|
if (nodes.length === 0) return true;
|
|
@@ -159,16 +160,16 @@ export function trimBlankStart<T>(parser: Parser<T>): Parser<T> {
|
|
|
159
160
|
source => source.replace(blank.start, ''),
|
|
160
161
|
parser);
|
|
161
162
|
}
|
|
162
|
-
function trimBlankEnd<P extends Parser<HTMLElement | string>>(parser: P): P;
|
|
163
|
-
function trimBlankEnd<T extends HTMLElement | string>(parser: Parser<T>): Parser<T> {
|
|
163
|
+
export function trimBlankEnd<P extends Parser<HTMLElement | string>>(parser: P): P;
|
|
164
|
+
export function trimBlankEnd<T extends HTMLElement | string>(parser: Parser<T>): Parser<T> {
|
|
164
165
|
return fmap(
|
|
165
166
|
parser,
|
|
166
|
-
|
|
167
|
+
trimBlankNodeEnd);
|
|
167
168
|
}
|
|
168
|
-
//export function
|
|
169
|
-
// return
|
|
169
|
+
//export function trimBlankNode<T extends HTMLElement | string>(nodes: T[]): T[] {
|
|
170
|
+
// return trimBlankNodeStart(trimBlankNodeEnd(nodes));
|
|
170
171
|
//}
|
|
171
|
-
//function
|
|
172
|
+
//function trimBlankNodeStart<T extends HTMLElement | string>(nodes: T[]): T[] {
|
|
172
173
|
// for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes[0], 0);) {
|
|
173
174
|
// if (typeof node === 'string') {
|
|
174
175
|
// const pos = node.trimStart().length;
|
|
@@ -184,7 +185,7 @@ function trimBlankEnd<T extends HTMLElement | string>(parser: Parser<T>): Parser
|
|
|
184
185
|
// }
|
|
185
186
|
// return nodes;
|
|
186
187
|
//}
|
|
187
|
-
export function
|
|
188
|
+
export function trimBlankNodeEnd<T extends HTMLElement | string>(nodes: T[]): T[] {
|
|
188
189
|
const skip = nodes.length > 0 &&
|
|
189
190
|
typeof nodes.at(-1) === 'object' &&
|
|
190
191
|
nodes.at(-1)!['className'] === 'indexer'
|
|
@@ -192,9 +193,9 @@ export function trimNodeEnd<T extends HTMLElement | string>(nodes: T[]): T[] {
|
|
|
192
193
|
: [];
|
|
193
194
|
for (let node = nodes[0]; nodes.length > 0 && !isVisible(node = nodes.at(-1)!, -1);) {
|
|
194
195
|
if (typeof node === 'string') {
|
|
195
|
-
const
|
|
196
|
-
if (
|
|
197
|
-
nodes[nodes.length - 1] = node.slice(0,
|
|
196
|
+
const len = node.trimEnd().length;
|
|
197
|
+
if (len > 0) {
|
|
198
|
+
nodes[nodes.length - 1] = node.slice(0, len) as T;
|
|
198
199
|
break;
|
|
199
200
|
}
|
|
200
201
|
}
|