feat: code wrapper
This commit is contained in:
parent
e48c4dc2e9
commit
bfce358f9e
|
|
@ -8,6 +8,7 @@ import { cssVariables } from './theme/config/shiki'
|
|||
// import { transformerMetaWordHighlight, transformerNotationWordHighlight } from '@shikijs/transformers'
|
||||
import { siteConfig } from './theme/config/site'
|
||||
import ComponentPreviewPlugin from './theme/plugins/previewer'
|
||||
import CodeWrapperPlugin from './theme/plugins/codewrapper'
|
||||
|
||||
// https://vitepress.dev/reference/site-config
|
||||
export default defineConfig({
|
||||
|
|
@ -60,6 +61,7 @@ export default defineConfig({
|
|||
],
|
||||
config(md) {
|
||||
md.use(ComponentPreviewPlugin)
|
||||
md.use(CodeWrapperPlugin)
|
||||
},
|
||||
},
|
||||
rewrites: {
|
||||
|
|
|
|||
37
apps/www/.vitepress/theme/components/CodeWrapper.ts
Normal file
37
apps/www/.vitepress/theme/components/CodeWrapper.ts
Normal 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?.()
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
export { default as CodeWrapper } from './CodeWrapper'
|
||||
export { default as ComponentPreview } from './ComponentPreview.vue'
|
||||
export { default as TabPreview } from './TabPreview.vue'
|
||||
export { default as TabMarkdown } from './TabMarkdown.vue'
|
||||
|
|
|
|||
19
apps/www/.vitepress/theme/plugins/codewrapper.ts
Normal file
19
apps/www/.vitepress/theme/plugins/codewrapper.ts
Normal 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)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user