@hejiayue/x-markdown-test 0.0.1-beta.113 → 0.0.1-beta.115
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/style.css +1 -1
- package/dist/x-markdown.cjs.js +1 -1
- package/dist/x-markdown.cjs10.js +2 -0
- package/dist/x-markdown.cjs10.js.map +1 -0
- package/dist/x-markdown.cjs11.js +2 -0
- package/dist/x-markdown.cjs11.js.map +1 -0
- package/dist/x-markdown.cjs13.js +2 -0
- package/dist/x-markdown.cjs13.js.map +1 -0
- package/dist/x-markdown.cjs14.js +2 -0
- package/dist/x-markdown.cjs14.js.map +1 -0
- package/dist/x-markdown.cjs15.js +2 -0
- package/dist/x-markdown.cjs15.js.map +1 -0
- package/dist/x-markdown.cjs16.js +2 -0
- package/dist/x-markdown.cjs16.js.map +1 -0
- package/dist/x-markdown.cjs17.js +2 -0
- package/dist/x-markdown.cjs17.js.map +1 -0
- package/dist/x-markdown.cjs18.js +2 -0
- package/dist/x-markdown.cjs18.js.map +1 -0
- package/dist/x-markdown.cjs19.js +2 -0
- package/dist/x-markdown.cjs19.js.map +1 -0
- package/dist/x-markdown.cjs2.js +2 -0
- package/dist/x-markdown.cjs2.js.map +1 -0
- package/dist/x-markdown.cjs21.js +2 -0
- package/dist/x-markdown.cjs21.js.map +1 -0
- package/dist/x-markdown.cjs22.js +2 -0
- package/dist/x-markdown.cjs22.js.map +1 -0
- package/dist/x-markdown.cjs24.js +2 -0
- package/dist/x-markdown.cjs24.js.map +1 -0
- package/dist/x-markdown.cjs26.js +2 -0
- package/dist/x-markdown.cjs26.js.map +1 -0
- package/dist/x-markdown.cjs27.js +2 -0
- package/dist/x-markdown.cjs27.js.map +1 -0
- package/dist/x-markdown.cjs28.js +2 -0
- package/dist/x-markdown.cjs28.js.map +1 -0
- package/dist/x-markdown.cjs3.js +2 -0
- package/dist/x-markdown.cjs3.js.map +1 -0
- package/dist/x-markdown.cjs30.js +2 -0
- package/dist/x-markdown.cjs30.js.map +1 -0
- package/dist/x-markdown.cjs31.js +2 -0
- package/dist/x-markdown.cjs31.js.map +1 -0
- package/dist/x-markdown.cjs33.js +2 -0
- package/dist/x-markdown.cjs33.js.map +1 -0
- package/dist/x-markdown.cjs4.js +2 -0
- package/dist/x-markdown.cjs4.js.map +1 -0
- package/dist/x-markdown.cjs5.js +2 -0
- package/dist/x-markdown.cjs5.js.map +1 -0
- package/dist/x-markdown.cjs6.js +2 -0
- package/dist/x-markdown.cjs6.js.map +1 -0
- package/dist/x-markdown.cjs7.js +2 -0
- package/dist/x-markdown.cjs7.js.map +1 -0
- package/dist/x-markdown.cjs8.js +2 -0
- package/dist/x-markdown.cjs8.js.map +1 -0
- package/dist/x-markdown.cjs9.js +2 -0
- package/dist/x-markdown.cjs9.js.map +1 -0
- package/dist/x-markdown.es.js +26 -17
- package/dist/x-markdown.es.js.map +1 -1
- package/dist/x-markdown.es10.js +49 -0
- package/dist/x-markdown.es10.js.map +1 -0
- package/dist/x-markdown.es11.js +54 -0
- package/dist/x-markdown.es11.js.map +1 -0
- package/dist/x-markdown.es13.js +89 -0
- package/dist/x-markdown.es13.js.map +1 -0
- package/dist/x-markdown.es14.js +34 -0
- package/dist/x-markdown.es14.js.map +1 -0
- package/dist/x-markdown.es15.js +5 -0
- package/dist/x-markdown.es15.js.map +1 -0
- package/dist/x-markdown.es16.js +6 -0
- package/dist/x-markdown.es16.js.map +1 -0
- package/dist/x-markdown.es17.js +8 -0
- package/dist/x-markdown.es17.js.map +1 -0
- package/dist/x-markdown.es18.js +8 -0
- package/dist/x-markdown.es18.js.map +1 -0
- package/dist/x-markdown.es19.js +207 -0
- package/dist/x-markdown.es19.js.map +1 -0
- package/dist/x-markdown.es2.js +83 -0
- package/dist/x-markdown.es2.js.map +1 -0
- package/dist/x-markdown.es21.js +11 -0
- package/dist/x-markdown.es21.js.map +1 -0
- package/dist/x-markdown.es22.js +75 -0
- package/dist/x-markdown.es22.js.map +1 -0
- package/dist/{index-SElRorTo.js → x-markdown.es24.js} +7 -139
- package/dist/x-markdown.es24.js.map +1 -0
- package/dist/x-markdown.es26.js +160 -0
- package/dist/x-markdown.es26.js.map +1 -0
- package/dist/x-markdown.es27.js +8 -0
- package/dist/x-markdown.es27.js.map +1 -0
- package/dist/x-markdown.es28.js +142 -0
- package/dist/x-markdown.es28.js.map +1 -0
- package/dist/x-markdown.es3.js +94 -0
- package/dist/x-markdown.es3.js.map +1 -0
- package/dist/x-markdown.es30.js +78 -0
- package/dist/x-markdown.es30.js.map +1 -0
- package/dist/x-markdown.es31.js +125 -0
- package/dist/x-markdown.es31.js.map +1 -0
- package/dist/x-markdown.es33.js +6 -0
- package/dist/x-markdown.es33.js.map +1 -0
- package/dist/x-markdown.es4.js +150 -0
- package/dist/x-markdown.es4.js.map +1 -0
- package/dist/x-markdown.es5.js +40 -0
- package/dist/x-markdown.es5.js.map +1 -0
- package/dist/x-markdown.es6.js +24 -0
- package/dist/x-markdown.es6.js.map +1 -0
- package/dist/x-markdown.es7.js +279 -0
- package/dist/x-markdown.es7.js.map +1 -0
- package/dist/x-markdown.es8.js +27 -0
- package/dist/x-markdown.es8.js.map +1 -0
- package/dist/x-markdown.es9.js +409 -0
- package/dist/x-markdown.es9.js.map +1 -0
- package/package.json +5 -5
- package/dist/index-D9u8JldH.cjs +0 -2
- package/dist/index-D9u8JldH.cjs.map +0 -1
- package/dist/index-SElRorTo.js.map +0 -1
- package/dist/index-lQ_FQFr2.js +0 -1882
- package/dist/index-lQ_FQFr2.js.map +0 -1
- package/dist/index-nZ5iH1aN.cjs +0 -2
- package/dist/index-nZ5iH1aN.cjs.map +0 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import rehypeKatex from "rehype-katex";
|
|
2
|
+
import rehypeRaw from "rehype-raw";
|
|
3
|
+
import remarkBreaks from "remark-breaks";
|
|
4
|
+
import remarkGfm from "remark-gfm";
|
|
5
|
+
import remarkMath from "remark-math";
|
|
6
|
+
import { toRefs, computed } from "vue";
|
|
7
|
+
import { rehypeAnimatedPlugin } from "./x-markdown.es14.js";
|
|
8
|
+
function usePlugins(props) {
|
|
9
|
+
const {
|
|
10
|
+
allowHtml,
|
|
11
|
+
enableAnimate,
|
|
12
|
+
enableLatex,
|
|
13
|
+
enableBreaks,
|
|
14
|
+
enableGfm,
|
|
15
|
+
rehypePlugins,
|
|
16
|
+
remarkPlugins,
|
|
17
|
+
rehypePluginsAhead,
|
|
18
|
+
remarkPluginsAhead
|
|
19
|
+
} = toRefs(props);
|
|
20
|
+
const rehype = computed(() => {
|
|
21
|
+
return [
|
|
22
|
+
...rehypePluginsAhead.value,
|
|
23
|
+
allowHtml.value && rehypeRaw,
|
|
24
|
+
enableLatex.value && rehypeKatex,
|
|
25
|
+
enableAnimate.value && rehypeAnimatedPlugin,
|
|
26
|
+
...rehypePlugins.value
|
|
27
|
+
].filter(Boolean);
|
|
28
|
+
});
|
|
29
|
+
const remark = computed(() => {
|
|
30
|
+
const base = [
|
|
31
|
+
enableLatex.value && remarkMath,
|
|
32
|
+
enableGfm.value !== false && [remarkGfm, { singleTilde: false }],
|
|
33
|
+
enableBreaks.value && remarkBreaks
|
|
34
|
+
].filter(Boolean);
|
|
35
|
+
return [
|
|
36
|
+
...remarkPluginsAhead.value,
|
|
37
|
+
...base,
|
|
38
|
+
...remarkPlugins.value
|
|
39
|
+
];
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
rehypePlugins: rehype,
|
|
43
|
+
remarkPlugins: remark
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
usePlugins
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=x-markdown.es10.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x-markdown.es10.js","sources":["../src/hooks/usePlugins.ts"],"sourcesContent":["import type { Pluggable } from 'unified'\r\nimport rehypeKatex from 'rehype-katex'\r\nimport rehypeRaw from 'rehype-raw'\r\nimport remarkBreaks from 'remark-breaks'\r\nimport remarkGfm from 'remark-gfm'\r\nimport remarkMath from 'remark-math'\r\nimport { computed, toRefs } from 'vue'\r\nimport { rehypeAnimatedPlugin } from '../plugins/rehypePlugin'\r\n\r\nfunction usePlugins(props: any) {\r\n const {\r\n allowHtml,\r\n enableAnimate,\r\n enableLatex,\r\n enableBreaks,\r\n enableGfm,\r\n rehypePlugins,\r\n remarkPlugins,\r\n rehypePluginsAhead,\r\n remarkPluginsAhead,\r\n } = toRefs(props)\r\n\r\n const rehype = computed(() => {\r\n return [\r\n ...(rehypePluginsAhead.value as Pluggable[]),\r\n allowHtml.value && rehypeRaw,\r\n enableLatex.value && rehypeKatex,\r\n enableAnimate.value && rehypeAnimatedPlugin,\r\n ...(rehypePlugins.value as Pluggable[]),\r\n ].filter(Boolean) as Pluggable[]\r\n })\r\n\r\n const remark = computed(() => {\r\n const base: (Pluggable | { plugins: Pluggable[] })[] = [\r\n enableLatex.value && remarkMath,\r\n enableGfm.value !== false && [remarkGfm, { singleTilde: false }],\r\n enableBreaks.value && remarkBreaks,\r\n ].filter(Boolean) as (Pluggable | { plugins: Pluggable[] })[]\r\n\r\n return [\r\n ...(remarkPluginsAhead.value as (Pluggable | { plugins: Pluggable[] })[]),\r\n ...base,\r\n ...(remarkPlugins.value as (Pluggable | { plugins: Pluggable[] })[]),\r\n ]\r\n })\r\n\r\n return {\r\n rehypePlugins: rehype,\r\n remarkPlugins: remark,\r\n }\r\n}\r\nexport { usePlugins }\r\n"],"names":[],"mappings":";;;;;;;AASA,SAAS,WAAW,OAAY;AAC9B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE,OAAO,KAAK;AAEhB,QAAM,SAAS,SAAS,MAAM;AAC5B,WAAO;AAAA,MACL,GAAI,mBAAmB;AAAA,MACvB,UAAU,SAAS;AAAA,MACnB,YAAY,SAAS;AAAA,MACrB,cAAc,SAAS;AAAA,MACvB,GAAI,cAAc;AAAA,IAAA,EAClB,OAAO,OAAO;AAAA,EAClB,CAAC;AAED,QAAM,SAAS,SAAS,MAAM;AAC5B,UAAM,OAAiD;AAAA,MACrD,YAAY,SAAS;AAAA,MACrB,UAAU,UAAU,SAAS,CAAC,WAAW,EAAE,aAAa,OAAO;AAAA,MAC/D,aAAa,SAAS;AAAA,IAAA,EACtB,OAAO,OAAO;AAEhB,WAAO;AAAA,MACL,GAAI,mBAAmB;AAAA,MACvB,GAAG;AAAA,MACH,GAAI,cAAc;AAAA,IAAA;AAAA,EAEtB,CAAC;AAED,SAAO;AAAA,IACL,eAAe;AAAA,IACf,eAAe;AAAA,EAAA;AAEnB;"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ref, isRef, computed } from "vue";
|
|
2
|
+
const themeMap = {
|
|
3
|
+
light: "vitesse-light",
|
|
4
|
+
dark: "vitesse-dark"
|
|
5
|
+
};
|
|
6
|
+
function useTheme(options = {}) {
|
|
7
|
+
const { lightTheme = themeMap.light, darkTheme = themeMap.dark } = options;
|
|
8
|
+
const internalMode = ref(isRef(options.mode) ? options.mode.value : options.mode || "auto");
|
|
9
|
+
const mode = computed({
|
|
10
|
+
get: () => isRef(options.mode) ? options.mode.value : internalMode.value,
|
|
11
|
+
set: (val) => {
|
|
12
|
+
internalMode.value = val;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
const systemIsDark = ref(false);
|
|
16
|
+
if (typeof window !== "undefined") {
|
|
17
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
18
|
+
systemIsDark.value = mediaQuery.matches;
|
|
19
|
+
mediaQuery.addEventListener("change", (e) => {
|
|
20
|
+
systemIsDark.value = e.matches;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const isDark = computed(() => {
|
|
24
|
+
if (mode.value === "auto") {
|
|
25
|
+
return systemIsDark.value;
|
|
26
|
+
}
|
|
27
|
+
return mode.value === "dark";
|
|
28
|
+
});
|
|
29
|
+
const actualTheme = computed(() => {
|
|
30
|
+
const customTheme = isRef(options.theme) ? options.theme.value : options.theme;
|
|
31
|
+
if (customTheme) return customTheme;
|
|
32
|
+
return isDark.value ? darkTheme : lightTheme;
|
|
33
|
+
});
|
|
34
|
+
const setMode = (newMode) => {
|
|
35
|
+
internalMode.value = newMode;
|
|
36
|
+
};
|
|
37
|
+
const toggleMode = () => {
|
|
38
|
+
const modes = ["light", "dark", "auto"];
|
|
39
|
+
const currentIndex = modes.indexOf(mode.value);
|
|
40
|
+
internalMode.value = modes[(currentIndex + 1) % modes.length];
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
mode,
|
|
44
|
+
isDark,
|
|
45
|
+
actualTheme,
|
|
46
|
+
setMode,
|
|
47
|
+
toggleMode
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
themeMap,
|
|
52
|
+
useTheme
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=x-markdown.es11.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x-markdown.es11.js","sources":["../src/hooks/useTheme.ts"],"sourcesContent":["import { computed, isRef, ref, type Ref } from 'vue'\r\n\r\nexport type ThemeMode = 'light' | 'dark' | 'auto'\r\nexport type ShikiThemeName = string // Shiki 主题名称(字符串类型,支持动态导入)\r\n\r\n// 内置主题映射\r\nexport const themeMap = {\r\n light: 'vitesse-light',\r\n dark: 'vitesse-dark',\r\n} as const\r\n\r\nexport interface UseThemeOptions {\r\n mode?: ThemeMode | Ref<ThemeMode>\r\n theme?: ShikiThemeName | Ref<ShikiThemeName | undefined>\r\n lightTheme?: ShikiThemeName\r\n darkTheme?: ShikiThemeName\r\n}\r\n\r\nexport interface UseThemeReturn {\r\n mode: Ref<ThemeMode>\r\n isDark: Ref<boolean>\r\n actualTheme: Ref<ShikiThemeName>\r\n setMode: (mode: ThemeMode) => void\r\n toggleMode: () => void\r\n}\r\n\r\n/**\r\n * 主题管理 Hook\r\n * 支持 light/dark/auto 模式切换\r\n */\r\nexport function useTheme(options: UseThemeOptions = {}): UseThemeReturn {\r\n const { lightTheme = themeMap.light, darkTheme = themeMap.dark } = options\r\n\r\n // 内部 mode(用于 setMode/toggleMode 修改)\r\n const internalMode = ref<ThemeMode>(isRef(options.mode) ? options.mode.value : options.mode || 'auto')\r\n\r\n // 实际使用的 mode(优先使用外部传入的响应式值)\r\n const mode = computed<ThemeMode>({\r\n get: () => (isRef(options.mode) ? options.mode.value : internalMode.value),\r\n set: (val) => {\r\n internalMode.value = val\r\n },\r\n })\r\n\r\n // 系统是否为暗色模式\r\n const systemIsDark = ref(false)\r\n\r\n // 监听系统主题变化\r\n if (typeof window !== 'undefined') {\r\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\r\n systemIsDark.value = mediaQuery.matches\r\n\r\n mediaQuery.addEventListener('change', (e) => {\r\n systemIsDark.value = e.matches\r\n })\r\n }\r\n\r\n // 当前是否为暗色模式\r\n const isDark = computed(() => {\r\n if (mode.value === 'auto') {\r\n return systemIsDark.value\r\n }\r\n return mode.value === 'dark'\r\n })\r\n\r\n // 实际使用的 Shiki 主题\r\n const actualTheme = computed<ShikiThemeName>(() => {\r\n // 如果传入了具体的 theme,优先使用\r\n const customTheme = isRef(options.theme) ? options.theme.value : options.theme\r\n if (customTheme) return customTheme\r\n\r\n return isDark.value ? darkTheme : lightTheme\r\n })\r\n\r\n // 设置模式\r\n const setMode = (newMode: ThemeMode) => {\r\n internalMode.value = newMode\r\n }\r\n\r\n // 切换模式 (light -> dark -> auto -> light)\r\n const toggleMode = () => {\r\n const modes: ThemeMode[] = ['light', 'dark', 'auto']\r\n const currentIndex = modes.indexOf(mode.value)\r\n internalMode.value = modes[(currentIndex + 1) % modes.length]\r\n }\r\n\r\n return {\r\n mode,\r\n isDark,\r\n actualTheme,\r\n setMode,\r\n toggleMode,\r\n }\r\n}\r\n"],"names":[],"mappings":";AAMO,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,MAAM;AACR;AAqBO,SAAS,SAAS,UAA2B,IAAoB;AACtE,QAAM,EAAE,aAAa,SAAS,OAAO,YAAY,SAAS,SAAS;AAGnE,QAAM,eAAe,IAAe,MAAM,QAAQ,IAAI,IAAI,QAAQ,KAAK,QAAQ,QAAQ,QAAQ,MAAM;AAGrG,QAAM,OAAO,SAAoB;AAAA,IAC/B,KAAK,MAAO,MAAM,QAAQ,IAAI,IAAI,QAAQ,KAAK,QAAQ,aAAa;AAAA,IACpE,KAAK,CAAC,QAAQ;AACZ,mBAAa,QAAQ;AAAA,IACvB;AAAA,EAAA,CACD;AAGD,QAAM,eAAe,IAAI,KAAK;AAG9B,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,aAAa,OAAO,WAAW,8BAA8B;AACnE,iBAAa,QAAQ,WAAW;AAEhC,eAAW,iBAAiB,UAAU,CAAC,MAAM;AAC3C,mBAAa,QAAQ,EAAE;AAAA,IACzB,CAAC;AAAA,EACH;AAGA,QAAM,SAAS,SAAS,MAAM;AAC5B,QAAI,KAAK,UAAU,QAAQ;AACzB,aAAO,aAAa;AAAA,IACtB;AACA,WAAO,KAAK,UAAU;AAAA,EACxB,CAAC;AAGD,QAAM,cAAc,SAAyB,MAAM;AAEjD,UAAM,cAAc,MAAM,QAAQ,KAAK,IAAI,QAAQ,MAAM,QAAQ,QAAQ;AACzE,QAAI,YAAa,QAAO;AAExB,WAAO,OAAO,QAAQ,YAAY;AAAA,EACpC,CAAC;AAGD,QAAM,UAAU,CAAC,YAAuB;AACtC,iBAAa,QAAQ;AAAA,EACvB;AAGA,QAAM,aAAa,MAAM;AACvB,UAAM,QAAqB,CAAC,SAAS,QAAQ,MAAM;AACnD,UAAM,eAAe,MAAM,QAAQ,KAAK,KAAK;AAC7C,iBAAa,QAAQ,OAAO,eAAe,KAAK,MAAM,MAAM;AAAA,EAC9D;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { defineComponent, h, defineAsyncComponent } from "vue";
|
|
2
|
+
import CodeBlock from "./x-markdown.es17.js";
|
|
3
|
+
import CodeLine from "./x-markdown.es18.js";
|
|
4
|
+
const Mermaid = defineAsyncComponent(() => import("./x-markdown.es16.js"));
|
|
5
|
+
const _sfc_main = defineComponent({
|
|
6
|
+
props: {
|
|
7
|
+
raw: { type: Object, default: () => ({}) },
|
|
8
|
+
codeXRender: { type: Object, default: () => ({}) },
|
|
9
|
+
isDark: { type: Boolean, default: false },
|
|
10
|
+
shikiTheme: {
|
|
11
|
+
type: Array,
|
|
12
|
+
default: () => ["vitesse-light", "vitesse-dark"]
|
|
13
|
+
},
|
|
14
|
+
showCodeBlockHeader: { type: Boolean, default: true },
|
|
15
|
+
stickyCodeBlockHeader: { type: Boolean, default: true },
|
|
16
|
+
codeMaxHeight: { type: String, default: void 0 },
|
|
17
|
+
enableAnimate: { type: Boolean, default: false },
|
|
18
|
+
codeBlockActions: { type: Array, default: void 0 },
|
|
19
|
+
mermaidActions: { type: Array, default: void 0 },
|
|
20
|
+
mermaidConfig: { type: Object, default: void 0 }
|
|
21
|
+
},
|
|
22
|
+
setup(props, { slots }) {
|
|
23
|
+
const { codeXRender } = props;
|
|
24
|
+
return () => {
|
|
25
|
+
if (props.raw.inline) {
|
|
26
|
+
if (codeXRender && codeXRender.inline) {
|
|
27
|
+
const renderer = codeXRender.inline;
|
|
28
|
+
if (typeof renderer === "function") {
|
|
29
|
+
return renderer(props);
|
|
30
|
+
}
|
|
31
|
+
return h(renderer, props);
|
|
32
|
+
}
|
|
33
|
+
return h(CodeLine, {
|
|
34
|
+
raw: props.raw,
|
|
35
|
+
isDark: props.isDark,
|
|
36
|
+
shikiTheme: props.shikiTheme,
|
|
37
|
+
enableAnimate: props.enableAnimate
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const { language } = props.raw;
|
|
41
|
+
if (codeXRender && codeXRender[language]) {
|
|
42
|
+
const renderer = codeXRender[language];
|
|
43
|
+
if (typeof renderer === "function") {
|
|
44
|
+
return renderer(props);
|
|
45
|
+
}
|
|
46
|
+
return h(renderer, props);
|
|
47
|
+
}
|
|
48
|
+
if (language === "mermaid") {
|
|
49
|
+
const mermaidSlots = {};
|
|
50
|
+
Object.keys(slots).forEach((key) => {
|
|
51
|
+
if (key.startsWith("mermaid")) {
|
|
52
|
+
mermaidSlots[key] = slots[key];
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return h(
|
|
56
|
+
Mermaid,
|
|
57
|
+
{
|
|
58
|
+
raw: props.raw,
|
|
59
|
+
isDark: props.isDark,
|
|
60
|
+
shikiTheme: props.shikiTheme,
|
|
61
|
+
mermaidActions: props.mermaidActions,
|
|
62
|
+
config: props.mermaidConfig
|
|
63
|
+
},
|
|
64
|
+
mermaidSlots
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return h(
|
|
68
|
+
CodeBlock,
|
|
69
|
+
{
|
|
70
|
+
code: props.raw.content || "",
|
|
71
|
+
language: props.raw.language || "text",
|
|
72
|
+
isDark: props.isDark,
|
|
73
|
+
lightTheme: props.shikiTheme[0],
|
|
74
|
+
darkTheme: props.shikiTheme[1],
|
|
75
|
+
showCodeBlockHeader: props.showCodeBlockHeader,
|
|
76
|
+
stickyCodeBlockHeader: props.stickyCodeBlockHeader,
|
|
77
|
+
codeMaxHeight: props.codeMaxHeight,
|
|
78
|
+
enableAnimate: props.enableAnimate,
|
|
79
|
+
codeBlockActions: props.codeBlockActions
|
|
80
|
+
},
|
|
81
|
+
slots
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
export {
|
|
87
|
+
_sfc_main as default
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=x-markdown.es13.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x-markdown.es13.js","sources":["../src/components/CodeX/index.vue"],"sourcesContent":["<script lang=\"ts\">\r\nimport { defineComponent, h, type PropType, defineAsyncComponent } from 'vue'\r\nimport type { CodeBlockAction } from '../CodeBlock/types'\r\nimport type { MermaidAction } from '../Mermaid/types'\r\nimport CodeBlock from '../CodeBlock/index.vue'\r\nimport CodeLine from '../CodeLine/index.vue'\r\n// Mermaid 组件改为动态导入,实现按需加载\r\nconst Mermaid = defineAsyncComponent(() => import('../Mermaid/index.vue'))\r\n\r\nexport default defineComponent({\r\n props: {\r\n raw: { type: Object, default: () => ({}) },\r\n codeXRender: { type: Object, default: () => ({}) },\r\n isDark: { type: Boolean, default: false },\r\n shikiTheme: {\r\n type: Array as PropType<[string, string]>,\r\n default: () => ['vitesse-light', 'vitesse-dark'],\r\n },\r\n showCodeBlockHeader: { type: Boolean, default: true },\r\n stickyCodeBlockHeader: { type: Boolean, default: true },\r\n codeMaxHeight: { type: String, default: undefined },\r\n enableAnimate: { type: Boolean, default: false },\r\n codeBlockActions: { type: Array as PropType<CodeBlockAction[]>, default: undefined },\r\n mermaidActions: { type: Array as PropType<MermaidAction[]>, default: undefined },\r\n mermaidConfig: { type: Object as PropType<Record<string, any>>, default: undefined },\r\n },\r\n setup(props, { slots }) {\r\n const { codeXRender } = props\r\n\r\n return (): ReturnType<typeof h> | null => {\r\n // 处理行内代码\r\n if (props.raw.inline) {\r\n if (codeXRender && codeXRender.inline) {\r\n const renderer = codeXRender.inline\r\n if (typeof renderer === 'function') {\r\n return renderer(props)\r\n }\r\n return h(renderer, props)\r\n }\r\n // 传递完整的配置给 CodeLine,包括主题和动画设置\r\n return h(CodeLine, {\r\n raw: props.raw,\r\n isDark: props.isDark,\r\n shikiTheme: props.shikiTheme,\r\n enableAnimate: props.enableAnimate,\r\n })\r\n }\r\n\r\n const { language } = props.raw\r\n\r\n // 处理自定义渲染器\r\n if (codeXRender && codeXRender[language]) {\r\n const renderer = codeXRender[language]\r\n if (typeof renderer === 'function') {\r\n return renderer(props)\r\n }\r\n return h(renderer, props)\r\n }\r\n\r\n // 处理 Mermaid 图表\r\n if (language === 'mermaid') {\r\n const mermaidSlots: Record<string, any> = {}\r\n Object.keys(slots).forEach((key) => {\r\n if (key.startsWith('mermaid')) {\r\n mermaidSlots[key] = slots[key]\r\n }\r\n })\r\n\r\n return h(\r\n Mermaid,\r\n {\r\n raw: props.raw,\r\n isDark: props.isDark,\r\n shikiTheme: props.shikiTheme,\r\n mermaidActions: props.mermaidActions,\r\n config: props.mermaidConfig,\r\n },\r\n mermaidSlots,\r\n )\r\n }\r\n\r\n // 渲染标准代码块\r\n return h(\r\n CodeBlock,\r\n {\r\n code: props.raw.content || '',\r\n language: props.raw.language || 'text',\r\n isDark: props.isDark,\r\n lightTheme: props.shikiTheme[0],\r\n darkTheme: props.shikiTheme[1],\r\n showCodeBlockHeader: props.showCodeBlockHeader,\r\n stickyCodeBlockHeader: props.stickyCodeBlockHeader,\r\n codeMaxHeight: props.codeMaxHeight,\r\n enableAnimate: props.enableAnimate,\r\n codeBlockActions: props.codeBlockActions,\r\n },\r\n slots,\r\n )\r\n }\r\n },\r\n})\r\n</script>\r\n"],"names":[],"mappings":";;;AAOA,MAAM,UAAU,qBAAqB,MAAM,OAAO,sBAAsB,CAAC;AAEzE,MAAA,YAAe,gBAAgB;AAAA,EAC7B,OAAO;AAAA,IACL,KAAK,EAAE,MAAM,QAAQ,SAAS,OAAO,CAAA,GAAC;AAAA,IACtC,aAAa,EAAE,MAAM,QAAQ,SAAS,OAAO,CAAA,GAAC;AAAA,IAC9C,QAAQ,EAAE,MAAM,SAAS,SAAS,MAAA;AAAA,IAClC,YAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS,MAAM,CAAC,iBAAiB,cAAc;AAAA,IAAA;AAAA,IAEjD,qBAAqB,EAAE,MAAM,SAAS,SAAS,KAAA;AAAA,IAC/C,uBAAuB,EAAE,MAAM,SAAS,SAAS,KAAA;AAAA,IACjD,eAAe,EAAE,MAAM,QAAQ,SAAS,OAAA;AAAA,IACxC,eAAe,EAAE,MAAM,SAAS,SAAS,MAAA;AAAA,IACzC,kBAAkB,EAAE,MAAM,OAAsC,SAAS,OAAA;AAAA,IACzE,gBAAgB,EAAE,MAAM,OAAoC,SAAS,OAAA;AAAA,IACrE,eAAe,EAAE,MAAM,QAAyC,SAAS,OAAA;AAAA,EAAU;AAAA,EAErF,MAAM,OAAO,EAAE,SAAS;AACtB,UAAM,EAAE,gBAAgB;AAExB,WAAO,MAAmC;AAExC,UAAI,MAAM,IAAI,QAAQ;AACpB,YAAI,eAAe,YAAY,QAAQ;AACrC,gBAAM,WAAW,YAAY;AAC7B,cAAI,OAAO,aAAa,YAAY;AAClC,mBAAO,SAAS,KAAK;AAAA,UACvB;AACA,iBAAO,EAAE,UAAU,KAAK;AAAA,QAC1B;AAEA,eAAO,EAAE,UAAU;AAAA,UACjB,KAAK,MAAM;AAAA,UACX,QAAQ,MAAM;AAAA,UACd,YAAY,MAAM;AAAA,UAClB,eAAe,MAAM;AAAA,QAAA,CACtB;AAAA,MACH;AAEA,YAAM,EAAE,aAAa,MAAM;AAG3B,UAAI,eAAe,YAAY,QAAQ,GAAG;AACxC,cAAM,WAAW,YAAY,QAAQ;AACrC,YAAI,OAAO,aAAa,YAAY;AAClC,iBAAO,SAAS,KAAK;AAAA,QACvB;AACA,eAAO,EAAE,UAAU,KAAK;AAAA,MAC1B;AAGA,UAAI,aAAa,WAAW;AAC1B,cAAM,eAAoC,CAAA;AAC1C,eAAO,KAAK,KAAK,EAAE,QAAQ,CAAC,QAAQ;AAClC,cAAI,IAAI,WAAW,SAAS,GAAG;AAC7B,yBAAa,GAAG,IAAI,MAAM,GAAG;AAAA,UAC/B;AAAA,QACF,CAAC;AAED,eAAO;AAAA,UACL;AAAA,UACA;AAAA,YACE,KAAK,MAAM;AAAA,YACX,QAAQ,MAAM;AAAA,YACd,YAAY,MAAM;AAAA,YAClB,gBAAgB,MAAM;AAAA,YACtB,QAAQ,MAAM;AAAA,UAAA;AAAA,UAEhB;AAAA,QAAA;AAAA,MAEJ;AAGA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,UACE,MAAM,MAAM,IAAI,WAAW;AAAA,UAC3B,UAAU,MAAM,IAAI,YAAY;AAAA,UAChC,QAAQ,MAAM;AAAA,UACd,YAAY,MAAM,WAAW,CAAC;AAAA,UAC9B,WAAW,MAAM,WAAW,CAAC;AAAA,UAC7B,qBAAqB,MAAM;AAAA,UAC3B,uBAAuB,MAAM;AAAA,UAC7B,eAAe,MAAM;AAAA,UACrB,eAAe,MAAM;AAAA,UACrB,kBAAkB,MAAM;AAAA,QAAA;AAAA,QAE1B;AAAA,MAAA;AAAA,IAEJ;AAAA,EACF;AACF,CAAC;"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { visit } from "unist-util-visit";
|
|
2
|
+
function rehypeAnimatedPlugin() {
|
|
3
|
+
return (tree) => {
|
|
4
|
+
visit(tree, "element", (node) => {
|
|
5
|
+
if (["p", "h1", "h2", "h3", "h4", "h5", "h6", "li", "strong", "th", "td"].includes(node.tagName) && node.children) {
|
|
6
|
+
const newChildren = [];
|
|
7
|
+
for (const child of node.children) {
|
|
8
|
+
if (child.type === "text") {
|
|
9
|
+
const segmenter = new Intl.Segmenter("zh", { granularity: "word" });
|
|
10
|
+
const segments = segmenter.segment(child.value);
|
|
11
|
+
const words = [...segments].map((segment) => segment.segment).filter(Boolean);
|
|
12
|
+
words.forEach((word) => {
|
|
13
|
+
newChildren.push({
|
|
14
|
+
children: [{ type: "text", value: word }],
|
|
15
|
+
properties: {
|
|
16
|
+
className: "x-md-animated-word"
|
|
17
|
+
},
|
|
18
|
+
tagName: "span",
|
|
19
|
+
type: "element"
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
} else {
|
|
23
|
+
newChildren.push(child);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
node.children = newChildren;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
rehypeAnimatedPlugin
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=x-markdown.es14.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x-markdown.es14.js","sources":["../src/plugins/rehypePlugin.ts"],"sourcesContent":["// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\r\n// SPDX-License-Identifier: MIT\r\nimport type { Element, ElementContent, Root } from 'hast'\r\nimport type { BuildVisitor } from 'unist-util-visit'\r\nimport { visit } from 'unist-util-visit'\r\n\r\nexport function rehypeAnimatedPlugin() {\r\n return (tree: Root) => {\r\n visit(tree, 'element', ((node: Element) => {\r\n if (\r\n ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'strong', 'th', 'td'].includes(node.tagName) &&\r\n node.children\r\n ) {\r\n const newChildren: Array<ElementContent> = []\r\n for (const child of node.children) {\r\n if (child.type === 'text') {\r\n // @ts-expect-error Segmenter is not available in all environments\r\n const segmenter = new Intl.Segmenter('zh', { granularity: 'word' })\r\n const segments = segmenter.segment(child.value)\r\n const words = [...segments].map((segment) => segment.segment).filter(Boolean)\r\n words.forEach((word: string) => {\r\n newChildren.push({\r\n children: [{ type: 'text', value: word }],\r\n properties: {\r\n className: 'x-md-animated-word',\r\n },\r\n tagName: 'span',\r\n type: 'element',\r\n })\r\n })\r\n } else {\r\n newChildren.push(child)\r\n }\r\n }\r\n node.children = newChildren\r\n }\r\n }) as BuildVisitor<Root, 'element'>)\r\n }\r\n}\r\n"],"names":[],"mappings":";AAMO,SAAS,uBAAuB;AACrC,SAAO,CAAC,SAAe;AACrB,UAAM,MAAM,WAAY,CAAC,SAAkB;AACzC,UACE,CAAC,KAAK,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,UAAU,MAAM,IAAI,EAAE,SAAS,KAAK,OAAO,KAC3F,KAAK,UACL;AACA,cAAM,cAAqC,CAAA;AAC3C,mBAAW,SAAS,KAAK,UAAU;AACjC,cAAI,MAAM,SAAS,QAAQ;AAEzB,kBAAM,YAAY,IAAI,KAAK,UAAU,MAAM,EAAE,aAAa,QAAQ;AAClE,kBAAM,WAAW,UAAU,QAAQ,MAAM,KAAK;AAC9C,kBAAM,QAAQ,CAAC,GAAG,QAAQ,EAAE,IAAI,CAAC,YAAY,QAAQ,OAAO,EAAE,OAAO,OAAO;AAC5E,kBAAM,QAAQ,CAAC,SAAiB;AAC9B,0BAAY,KAAK;AAAA,gBACf,UAAU,CAAC,EAAE,MAAM,QAAQ,OAAO,MAAM;AAAA,gBACxC,YAAY;AAAA,kBACV,WAAW;AAAA,gBAAA;AAAA,gBAEb,SAAS;AAAA,gBACT,MAAM;AAAA,cAAA,CACP;AAAA,YACH,CAAC;AAAA,UACH,OAAO;AACL,wBAAY,KAAK,KAAK;AAAA,UACxB;AAAA,QACF;AACA,aAAK,WAAW;AAAA,MAClB;AAAA,IACF,CAAmC;AAAA,EACrC;AACF;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x-markdown.es15.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x-markdown.es16.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import _sfc_main from "./x-markdown.es19.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
import _export_sfc from "./x-markdown.es21.js";
|
|
4
|
+
const CodeBlock = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-8b0fb0b9"]]);
|
|
5
|
+
export {
|
|
6
|
+
CodeBlock as default
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=x-markdown.es17.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x-markdown.es17.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import _sfc_main from "./x-markdown.es22.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
import _export_sfc from "./x-markdown.es21.js";
|
|
4
|
+
const CodeLine = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-97166d5b"]]);
|
|
5
|
+
export {
|
|
6
|
+
CodeLine as default
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=x-markdown.es18.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x-markdown.es18.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { defineComponent, ref, computed, createElementBlock, openBlock, normalizeClass, createCommentVNode, createElementVNode, renderSlot, unref, toDisplayString, Fragment, renderList, normalizeStyle, createBlock, resolveDynamicComponent, createVNode, h } from "vue";
|
|
2
|
+
import { useClipboard } from "./x-markdown.es26.js";
|
|
3
|
+
import SyntaxCodeBlock from "./x-markdown.es27.js";
|
|
4
|
+
const _hoisted_1 = { class: "x-md-code-header" };
|
|
5
|
+
const _hoisted_2 = { class: "x-md-code-header__left" };
|
|
6
|
+
const _hoisted_3 = ["title"];
|
|
7
|
+
const _hoisted_4 = { class: "x-md-code-lang" };
|
|
8
|
+
const _hoisted_5 = { class: "x-md-code-header__right" };
|
|
9
|
+
const _hoisted_6 = ["title", "disabled", "onClick"];
|
|
10
|
+
const _hoisted_7 = {
|
|
11
|
+
key: 0,
|
|
12
|
+
class: "x-md-copy-icon",
|
|
13
|
+
width: "16",
|
|
14
|
+
height: "16",
|
|
15
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
16
|
+
viewBox: "0 0 1024 1024"
|
|
17
|
+
};
|
|
18
|
+
const _hoisted_8 = {
|
|
19
|
+
key: 1,
|
|
20
|
+
class: "x-md-copy-icon",
|
|
21
|
+
width: "16",
|
|
22
|
+
height: "16",
|
|
23
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
24
|
+
viewBox: "0 0 1024 1024"
|
|
25
|
+
};
|
|
26
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
27
|
+
...{
|
|
28
|
+
name: "CodeBlock"
|
|
29
|
+
},
|
|
30
|
+
__name: "index",
|
|
31
|
+
props: {
|
|
32
|
+
code: {},
|
|
33
|
+
language: {},
|
|
34
|
+
lightTheme: { default: "vitesse-light" },
|
|
35
|
+
darkTheme: { default: "vitesse-dark" },
|
|
36
|
+
isDark: { type: Boolean, default: false },
|
|
37
|
+
colorReplacements: {},
|
|
38
|
+
codeMaxHeight: {},
|
|
39
|
+
showCodeBlockHeader: { type: Boolean, default: true },
|
|
40
|
+
enableAnimate: { type: Boolean, default: false },
|
|
41
|
+
codeBlockActions: { default: void 0 },
|
|
42
|
+
stickyCodeBlockHeader: { type: Boolean, default: true }
|
|
43
|
+
},
|
|
44
|
+
setup(__props, { expose: __expose }) {
|
|
45
|
+
const { copy, copied } = useClipboard({ copiedDuring: 2e3 });
|
|
46
|
+
const collapsed = ref(false);
|
|
47
|
+
const syntaxCodeBlockRef = ref(null);
|
|
48
|
+
const toggleCollapse = () => {
|
|
49
|
+
collapsed.value = !collapsed.value;
|
|
50
|
+
};
|
|
51
|
+
const props = __props;
|
|
52
|
+
const code = computed(() => props.code.trim());
|
|
53
|
+
const language = computed(() => props.language || "text");
|
|
54
|
+
const normalizedActions = computed(() => {
|
|
55
|
+
return props.codeBlockActions || [];
|
|
56
|
+
});
|
|
57
|
+
const filteredActions = computed(() => {
|
|
58
|
+
return normalizedActions.value.filter((action) => {
|
|
59
|
+
if (!action.show) return true;
|
|
60
|
+
return action.show(slotProps.value);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
const slotProps = computed(() => ({
|
|
64
|
+
language: language.value,
|
|
65
|
+
code: code.value,
|
|
66
|
+
copy,
|
|
67
|
+
copied: copied.value,
|
|
68
|
+
collapsed: collapsed.value,
|
|
69
|
+
toggleCollapse
|
|
70
|
+
}));
|
|
71
|
+
function renderActionIcon(action) {
|
|
72
|
+
if (!action.icon) return null;
|
|
73
|
+
if (typeof action.icon === "string") {
|
|
74
|
+
return h("span", {
|
|
75
|
+
class: "x-md-action-icon",
|
|
76
|
+
innerHTML: action.icon
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (typeof action.icon === "function") {
|
|
80
|
+
try {
|
|
81
|
+
const result = action.icon(slotProps.value);
|
|
82
|
+
if (result && typeof result === "object" && "__v_isVNode" in result) {
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
} catch {
|
|
86
|
+
}
|
|
87
|
+
return h(action.icon);
|
|
88
|
+
}
|
|
89
|
+
return h(action.icon);
|
|
90
|
+
}
|
|
91
|
+
function handleActionClick(action) {
|
|
92
|
+
if (action.disabled) return;
|
|
93
|
+
action.onClick?.(slotProps.value);
|
|
94
|
+
}
|
|
95
|
+
__expose({
|
|
96
|
+
copy,
|
|
97
|
+
copied,
|
|
98
|
+
collapsed,
|
|
99
|
+
toggleCollapse,
|
|
100
|
+
syntaxCodeBlockRef
|
|
101
|
+
});
|
|
102
|
+
return (_ctx, _cache) => {
|
|
103
|
+
return openBlock(), createElementBlock("div", {
|
|
104
|
+
class: normalizeClass(["x-md-code-block", { "x-md-code-block--dark": props.isDark }])
|
|
105
|
+
}, [
|
|
106
|
+
__props.showCodeBlockHeader ? (openBlock(), createElementBlock("div", {
|
|
107
|
+
key: 0,
|
|
108
|
+
class: normalizeClass(["x-md-code-header-wrapper", [{ "x-md-code-header-wrapper--sticky": props.stickyCodeBlockHeader }, { "x-md-code-header-wrapper--collapsed": collapsed.value }]])
|
|
109
|
+
}, [
|
|
110
|
+
createElementVNode("div", _hoisted_1, [
|
|
111
|
+
renderSlot(_ctx.$slots, "codeHeader", {
|
|
112
|
+
language: language.value,
|
|
113
|
+
code: code.value,
|
|
114
|
+
copy: unref(copy),
|
|
115
|
+
copied: unref(copied),
|
|
116
|
+
collapsed: collapsed.value,
|
|
117
|
+
toggleCollapse
|
|
118
|
+
}, () => [
|
|
119
|
+
createElementVNode("div", _hoisted_2, [
|
|
120
|
+
createElementVNode("button", {
|
|
121
|
+
class: normalizeClass(["x-md-collapse-btn", { "x-md-collapse-btn--collapsed": collapsed.value }]),
|
|
122
|
+
onClick: toggleCollapse,
|
|
123
|
+
title: collapsed.value ? "展开代码" : "折叠代码"
|
|
124
|
+
}, [..._cache[1] || (_cache[1] = [
|
|
125
|
+
createElementVNode("svg", {
|
|
126
|
+
class: "x-md-collapse-icon",
|
|
127
|
+
viewBox: "0 0 24 24",
|
|
128
|
+
width: "14",
|
|
129
|
+
height: "14",
|
|
130
|
+
fill: "none",
|
|
131
|
+
stroke: "currentColor",
|
|
132
|
+
"stroke-width": "2",
|
|
133
|
+
"stroke-linecap": "round",
|
|
134
|
+
"stroke-linejoin": "round"
|
|
135
|
+
}, [
|
|
136
|
+
createElementVNode("polyline", { points: "6 9 12 15 18 9" })
|
|
137
|
+
], -1)
|
|
138
|
+
])], 10, _hoisted_3),
|
|
139
|
+
createElementVNode("span", _hoisted_4, toDisplayString(language.value), 1)
|
|
140
|
+
]),
|
|
141
|
+
createElementVNode("div", _hoisted_5, [
|
|
142
|
+
renderSlot(_ctx.$slots, "codeActions", {
|
|
143
|
+
code: code.value,
|
|
144
|
+
copy: unref(copy),
|
|
145
|
+
copied: unref(copied)
|
|
146
|
+
}, () => [
|
|
147
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(filteredActions.value, (action) => {
|
|
148
|
+
return openBlock(), createElementBlock("button", {
|
|
149
|
+
key: action.key,
|
|
150
|
+
class: normalizeClass(["x-md-action-btn", [action.class, { "x-md-action-btn--disabled": action.disabled }]]),
|
|
151
|
+
style: normalizeStyle(action.style),
|
|
152
|
+
title: action.title,
|
|
153
|
+
disabled: action.disabled,
|
|
154
|
+
onClick: ($event) => handleActionClick(action)
|
|
155
|
+
}, [
|
|
156
|
+
action.icon ? (openBlock(), createBlock(resolveDynamicComponent(renderActionIcon(action)), { key: 0 })) : createCommentVNode("", true)
|
|
157
|
+
], 14, _hoisted_6);
|
|
158
|
+
}), 128)),
|
|
159
|
+
createElementVNode("button", {
|
|
160
|
+
class: normalizeClass(["x-md-copy-btn", { "x-md-copy-btn--copied": unref(copied) }]),
|
|
161
|
+
onClick: _cache[0] || (_cache[0] = ($event) => unref(copy)(code.value))
|
|
162
|
+
}, [
|
|
163
|
+
unref(copied) ? (openBlock(), createElementBlock("svg", _hoisted_7, [..._cache[2] || (_cache[2] = [
|
|
164
|
+
createElementVNode("path", {
|
|
165
|
+
fill: "currentColor",
|
|
166
|
+
d: "M406.656 706.944 195.84 496.256a32 32 0 1 0-45.248 45.248l256 256 512-512a32 32 0 0 0-45.248-45.248L406.592 706.944z"
|
|
167
|
+
}, null, -1)
|
|
168
|
+
])])) : (openBlock(), createElementBlock("svg", _hoisted_8, [..._cache[3] || (_cache[3] = [
|
|
169
|
+
createElementVNode("path", {
|
|
170
|
+
fill: "currentColor",
|
|
171
|
+
d: "M768 832a128 128 0 0 1-128 128H192A128 128 0 0 1 64 832V384a128 128 0 0 1 128-128v64a64 64 0 0 0-64 64v448a64 64 0 0 0 64 64h448a64 64 0 0 0 64-64z"
|
|
172
|
+
}, null, -1),
|
|
173
|
+
createElementVNode("path", {
|
|
174
|
+
fill: "currentColor",
|
|
175
|
+
d: "M384 128a64 64 0 0 0-64 64v448a64 64 0 0 0 64 64h448a64 64 0 0 0 64-64V192a64 64 0 0 0-64-64zm0-64h448a128 128 0 0 1 128 128v448a128 128 0 0 1-128 128H384a128 128 0 0 1-128-128V192A128 128 0 0 1 384 64"
|
|
176
|
+
}, null, -1)
|
|
177
|
+
])]))
|
|
178
|
+
], 2)
|
|
179
|
+
], true)
|
|
180
|
+
])
|
|
181
|
+
], true)
|
|
182
|
+
])
|
|
183
|
+
], 2)) : createCommentVNode("", true),
|
|
184
|
+
createElementVNode("div", {
|
|
185
|
+
class: normalizeClass(["x-md-code-body", { "x-md-code-body--collapsed": collapsed.value }])
|
|
186
|
+
}, [
|
|
187
|
+
createVNode(SyntaxCodeBlock, {
|
|
188
|
+
ref_key: "syntaxCodeBlockRef",
|
|
189
|
+
ref: syntaxCodeBlockRef,
|
|
190
|
+
code: code.value,
|
|
191
|
+
language: language.value,
|
|
192
|
+
"light-theme": props.lightTheme,
|
|
193
|
+
"dark-theme": props.darkTheme,
|
|
194
|
+
"is-dark": props.isDark,
|
|
195
|
+
"color-replacements": props.colorReplacements,
|
|
196
|
+
"code-max-height": props.codeMaxHeight,
|
|
197
|
+
"enable-animate": props.enableAnimate
|
|
198
|
+
}, null, 8, ["code", "language", "light-theme", "dark-theme", "is-dark", "color-replacements", "code-max-height", "enable-animate"])
|
|
199
|
+
], 2)
|
|
200
|
+
], 2);
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
export {
|
|
205
|
+
_sfc_main as default
|
|
206
|
+
};
|
|
207
|
+
//# sourceMappingURL=x-markdown.es19.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x-markdown.es19.js","sources":["../src/components/CodeBlock/index.vue"],"sourcesContent":["<template>\r\n <div class=\"x-md-code-block\" :class=\"{ 'x-md-code-block--dark': props.isDark }\">\r\n <!-- 头部区域:支持完全自定义或默认渲染 -->\r\n <div\r\n v-if=\"showCodeBlockHeader\"\r\n class=\"x-md-code-header-wrapper\"\r\n :class=\"[{'x-md-code-header-wrapper--sticky': props.stickyCodeBlockHeader }, { 'x-md-code-header-wrapper--collapsed': collapsed }]\"\r\n >\r\n <div class=\"x-md-code-header\">\r\n <slot\r\n name=\"codeHeader\"\r\n :language=\"language\"\r\n :code=\"code\"\r\n :copy=\"copy\"\r\n :copied=\"copied\"\r\n :collapsed=\"collapsed\"\r\n :toggleCollapse=\"toggleCollapse\"\r\n >\r\n <div class=\"x-md-code-header__left\">\r\n <button\r\n class=\"x-md-collapse-btn\"\r\n :class=\"{ 'x-md-collapse-btn--collapsed': collapsed }\"\r\n @click=\"toggleCollapse\"\r\n :title=\"collapsed ? '展开代码' : '折叠代码'\"\r\n >\r\n <svg\r\n class=\"x-md-collapse-icon\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"14\"\r\n height=\"14\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n <span class=\"x-md-code-lang\">{{ language }}</span>\r\n </div>\r\n <div class=\"x-md-code-header__right\">\r\n <slot name=\"codeActions\" :code=\"code\" :copy=\"copy\" :copied=\"copied\">\r\n <button\r\n v-for=\"action in filteredActions\"\r\n :key=\"action.key\"\r\n class=\"x-md-action-btn\"\r\n :class=\"[action.class, { 'x-md-action-btn--disabled': action.disabled }]\"\r\n :style=\"action.style\"\r\n :title=\"action.title\"\r\n :disabled=\"action.disabled\"\r\n @click=\"handleActionClick(action)\"\r\n >\r\n <component :is=\"renderActionIcon(action)\" v-if=\"action.icon\" />\r\n </button>\r\n <button class=\"x-md-copy-btn\" :class=\"{ 'x-md-copy-btn--copied': copied }\" @click=\"copy(code)\">\r\n <svg\r\n v-if=\"copied\"\r\n class=\"x-md-copy-icon\"\r\n width=\"16\"\r\n height=\"16\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 1024 1024\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M406.656 706.944 195.84 496.256a32 32 0 1 0-45.248 45.248l256 256 512-512a32 32 0 0 0-45.248-45.248L406.592 706.944z\"\r\n />\r\n </svg>\r\n <svg\r\n v-else\r\n class=\"x-md-copy-icon\"\r\n width=\"16\"\r\n height=\"16\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 1024 1024\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M768 832a128 128 0 0 1-128 128H192A128 128 0 0 1 64 832V384a128 128 0 0 1 128-128v64a64 64 0 0 0-64 64v448a64 64 0 0 0 64 64h448a64 64 0 0 0 64-64z\"\r\n />\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M384 128a64 64 0 0 0-64 64v448a64 64 0 0 0 64 64h448a64 64 0 0 0 64-64V192a64 64 0 0 0-64-64zm0-64h448a128 128 0 0 1 128 128v448a128 128 0 0 1-128 128H384a128 128 0 0 1-128-128V192A128 128 0 0 1 384 64\"\r\n />\r\n </svg>\r\n </button>\r\n </slot>\r\n </div>\r\n </slot>\r\n </div>\r\n </div>\r\n <div class=\"x-md-code-body\" :class=\"{ 'x-md-code-body--collapsed': collapsed }\">\r\n <SyntaxCodeBlock\r\n ref=\"syntaxCodeBlockRef\"\r\n :code=\"code\"\r\n :language=\"language\"\r\n :light-theme=\"props.lightTheme\"\r\n :dark-theme=\"props.darkTheme\"\r\n :is-dark=\"props.isDark\"\r\n :color-replacements=\"props.colorReplacements\"\r\n :code-max-height=\"props.codeMaxHeight\"\r\n :enable-animate=\"props.enableAnimate\"\r\n />\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, h, type VNode } from 'vue'\r\nimport { useClipboard } from '@vueuse/core'\r\nimport type { CodeBlockProps, CodeBlockAction, CodeBlockSlotProps } from './types'\r\nimport SyntaxCodeBlock from './SyntaxCodeBlock.vue'\r\n\r\ndefineOptions({\r\n name: 'CodeBlock',\r\n})\r\n\r\nconst { copy, copied } = useClipboard({ copiedDuring: 2000 })\r\n\r\nconst collapsed = ref(false)\r\n\r\nconst syntaxCodeBlockRef = ref<InstanceType<typeof SyntaxCodeBlock> | null>(null)\r\n\r\nconst toggleCollapse = () => {\r\n collapsed.value = !collapsed.value\r\n}\r\n\r\nconst props = withDefaults(defineProps<CodeBlockProps>(), {\r\n lightTheme: 'vitesse-light',\r\n darkTheme: 'vitesse-dark',\r\n isDark: false,\r\n showCodeBlockHeader: true,\r\n enableAnimate: false,\r\n codeBlockActions: undefined,\r\n stickyCodeBlockHeader: true,\r\n})\r\n\r\nconst code = computed(() => props.code.trim())\r\n\r\nconst language = computed(() => props.language || 'text')\r\n\r\nconst normalizedActions = computed<CodeBlockAction[]>(() => {\r\n return props.codeBlockActions || []\r\n})\r\n\r\nconst filteredActions = computed<CodeBlockAction[]>(() => {\r\n return normalizedActions.value.filter((action) => {\r\n if (!action.show) return true\r\n return action.show(slotProps.value)\r\n })\r\n})\r\n\r\nconst slotProps = computed<CodeBlockSlotProps>(() => ({\r\n language: language.value,\r\n code: code.value,\r\n copy,\r\n copied: copied.value,\r\n collapsed: collapsed.value,\r\n toggleCollapse,\r\n}))\r\n\r\nfunction renderActionIcon(action: CodeBlockAction): VNode | null {\r\n if (!action.icon) return null\r\n\r\n if (typeof action.icon === 'string') {\r\n return h('span', {\r\n class: 'x-md-action-icon',\r\n innerHTML: action.icon,\r\n })\r\n }\r\n\r\n if (typeof action.icon === 'function') {\r\n try {\r\n const result = (action.icon as (props: CodeBlockSlotProps) => VNode)(slotProps.value)\r\n if (result && typeof result === 'object' && '__v_isVNode' in result) {\r\n return result\r\n }\r\n } catch {\r\n }\r\n return h(action.icon as any)\r\n }\r\n\r\n return h(action.icon as any)\r\n}\r\n\r\nfunction handleActionClick(action: CodeBlockAction) {\r\n if (action.disabled) return\r\n action.onClick?.(slotProps.value)\r\n}\r\n\r\ndefineExpose({\r\n copy,\r\n copied,\r\n collapsed,\r\n toggleCollapse,\r\n syntaxCodeBlockRef,\r\n})\r\n</script>\r\n\r\n<style scoped>\r\n.x-md-code-block {\r\n border-radius: 8px;\r\n overflow: hidden;\r\n font-size: 0;\r\n background: rgba(0, 0, 0, 0.03);\r\n}\r\n\r\n.x-md-code-block.x-md-code-block--dark {\r\n background: rgba(255, 255, 255, 0.13);\r\n}\r\n\r\n.x-md-code-header-wrapper--sticky {\r\n background: #fff;\r\n position: sticky;\r\n top: 0;\r\n}\r\n\r\n.x-md-code-block.x-md-code-block--dark .x-md-code-header-wrapper--sticky {\r\n background: #1a1a1a;\r\n}\r\n\r\n.x-md-code-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 8px 16px;\r\n background: rgba(0, 0, 0, 0.05);\r\n color: #333;\r\n}\r\n\r\n.x-md-code-block .x-md-code-header-wrapper--sticky .x-md-code-header{\r\n background: rgba(235, 235, 235);\r\n border-radius: 8px 8px 0 0;\r\n}\r\n\r\n.x-md-code-block:has(.x-md-code-header-wrapper--sticky) {\r\n overflow: visible;\r\n}\r\n\r\n.x-md-code-block.x-md-code-block--dark .x-md-code-header {\r\n background: rgba(0, 0, 0, 0.25);\r\n color: #fff;\r\n}\r\n\r\n.x-md-code-block.x-md-code-block--dark .x-md-code-header-wrapper--sticky .x-md-code-header {\r\n background: rgba(44, 44, 44);\r\n}\r\n\r\n.x-md-code-block .x-md-code-header-wrapper--collapsed .x-md-code-header {\r\n border-radius: 8px;\r\n}\r\n\r\n.x-md-code-header__left,\r\n.x-md-code-header__right {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n}\r\n\r\n.x-md-code-lang {\r\n font-size: 12px;\r\n font-weight: 500;\r\n opacity: 0.6;\r\n text-transform: lowercase;\r\n}\r\n\r\n.x-md-copy-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 28px;\r\n height: 28px;\r\n padding: 0;\r\n border: none;\r\n border-radius: 4px;\r\n background: transparent;\r\n color: inherit;\r\n cursor: pointer;\r\n opacity: 0.7;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.x-md-copy-btn:hover {\r\n opacity: 1;\r\n background: rgba(0, 0, 0, 0.08);\r\n}\r\n\r\n.x-md-code-block.x-md-code-block--dark .x-md-copy-btn:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n}\r\n\r\n.x-md-copy-btn.x-md-copy-btn--copied {\r\n opacity: 1;\r\n color: #22c55e;\r\n}\r\n\r\n.x-md-copy-icon {\r\n flex-shrink: 0;\r\n}\r\n\r\n.x-md-action-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 28px;\r\n height: 28px;\r\n padding: 0;\r\n border: none;\r\n border-radius: 4px;\r\n background: transparent;\r\n color: inherit;\r\n cursor: pointer;\r\n opacity: 0.7;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.x-md-action-btn:hover {\r\n opacity: 1;\r\n background: rgba(0, 0, 0, 0.08);\r\n}\r\n\r\n.x-md-code-block.x-md-code-block--dark .x-md-action-btn:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n}\r\n\r\n.x-md-action-btn.x-md-action-btn--disabled {\r\n opacity: 0.3;\r\n cursor: not-allowed;\r\n pointer-events: none;\r\n}\r\n\r\n.x-md-action-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.x-md-action-icon :deep(svg) {\r\n width: 16px;\r\n height: 16px;\r\n flex-shrink: 0;\r\n}\r\n\r\n.x-md-collapse-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 20px;\r\n height: 20px;\r\n padding: 0;\r\n border: none;\r\n border-radius: 4px;\r\n background: transparent;\r\n color: inherit;\r\n cursor: pointer;\r\n opacity: 0.5;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.x-md-collapse-btn:hover {\r\n opacity: 1;\r\n background: rgba(0, 0, 0, 0.08);\r\n}\r\n\r\n.x-md-code-block.x-md-code-block--dark .x-md-collapse-btn:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n}\r\n\r\n.x-md-collapse-icon {\r\n transition: transform 0.2s ease;\r\n}\r\n\r\n.x-md-collapse-btn--collapsed .x-md-collapse-icon {\r\n transform: rotate(-90deg);\r\n}\r\n\r\n.x-md-code-body {\r\n overflow: hidden;\r\n transition:\r\n max-height 0.3s ease,\r\n opacity 0.2s ease;\r\n}\r\n\r\n.x-md-code-body--collapsed {\r\n max-height: 0 !important;\r\n opacity: 0;\r\n}\r\n</style>"],"names":["_createElementBlock","_normalizeClass","_createElementVNode","_renderSlot","_unref","_toDisplayString","_Fragment","_renderList","_normalizeStyle","_createBlock","_resolveDynamicComponent","_openBlock","_createVNode"],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { defineComponent, toRefs, shallowRef, watch } from "vue";
|
|
2
|
+
import { render } from "./x-markdown.es4.js";
|
|
3
|
+
import { useMarkdownProcessor } from "./x-markdown.es5.js";
|
|
4
|
+
const sharedProps = {
|
|
5
|
+
markdown: {
|
|
6
|
+
type: String,
|
|
7
|
+
default: ""
|
|
8
|
+
},
|
|
9
|
+
customAttrs: {
|
|
10
|
+
type: Object,
|
|
11
|
+
default: () => ({})
|
|
12
|
+
},
|
|
13
|
+
remarkPlugins: {
|
|
14
|
+
type: Array,
|
|
15
|
+
default: () => []
|
|
16
|
+
},
|
|
17
|
+
rehypePlugins: {
|
|
18
|
+
type: Array,
|
|
19
|
+
default: () => []
|
|
20
|
+
},
|
|
21
|
+
rehypeOptions: {
|
|
22
|
+
type: Object,
|
|
23
|
+
default: () => ({})
|
|
24
|
+
},
|
|
25
|
+
sanitize: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: false
|
|
28
|
+
},
|
|
29
|
+
sanitizeOptions: {
|
|
30
|
+
type: Object,
|
|
31
|
+
default: () => ({})
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const vueMarkdownImpl = defineComponent({
|
|
35
|
+
name: "VueMarkdown",
|
|
36
|
+
props: sharedProps,
|
|
37
|
+
setup(props, { slots, attrs }) {
|
|
38
|
+
const { markdown, remarkPlugins, rehypePlugins, rehypeOptions, sanitize, sanitizeOptions, customAttrs } = toRefs(props);
|
|
39
|
+
const { processor } = useMarkdownProcessor({
|
|
40
|
+
remarkPlugins,
|
|
41
|
+
rehypePlugins,
|
|
42
|
+
rehypeOptions,
|
|
43
|
+
sanitize,
|
|
44
|
+
sanitizeOptions
|
|
45
|
+
});
|
|
46
|
+
return () => {
|
|
47
|
+
const mdast = processor.value.parse(markdown.value);
|
|
48
|
+
const hast = processor.value.runSync(mdast);
|
|
49
|
+
return render(hast, attrs, slots, customAttrs.value);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
const vueMarkdownAsyncImpl = defineComponent({
|
|
54
|
+
name: "VueMarkdownAsync",
|
|
55
|
+
props: sharedProps,
|
|
56
|
+
async setup(props, { slots, attrs }) {
|
|
57
|
+
const { markdown, remarkPlugins, rehypePlugins, rehypeOptions, sanitize, sanitizeOptions, customAttrs } = toRefs(props);
|
|
58
|
+
const { processor } = useMarkdownProcessor({
|
|
59
|
+
remarkPlugins,
|
|
60
|
+
rehypePlugins,
|
|
61
|
+
rehypeOptions,
|
|
62
|
+
sanitize,
|
|
63
|
+
sanitizeOptions
|
|
64
|
+
});
|
|
65
|
+
const hast = shallowRef(null);
|
|
66
|
+
const process = async () => {
|
|
67
|
+
const mdast = processor.value.parse(markdown.value);
|
|
68
|
+
hast.value = await processor.value.run(mdast);
|
|
69
|
+
};
|
|
70
|
+
watch(() => [markdown.value, processor.value], process, { flush: "sync" });
|
|
71
|
+
await process();
|
|
72
|
+
return () => {
|
|
73
|
+
return hast.value ? render(hast.value, attrs, slots, customAttrs.value) : null;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
const VueMarkdown = vueMarkdownImpl;
|
|
78
|
+
const VueMarkdownAsync = vueMarkdownAsyncImpl;
|
|
79
|
+
export {
|
|
80
|
+
VueMarkdown,
|
|
81
|
+
VueMarkdownAsync
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=x-markdown.es2.js.map
|