Files
Claude-Code-Workflow/docs/.vitepress/theme/markdownTransform.ts
catlog22 8ceae6d6fd Add Chinese documentation for custom skills development and reference guide
- Created a new document for custom skills development (`custom.md`) detailing the structure, creation, implementation, and best practices for developing custom CCW skills.
- Added an index document (`index.md`) summarizing all built-in skills, their categories, and usage examples.
- Introduced a reference guide (`reference.md`) providing a quick reference for all 33 built-in CCW skills, including triggers and purposes.
2026-03-01 13:08:12 +08:00

96 lines
2.7 KiB
TypeScript

import type { MarkdownTransformContext } from 'vitepress'
// Multi-line demo block: :::demo Name #file ...code... :::
const demoBlockRE = /:::\s*demo\s+([^\n]+)\n([\s\S]*?)\n:::/g
// Single-line demo block: :::demo Name #file :::
const demoBlockSingleRE = /:::\s*demo\s+(\S+)\s*(#\S+)?\s*:::/g
export interface DemoBlockMeta {
name: string
file?: string
code?: string
height?: string
expandable?: boolean
showCode?: boolean
title?: string
}
export function transformDemoBlocks(
code: string,
ctx: MarkdownTransformContext
): string {
// First handle multi-line demo blocks with inline code
let result = code.replace(demoBlockRE, (match, headerLine, codeContent) => {
const meta = parseDemoHeader(headerLine)
const demoId = `demo-${ctx.path.replace(/[^a-z0-9]/gi, '-')}-${meta.name}-${Date.now().toString(36)}`
const props = [
`id="${demoId}"`,
`name="${meta.name}"`,
meta.file ? `file="${meta.file}"` : '',
meta.height ? `height="${meta.height}"` : '',
meta.expandable === false ? ':expandable="false"' : '',
meta.showCode === false ? ':show-code="false"' : '',
meta.title ? `title="${meta.title}"` : ''
].filter(Boolean).join(' ')
// Return a simple comment placeholder - the inline code will be ignored
// This avoids Vue parsing issues with JSX in markdown
return `<DemoContainer ${props} />`
})
// Then handle single-line demo blocks (file references only)
result = result.replace(demoBlockSingleRE, (match, name, fileRef) => {
const demoId = `demo-${ctx.path.replace(/[^a-z0-9]/gi, '-')}-${name}-${Date.now().toString(36)}`
const file = fileRef ? fileRef.slice(1) : undefined
const props = [
`id="${demoId}"`,
`name="${name}"`,
file ? `file="${file}"` : '',
':expandable="true"',
':show-code="true"'
].filter(Boolean).join(' ')
return `<DemoContainer ${props} />`
})
return result
}
function parseDemoHeader(headerLine: string): DemoBlockMeta {
const parts = headerLine.trim().split(/\s+/)
const name = parts[0] || ''
const file = parts.find(p => p.startsWith('#'))?.slice(1)
// Extract props from remaining parts
const props: Record<string, string> = {}
for (const part of parts.slice(1)) {
if (part.includes(':')) {
const [key, value] = part.split(':', 2)
props[key] = value
}
}
return {
name,
file,
height: props.height,
expandable: props.expandable !== 'false',
showCode: props.showCode !== 'false',
title: props.title
}
}
// VitePress markdown configuration hook
export function markdownTransformSetup() {
return {
transform: (code: string, ctx: MarkdownTransformContext) => {
return transformDemoBlocks(code, ctx)
}
}
}