feat: code wrapper

This commit is contained in:
zernonia 2024-03-14 13:35:02 +08:00
parent e48c4dc2e9
commit bfce358f9e
4 changed files with 59 additions and 0 deletions

View File

@ -8,6 +8,7 @@ import { cssVariables } from './theme/config/shiki'
// import { transformerMetaWordHighlight, transformerNotationWordHighlight } from '@shikijs/transformers' // import { transformerMetaWordHighlight, transformerNotationWordHighlight } from '@shikijs/transformers'
import { siteConfig } from './theme/config/site' import { siteConfig } from './theme/config/site'
import ComponentPreviewPlugin from './theme/plugins/previewer' import ComponentPreviewPlugin from './theme/plugins/previewer'
import CodeWrapperPlugin from './theme/plugins/codewrapper'
// https://vitepress.dev/reference/site-config // https://vitepress.dev/reference/site-config
export default defineConfig({ export default defineConfig({
@ -60,6 +61,7 @@ export default defineConfig({
], ],
config(md) { config(md) {
md.use(ComponentPreviewPlugin) md.use(ComponentPreviewPlugin)
md.use(CodeWrapperPlugin)
}, },
}, },
rewrites: { rewrites: {

View File

@ -0,0 +1,37 @@
import { type VNode, cloneVNode, defineComponent } from 'vue'
import { useConfigStore } from '@/stores/config'
export default defineComponent(
(props, { slots }) => {
const { codeConfig } = useConfigStore()
return () => {
const clonedVNode = slots.default?.()?.[0] ? cloneVNode(slots.default?.()?.[0]) : undefined
// @ts-expect-error cloneVNode
const preVNode = [...clonedVNode?.children].find((node: VNode) => node.type === 'pre') as VNode
// @ts-expect-error cloneVNode
const codeVNode = preVNode.children?.at(0) as VNode
if (codeVNode) {
// @ts-expect-error cloneVNode
[...codeVNode.children]
.filter((node: VNode) => node.type === 'span')
.forEach((node: VNode) => {
if (node.children) {
// @ts-expect-error cloneVNode
[...node.children].forEach((childNode: VNode) => {
if (typeof childNode.children === 'string') {
childNode.children = childNode.children.replaceAll('@/components', codeConfig.value.componentsPath)
childNode.children = childNode.children.replaceAll('@/libs', codeConfig.value.utilsPath)
}
})
}
})
return clonedVNode
}
else {
return slots.default?.()
}
}
},
)

View File

@ -1,3 +1,4 @@
export { default as CodeWrapper } from './CodeWrapper'
export { default as ComponentPreview } from './ComponentPreview.vue' export { default as ComponentPreview } from './ComponentPreview.vue'
export { default as TabPreview } from './TabPreview.vue' export { default as TabPreview } from './TabPreview.vue'
export { default as TabMarkdown } from './TabMarkdown.vue' export { default as TabMarkdown } from './TabMarkdown.vue'

View File

@ -0,0 +1,19 @@
import type { MarkdownRenderer } from 'vitepress'
export default function (md: MarkdownRenderer) {
const defaultFenceRenderer = md.renderer.rules.fence
if (!defaultFenceRenderer)
return
md.renderer.rules.fence = function (tokens, idx, options, env, self) {
// Check if this is a code block
const token = tokens[idx]
if (token && token.tag === 'code' && token.info) {
// Wrap the code block in CodeWrapper
return `<CodeWrapper>${defaultFenceRenderer(tokens, idx, options, env, self)}</CodeWrapper>`
}
// If not a code block, return the default rendering
return defaultFenceRenderer(tokens, idx, options, env, self)
}
}