Luxx/dashboard/src/utils/markdown.js

74 lines
1.7 KiB
JavaScript

import { marked } from 'marked'
import { markedHighlight } from 'marked-highlight'
import katex from 'katex'
import hljs from 'highlight.js'
function renderMath(text, displayMode) {
try {
return katex.renderToString(text, {
displayMode,
throwOnError: false,
strict: false,
})
} catch {
return text
}
}
// marked extension for inline math $...$
const mathExtension = {
name: 'math',
level: 'inline',
start(src) {
const idx = src.search(/(?<!\$)\$(?!\$)/)
return idx === -1 ? undefined : idx
},
tokenizer(src) {
const match = src.match(/^\$\s*([^\$\n]+?)\s*\$/)
if (match) {
return { type: 'math', raw: match[0], text: match[1].trim(), displayMode: false }
}
},
renderer(token) {
return renderMath(token.text, token.displayMode)
},
}
// marked extension for block math $$...$$
const blockMathExtension = {
name: 'blockMath',
level: 'block',
start(src) {
const idx = src.indexOf('$$')
return idx === -1 ? undefined : idx
},
tokenizer(src) {
const match = src.match(/^\$\$\s*([\s\S]+?)\s*\$\$\n?/)
if (match) {
return { type: 'blockMath', raw: match[0], text: match[1].trim() }
}
},
renderer(token) {
return `<div class="math-block">${renderMath(token.text, true)}</div>`
},
}
// 配置 marked 支持代码高亮
marked.use(markedHighlight({
langPrefix: 'hljs language-',
highlight(code, lang) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext'
return hljs.highlight(code, { language }).value
}
}))
marked.use({
gfm: true,
breaks: true,
extensions: [blockMathExtension, mathExtension]
})
export function renderMarkdown(text) {
return marked.parse(text)
}