securemark 0.248.1 → 0.249.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 +96 -159
- package/markdown.d.ts +10 -4
- package/package.json +6 -6
- package/src/parser/inline/annotation.test.ts +2 -2
- package/src/parser/inline/annotation.ts +3 -4
- package/src/parser/inline/comment.ts +1 -1
- package/src/parser/inline/deletion.ts +3 -3
- package/src/parser/inline/emphasis.test.ts +5 -4
- package/src/parser/inline/emphasis.ts +8 -3
- package/src/parser/inline/emstrong.ts +14 -6
- package/src/parser/inline/html.test.ts +5 -2
- package/src/parser/inline/html.ts +5 -8
- package/src/parser/inline/insertion.ts +3 -3
- package/src/parser/inline/link.test.ts +2 -2
- package/src/parser/inline/link.ts +3 -4
- package/src/parser/inline/mark.test.ts +5 -4
- package/src/parser/inline/mark.ts +3 -3
- package/src/parser/inline/reference.test.ts +5 -5
- package/src/parser/inline/reference.ts +7 -9
- package/src/parser/inline/strong.test.ts +5 -4
- package/src/parser/inline/strong.ts +7 -3
- package/src/parser/source/escapable.test.ts +4 -3
- package/src/parser/source/escapable.ts +3 -3
- package/src/parser/source/text.test.ts +4 -4
- package/src/parser/source/text.ts +3 -3
- package/src/parser/source/unescapable.test.ts +4 -3
- package/src/parser/source/unescapable.ts +3 -3
- package/src/parser/util.ts +26 -13
- package/src/renderer/render/media/image.ts +3 -3
- package/src/renderer/render/media/video.ts +2 -2
|
@@ -4,14 +4,14 @@ import { union, focus, creator } from '../../combinator';
|
|
|
4
4
|
import { str } from './str';
|
|
5
5
|
import { html } from 'typed-dom/dom';
|
|
6
6
|
|
|
7
|
-
export const
|
|
7
|
+
export const delimiter = /[\s\x00-\x7F]|\S#|[、。!?][^\S\n]*(?=\\\n)/;
|
|
8
8
|
export const nonWhitespace = /[\S\n]|$/;
|
|
9
9
|
export const nonAlphanumeric = /[^0-9A-Za-z]|\S#|$/;
|
|
10
10
|
const repeat = str(/^(.)\1*/);
|
|
11
11
|
|
|
12
12
|
export const text: TextParser = creator((source, context) => {
|
|
13
13
|
if (source === '') return;
|
|
14
|
-
const i = source.search(
|
|
14
|
+
const i = source.search(delimiter);
|
|
15
15
|
switch (i) {
|
|
16
16
|
case -1:
|
|
17
17
|
return [[source], ''];
|
|
@@ -70,7 +70,7 @@ export const text: TextParser = creator((source, context) => {
|
|
|
70
70
|
|| b && source[i] === '\n'
|
|
71
71
|
|| b && source[i] === '\\' && source[i + 1] === '\n'
|
|
72
72
|
? [[], source.slice(i)]
|
|
73
|
-
: [[source.slice(0, i)], source.slice(i)];
|
|
73
|
+
: [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
|
|
74
74
|
}
|
|
75
75
|
default:
|
|
76
76
|
return [[source.slice(0, i)], source.slice(i)];
|
|
@@ -18,10 +18,11 @@ describe('Unit: parser/source/unescapable', () => {
|
|
|
18
18
|
|
|
19
19
|
it('space', () => {
|
|
20
20
|
assert.deepStrictEqual(inspect(parser(' ')), [[' '], '']);
|
|
21
|
-
assert.deepStrictEqual(inspect(parser(' ')), [['
|
|
22
|
-
assert.deepStrictEqual(inspect(parser(' ')), [['
|
|
21
|
+
assert.deepStrictEqual(inspect(parser(' ')), [[' ', ' '], '']);
|
|
22
|
+
assert.deepStrictEqual(inspect(parser(' ')), [[' ', ' '], '']);
|
|
23
23
|
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', '\n'], '']);
|
|
24
|
-
assert.deepStrictEqual(inspect(parser(' \n')), [['
|
|
24
|
+
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', ' ', '\n'], '']);
|
|
25
|
+
assert.deepStrictEqual(inspect(parser(' \n')), [[' ', ' ', '\n'], '']);
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
it('linebreak', () => {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { UnescapableSourceParser } from '../source';
|
|
2
2
|
import { creator } from '../../combinator';
|
|
3
|
-
import {
|
|
3
|
+
import { delimiter, nonWhitespace, nonAlphanumeric, isAlphanumeric } from './text';
|
|
4
4
|
|
|
5
5
|
export const unescsource: UnescapableSourceParser = creator(source => {
|
|
6
6
|
assert(source[0] !== '\x1B');
|
|
7
7
|
if (source === '') return;
|
|
8
|
-
const i = source.search(
|
|
8
|
+
const i = source.search(delimiter);
|
|
9
9
|
switch (i) {
|
|
10
10
|
case -1:
|
|
11
11
|
return [[source], ''];
|
|
@@ -15,7 +15,7 @@ export const unescsource: UnescapableSourceParser = creator(source => {
|
|
|
15
15
|
? source.search(b ? nonWhitespace : nonAlphanumeric) || 1
|
|
16
16
|
: 1;
|
|
17
17
|
assert(i > 0);
|
|
18
|
-
return [[source.slice(0, i)], source.slice(i)];
|
|
18
|
+
return [[source.slice(0, i - +b || 1)], source.slice(i - +b || 1)];
|
|
19
19
|
}
|
|
20
20
|
default:
|
|
21
21
|
return [[source.slice(0, i)], source.slice(i)];
|
package/src/parser/util.ts
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import { undefined } from 'spica/global';
|
|
2
2
|
import { MarkdownParser } from '../../markdown';
|
|
3
3
|
import { Parser, eval } from '../combinator/data/parser';
|
|
4
|
-
import { union, some, verify, convert } from '../combinator';
|
|
4
|
+
import { union, some, verify, convert, fmap } from '../combinator';
|
|
5
5
|
import { unsafehtmlentity } from './inline/htmlentity';
|
|
6
6
|
import { linebreak, unescsource } from './source';
|
|
7
7
|
import { invisibleHTMLEntityNames } from './api/normalize';
|
|
8
8
|
import { reduce } from 'spica/memoize';
|
|
9
9
|
import { push } from 'spica/array';
|
|
10
10
|
|
|
11
|
-
export
|
|
11
|
+
export const regBlankInlineStart = new RegExp(String.raw
|
|
12
|
+
`^(?:\\?[^\S\n]|&(?:${invisibleHTMLEntityNames.join('|')});|<wbr>)+`);
|
|
13
|
+
|
|
14
|
+
export function blankWith(delimiter: string | RegExp): RegExp;
|
|
15
|
+
export function blankWith(starting: '' | '\n', delimiter: string | RegExp): RegExp;
|
|
16
|
+
export function blankWith(starting: '' | '\n', delimiter?: string | RegExp): RegExp {
|
|
17
|
+
if (delimiter === undefined) return blankWith('', starting);
|
|
12
18
|
return new RegExp(String.raw
|
|
13
|
-
`^(
|
|
14
|
-
|
|
15
|
-
}(
|
|
16
|
-
typeof
|
|
19
|
+
`^(?:(?=${
|
|
20
|
+
starting
|
|
21
|
+
})(?:\\?\s|&(?:${invisibleHTMLEntityNames.join('|')});|<wbr>)${starting && '+'})?${
|
|
22
|
+
typeof delimiter === 'string' ? delimiter.replace(/[*+()\[\]]/g, '\\$&') : delimiter.source
|
|
17
23
|
}`);
|
|
18
24
|
}
|
|
19
25
|
|
|
@@ -53,9 +59,10 @@ export function startLoose<T extends HTMLElement | string>(parser: Parser<T>, ex
|
|
|
53
59
|
? parser(source, context)
|
|
54
60
|
: undefined;
|
|
55
61
|
}
|
|
56
|
-
|
|
57
|
-
return isStartTight(source.replace(
|
|
62
|
+
const isStartLoose = reduce((source: string, context: MarkdownParser.Context, except?: string): boolean => {
|
|
63
|
+
return isStartTight(source.replace(regBlankInlineStart, ''), context, except);
|
|
58
64
|
}, (source, _, except = '') => `${source}\x1E${except}`);
|
|
65
|
+
|
|
59
66
|
export function startTight<P extends Parser<unknown>>(parser: P, except?: string): P;
|
|
60
67
|
export function startTight<T>(parser: Parser<T>, except?: string): Parser<T> {
|
|
61
68
|
return (source, context) =>
|
|
@@ -130,10 +137,16 @@ function isVisible(node: HTMLElement | string, strpos?: number): boolean {
|
|
|
130
137
|
}
|
|
131
138
|
}
|
|
132
139
|
|
|
133
|
-
export function
|
|
134
|
-
export function
|
|
140
|
+
export function trimBlankInline<P extends Parser<HTMLElement | string>>(parser: P): P;
|
|
141
|
+
export function trimBlankInline<T extends HTMLElement | string>(parser: Parser<T>): Parser<T> {
|
|
142
|
+
return fmap(
|
|
143
|
+
trimBlankInlineStart(parser),
|
|
144
|
+
trimNodeEnd);
|
|
145
|
+
}
|
|
146
|
+
function trimBlankInlineStart<P extends Parser<unknown>>(parser: P): P;
|
|
147
|
+
function trimBlankInlineStart<T>(parser: Parser<T>): Parser<T> {
|
|
135
148
|
return convert(
|
|
136
|
-
reduce(source => source.replace(
|
|
149
|
+
reduce(source => source.replace(regBlankInlineStart, '')),
|
|
137
150
|
parser);
|
|
138
151
|
}
|
|
139
152
|
//export function trimNode(nodes: (HTMLElement | string)[]): (HTMLElement | string)[] {
|
|
@@ -153,7 +166,7 @@ export function trimSpaceStart<T>(parser: Parser<T>): Parser<T> {
|
|
|
153
166
|
// }
|
|
154
167
|
// return nodes;
|
|
155
168
|
//}
|
|
156
|
-
export function trimNodeEnd
|
|
169
|
+
export function trimNodeEnd<T extends HTMLElement | string>(nodes: T[]): T[] {
|
|
157
170
|
const skip = nodes.length > 0 &&
|
|
158
171
|
typeof nodes[nodes.length - 1] === 'object' &&
|
|
159
172
|
nodes[nodes.length - 1]['className'] === 'indexer'
|
|
@@ -163,7 +176,7 @@ export function trimNodeEnd(nodes: (HTMLElement | string)[]): (HTMLElement | str
|
|
|
163
176
|
if (typeof node === 'string') {
|
|
164
177
|
const pos = node.trimEnd().length;
|
|
165
178
|
if (pos > 0) {
|
|
166
|
-
nodes[nodes.length - 1] = node.slice(0, pos);
|
|
179
|
+
nodes[nodes.length - 1] = node.slice(0, pos) as T;
|
|
167
180
|
break;
|
|
168
181
|
}
|
|
169
182
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Object } from 'spica/global';
|
|
2
2
|
import { Collection } from 'spica/collection';
|
|
3
3
|
import { define } from 'typed-dom/dom';
|
|
4
4
|
|
|
5
5
|
export function image(source: HTMLImageElement, url: URL, cache?: Collection<string, HTMLElement>): HTMLImageElement {
|
|
6
6
|
if (cache?.has(url.href)) return define(
|
|
7
7
|
cache.get(url.href)!.cloneNode(true) as HTMLImageElement,
|
|
8
|
-
|
|
8
|
+
Object.fromEntries([...source.attributes]
|
|
9
9
|
.map(attr => [attr.name, attr.value])));
|
|
10
10
|
define(source, {
|
|
11
11
|
'data-type': 'image',
|
|
@@ -14,7 +14,7 @@ export function image(source: HTMLImageElement, url: URL, cache?: Collection<str
|
|
|
14
14
|
});
|
|
15
15
|
cache?.set(url.href, define(
|
|
16
16
|
source.cloneNode(true),
|
|
17
|
-
|
|
17
|
+
Object.fromEntries([...source.attributes]
|
|
18
18
|
.filter(attr => !['class', 'data-type', 'data-src', 'src', 'loading'].includes(attr.name))
|
|
19
19
|
.map(attr => [attr.name, null]))));
|
|
20
20
|
return source;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Object } from 'spica/global';
|
|
2
2
|
import { html } from 'typed-dom/dom';
|
|
3
3
|
|
|
4
4
|
const extensions = [
|
|
@@ -11,7 +11,7 @@ export function video(source: HTMLImageElement, url: URL): HTMLVideoElement | un
|
|
|
11
11
|
return html('video', {
|
|
12
12
|
src: source.getAttribute('data-src'),
|
|
13
13
|
'data-type': 'video',
|
|
14
|
-
...
|
|
14
|
+
...Object.fromEntries([...source.attributes]
|
|
15
15
|
.map(attr => [attr.name, attr.value])),
|
|
16
16
|
muted: '',
|
|
17
17
|
controls: '',
|