LaTex、MathQuill与Mathjax与数学公式

从入职新公司以来,就接手了一个关于作业的需求,于是数学公式的显示问题甩也甩不掉,甚至还会有其他需求因为需要展示公式而分给我,也是因为这样才决定好好整理一下关于前端公式显示的思路。

一、LaTex是什么

实话讲,最开始我以为LaTex就是专门用来标记数学公式的一门语言,直到有一天我看到这篇文章(http://www.ctex.org/documents/shredder/tex_frame.html),才知道自己的想法对于LaTex来说多么表面

总结一下:LaTex的基础是Tex,Tex是一个排版系统,是一个拥有自己完整体系的语法,可以用于各种科研、试卷甚至音乐需要,而LaTex建立在Tex的基础上进行性能扩展,相当于Tex的一个宏包

而对于使用者来说,由于LaTex的使用还是有一定的难度和复杂度,大家还是只在公式方面比较青睐它,所以大多数我们常看见的应用也都是与公式相关

二、公式输入时的即时显示MathQuill

MathQuill是一个JS库,通过自己暴露出来的接口调用来即时显示输入的公式结果,一般用来和键盘输入的input配合使用,官网链接(http://mathquill.com/

一般使用的情况,官网上的例子里的api就足够了

<p>Type math here: <span id="math-field"></span></p>
<p>LaTeX of what you typed: <span id="latex"></span></p>

<script>
var mathFieldSpan = document.getElementById('math-field');
var latexSpan = document.getElementById('latex');

var MQ = MathQuill.getInterface(2); // for backcompat
var mathField = MQ.MathField(mathFieldSpan, {
  spaceBehavesLikeTab: true, // configurable
  handlers: {
    edit: function() { // useful event handlers
      latexSpan.textContent = mathField.latex(); // simple API
    }
  }
});
</script>

 这里MathField传入的第一个参数是需要实时展示公式的input框(dom),每次输入完都会触发handlers里的edit,如果需要获取输入内容,例如在答题时,就要在这里拿结果

三、MathJax展示数学公式

举例:在我们的业务中,公式编辑器返回的LaTex公式是这样的

<p><span class="math-tex">\(x\le y\pm3\)</span></p>

而它实际代表的公式是这样的:

MathJax就可以帮助我们前端把前面这行代码转换为能够展示的公式,并且这个公式还不是不好控制的图片形式,而是一段html代码

MathJax是一款运行在浏览器中的开源数学符号渲染引擎,使用MathJax可以方便的在浏览器中显示数学公式,不需要使用图片。目前,MathJax可以解析Latex、MathML和ASCIIMathML的标记语言。

MathJax根据特殊的分隔符来识别公式区域,并且根据不同的分隔符将公式展示模式分为inline(不单独占一行)和displayed(占一行),这一点可以通过window.MathJax.Hub.Config的配置信息来看一下:

window.MathJax.Hub.Config({
    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 //关闭右击菜单显示
    }
  });

 我们可以看到inlineMath所对应的两种标识和displayMath对应的两种标识

MathJax可以根据自己的规则将LaTex公式很好的翻译展示,包括一些复杂的矩阵、方程组、连分数都可以进行展示,如果想看一下具体有哪些对应规则可以参考这篇文章(https://www.cnblogs.com/linxd/p/4955530.html),实际应用中,我们可以把这个工作托管给MathJax

四、MathJax的使用和展示效果

这里采用的示例是vue框架下

1. 首先,在入口文件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>

注:这里要放在index.html的body标签内

2. 书写配置js文件(mathConfig.js)

let isMathjaxConfig = false; //用于标识是否配置
const initMathjaxConfig = () => {
  if (!window.MathJax) {
    return;
  }
  window.MathJax.Hub.Config({
    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.getElementById(elementId)
  ]);
};

export default {
  isMathjaxConfig,
  initMathjaxConfig,
  MathQueue
};

初始化时页面isMathjaxConfig为false,证明还没配置mathJax,此时进行initMathjaxConfig配置,等待mathJax配置完成后,调用MathQueue进行指定位置的公式渲染

3. 在需要展示公式的vue文件内引入配置js

import mathConfig from "../../utils/mathConfig";

4. 在页面加载完成后进行公示渲染

mounted() {
    if (!mathConfig.isMathjaxConfig) {
      //判断是否初始配置,若无则配置。
      mathConfig.initMathjaxConfig();
    }
    mathConfig.MathQueue("组件id"); //传入组件id,让组件被MathJax渲染
},

编辑器返回的内容是

<span class="math-tex">\\(^1/_2\\pi\\)</span>

展示出来是这样的

对应的元素是这样的

可以看到,其实这里mathJax给我们生成了一堆东西来展示这一个很短且简单的公式,但是从头到尾都没有用到img标签

猜你喜欢

转载自www.cnblogs.com/neverclick/p/13202806.html
今日推荐