import { marked } from 'marked' import hljs from 'highlight.js' import 'highlight.js/lib/common' // 额外导入 common 包不包含的语言 import 'highlight.js/lib/languages/bash' import 'highlight.js/lib/languages/go' import 'highlight.js/styles/github-dark.css' import 'highlight.js/styles/github.css' // 语言别名映射(sh -> bash 等) const languageAliases: Record = { 'sh': 'bash', 'shell': 'bash', 'zsh': 'bash', 'ksh': 'bash', 'ts': 'typescript', 'js': 'javascript', 'py': 'python', 'rb': 'ruby', 'yml': 'yaml', 'md': 'markdown' } let mermaidInstance: typeof import('mermaid').default | null = null async function loadMermaid() { if (mermaidInstance) return mermaidInstance try { const mermaid = await import('mermaid') mermaid.default.initialize({ startOnLoad: false, theme: 'default', securityLevel: 'loose' }) mermaidInstance = mermaid.default return mermaidInstance } catch { return null } } const renderer = new marked.Renderer() renderer.code = function(token: any) { if (token.lang === 'mermaid') { return `
${token.text}
` } // 获取语言,支持别名 let lang = token.lang || 'plaintext' lang = languageAliases[lang] || lang // 检查语言是否支持 if (!hljs.getLanguage(lang)) { lang = 'plaintext' } const highlighted = hljs.highlight(token.text, { language: lang }).value return `
${highlighted}
` } renderer.heading = function(token: any) { const raw = token.raw || '' const depth = token.depth || 1 const text = token.text || '' const id = raw .toLowerCase() .replace(/[^\u4e00-\u9fa5a-z0-9\s-]/g, '') .trim() .replace(/\s+/g, '-') .replace(/-+/g, '-') .replace(/^-+|-+$/g, '') || `heading-${Math.random().toString(36).slice(2, 11)}` return ` ${text} ` } // 判断是否为本地文件链接(相对路径或本地绝对路径) const isLocalFileLink = (href: string): boolean => { if (!href) return false // 排除 http/https/ftp/mailto 等外部链接 if (/^(https?|ftp|mailto|tel|data):/i.test(href)) return false // 排除锚点链接 if (href.startsWith('#')) return false // 相对路径或本地路径(如 ./file.md, ../file.md, /path/to/file, C:\path\file) return true } // 自定义链接渲染器 - 支持本地文件链接 renderer.link = function(token: any) { const href = token.href || '' // 解析链接文本中的内联元素(如加粗、斜体等) const text = this.parser.parseInline(token.tokens) || token.text || '' const title = token.title || '' const titleAttr = title ? ` title="${title}"` : '' // 锚点链接 - 保持原样,页面内跳转 if (href.startsWith('#')) { return `${text}` } // 判断是否为本地文件链接 if (isLocalFileLink(href)) { return `${text}` } // 外部链接使用默认行为 return `${text}` } marked.use({ renderer, breaks: true, gfm: true }) export { marked } export async function renderMermaidDiagrams() { const mermaid = await loadMermaid() if (mermaid) { await mermaid.run() } }