vuepress-plugin-md-power 1.0.0-rc.48

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.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +201 -0
  3. package/lib/client/components/Bilibili.vue +45 -0
  4. package/lib/client/components/PDFViewer.vue +39 -0
  5. package/lib/client/components/Replit.vue +54 -0
  6. package/lib/client/components/Youtube.vue +41 -0
  7. package/lib/client/composables/pdf.d.ts +3 -0
  8. package/lib/client/composables/pdf.js +75 -0
  9. package/lib/client/composables/setupCanIUse.d.ts +1 -0
  10. package/lib/client/composables/setupCanIUse.js +18 -0
  11. package/lib/client/composables/size.d.ts +10 -0
  12. package/lib/client/composables/size.js +33 -0
  13. package/lib/client/config.d.ts +4 -0
  14. package/lib/client/config.js +27 -0
  15. package/lib/client/index.d.ts +1 -0
  16. package/lib/client/index.js +1 -0
  17. package/lib/client/options.d.ts +2 -0
  18. package/lib/client/options.js +1 -0
  19. package/lib/client/shim.d.ts +6 -0
  20. package/lib/client/utils/is.d.ts +3 -0
  21. package/lib/client/utils/is.js +13 -0
  22. package/lib/client/utils/link.d.ts +1 -0
  23. package/lib/client/utils/link.js +5 -0
  24. package/lib/node/features/caniuse.d.ts +25 -0
  25. package/lib/node/features/caniuse.js +129 -0
  26. package/lib/node/features/codepen.d.ts +7 -0
  27. package/lib/node/features/codepen.js +72 -0
  28. package/lib/node/features/icons/index.d.ts +2 -0
  29. package/lib/node/features/icons/index.js +2 -0
  30. package/lib/node/features/icons/plugin.d.ts +10 -0
  31. package/lib/node/features/icons/plugin.js +60 -0
  32. package/lib/node/features/icons/writer.d.ts +11 -0
  33. package/lib/node/features/icons/writer.js +100 -0
  34. package/lib/node/features/pdf.d.ts +2 -0
  35. package/lib/node/features/pdf.js +68 -0
  36. package/lib/node/features/replit.d.ts +7 -0
  37. package/lib/node/features/replit.js +59 -0
  38. package/lib/node/features/video/bilibili.d.ts +2 -0
  39. package/lib/node/features/video/bilibili.js +83 -0
  40. package/lib/node/features/video/youtube.d.ts +2 -0
  41. package/lib/node/features/video/youtube.js +74 -0
  42. package/lib/node/index.d.ts +2 -0
  43. package/lib/node/index.js +2 -0
  44. package/lib/node/markdown-it-container.d.ts +6 -0
  45. package/lib/node/plugin.d.ts +3 -0
  46. package/lib/node/plugin.js +55 -0
  47. package/lib/node/utils/package.d.ts +4 -0
  48. package/lib/node/utils/package.js +4 -0
  49. package/lib/node/utils/parseRect.d.ts +1 -0
  50. package/lib/node/utils/parseRect.js +5 -0
  51. package/lib/node/utils/resolveAttrs.d.ts +4 -0
  52. package/lib/node/utils/resolveAttrs.js +29 -0
  53. package/lib/node/utils/timeToSeconds.d.ts +1 -0
  54. package/lib/node/utils/timeToSeconds.js +8 -0
  55. package/lib/shared/caniuse.d.ts +18 -0
  56. package/lib/shared/caniuse.js +1 -0
  57. package/lib/shared/codepen.d.ts +10 -0
  58. package/lib/shared/codepen.js +1 -0
  59. package/lib/shared/icons.d.ts +17 -0
  60. package/lib/shared/icons.js +1 -0
  61. package/lib/shared/index.d.ts +6 -0
  62. package/lib/shared/index.js +6 -0
  63. package/lib/shared/pdf.d.ts +15 -0
  64. package/lib/shared/pdf.js +1 -0
  65. package/lib/shared/plugin.d.ts +12 -0
  66. package/lib/shared/plugin.js +1 -0
  67. package/lib/shared/replit.d.ts +6 -0
  68. package/lib/shared/replit.js +1 -0
  69. package/lib/shared/size.d.ts +5 -0
  70. package/lib/shared/size.js +1 -0
  71. package/lib/shared/video.d.ts +22 -0
  72. package/lib/shared/video.js +1 -0
  73. package/package.json +69 -0
@@ -0,0 +1,74 @@
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
+ const YOUTUBE_LINK = 'https://www.youtube.com/embed/';
9
+ // @[youtube]()
10
+ const MIN_LENGTH = 13;
11
+ // char codes of '@[youtube'
12
+ const START_CODES = [64, 91, 121, 111, 117, 116, 117, 98, 101];
13
+ // regexp to match the import syntax
14
+ const SYNTAX_RE = /^@\[youtube(?:\s+([^]*?))?\]\(([^)]*)\)/;
15
+ function createYoutubeRuleBlock() {
16
+ return (state, startLine, endLine, silent) => {
17
+ const pos = state.bMarks[startLine] + state.tShift[startLine];
18
+ const max = state.eMarks[startLine];
19
+ // return false if the length is shorter than min length
20
+ if (pos + MIN_LENGTH > max)
21
+ return false;
22
+ // check if it's matched the start
23
+ for (let i = 0; i < START_CODES.length; i += 1) {
24
+ if (state.src.charCodeAt(pos + i) !== START_CODES[i])
25
+ return false;
26
+ }
27
+ // check if it's matched the syntax
28
+ const match = state.src.slice(pos, max).match(SYNTAX_RE);
29
+ if (!match)
30
+ return false;
31
+ // return true as we have matched the syntax
32
+ if (silent)
33
+ return true;
34
+ const [, info = '', id = ''] = match;
35
+ const { attrs } = resolveAttrs(info);
36
+ const meta = {
37
+ id,
38
+ autoplay: attrs.autoplay ?? false,
39
+ loop: attrs.loop ?? false,
40
+ start: timeToSeconds(attrs.start),
41
+ end: timeToSeconds(attrs.end),
42
+ title: attrs.title,
43
+ width: attrs.width ? parseRect(attrs.width) : '100%',
44
+ height: attrs.height ? parseRect(attrs.height) : '',
45
+ ratio: attrs.ratio ? parseRect(attrs.ratio) : '',
46
+ };
47
+ const token = state.push('video_youtube', '', 0);
48
+ token.meta = meta;
49
+ token.map = [startLine, startLine + 1];
50
+ token.info = info;
51
+ state.line = startLine + 1;
52
+ return true;
53
+ };
54
+ }
55
+ function resolveYoutube(meta) {
56
+ const params = new URLSearchParams();
57
+ meta.autoplay && params.set('autoplay', '1');
58
+ meta.loop && params.set('loop', '1');
59
+ meta.start && params.set('start', meta.start.toString());
60
+ meta.end && params.set('end', meta.end.toString());
61
+ const source = `${YOUTUBE_LINK}/${meta.id}?${params.toString()}`;
62
+ return `<VideoYoutube src="${source}" width="${meta.width}" height="${meta.height}" ratio="${meta.ratio}" title="${meta.title}" />`;
63
+ }
64
+ export const youtubePlugin = (md) => {
65
+ md.block.ruler.before('import_code', 'video_youtube', createYoutubeRuleBlock(), {
66
+ alt: ['paragraph', 'reference', 'blockquote', 'list'],
67
+ });
68
+ md.renderer.rules.video_youtube = (tokens, index) => {
69
+ const token = tokens[index];
70
+ const content = resolveYoutube(token.meta);
71
+ token.content = content;
72
+ return content;
73
+ };
74
+ };
@@ -0,0 +1,2 @@
1
+ export * from './plugin.js';
2
+ export * from '../shared/index.js';
@@ -0,0 +1,2 @@
1
+ export * from './plugin.js';
2
+ export * from '../shared/index.js';
@@ -0,0 +1,6 @@
1
+ declare module 'markdown-it-container' {
2
+ import type { PluginWithParams } from 'markdown-it'
3
+
4
+ const container: PluginWithParams
5
+ export = container
6
+ }
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from 'vuepress/core';
2
+ import type { MarkdownPowerPluginOptions } from '../shared/index.js';
3
+ export declare function markdownPowerPlugin(options?: MarkdownPowerPluginOptions): Plugin;
@@ -0,0 +1,55 @@
1
+ import { getDirname, path } from 'vuepress/utils';
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
+ const __dirname = getDirname(import.meta.url);
10
+ export function markdownPowerPlugin(options = {}) {
11
+ return (app) => {
12
+ const { initIcon, addIcon } = createIconCSSWriter(app, options.icons);
13
+ return {
14
+ name: '@vuepress-plume/plugin-md-power',
15
+ clientConfigFile: path.resolve(__dirname, '../client/config.js'),
16
+ define: {
17
+ __MD_POWER_INJECT_OPTIONS__: options,
18
+ },
19
+ onInitialized: async () => await initIcon(),
20
+ extendsMarkdown(md) {
21
+ if (options.caniuse) {
22
+ const caniuse = options.caniuse === true ? {} : options.caniuse;
23
+ // @[caniuse](feature_name)
24
+ md.use(caniusePlugin, caniuse);
25
+ // 兼容旧语法
26
+ legacyCaniuse(md, caniuse);
27
+ }
28
+ if (options.pdf) {
29
+ // @[pdf](url)
30
+ md.use(pdfPlugin);
31
+ }
32
+ if (options.icons) {
33
+ // :[collect:name]:
34
+ md.use(iconsPlugin, addIcon);
35
+ }
36
+ if (options.bilibili) {
37
+ // @[bilibili](bvid aid cid)
38
+ md.use(bilibiliPlugin);
39
+ }
40
+ if (options.youtube) {
41
+ // @[youtube](id)
42
+ md.use(youtubePlugin);
43
+ }
44
+ if (options.codepen) {
45
+ // @[codepen](user/slash)
46
+ md.use(codepenPlugin);
47
+ }
48
+ if (options.replit) {
49
+ // @[replit](user/repl-name)
50
+ md.use(replitPlugin);
51
+ }
52
+ },
53
+ };
54
+ };
55
+ }
@@ -0,0 +1,4 @@
1
+ export type Awaitable<T> = T | Promise<T>;
2
+ export declare function interopDefault<T>(m: Awaitable<T>): Promise<T extends {
3
+ default: infer U;
4
+ } ? U : T>;
@@ -0,0 +1,4 @@
1
+ export async function interopDefault(m) {
2
+ const resolved = await m;
3
+ return resolved.default || resolved;
4
+ }
@@ -0,0 +1 @@
1
+ export declare function parseRect(str: string, unit?: string): string;
@@ -0,0 +1,5 @@
1
+ export function parseRect(str, unit = 'px') {
2
+ if (Number.parseFloat(str) === Number(str))
3
+ return `${str}${unit}`;
4
+ return str;
5
+ }
@@ -0,0 +1,4 @@
1
+ export declare function resolveAttrs(info: string): {
2
+ attrs: Record<string, any>;
3
+ rawAttrs: string;
4
+ };
@@ -0,0 +1,29 @@
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
+ }
@@ -0,0 +1 @@
1
+ export declare function timeToSeconds(time: string): number;
@@ -0,0 +1,8 @@
1
+ export function timeToSeconds(time) {
2
+ if (!time)
3
+ return 0;
4
+ if (Number.parseFloat(time) === Number(time))
5
+ return Number(time);
6
+ const [s, m, h] = time.split(':').reverse().map(n => Number(n) || 0);
7
+ return s + m * 60 + h * 3600;
8
+ }
@@ -0,0 +1,18 @@
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
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { SizeOptions } from './size';
2
+ export interface CodepenTokenMeta extends SizeOptions {
3
+ title?: string;
4
+ user?: string;
5
+ slash?: string;
6
+ tab?: string;
7
+ theme?: string;
8
+ preview?: boolean;
9
+ editable?: boolean;
10
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ export interface IconsOptions {
2
+ /**
3
+ * The prefix of the icon className
4
+ * @default 'vp-mdi'
5
+ */
6
+ prefix?: string;
7
+ /**
8
+ * The size of the icon
9
+ * @default '1em'
10
+ */
11
+ size?: string | number;
12
+ /**
13
+ * The color of the icon
14
+ * @default 'currentColor'
15
+ */
16
+ color?: string;
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ export * from './caniuse.js';
2
+ export * from './pdf.js';
3
+ export * from './icons.js';
4
+ export * from './video.js';
5
+ export * from './codepen.js';
6
+ export * from './plugin.js';
@@ -0,0 +1,6 @@
1
+ export * from './caniuse.js';
2
+ export * from './pdf.js';
3
+ export * from './icons.js';
4
+ export * from './video.js';
5
+ export * from './codepen.js';
6
+ export * from './plugin.js';
@@ -0,0 +1,15 @@
1
+ import type { SizeOptions } from './size';
2
+ export type PDFEmbedType = 'iframe' | 'embed' | 'pdfjs';
3
+ export interface PDFTokenMeta extends SizeOptions {
4
+ page?: number;
5
+ noToolbar?: boolean;
6
+ zoom?: number;
7
+ src?: string;
8
+ title?: string;
9
+ }
10
+ export interface PDFOptions {
11
+ /**
12
+ * pdfjs url
13
+ */
14
+ pdfjsUrl?: string;
15
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { CanIUseOptions } from './caniuse.js';
2
+ import type { PDFOptions } from './pdf.js';
3
+ import type { IconsOptions } from './icons.js';
4
+ export interface MarkdownPowerPluginOptions {
5
+ pdf?: boolean | PDFOptions;
6
+ icons?: boolean | IconsOptions;
7
+ bilibili?: boolean;
8
+ youtube?: boolean;
9
+ codepen?: boolean;
10
+ replit?: boolean;
11
+ caniuse?: boolean | CanIUseOptions;
12
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { SizeOptions } from './size';
2
+ export interface ReplitTokenMeta extends SizeOptions {
3
+ title?: string;
4
+ source?: string;
5
+ theme?: string;
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export interface SizeOptions {
2
+ width?: string;
3
+ height?: string;
4
+ ratio?: number | string;
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ import type { SizeOptions } from './size';
2
+ export interface VideoOptions {
3
+ bilibili?: boolean;
4
+ youtube?: boolean;
5
+ }
6
+ export interface BilibiliTokenMeta extends SizeOptions {
7
+ title?: string;
8
+ bvid?: string;
9
+ aid?: string;
10
+ cid?: string;
11
+ autoplay?: boolean;
12
+ time?: string | number;
13
+ page?: number;
14
+ }
15
+ export interface YoutubeTokenMeta extends SizeOptions {
16
+ title?: string;
17
+ id: string;
18
+ autoplay?: boolean;
19
+ loop?: boolean;
20
+ start?: string | number;
21
+ end?: string | number;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "vuepress-plugin-md-power",
3
+ "type": "module",
4
+ "version": "1.0.0-rc.48",
5
+ "description": "The Plugin for VuePres 2 - markdown power",
6
+ "author": "pengzhanbo <volodymyr@foxmail.com>",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/pengzhanbo/vuepress-theme-plume#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/pengzhanbo/vuepress-theme-plume.git",
12
+ "directory": "plugins/plugin-md-power"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/pengzhanbo/vuepress-theme-plume/issues"
16
+ },
17
+ "exports": {
18
+ ".": {
19
+ "types": "./lib/node/index.d.ts",
20
+ "import": "./lib/node/index.js"
21
+ },
22
+ "./client": {
23
+ "types": "./lib/client/index.d.ts",
24
+ "import": "./lib/client/index.js"
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
28
+ "main": "lib/node/index.js",
29
+ "types": "./lib/node/index.d.ts",
30
+ "files": [
31
+ "lib"
32
+ ],
33
+ "peerDependencies": {
34
+ "@iconify/json": "^2",
35
+ "vuepress": "2.0.0-rc.9"
36
+ },
37
+ "peerDependenciesMeta": {
38
+ "@iconify/json": {
39
+ "optional": true
40
+ }
41
+ },
42
+ "dependencies": {
43
+ "@iconify/utils": "^2.1.22",
44
+ "@vueuse/core": "^10.9.0",
45
+ "local-pkg": "^0.5.0",
46
+ "markdown-it-container": "^4.0.0",
47
+ "nanoid": "^5.0.6",
48
+ "vue": "^3.4.21"
49
+ },
50
+ "devDependencies": {
51
+ "@iconify/json": "^2.2.196",
52
+ "@types/markdown-it": "^13.0.7"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "keyword": [
58
+ "VuePress",
59
+ "vuepress plugin",
60
+ "markdown power",
61
+ "vuepress-plugin-md-power"
62
+ ],
63
+ "scripts": {
64
+ "build": "pnpm run copy && pnpm run ts",
65
+ "clean": "rimraf --glob ./lib ./*.tsbuildinfo",
66
+ "copy": "cpx \"src/**/*.{d.ts,vue,css,scss,jpg,png}\" lib",
67
+ "ts": "tsc -b tsconfig.build.json"
68
+ }
69
+ }