vuepress-plugin-md-power 1.0.0-rc.79 → 1.0.0-rc.81
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/lib/client/components/CodeSandbox.vue +1 -1
- package/lib/client/components/PDFViewer.vue +1 -1
- package/lib/client/components/Plot.vue +1 -1
- package/lib/client/components/Replit.vue +1 -1
- package/lib/client/composables/codeRepl.d.ts +7 -5
- package/lib/client/composables/codeRepl.js +253 -145
- package/lib/client/composables/pdf.d.ts +7 -3
- package/lib/client/composables/pdf.js +55 -81
- package/lib/client/composables/rustRepl.d.ts +3 -2
- package/lib/client/composables/rustRepl.js +96 -94
- package/lib/client/composables/size.d.ts +9 -5
- package/lib/client/composables/size.js +36 -44
- package/lib/client/index.js +2 -1
- package/lib/client/options.d.ts +5 -2
- package/lib/client/options.js +5 -1
- package/lib/client/utils/http.d.ts +3 -1
- package/lib/client/utils/http.js +24 -20
- package/lib/client/utils/is.d.ts +5 -3
- package/lib/client/utils/is.js +16 -10
- package/lib/client/utils/link.d.ts +3 -1
- package/lib/client/utils/link.js +8 -4
- package/lib/client/utils/sleep.d.ts +3 -1
- package/lib/client/utils/sleep.js +8 -4
- package/lib/node/index.d.ts +188 -2
- package/lib/node/index.js +833 -2
- package/lib/shared/index.d.ts +185 -10
- package/lib/shared/index.js +0 -10
- package/package.json +5 -5
- package/lib/node/features/caniuse.d.ts +0 -25
- package/lib/node/features/caniuse.js +0 -87
- package/lib/node/features/codeSandbox.d.ts +0 -7
- package/lib/node/features/codeSandbox.js +0 -29
- package/lib/node/features/codepen.d.ts +0 -7
- package/lib/node/features/codepen.js +0 -42
- package/lib/node/features/icons/index.d.ts +0 -2
- package/lib/node/features/icons/index.js +0 -2
- package/lib/node/features/icons/plugin.d.ts +0 -10
- package/lib/node/features/icons/plugin.js +0 -61
- package/lib/node/features/icons/writer.d.ts +0 -11
- package/lib/node/features/icons/writer.js +0 -126
- package/lib/node/features/jsfiddle.d.ts +0 -6
- package/lib/node/features/jsfiddle.js +0 -28
- package/lib/node/features/langRepl.d.ts +0 -4
- package/lib/node/features/langRepl.js +0 -59
- package/lib/node/features/pdf.d.ts +0 -2
- package/lib/node/features/pdf.js +0 -31
- package/lib/node/features/plot.d.ts +0 -5
- package/lib/node/features/plot.js +0 -48
- package/lib/node/features/replit.d.ts +0 -7
- package/lib/node/features/replit.js +0 -22
- package/lib/node/features/video/bilibili.d.ts +0 -2
- package/lib/node/features/video/bilibili.js +0 -58
- package/lib/node/features/video/youtube.d.ts +0 -2
- package/lib/node/features/video/youtube.js +0 -47
- package/lib/node/plugin.d.ts +0 -3
- package/lib/node/plugin.js +0 -80
- package/lib/node/prepareConfigFile.d.ts +0 -3
- package/lib/node/prepareConfigFile.js +0 -59
- package/lib/node/utils/createRuleBlock.d.ts +0 -18
- package/lib/node/utils/createRuleBlock.js +0 -34
- package/lib/node/utils/package.d.ts +0 -4
- package/lib/node/utils/package.js +0 -4
- package/lib/node/utils/parseRect.d.ts +0 -1
- package/lib/node/utils/parseRect.js +0 -5
- package/lib/node/utils/resolveAttrs.d.ts +0 -4
- package/lib/node/utils/resolveAttrs.js +0 -29
- package/lib/node/utils/timeToSeconds.d.ts +0 -1
- package/lib/node/utils/timeToSeconds.js +0 -8
- package/lib/shared/caniuse.d.ts +0 -18
- package/lib/shared/caniuse.js +0 -1
- package/lib/shared/codeSandbox.d.ts +0 -11
- package/lib/shared/codeSandbox.js +0 -1
- package/lib/shared/codepen.d.ts +0 -10
- package/lib/shared/codepen.js +0 -1
- package/lib/shared/icons.d.ts +0 -17
- package/lib/shared/icons.js +0 -1
- package/lib/shared/jsfiddle.d.ts +0 -8
- package/lib/shared/jsfiddle.js +0 -1
- package/lib/shared/pdf.d.ts +0 -15
- package/lib/shared/pdf.js +0 -1
- package/lib/shared/plot.d.ts +0 -27
- package/lib/shared/plot.js +0 -1
- package/lib/shared/plugin.d.ts +0 -21
- package/lib/shared/plugin.js +0 -1
- package/lib/shared/repl.d.ts +0 -22
- package/lib/shared/repl.js +0 -1
- package/lib/shared/replit.d.ts +0 -6
- package/lib/shared/replit.js +0 -1
- package/lib/shared/size.d.ts +0 -5
- package/lib/shared/size.js +0 -1
- package/lib/shared/video.d.ts +0 -22
- package/lib/shared/video.js +0 -1
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { resolveAttrs } from '../utils/resolveAttrs.js';
|
|
2
|
-
import { parseRect } from '../utils/parseRect.js';
|
|
3
|
-
import { createRuleBlock } from '../utils/createRuleBlock.js';
|
|
4
|
-
export const jsfiddlePlugin = (md) => {
|
|
5
|
-
createRuleBlock(md, {
|
|
6
|
-
type: 'jsfiddle',
|
|
7
|
-
syntaxPattern: /^@\[jsfiddle(?:\s+([^]*?))?\]\(([^)]*?)\)/,
|
|
8
|
-
meta([, info = '', source]) {
|
|
9
|
-
const { attrs } = resolveAttrs(info);
|
|
10
|
-
const [user, id] = source.split('/');
|
|
11
|
-
return {
|
|
12
|
-
width: attrs.width ? parseRect(attrs.width) : '100%',
|
|
13
|
-
height: attrs.height ? parseRect(attrs.height) : '400px',
|
|
14
|
-
user,
|
|
15
|
-
id,
|
|
16
|
-
title: attrs.title || 'JS Fiddle',
|
|
17
|
-
tab: attrs.tab?.replace(/\s+/g, '') || 'js,css,html,result',
|
|
18
|
-
theme: attrs.theme || 'dark',
|
|
19
|
-
};
|
|
20
|
-
},
|
|
21
|
-
content: ({ title = 'JS Fiddle', height, width, user, id, tab, theme }) => {
|
|
22
|
-
theme = theme === 'dark' ? '/dark/' : '';
|
|
23
|
-
const link = `https://jsfiddle.net/${user}/${id}/embedded/${tab}${theme}`;
|
|
24
|
-
const style = `width:${width};height:${height};margin:16px auto;border:none;border-radius:5px;`;
|
|
25
|
-
return `<iframe class="js-fiddle-iframe-wrapper" style="${style}" title="${title}" src="${link}" allowfullscreen="true" allowpaymentrequest="true"></iframe>`;
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
};
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import container from 'markdown-it-container';
|
|
2
|
-
import { fs, getDirname, path } from 'vuepress/utils';
|
|
3
|
-
const RE_INFO = /^(#editable)?\s*?(.*)$/;
|
|
4
|
-
function createReplContainer(md, lang) {
|
|
5
|
-
const type = `${lang}-repl`;
|
|
6
|
-
const validate = (info) => info.trim().startsWith(type);
|
|
7
|
-
const render = (tokens, index) => {
|
|
8
|
-
const token = tokens[index];
|
|
9
|
-
const info = token.info.trim().slice(type.length).trim() || '';
|
|
10
|
-
// :::lang-repl#editable title
|
|
11
|
-
const [, editable, title] = info.match(RE_INFO) ?? [];
|
|
12
|
-
if (token.nesting === 1)
|
|
13
|
-
return `<CodeRepl ${editable ? 'editable' : ''} title="${title || `${lang} playground`}">`;
|
|
14
|
-
else
|
|
15
|
-
return '</CodeRepl>';
|
|
16
|
-
};
|
|
17
|
-
md.use(container, type, { validate, render });
|
|
18
|
-
}
|
|
19
|
-
export async function langReplPlugin(app, md, { theme, go = false, kotlin = false, rust = false, }) {
|
|
20
|
-
if (kotlin) {
|
|
21
|
-
createReplContainer(md, 'kotlin');
|
|
22
|
-
}
|
|
23
|
-
if (go) {
|
|
24
|
-
createReplContainer(md, 'go');
|
|
25
|
-
}
|
|
26
|
-
if (rust) {
|
|
27
|
-
createReplContainer(md, 'rust');
|
|
28
|
-
}
|
|
29
|
-
theme ??= { light: 'github-light', dark: 'github-dark' };
|
|
30
|
-
const data = { grammars: {} };
|
|
31
|
-
const themesPath = getDirname(import.meta.resolve('tm-themes'));
|
|
32
|
-
const grammarsPath = getDirname(import.meta.resolve('tm-grammars'));
|
|
33
|
-
const readTheme = (theme) => read(path.join(themesPath, 'themes', `${theme}.json`));
|
|
34
|
-
const readGrammar = (grammar) => read(path.join(grammarsPath, 'grammars', `${grammar}.json`));
|
|
35
|
-
if (typeof theme === 'string') {
|
|
36
|
-
data.theme = await readTheme(theme);
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
data.theme = await Promise.all([
|
|
40
|
-
readTheme(theme.light),
|
|
41
|
-
readTheme(theme.dark),
|
|
42
|
-
]).then(([light, dark]) => ({ light, dark }));
|
|
43
|
-
}
|
|
44
|
-
if (kotlin)
|
|
45
|
-
data.grammars.kotlin = await readGrammar('kotlin');
|
|
46
|
-
if (go)
|
|
47
|
-
data.grammars.go = await readGrammar('go');
|
|
48
|
-
if (rust)
|
|
49
|
-
data.grammars.rust = await readGrammar('rust');
|
|
50
|
-
await app.writeTemp('internal/md-power/replEditorData.js', `export default ${JSON.stringify(data, null, 2)}`);
|
|
51
|
-
}
|
|
52
|
-
async function read(file) {
|
|
53
|
-
try {
|
|
54
|
-
const content = await fs.readFile(file, 'utf-8');
|
|
55
|
-
return JSON.parse(content);
|
|
56
|
-
}
|
|
57
|
-
catch { }
|
|
58
|
-
return undefined;
|
|
59
|
-
}
|
package/lib/node/features/pdf.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @[pdf](/xxx)
|
|
3
|
-
* @[pdf 1](/xxx)
|
|
4
|
-
* @[pdf 1 no-toolbar width="100%" height="600px" zoom="1" ratio="1:1"](/xxx)
|
|
5
|
-
*/
|
|
6
|
-
import { path } from 'vuepress/utils';
|
|
7
|
-
import { resolveAttrs } from '../utils/resolveAttrs.js';
|
|
8
|
-
import { parseRect } from '../utils/parseRect.js';
|
|
9
|
-
import { createRuleBlock } from '../utils/createRuleBlock.js';
|
|
10
|
-
export const pdfPlugin = (md) => {
|
|
11
|
-
createRuleBlock(md, {
|
|
12
|
-
type: 'pdf',
|
|
13
|
-
syntaxPattern: /^@\[pdf(?:\s+(\d+))?(?:\s+([^]*?))?\]\(([^)]*?)\)/,
|
|
14
|
-
meta([, page, info = '', src = '']) {
|
|
15
|
-
const { attrs } = resolveAttrs(info);
|
|
16
|
-
return {
|
|
17
|
-
src,
|
|
18
|
-
page: +page || 1,
|
|
19
|
-
noToolbar: Boolean(attrs.noToolbar ?? false),
|
|
20
|
-
zoom: +attrs.zoom || 50,
|
|
21
|
-
width: attrs.width ? parseRect(attrs.width) : '100%',
|
|
22
|
-
height: attrs.height ? parseRect(attrs.height) : '',
|
|
23
|
-
ratio: attrs.ratio ? parseRect(attrs.ratio) : '',
|
|
24
|
-
title: path.basename(src || ''),
|
|
25
|
-
};
|
|
26
|
-
},
|
|
27
|
-
content({ title, src, page, noToolbar, width, height, ratio, zoom }) {
|
|
28
|
-
return `<PDFViewer src="${src}" title="${title}" :page="${page}" :no-toolbar="${noToolbar}" width="${width}" height="${height}" ratio="${ratio}" :zoom="${zoom}" />`;
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const [openTag, endTag] = ['!!', '!!'];
|
|
2
|
-
function createTokenizer() {
|
|
3
|
-
return (state, silent) => {
|
|
4
|
-
let found = false;
|
|
5
|
-
const max = state.posMax;
|
|
6
|
-
const start = state.pos;
|
|
7
|
-
if (state.src.slice(start, start + 2) !== openTag)
|
|
8
|
-
return false;
|
|
9
|
-
if (silent)
|
|
10
|
-
return false;
|
|
11
|
-
// - !!!!
|
|
12
|
-
if (max - start < 5)
|
|
13
|
-
return false;
|
|
14
|
-
state.pos = start + 2;
|
|
15
|
-
while (state.pos < max) {
|
|
16
|
-
if (state.src.slice(state.pos - 1, state.pos + 1) === endTag) {
|
|
17
|
-
found = true;
|
|
18
|
-
break;
|
|
19
|
-
}
|
|
20
|
-
state.md.inline.skipToken(state);
|
|
21
|
-
}
|
|
22
|
-
if (!found || start + 2 === state.pos) {
|
|
23
|
-
state.pos = start;
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
const content = state.src.slice(start + 2, state.pos - 1);
|
|
27
|
-
// 不允许前后带有空格
|
|
28
|
-
if (/^\s|\s$/.test(content)) {
|
|
29
|
-
state.pos = start;
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
// found!
|
|
33
|
-
state.posMax = state.pos - 1;
|
|
34
|
-
state.pos = start + 2;
|
|
35
|
-
const open = state.push('plot_open', 'Plot', 1);
|
|
36
|
-
open.markup = openTag;
|
|
37
|
-
const text = state.push('text', '', 0);
|
|
38
|
-
text.content = content;
|
|
39
|
-
const close = state.push('plot_close', 'Plot', -1);
|
|
40
|
-
close.markup = endTag;
|
|
41
|
-
state.pos = state.posMax + 2;
|
|
42
|
-
state.posMax = max;
|
|
43
|
-
return true;
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
export const plotPlugin = (md) => {
|
|
47
|
-
md.inline.ruler.before('emphasis', 'plot', createTokenizer());
|
|
48
|
-
};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @[replit](user/repl-name)
|
|
3
|
-
* @[replit](user/repl-name#filepath)
|
|
4
|
-
* @[replit title="" height="400px" width="100%" theme="dark"](user/repl-name)
|
|
5
|
-
*/
|
|
6
|
-
import type { PluginWithOptions } from 'markdown-it';
|
|
7
|
-
export declare const replitPlugin: PluginWithOptions<never>;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { resolveAttrs } from '../utils/resolveAttrs.js';
|
|
2
|
-
import { parseRect } from '../utils/parseRect.js';
|
|
3
|
-
import { createRuleBlock } from '../utils/createRuleBlock.js';
|
|
4
|
-
export const replitPlugin = (md) => {
|
|
5
|
-
createRuleBlock(md, {
|
|
6
|
-
type: 'replit',
|
|
7
|
-
syntaxPattern: /^@\[replit(?:\s+([^]*?))?\]\(([^)]*?)\)/,
|
|
8
|
-
meta: ([, info = '', source = '']) => {
|
|
9
|
-
const { attrs } = resolveAttrs(info);
|
|
10
|
-
return {
|
|
11
|
-
width: attrs.width ? parseRect(attrs.width) : '100%',
|
|
12
|
-
height: attrs.height ? parseRect(attrs.height) : '450px',
|
|
13
|
-
source: source.startsWith('@') ? source : `@${source}`,
|
|
14
|
-
title: attrs.title,
|
|
15
|
-
theme: attrs.theme || '',
|
|
16
|
-
};
|
|
17
|
-
},
|
|
18
|
-
content({ title, height, width, source, theme }) {
|
|
19
|
-
return `<ReplitViewer title="${title || ''}" height="${height}" width="${width}" source="${source}" theme="${theme}" />`;
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
};
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @[bilibili](bid)
|
|
3
|
-
* @[bilibili](aid cid)
|
|
4
|
-
* @[bilibili](bid aid cid)
|
|
5
|
-
* @[bilibili p1 autoplay time=1](aid cid)
|
|
6
|
-
*/
|
|
7
|
-
import { URLSearchParams } from 'node:url';
|
|
8
|
-
import { resolveAttrs } from '../../utils/resolveAttrs.js';
|
|
9
|
-
import { parseRect } from '../../utils/parseRect.js';
|
|
10
|
-
import { timeToSeconds } from '../../utils/timeToSeconds.js';
|
|
11
|
-
import { createRuleBlock } from '../../utils/createRuleBlock.js';
|
|
12
|
-
const BILIBILI_LINK = 'https://player.bilibili.com/player.html';
|
|
13
|
-
export const bilibiliPlugin = (md) => {
|
|
14
|
-
createRuleBlock(md, {
|
|
15
|
-
type: 'bilibili',
|
|
16
|
-
name: 'video_bilibili',
|
|
17
|
-
syntaxPattern: /^@\[bilibili(?:\s+p(\d+))?(?:\s+([^]*?))?\]\(([^)]*)\)/,
|
|
18
|
-
meta([, page, info = '', source = '']) {
|
|
19
|
-
const { attrs } = resolveAttrs(info);
|
|
20
|
-
const ids = source.trim().split(/\s+/);
|
|
21
|
-
const bvid = ids.find(id => id.startsWith('BV'));
|
|
22
|
-
const [aid, cid] = ids.filter(id => !id.startsWith('BV'));
|
|
23
|
-
return {
|
|
24
|
-
page: +page || 1,
|
|
25
|
-
bvid,
|
|
26
|
-
aid,
|
|
27
|
-
cid,
|
|
28
|
-
autoplay: attrs.autoplay ?? false,
|
|
29
|
-
time: timeToSeconds(attrs.time),
|
|
30
|
-
title: attrs.title,
|
|
31
|
-
width: attrs.width ? parseRect(attrs.width) : '100%',
|
|
32
|
-
height: attrs.height ? parseRect(attrs.height) : '',
|
|
33
|
-
ratio: attrs.ratio ? parseRect(attrs.ratio) : '',
|
|
34
|
-
};
|
|
35
|
-
},
|
|
36
|
-
content(meta) {
|
|
37
|
-
const params = new URLSearchParams();
|
|
38
|
-
if (meta.bvid) {
|
|
39
|
-
params.set('bvid', meta.bvid);
|
|
40
|
-
}
|
|
41
|
-
if (meta.aid) {
|
|
42
|
-
params.set('aid', meta.aid);
|
|
43
|
-
}
|
|
44
|
-
if (meta.cid) {
|
|
45
|
-
params.set('cid', meta.cid);
|
|
46
|
-
}
|
|
47
|
-
if (meta.page) {
|
|
48
|
-
params.set('p', meta.page.toString());
|
|
49
|
-
}
|
|
50
|
-
if (meta.time) {
|
|
51
|
-
params.set('t', meta.time.toString());
|
|
52
|
-
}
|
|
53
|
-
params.set('autoplay', meta.autoplay ? '1' : '0');
|
|
54
|
-
const source = `${BILIBILI_LINK}?${params.toString()}`;
|
|
55
|
-
return `<VideoBilibili src="${source}" width="${meta.width}" height="${meta.height}" ratio="${meta.ratio}" title="${meta.title}" />`;
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @[youtube](id)
|
|
3
|
-
*/
|
|
4
|
-
import { URLSearchParams } from 'node:url';
|
|
5
|
-
import { resolveAttrs } from '../../utils/resolveAttrs.js';
|
|
6
|
-
import { parseRect } from '../../utils/parseRect.js';
|
|
7
|
-
import { timeToSeconds } from '../../utils/timeToSeconds.js';
|
|
8
|
-
import { createRuleBlock } from '../../utils/createRuleBlock.js';
|
|
9
|
-
const YOUTUBE_LINK = 'https://www.youtube.com/embed/';
|
|
10
|
-
export const youtubePlugin = (md) => {
|
|
11
|
-
createRuleBlock(md, {
|
|
12
|
-
type: 'youtube',
|
|
13
|
-
name: 'video_youtube',
|
|
14
|
-
syntaxPattern: /^@\[youtube(?:\s+([^]*?))?\]\(([^)]*)\)/,
|
|
15
|
-
meta([, info = '', id = '']) {
|
|
16
|
-
const { attrs } = resolveAttrs(info);
|
|
17
|
-
return {
|
|
18
|
-
id,
|
|
19
|
-
autoplay: attrs.autoplay ?? false,
|
|
20
|
-
loop: attrs.loop ?? false,
|
|
21
|
-
start: timeToSeconds(attrs.start),
|
|
22
|
-
end: timeToSeconds(attrs.end),
|
|
23
|
-
title: attrs.title,
|
|
24
|
-
width: attrs.width ? parseRect(attrs.width) : '100%',
|
|
25
|
-
height: attrs.height ? parseRect(attrs.height) : '',
|
|
26
|
-
ratio: attrs.ratio ? parseRect(attrs.ratio) : '',
|
|
27
|
-
};
|
|
28
|
-
},
|
|
29
|
-
content(meta) {
|
|
30
|
-
const params = new URLSearchParams();
|
|
31
|
-
if (meta.autoplay) {
|
|
32
|
-
params.set('autoplay', '1');
|
|
33
|
-
}
|
|
34
|
-
if (meta.loop) {
|
|
35
|
-
params.set('loop', '1');
|
|
36
|
-
}
|
|
37
|
-
if (meta.start) {
|
|
38
|
-
params.set('start', meta.start.toString());
|
|
39
|
-
}
|
|
40
|
-
if (meta.end) {
|
|
41
|
-
params.set('end', meta.end.toString());
|
|
42
|
-
}
|
|
43
|
-
const source = `${YOUTUBE_LINK}/${meta.id}?${params.toString()}`;
|
|
44
|
-
return `<VideoYoutube src="${source}" width="${meta.width}" height="${meta.height}" ratio="${meta.ratio}" title="${meta.title}" />`;
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
|
-
};
|
package/lib/node/plugin.d.ts
DELETED
package/lib/node/plugin.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { addViteOptimizeDepsInclude } from '@vuepress/helper';
|
|
2
|
-
import { caniusePlugin, legacyCaniuse } from './features/caniuse.js';
|
|
3
|
-
import { pdfPlugin } from './features/pdf.js';
|
|
4
|
-
import { createIconCSSWriter, iconsPlugin } from './features/icons/index.js';
|
|
5
|
-
import { bilibiliPlugin } from './features/video/bilibili.js';
|
|
6
|
-
import { youtubePlugin } from './features/video/youtube.js';
|
|
7
|
-
import { codepenPlugin } from './features/codepen.js';
|
|
8
|
-
import { replitPlugin } from './features/replit.js';
|
|
9
|
-
import { codeSandboxPlugin } from './features/codeSandbox.js';
|
|
10
|
-
import { jsfiddlePlugin } from './features/jsfiddle.js';
|
|
11
|
-
import { plotPlugin } from './features/plot.js';
|
|
12
|
-
import { langReplPlugin } from './features/langRepl.js';
|
|
13
|
-
import { prepareConfigFile } from './prepareConfigFile.js';
|
|
14
|
-
export function markdownPowerPlugin(options = {}) {
|
|
15
|
-
return (app) => {
|
|
16
|
-
const { initIcon, addIcon } = createIconCSSWriter(app, options.icons);
|
|
17
|
-
return {
|
|
18
|
-
name: 'vuepress-plugin-md-power',
|
|
19
|
-
// clientConfigFile: path.resolve(__dirname, '../client/config.js'),
|
|
20
|
-
clientConfigFile: app => prepareConfigFile(app, options),
|
|
21
|
-
define: {
|
|
22
|
-
__MD_POWER_INJECT_OPTIONS__: options,
|
|
23
|
-
},
|
|
24
|
-
onInitialized: async () => await initIcon(),
|
|
25
|
-
extendsBundlerOptions(bundlerOptions) {
|
|
26
|
-
if (options.repl) {
|
|
27
|
-
addViteOptimizeDepsInclude(bundlerOptions, app, ['shiki/core', 'shiki/wasm']);
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
extendsMarkdown: async (md, app) => {
|
|
31
|
-
if (options.caniuse) {
|
|
32
|
-
const caniuse = options.caniuse === true ? {} : options.caniuse;
|
|
33
|
-
// @[caniuse](feature_name)
|
|
34
|
-
md.use(caniusePlugin, caniuse);
|
|
35
|
-
// 兼容旧语法
|
|
36
|
-
legacyCaniuse(md, caniuse);
|
|
37
|
-
}
|
|
38
|
-
if (options.pdf) {
|
|
39
|
-
// @[pdf](url)
|
|
40
|
-
md.use(pdfPlugin);
|
|
41
|
-
}
|
|
42
|
-
if (options.icons) {
|
|
43
|
-
// :[collect:name]:
|
|
44
|
-
md.use(iconsPlugin, addIcon);
|
|
45
|
-
}
|
|
46
|
-
if (options.bilibili) {
|
|
47
|
-
// @[bilibili](bvid aid cid)
|
|
48
|
-
md.use(bilibiliPlugin);
|
|
49
|
-
}
|
|
50
|
-
if (options.youtube) {
|
|
51
|
-
// @[youtube](id)
|
|
52
|
-
md.use(youtubePlugin);
|
|
53
|
-
}
|
|
54
|
-
if (options.codepen) {
|
|
55
|
-
// @[codepen](user/slash)
|
|
56
|
-
md.use(codepenPlugin);
|
|
57
|
-
}
|
|
58
|
-
if (options.replit) {
|
|
59
|
-
// @[replit](user/repl-name)
|
|
60
|
-
md.use(replitPlugin);
|
|
61
|
-
}
|
|
62
|
-
if (options.codeSandbox) {
|
|
63
|
-
// @[codesandbox](id)
|
|
64
|
-
md.use(codeSandboxPlugin);
|
|
65
|
-
}
|
|
66
|
-
if (options.jsfiddle) {
|
|
67
|
-
// @[jsfiddle](user/id)
|
|
68
|
-
md.use(jsfiddlePlugin);
|
|
69
|
-
}
|
|
70
|
-
if (options.plot === true
|
|
71
|
-
|| (typeof options.plot === 'object' && options.plot.tag !== false)) {
|
|
72
|
-
// =|plot|=
|
|
73
|
-
md.use(plotPlugin);
|
|
74
|
-
}
|
|
75
|
-
if (options.repl)
|
|
76
|
-
await langReplPlugin(app, md, options.repl);
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
};
|
|
80
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { getDirname, path } from 'vuepress/utils';
|
|
2
|
-
import { ensureEndingSlash } from '@vuepress/helper';
|
|
3
|
-
const { url: filepath } = import.meta;
|
|
4
|
-
const __dirname = getDirname(filepath);
|
|
5
|
-
const CLIENT_FOLDER = ensureEndingSlash(path.resolve(__dirname, '../client'));
|
|
6
|
-
export async function prepareConfigFile(app, options) {
|
|
7
|
-
const imports = new Set();
|
|
8
|
-
const enhances = new Set();
|
|
9
|
-
imports.add(`import '@internal/md-power/icons.css'`);
|
|
10
|
-
if (options.pdf) {
|
|
11
|
-
imports.add(`import PDFViewer from '${CLIENT_FOLDER}components/PDFViewer.vue'`);
|
|
12
|
-
enhances.add(`app.component('PDFViewer', PDFViewer)`);
|
|
13
|
-
}
|
|
14
|
-
if (options.bilibili) {
|
|
15
|
-
imports.add(`import Bilibili from '${CLIENT_FOLDER}components/Bilibili.vue'`);
|
|
16
|
-
enhances.add(`app.component('VideoBilibili', Bilibili)`);
|
|
17
|
-
}
|
|
18
|
-
if (options.youtube) {
|
|
19
|
-
imports.add(`import Youtube from '${CLIENT_FOLDER}components/Youtube.vue'`);
|
|
20
|
-
enhances.add(`app.component('VideoYoutube', Youtube)`);
|
|
21
|
-
}
|
|
22
|
-
if (options.replit) {
|
|
23
|
-
imports.add(`import Replit from '${CLIENT_FOLDER}components/Replit.vue'`);
|
|
24
|
-
enhances.add(`app.component('ReplitViewer', Replit)`);
|
|
25
|
-
}
|
|
26
|
-
if (options.codeSandbox) {
|
|
27
|
-
imports.add(`import CodeSandbox from '${CLIENT_FOLDER}components/CodeSandbox.vue'`);
|
|
28
|
-
enhances.add(`app.component('CodeSandboxViewer', CodeSandbox)`);
|
|
29
|
-
}
|
|
30
|
-
if (options.plot) {
|
|
31
|
-
imports.add(`import Plot from '${CLIENT_FOLDER}components/Plot.vue'`);
|
|
32
|
-
enhances.add(`app.component('Plot', Plot)`);
|
|
33
|
-
}
|
|
34
|
-
if (options.repl) {
|
|
35
|
-
imports.add(`import CodeRepl from '${CLIENT_FOLDER}components/CodeRepl.vue'`);
|
|
36
|
-
enhances.add(`app.component('CodeRepl', CodeRepl)`);
|
|
37
|
-
}
|
|
38
|
-
// enhances.add(`if (__VUEPRESS_SSR__) return`)
|
|
39
|
-
if (options.caniuse) {
|
|
40
|
-
imports.add(`import CanIUse from '${CLIENT_FOLDER}components/CanIUse.vue'`);
|
|
41
|
-
enhances.add(`app.component('CanIUseViewer', CanIUse)`);
|
|
42
|
-
}
|
|
43
|
-
// if (options.caniuse) {
|
|
44
|
-
// imports.add(`import { setupCanIUse } from '${CLIENT_FOLDER}composables/setupCanIUse.js'`)
|
|
45
|
-
// enhances.add(`router.afterEach(() => setupCanIUse())`)
|
|
46
|
-
// }
|
|
47
|
-
return app.writeTemp('md-power/config.js', `\
|
|
48
|
-
import { defineClientConfig } from 'vuepress/client'
|
|
49
|
-
${Array.from(imports.values()).join('\n')}
|
|
50
|
-
|
|
51
|
-
export default defineClientConfig({
|
|
52
|
-
enhance({ router, app }) {
|
|
53
|
-
${Array.from(enhances.values())
|
|
54
|
-
.map(item => ` ${item}`)
|
|
55
|
-
.join('\n')}
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
`);
|
|
59
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { RuleOptions } from 'markdown-it/lib/ruler.mjs';
|
|
2
|
-
import type { Markdown } from 'vuepress/markdown';
|
|
3
|
-
export interface RuleBlockOptions<Meta extends Record<string, any>> {
|
|
4
|
-
/**
|
|
5
|
-
* @[type]()
|
|
6
|
-
*/
|
|
7
|
-
type: string;
|
|
8
|
-
/**
|
|
9
|
-
* token name
|
|
10
|
-
*/
|
|
11
|
-
name?: string;
|
|
12
|
-
beforeName?: string;
|
|
13
|
-
syntaxPattern: RegExp;
|
|
14
|
-
ruleOptions?: RuleOptions;
|
|
15
|
-
meta: (match: RegExpMatchArray) => Meta;
|
|
16
|
-
content: (meta: Meta) => string;
|
|
17
|
-
}
|
|
18
|
-
export declare function createRuleBlock<Meta extends Record<string, any> = Record<string, any>>(md: Markdown, { type, name, syntaxPattern, beforeName, ruleOptions, meta, content, }: RuleBlockOptions<Meta>): void;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// @[name]()
|
|
2
|
-
export function createRuleBlock(md, { type, name = type, syntaxPattern, beforeName = 'import_code', ruleOptions = { alt: ['paragraph', 'reference', 'blockquote', 'list'] }, meta, content, }) {
|
|
3
|
-
const MIN_LENGTH = type.length + 5;
|
|
4
|
-
const START_CODES = [64, 91, ...type.split('').map(c => c.charCodeAt(0))];
|
|
5
|
-
md.block.ruler.before(beforeName, name, (state, startLine, endLine, silent) => {
|
|
6
|
-
const pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
7
|
-
const max = state.eMarks[startLine];
|
|
8
|
-
// return false if the length is shorter than min length
|
|
9
|
-
if (pos + MIN_LENGTH > max)
|
|
10
|
-
return false;
|
|
11
|
-
// check if it's matched the start
|
|
12
|
-
for (let i = 0; i < START_CODES.length; i += 1) {
|
|
13
|
-
if (state.src.charCodeAt(pos + i) !== START_CODES[i])
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
// check if it's matched the syntax
|
|
17
|
-
const match = state.src.slice(pos, max).match(syntaxPattern);
|
|
18
|
-
if (!match)
|
|
19
|
-
return false;
|
|
20
|
-
// return true as we have matched the syntax
|
|
21
|
-
if (silent)
|
|
22
|
-
return true;
|
|
23
|
-
const token = state.push(name, '', 0);
|
|
24
|
-
token.meta = meta(match);
|
|
25
|
-
token.map = [startLine, startLine + 1];
|
|
26
|
-
state.line = startLine + 1;
|
|
27
|
-
return true;
|
|
28
|
-
}, ruleOptions);
|
|
29
|
-
md.renderer.rules[name] = (tokens, index) => {
|
|
30
|
-
const token = tokens[index];
|
|
31
|
-
token.content = content(token.meta);
|
|
32
|
-
return token.content;
|
|
33
|
-
};
|
|
34
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function parseRect(str: string, unit?: string): string;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
const RE_ATTR_VALUE = /(?:^|\s+)(?<attr>[\w\d-]+)(?:=\s*(?<quote>['"])(?<value>.+?)\k<quote>)?(?:\s+|$)/;
|
|
2
|
-
export function resolveAttrs(info) {
|
|
3
|
-
info = info.trim();
|
|
4
|
-
if (!info)
|
|
5
|
-
return { rawAttrs: '', attrs: {} };
|
|
6
|
-
const attrs = {};
|
|
7
|
-
const rawAttrs = info;
|
|
8
|
-
let matched;
|
|
9
|
-
// eslint-disable-next-line no-cond-assign
|
|
10
|
-
while (matched = info.match(RE_ATTR_VALUE)) {
|
|
11
|
-
const { attr, value } = matched.groups || {};
|
|
12
|
-
attrs[attr] = value ?? true;
|
|
13
|
-
info = info.slice(matched[0].length);
|
|
14
|
-
}
|
|
15
|
-
Object.keys(attrs).forEach((key) => {
|
|
16
|
-
let value = attrs[key];
|
|
17
|
-
value = typeof value === 'string' ? value.trim() : value;
|
|
18
|
-
if (value === 'true')
|
|
19
|
-
value = true;
|
|
20
|
-
else if (value === 'false')
|
|
21
|
-
value = false;
|
|
22
|
-
attrs[key] = value;
|
|
23
|
-
if (key.includes('-')) {
|
|
24
|
-
const _key = key.replace(/-(\w)/g, (_, c) => c.toUpperCase());
|
|
25
|
-
attrs[_key] = value;
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
return { attrs, rawAttrs };
|
|
29
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function timeToSeconds(time: string): number;
|
package/lib/shared/caniuse.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export type CanIUseMode = 'embed' | 'image';
|
|
2
|
-
export interface CanIUseTokenMeta {
|
|
3
|
-
feature: string;
|
|
4
|
-
mode: CanIUseMode;
|
|
5
|
-
versions: string;
|
|
6
|
-
}
|
|
7
|
-
export interface CanIUseOptions {
|
|
8
|
-
/**
|
|
9
|
-
* 嵌入模式
|
|
10
|
-
*
|
|
11
|
-
* embed 通过iframe嵌入,提供可交互视图
|
|
12
|
-
*
|
|
13
|
-
* image 通过图片嵌入,静态
|
|
14
|
-
*
|
|
15
|
-
* @default 'embed'
|
|
16
|
-
*/
|
|
17
|
-
mode?: CanIUseMode;
|
|
18
|
-
}
|
package/lib/shared/caniuse.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { SizeOptions } from './size.js';
|
|
2
|
-
export interface CodeSandboxTokenMeta extends SizeOptions {
|
|
3
|
-
user?: string;
|
|
4
|
-
id?: string;
|
|
5
|
-
layout?: string;
|
|
6
|
-
type?: 'button' | 'embed';
|
|
7
|
-
title?: string;
|
|
8
|
-
filepath?: string;
|
|
9
|
-
navbar?: boolean;
|
|
10
|
-
console?: boolean;
|
|
11
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|