vue3 在渲染md中的数学公式
常规的md转数学公式插件无法解决此问题
问题: 在渲染过程中 \t 被转义 导致渲染出错

**方案为:将\t 转义为\t **
依赖的插件及版本
"katex": "^0.16.15",
"markdown-it": "^14.1.0",
"markdown-it-katex": "^2.0.3",
"markdown-it-latex": "^0.2.0",
"markdown-it-mathjax": "^2.0.0",
"markdown-it-multimd-table": "^4.2.3",
"markdown-it-texmath": "^1.0.0",
"mathjax": "^3.2.2",
"vue-markdown": "^2.2.4",
utils 文件
mathjax.js
window.MathJax = {
tex: {
inlineMath: [
["$", "$"],
["\\(", "\\)"],
["\(", "\)"],
["\\[", "\\]"],
], // 行内公式选择符
displayMath: [
["$$", "$$"],
["\\[", "\\]"],
['?', '?'],
], // 段内公式选择符
},
startup: {
ready() {
MathJax.startup.defaultReady();
},
},
};
引入代码
在html中引入
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
vue文件中
import MarkdownIt from 'markdown-it';
import markdownItMathjax from 'markdown-it-mathjax';
import mk from 'markdown-it-katex';
import mkl from 'markdown-it-latex';
import 'katex/dist/katex.min.css';
import 'github-markdown-css';
如果是vue3+ts项目 则需要在声明文件,定义全局变量,要不然会有提示信息
// 声明文件,定义全局变量
/* eslint-disable */
declare interface Window {
nextLoading: boolean;
MathJax: any; // 这里先使用any类型占位,如果知道MathJax确切结构可替换为更准确类型
}
举例

方法调用
const preprocessLaTeX = (content: string) => {
if (typeof content !== 'string') return content;
return content
.replace(/\\\[(.*?)\\\]/gs, (_, equation) => `$$${equation}$$`)
.replace(/\\\((.*?)\\\)/gs, (_, equation) => `$$${equation}$$`)
.replace(/(^|[^\\])\$(.+?)\$/gs, (_, prefix, equation) => `${prefix}$${equation}$`)
.replace(/\t/g, '\\t');
};
const md = new MarkdownIt({
html: true,
linkify: true,
typographer: true,
});
md.use(markdownItMathjax);
md.use(mk, {
throwOnError: false,
});
md.use(mkl);
const renderMd = (text: string) => {
window.MathJax.startup.defaultReady();
text = preprocessLaTeX(text);
return md.render(text);
};
renderMd中传入的是需要 渲染到md中的文本

注意事项
就不需要在main.ts中引入
方案二
需要的依赖
package.json
"katex": "^0.16.15",
"markdown-it": "^14.1.0",
"markdown-it-katex": "^2.0.3",
"markdown-it-latex": "^0.2.0",
"markdown-it-mathjax": "^2.0.0",
"markdown-it-multimd-table": "^4.2.3",
"markdown-it-texmath": "^1.0.0",
"mathjax": "^3.2.2",

index.html
<script>
window.MathJax = {
tex: {
inlineMath: [
["$", "$"],
["\\(", "\\)"],
["\(", "\)"],
["\\[", "\\]"],
], // 行内公式选择符
displayMath: [
["$$", "$$"],
["\\[", "\\]"],
['?', '?'],
], // 段内公式选择符
},
startup: {
ready() {
MathJax.startup.defaultReady();
},
},
};
</script>
<script id="MathJax-script" async src="/utils/tex-svg.js"></script>
public/utils/tex-svg.js
tex-svg.js
src/types/global.d.ts
// 声明文件,定义全局变量
/* eslint-disable */
declare interface Window {
nextLoading: boolean;
MathJax: any; // 这里先使用any类型占位,如果知道MathJax确切结构可替换为更准确类型
}
页面中引入
import MarkdownIt from 'markdown-it';
import markdownItMultimdTable from 'markdown-it-multimd-table';
import markdownItMathjax from 'markdown-it-mathjax';
import mk from 'markdown-it-katex';
import mkl from 'markdown-it-latex';
import 'katex/dist/katex.min.css';
import 'github-markdown-css';
使用示例
// ======================================md 渲染
<div class="text markdown-body" v-html="renderMd(item.text, index)"></div>
// ======================================md 解析
const preprocessLaTeX = (content: string) => {
if (typeof content !== 'string') return content;
return (
content
// .replace(/\\text\{([^}]+)\}/g, function (match, p1) {
// return '$ \\' + match + ' $';
// })
.replace(/\\\[(.*?)\\\]/gs, (_, equation) => `$$${equation}$$`)
.replace(/\\\((.*?)\\\)/gs, (_, equation) => `$$${equation}$$`)
.replace(/(^|[^\\])\$(.+?)\$/gs, (_, prefix, equation) => `${prefix}$${equation}$`)
.replace(/\text\{([^}]+)\}/g, '($1)')
.replace(/\times/g, '\\times')
);
};
onMounted(() => {
// window.MathJax.startup.defaultReady();
// window.MathJax.typesetPromise()
});
const md = new MarkdownIt({
html: true,
linkify: true, // 自动识别链接
typographer: true, // 启用一些语言学的替换和格式
// html: false, // 禁用 HTML 标签
xhtmlOut: false, // 不使用 '/' 来闭合单标签
breaks: true, // 将连续的两个换行转换为 `<br>` 标签
});
md.use(markdownItMultimdTable);
md.use(markdownItMathjax);
md.use(mk, {
throwOnError: false,
});
md.use(mkl);
const defaultRender =
md.renderer.rules.link_open ||
function (tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options);
};
md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
// If you are sure other plugins can't add `target` - drop check below
var aIndex = tokens[idx].attrIndex('target');
if (aIndex < 0) {
tokens[idx].attrPush(['target', '_blank']); // add new attribute
} else {
tokens[idx].attrs[aIndex][1] = '_blank'; // replace value of existing attr
}
// pass token to default renderer.
return defaultRender(tokens, idx, options, env, self);
};
const renderMd = (text: string, index: number) => {
window.MathJax.startup.defaultReady();
text = preprocessLaTeX(text);
return md.render(text);
};
// =====================================

浙公网安备 33010602011771号