@diplodoc/transform 4.34.0 → 4.35.0-beta1
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/dist/css/_yfm-only.css.map +2 -2
- package/dist/css/_yfm-only.min.css.map +2 -2
- package/dist/css/base.css.map +2 -2
- package/dist/css/base.min.css.map +2 -2
- package/dist/css/print.css.map +2 -2
- package/dist/css/yfm.css.map +2 -2
- package/dist/css/yfm.min.css.map +2 -2
- package/dist/js/base.js +2 -2
- package/dist/js/base.js.map +1 -1
- package/dist/js/base.min.js +1 -1
- package/dist/js/base.min.js.map +2 -2
- package/dist/js/yfm.js +5 -5
- package/dist/js/yfm.js.map +1 -1
- package/dist/js/yfm.min.js +1 -1
- package/dist/js/yfm.min.js.map +2 -2
- package/lib/md.d.ts +2 -2
- package/lib/md.js +2 -2
- package/lib/plugins/csp.d.ts +6 -0
- package/lib/plugins/csp.js +26 -0
- package/lib/plugins/csp.js.map +1 -0
- package/lib/plugins/utils.d.ts +1 -0
- package/lib/plugins/utils.js +10 -1
- package/lib/plugins/utils.js.map +1 -1
- package/lib/plugins/video/const.d.ts +8 -1
- package/lib/plugins/video/const.js +4 -0
- package/lib/plugins/video/const.js.map +1 -1
- package/lib/plugins/video/index.js +10 -3
- package/lib/plugins/video/index.js.map +1 -1
- package/lib/plugins/video/parsers.d.ts +3 -1
- package/lib/plugins/video/parsers.js +59 -28
- package/lib/plugins/video/parsers.js.map +1 -1
- package/lib/plugins/video/types.d.ts +6 -27
- package/lib/plugins/video/utils.js +4 -0
- package/lib/plugins/video/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/transform/index.ts +2 -2
- package/src/transform/md.ts +2 -2
- package/src/transform/plugins/changelog/collect.ts +2 -2
- package/src/transform/plugins/utils.ts +16 -0
- package/src/transform/plugins/video/const.ts +11 -0
- package/src/transform/plugins/video/index.ts +13 -3
- package/src/transform/plugins/video/parsers.ts +63 -28
- package/src/transform/plugins/video/types.ts +8 -7
- package/src/transform/plugins/video/utils.ts +4 -0
|
@@ -20,6 +20,10 @@ const videoUrl = (service, videoID, options) => {
|
|
|
20
20
|
return `https://runtime.video.cloud.yandex.net/player/video/${videoID}`;
|
|
21
21
|
case 'vk':
|
|
22
22
|
return `https://vk.com/video_ext.php?${videoID}`;
|
|
23
|
+
case 'rutube':
|
|
24
|
+
return `https://rutube.ru/play/embed/${videoID}`;
|
|
25
|
+
case 'dzen':
|
|
26
|
+
return `https://dzen.ru/video/watch/${videoID}`;
|
|
23
27
|
default:
|
|
24
28
|
return service;
|
|
25
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/transform/plugins/video/utils.ts"],"names":[],"mappings":";;;AAEO,MAAM,QAAQ,GAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAC9D,QAAQ,OAAO,EAAE;QACb,KAAK,SAAS;YACV,OAAO,iCAAiC,OAAO,EAAE,CAAC;QACtD,KAAK,OAAO;YACR,OAAO,kCAAkC,OAAO,EAAE,CAAC;QACvD,KAAK,MAAM;YACP,OAAO,qBAAqB,OAAO,UAAU,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACtE,KAAK,OAAO;YACR,OAAO,CACH,2BAA2B,OAAO,EAAE;gBACpC,8EAA8E;gBAC9E,+GAA+G;gBAC/G,0DAA0D,CAC7D,CAAC;QACN,KAAK,KAAK;YACN,OAAO,gDAAgD,OAAO,mBAAmB,CAAC;QACtF,KAAK,QAAQ;YACT,OAAO,uDAAuD,OAAO,EAAE,CAAC;QAC5E,KAAK,IAAI;YACL,OAAO,gCAAgC,OAAO,EAAE,CAAC;QACrD;YACI,OAAO,OAAO,CAAC;KACtB;AACL,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/transform/plugins/video/utils.ts"],"names":[],"mappings":";;;AAEO,MAAM,QAAQ,GAAe,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAC9D,QAAQ,OAAO,EAAE;QACb,KAAK,SAAS;YACV,OAAO,iCAAiC,OAAO,EAAE,CAAC;QACtD,KAAK,OAAO;YACR,OAAO,kCAAkC,OAAO,EAAE,CAAC;QACvD,KAAK,MAAM;YACP,OAAO,qBAAqB,OAAO,UAAU,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACtE,KAAK,OAAO;YACR,OAAO,CACH,2BAA2B,OAAO,EAAE;gBACpC,8EAA8E;gBAC9E,+GAA+G;gBAC/G,0DAA0D,CAC7D,CAAC;QACN,KAAK,KAAK;YACN,OAAO,gDAAgD,OAAO,mBAAmB,CAAC;QACtF,KAAK,QAAQ;YACT,OAAO,uDAAuD,OAAO,EAAE,CAAC;QAC5E,KAAK,IAAI;YACL,OAAO,gCAAgC,OAAO,EAAE,CAAC;QACrD,KAAK,QAAQ;YACT,OAAO,gCAAgC,OAAO,EAAE,CAAC;QACrD,KAAK,MAAM;YACP,OAAO,+BAA+B,OAAO,EAAE,CAAC;QACpD;YACI,OAAO,OAAO,CAAC;KACtB;AACL,CAAC,CAAC;AA5BW,QAAA,QAAQ,YA4BnB"}
|
package/package.json
CHANGED
package/src/transform/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {bold} from 'chalk';
|
|
|
4
4
|
|
|
5
5
|
import {log} from './log';
|
|
6
6
|
import liquidSnippet from './liquid';
|
|
7
|
-
import
|
|
7
|
+
import initMarkdownIt from './md';
|
|
8
8
|
|
|
9
9
|
function applyLiquid(input: string, options: OptionsType) {
|
|
10
10
|
const {
|
|
@@ -36,7 +36,7 @@ function emitResult(html: string, env: EnvType): OutputType {
|
|
|
36
36
|
// eslint-disable-next-line consistent-return
|
|
37
37
|
function transform(originInput: string, options: OptionsType = {}) {
|
|
38
38
|
const input = applyLiquid(originInput, options);
|
|
39
|
-
const {parse, compile, env} =
|
|
39
|
+
const {parse, compile, env} = initMarkdownIt(options);
|
|
40
40
|
|
|
41
41
|
try {
|
|
42
42
|
return emitResult(compile(parse(input)), env);
|
package/src/transform/md.ts
CHANGED
|
@@ -12,7 +12,7 @@ import extractTitle from './title';
|
|
|
12
12
|
import getHeadings from './headings';
|
|
13
13
|
import sanitizeHtml from './sanitize';
|
|
14
14
|
|
|
15
|
-
function
|
|
15
|
+
function initMarkdownIt(options: OptionsType) {
|
|
16
16
|
const {
|
|
17
17
|
allowHTML = false,
|
|
18
18
|
linkify = false,
|
|
@@ -172,4 +172,4 @@ function initCompiler(md: MarkdownIt, options: OptionsType, env: EnvType) {
|
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
export =
|
|
175
|
+
export = initMarkdownIt;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {bold} from 'chalk';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import initMarkdownIt from '../../md';
|
|
4
4
|
import imsize from '../imsize';
|
|
5
5
|
import {MarkdownItPluginOpts} from '../typings';
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ const BLOCK_START = '{% changelog %}';
|
|
|
12
12
|
const BLOCK_END = '{% endchangelog %}';
|
|
13
13
|
|
|
14
14
|
function parseChangelogs(str: string, path?: string) {
|
|
15
|
-
const {parse, compile, env} =
|
|
15
|
+
const {parse, compile, env} = initMarkdownIt({
|
|
16
16
|
plugins: [changelogPlugin, imsize],
|
|
17
17
|
extractChangelogs: true,
|
|
18
18
|
path,
|
|
@@ -37,3 +37,19 @@ export const сarriage = platform === 'win32' ? '\r\n' : '\n';
|
|
|
37
37
|
export function generateID() {
|
|
38
38
|
return Math.random().toString(36).substr(2, 8);
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
export function append<T extends Record<string, []>, Key extends keyof T>(
|
|
42
|
+
target: T,
|
|
43
|
+
key: Key,
|
|
44
|
+
...values: T[Key]
|
|
45
|
+
) {
|
|
46
|
+
if (!target[key]) {
|
|
47
|
+
target[key] = values;
|
|
48
|
+
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
values.forEach((value) => target[key].push(value));
|
|
53
|
+
|
|
54
|
+
return target;
|
|
55
|
+
}
|
|
@@ -11,8 +11,17 @@ export enum VideoService {
|
|
|
11
11
|
Osf = 'osf',
|
|
12
12
|
Yandex = 'yandex',
|
|
13
13
|
Vk = 'vk',
|
|
14
|
+
Rutube = 'rutube',
|
|
15
|
+
Dzen = 'dzen',
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
export type Service = {
|
|
19
|
+
csp?: Record<string, string[]>;
|
|
20
|
+
extract(url: string): string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type Services = [VideoService, Service][];
|
|
24
|
+
|
|
16
25
|
export const defaults: VideoFullOptions = {
|
|
17
26
|
url: videoUrl,
|
|
18
27
|
youtube: {width: 640, height: 390},
|
|
@@ -22,4 +31,6 @@ export const defaults: VideoFullOptions = {
|
|
|
22
31
|
osf: {width: '100%', height: '100%'},
|
|
23
32
|
yandex: {width: 640, height: 390},
|
|
24
33
|
vk: {width: 640, height: 390},
|
|
34
|
+
dzen: {width: 640, height: 390},
|
|
35
|
+
rutube: {width: 640, height: 390},
|
|
25
36
|
};
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
// Process @[osf](guid)
|
|
6
6
|
// Process @[yandex](videoID)
|
|
7
7
|
// Process @[vk](videoID)
|
|
8
|
+
// Process @[dzen](videoID)
|
|
9
|
+
// Process @[rutube](videoID)
|
|
8
10
|
|
|
9
11
|
import type MarkdownIt from 'markdown-it';
|
|
10
12
|
// eslint-disable-next-line no-duplicate-imports
|
|
@@ -13,6 +15,8 @@ import type ParserInline from 'markdown-it/lib/parser_inline';
|
|
|
13
15
|
import type Renderer from 'markdown-it/lib/renderer';
|
|
14
16
|
import type {VideoFullOptions, VideoPluginOptions, VideoToken} from './types';
|
|
15
17
|
|
|
18
|
+
import {append} from '../utils';
|
|
19
|
+
|
|
16
20
|
import {parseVideoUrl} from './parsers';
|
|
17
21
|
import {VideoService, defaults} from './const';
|
|
18
22
|
|
|
@@ -80,7 +84,7 @@ function tokenizeVideo(md: MarkdownIt, options: VideoFullOptions): Renderer.Rend
|
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
const EMBED_REGEX = /@\[([a-zA-Z].+)]\([\s]*(.*?)[\s]*[)]/im;
|
|
83
|
-
|
|
87
|
+
|
|
84
88
|
function videoEmbed(md: MarkdownIt, _options: VideoFullOptions): ParserInline.RuleInline {
|
|
85
89
|
return (state, silent) => {
|
|
86
90
|
const theState = state;
|
|
@@ -100,12 +104,14 @@ function videoEmbed(md: MarkdownIt, _options: VideoFullOptions): ParserInline.Ru
|
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
const service = match[1];
|
|
103
|
-
const
|
|
107
|
+
const parsed = parseVideoUrl(service, match[2]);
|
|
104
108
|
|
|
105
|
-
if (
|
|
109
|
+
if (parsed === false) {
|
|
106
110
|
return false;
|
|
107
111
|
}
|
|
108
112
|
|
|
113
|
+
const [videoID, csp] = parsed;
|
|
114
|
+
|
|
109
115
|
const serviceStart = oldPos + 2;
|
|
110
116
|
const serviceEnd = md.helpers.parseLinkLabel(state, oldPos + 1, false);
|
|
111
117
|
|
|
@@ -127,6 +133,10 @@ function videoEmbed(md: MarkdownIt, _options: VideoFullOptions): ParserInline.Ru
|
|
|
127
133
|
}
|
|
128
134
|
|
|
129
135
|
theState.pos += theState.src.indexOf(')', theState.pos);
|
|
136
|
+
|
|
137
|
+
state.env.meta ??= {};
|
|
138
|
+
append(state.env.meta, 'csp', csp);
|
|
139
|
+
|
|
130
140
|
return true;
|
|
131
141
|
};
|
|
132
142
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {Services} from './const';
|
|
2
2
|
|
|
3
3
|
const ytRegex = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
|
|
4
4
|
export function youtubeParser(url: string) {
|
|
@@ -39,45 +39,80 @@ export function yandexParser(url: string) {
|
|
|
39
39
|
return match ? match[1] : url;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
const vkRegex = /^https:\/\/vk
|
|
42
|
+
const vkRegex = /^https:\/\/vk\.com\/video_ext\.php\?(oid=[-\d]+&id=[-\d]+)/;
|
|
43
43
|
export function vkParser(url: string) {
|
|
44
44
|
const match = url.match(vkRegex);
|
|
45
45
|
return match ? match[1] : url;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
const rutubeRegex = /^https:\/\/rutube\.ru\/video\/([a-zA-Z0-9]+)\/?/;
|
|
49
|
+
export function rutubeParser(url: string) {
|
|
50
|
+
const match = url.match(rutubeRegex);
|
|
51
|
+
return match ? match[1] : url;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const dzenRegex = /^https:\/\/dzen\.ru\/video\/watch\/([a-zA-Z0-9]+)/;
|
|
55
|
+
export function dzenParser(url: string) {
|
|
56
|
+
const match = url.match(dzenRegex);
|
|
57
|
+
return match ? match[1] : url;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const supportedServices = Object.entries({
|
|
61
|
+
osf: {
|
|
62
|
+
extract: mfrParser,
|
|
63
|
+
},
|
|
64
|
+
prezi: {
|
|
65
|
+
extract: preziParser,
|
|
66
|
+
},
|
|
67
|
+
vimeo: {
|
|
68
|
+
extract: vimeoParser,
|
|
69
|
+
},
|
|
70
|
+
vine: {
|
|
71
|
+
extract: vineParser,
|
|
72
|
+
},
|
|
73
|
+
yandex: {
|
|
74
|
+
extract: yandexParser,
|
|
75
|
+
},
|
|
76
|
+
youtube: {
|
|
77
|
+
extract: youtubeParser,
|
|
78
|
+
},
|
|
79
|
+
vk: {
|
|
80
|
+
extract: vkParser,
|
|
81
|
+
csp: {
|
|
82
|
+
'frame-src': 'https://vk.com/',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
rutube: {
|
|
86
|
+
extract: rutubeParser,
|
|
87
|
+
csp: {
|
|
88
|
+
'frame-src': 'https://rutube.ru/play/embed/',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
dzen: {
|
|
92
|
+
extract: dzenParser,
|
|
93
|
+
csp: {
|
|
94
|
+
'frame-src': 'https://dzen.ru/embed/',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
}) as Services;
|
|
98
|
+
|
|
99
|
+
export function parseVideoUrl(service: string, url: string) {
|
|
49
100
|
let videoID = '';
|
|
101
|
+
const normalizedService = service.toLowerCase();
|
|
102
|
+
const parsed = supportedServices.find(([name]) => name === normalizedService);
|
|
50
103
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
videoID = youtubeParser(url);
|
|
54
|
-
break;
|
|
55
|
-
case VideoService.Vimeo:
|
|
56
|
-
videoID = vimeoParser(url);
|
|
57
|
-
break;
|
|
58
|
-
case VideoService.Vine:
|
|
59
|
-
videoID = vineParser(url);
|
|
60
|
-
break;
|
|
61
|
-
case VideoService.Prezi:
|
|
62
|
-
videoID = preziParser(url);
|
|
63
|
-
break;
|
|
64
|
-
case VideoService.Osf:
|
|
65
|
-
videoID = mfrParser(url);
|
|
66
|
-
break;
|
|
67
|
-
case VideoService.Yandex:
|
|
68
|
-
videoID = yandexParser(url);
|
|
69
|
-
break;
|
|
70
|
-
case VideoService.Vk:
|
|
71
|
-
videoID = vkParser(url);
|
|
72
|
-
break;
|
|
73
|
-
default:
|
|
74
|
-
return false;
|
|
104
|
+
if (!parsed) {
|
|
105
|
+
return false;
|
|
75
106
|
}
|
|
76
107
|
|
|
108
|
+
const [, videoParser] = parsed;
|
|
109
|
+
|
|
110
|
+
videoID = videoParser.extract(url);
|
|
111
|
+
|
|
77
112
|
// If the videoID field is empty, regex currently make it the close parenthesis.
|
|
78
113
|
if (videoID === ')') {
|
|
79
114
|
videoID = '';
|
|
80
115
|
}
|
|
81
116
|
|
|
82
|
-
return videoID;
|
|
117
|
+
return [videoID, videoParser.csp] as const;
|
|
83
118
|
}
|
|
@@ -7,13 +7,14 @@ export type VideoToken = Token & {
|
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
export type VideoServicesOptions = {
|
|
10
|
-
[VideoService
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
[service in VideoService]: {
|
|
11
|
+
width: number | string;
|
|
12
|
+
height: number | string;
|
|
13
|
+
};
|
|
14
|
+
} & {
|
|
15
|
+
vine: {
|
|
16
|
+
embed: 'simple' | (string & {});
|
|
17
|
+
};
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
export type VideoFullOptions = VideoServicesOptions & {
|
|
@@ -21,6 +21,10 @@ export const videoUrl: VideoUrlFn = (service, videoID, options) => {
|
|
|
21
21
|
return `https://runtime.video.cloud.yandex.net/player/video/${videoID}`;
|
|
22
22
|
case 'vk':
|
|
23
23
|
return `https://vk.com/video_ext.php?${videoID}`;
|
|
24
|
+
case 'rutube':
|
|
25
|
+
return `https://rutube.ru/play/embed/${videoID}`;
|
|
26
|
+
case 'dzen':
|
|
27
|
+
return `https://dzen.ru/video/watch/${videoID}`;
|
|
24
28
|
default:
|
|
25
29
|
return service;
|
|
26
30
|
}
|