问题背景:
我在vue2中使用markdown-it渲染markdown语言,发现有些数学表达式渲染不出来(如下图),网上看到的是用markdown-it-katex可以渲染出来,查了下markdown-it-katex的官方文档,发现这些相似的markdown-katex依赖支持的都是用 $
或者 $$
包围起来的数学表达式,但我的markdown里数学表达式是用双斜杆包围起来的,如 \\(...\\)
和 \\[...\\]
。找不到适合我的依赖,于是只能自己改规则。
解决
- 下载markdown-it-katex
npm install markdown-it-katex
- 页面内引用
import katex from "katex";
import "katex/dist/katex.min.css";
import markdownit from "markdown-it";
- 添加markdown-it-katex和规则到markdown-it (规则部分的代码可以直接复制使用)
const md = markdownit()
// 添加规则和katex
// Define the katexInline and katexBlock rules
const katexInline = (state, silent) => {
const start = state.pos;
if (state.src[start] !== "\\" || state.src[start + 1] !== "(") {
return false;
}
const match = state.src.slice(start).match(/^\\\((.+?)\\\)/);
if (!match) return false;
const token = state.push("math_inline", "math", 0);
token.content = match[1];
state.pos += match[0].length;
return true;
};
const katexBlock = (state, start, end, silent) => {
const pos = state.bMarks[start] + state.tShift[start];
const max = state.eMarks[start];
if (pos + 1 >= max || state.src.slice(pos, pos + 2) !== "\\[") {
return false;
}
let endPos = pos + 2;
while (endPos < max && state.src.slice(endPos, endPos + 2) !== "\\]") {
endPos++;
}
if (state.src.slice(endPos, endPos + 2) !== "\\]") {
return false;
}
if (silent) {
return true;
}
const token = state.push("math_block", "math", 0);
token.content = state.src.slice(pos + 2, endPos);
token.map = [start, start + 1];
state.line = start + 1;
return true;
};
// Extend the markdown-it instance
md.inline.ruler.before("escape", "math_inline", katexInline);
md.block.ruler.before("blockquote", "math_block", katexBlock, {
alt: ["paragraph", "reference", "blockquote", "list"],
});
// Add rendering rules
md.renderer.rules.math_inline = (tokens, idx) => {
return katex.renderToString(tokens[idx].content);
};
md.renderer.rules.math_block = (tokens, idx) => {
return `<div class="katex-block">${katex.renderToString(
tokens[idx].content,
{
displayMode: true,
}
)}</div>`;
};