一、开发背景说明
近期在做题库类项目中需要解析latex格式的数学公式,搜集了一些常用的数学公式库,。因业务需求,需要解析的数学公式复杂,我采用的是MathJax,开发环境是vue2。
| 名称 | katex | MathJax |
|---|---|---|
| 官网地址 | katex.org/ | www.mathjax.org/ |
| 协议 | Apache 2.0 | Apache 2.0 |
| 渲染速度 | 快 | 慢 |
两者特点比较:
- katex渲染更快,支持若干简写字符,但是本身支持的范围较小;
- MathJax渲染稍慢,支持更多复杂的表示。
二、MathJax的使用介绍
1.引入Mathjax
在public文件夹下的index.html文件引入MathJax,该语句导入的是国内的CDN。
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"></script>
2.创建方法配置MathJax
新建配置文件globalVariable.js
const initMathjaxConfig = () => {
if (!window.MathJax) {
return;
}
window.MathJax.Hub.Config({
extensions: ["tex2jax.js"],
showProcessingMessages: false, //关闭js加载过程信息
messageStyle: "none", //不显示信息
jax: ["input/TeX", "output/HTML-CSS"],
tex2jax: {
inlineMath: [
["$", "$"],
["\\(", "\\)"]
], //行内公式选择符
displayMath: [
["$$", "$$"],
["\\[", "\\]"]
], //段内公式选择符
skipTags: ["script", "noscript", "style", "textarea", "pre", "code", "a"] //避开某些标签
},
"HTML-CSS": {
availableFonts: ["STIX", "TeX"], //可选字体
showMathMenu: false //关闭右击菜单显示
}
});
isMathjaxConfig = true; //配置完成,改为true
};
const MathQueue = function(elementId) {
if (!window.MathJax) {
return
}
window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, document.getElementsByClassName(elementId)]) // 根据class
}
export default {
isMathjaxConfig,
initMathjaxConfig,
MathQueue
}
3.全局引入
在main.js中将globalVariable.js引入,这样就可以在项目内任何地方都可以使用了。
import MathJax from '@/utils/globalVariable'
Vue.prototype.MathJax = MathJax
4.调用
html代码如下:因为MathJax渲染过得数据会不断堆积,造成错误,我使用的是v-html绑定标签,给需要识别公式的标签添加class名称。
<div class="question-stem" v-html="item.stem">{{ item.stem }}</div>
js代码如下: 调用的时候在$nextTick调用吧,不然单个反斜杠不识别,只转换部分。
this.$nextTick(function () {
if (!this.MathJax.isMathjaxConfig) {
//判断是否初始配置,若无则配置。
this.MathJax.initMathjaxConfig();
}
this.MathJax.MathQueue("question-stem");
});
三、自己使用的一些坑
- 在配置里有 ["\[", "\]"]格式的公式,这种的识别后会默认换行,修改全局样式。
.MJXc-display{ display: inline-block!important; }
- mock的静态数据不转换数学公式,后端获取的动态数据就识别了,也是和渲染机制相关。在调用后端接口,获取到返回的数据后,使用 this.$nextTick就可以识别了。
3.因为我的业务是数学公式的标签还需绑定el-chebox,el-chebox绑定后,会和v-html冲突,不识别,建议拆开。
- 数学公式会在小于号+变量的时候阻塞识别。例如:
$n<m$,解决方法:
-
给变量添加{},例如:`$n<{m}$` -
给小于号后的变量前添加空格,例如:`$n< m$` - 前端可以执行的方式:replace正则替换小于号为小于号+空格。例如:
item.optionName.replace(/</g, "< ")