You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
2.0 KiB
60 lines
2.0 KiB
import MarkdownIt from 'markdown-it'
|
|
import DOMPurify from 'isomorphic-dompurify'
|
|
import { stripFrontMatter } from './markdown-front-matter'
|
|
|
|
const md = new MarkdownIt({
|
|
html: false,
|
|
linkify: true,
|
|
typographer: false,
|
|
breaks: true,
|
|
// // 开启代码块语言识别
|
|
// highlight: function (str: string, lang: string) {
|
|
// // 处理语言标签(如果没有指定语言,默认 text)
|
|
// const language = lang || 'text'
|
|
// // 生成带语言标识 + 复制按钮的代码块外壳
|
|
// return `
|
|
// <div class="code-block-wrapper">
|
|
// <div class="code-header">
|
|
// <span class="code-lang">${language}</span>
|
|
// <button class="copy-btn" onclick="copyCode(this)">复制</button>
|
|
// </div>
|
|
// <pre><code class="language-${language}">${md.utils.escapeHtml(str)}</code></pre>
|
|
// </div>
|
|
// `
|
|
// },
|
|
})
|
|
|
|
// /** 全局复制代码函数(挂载到 window,确保页面可调用) */
|
|
// declare global {
|
|
// interface Window {
|
|
// copyCode: (btn: HTMLButtonElement) => void
|
|
// }
|
|
// }
|
|
|
|
// // 只在客户端环境注册复制函数
|
|
// if (typeof window !== 'undefined') {
|
|
// window.copyCode = function (btn: HTMLButtonElement) {
|
|
// const codeBlock = btn.closest('.code-block-wrapper')!.querySelector('code')!
|
|
// const text = codeBlock.textContent || ''
|
|
|
|
// navigator.clipboard.writeText(text).then(() => {
|
|
// const originalText = btn.textContent
|
|
// btn.textContent = '已复制'
|
|
// btn.style.backgroundColor = '#10b981'
|
|
|
|
// // 2秒后恢复按钮文字
|
|
// setTimeout(() => {
|
|
// btn.textContent = originalText
|
|
// btn.style.backgroundColor = ''
|
|
// }, 2000)
|
|
// })
|
|
// }
|
|
// }
|
|
|
|
/** 将 Markdown 转为可安全用于 `v-html` 的 HTML(禁用源码中的原始 HTML)。 */
|
|
export function renderSafeMarkdown(src: string): string {
|
|
if (!src.trim()) {
|
|
return ''
|
|
}
|
|
return DOMPurify.sanitize(md.render(stripFrontMatter(src)), { USE_PROFILES: { html: true } })
|
|
}
|
|
|