H5:MathJax解析数学公式

一、概述

MathJax是一款开源的JavaScript显示引擎,适用所有现代浏览器,使用MathJax可以方便的在浏览器中显示数学公式,不需要使用图片。

目前,MathJax可以解析Latex、MathML和ASCIIMathML的标记语言。

MathJax官网:MathJax官网

Github地址:MathJax Github

中文文档地址:MathJax中文文档

英文文档地址:MathJax英文文档

MathJax语法:MathJax语法

二、安装

1、引入

MathJax使用网络字体(大部分浏览器都支持)去产生高质量的排版,使其在所有分辨率都可缩放和显示。

字体资源较大,所以,通常推荐使用CDN网络分发进行加载。

国外用户基本上使用Jsdelivr。

<script id="MathJax-script" <strong>async</strong> src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

国内用户使用以下cdn

3.x版本

<script type="text/javascript" id="MathJax-script" async
  src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.0.0/es5/tex-mml-chtml.js">
</script>

2.x版本

<script type="text/javascript" async 
        src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"></script>

需要注意的是,MathJax 3.x和2.x版本差异比较大,3.x版本采用模块化开发,可以按需加载。部分2.x版本API在3.x中过时不可用。出于简便性和稳定性考虑,我选择了2.x版本。

2、配置

mathjax.js

let isMathjaxConfig = false;//用于标识是否配置

const initMathjaxConfig = () => {
  if (!window.MathJax) {
    return;
  }
  window.MathJax.Hub.Config({
    showProcessingMessages: true, //关闭js加载过程信息
    messageStyle: "none", //none不显示信息 normal和simple显示
    jax: ["input/TeX", "output/HTML-CSS"],
    tex2jax: {
      inlineMath: [["$", "$"], ["\\(", "\\)"]], //行内公式选择符
      displayMath: [["$$", "$$"], ["\\[", "\\]"]], //段内公式选择符
      // skipTags: ["script", "noscript", "style", "textarea", "pre", "code", "a"], //跳过指定标签
      //includeHtmlTags: {         //配置在数学公式里可以出现哪些标签,例如公式里出现 n可用于换行 
      //  	br: '\n', wbr: '', '#comment': ''
      //}
    },
    "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
}

更多配置详见概述中的文档链接。

其中,需要注意的是,以上配置基于2.7.5版本,而window.MathJax.Hub.Queue(["Typeset", MathJax.Hub])该方法在3.x版本中已过时。

在以下示例2中,使用的是MathJax.tex2chtmlPromise()函数,但也存在渲染的dom中存在非公式组件会样式丢失的问题。

查阅官方文档,看到如下:

在这里插入图片描述

因此,在3.x版本中,可以使用MathJax.typesetPromise()替代实现window.MathJax.Hub.Queue(["Typeset", MathJax.Hub])

index.js

import mathjax from '@/math/mathjax.js'
Vue.prototype.$mathjax = mathjax;

三、例子

1、静态页面渲染公式

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="viewport" content="width=device-width">
  <title>MathJax v3 with TeX input and HTML output</title>
  <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
  <script>
  MathJax = {
    tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]}
  };
  </script>
  <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
</head>
<body>
    <h1>MathJax v3 beta: TeX input, HTML output test</h1>

    <p>
    When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
    $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
    </p>

    <h2>The Lorenz Equations</h2>

    <p>
    \begin{align}
    \dot{x} &amp; = \sigma(y-x) \\
    \dot{y} &amp; = \rho x - y - xz \\
    \dot{z} &amp; = -\beta z + xy
    \end{align}
    </p>

    <h2>The Cauchy-Schwarz Inequality</h2>

    <p>\[
    \left( \sum_{k=1}^n a_k b_k \right)^{\!\!2} \leq
     \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
    \]</p>

    <h2>A Cross Product Formula</h2>

    <p>\[
      \mathbf{V}_1 \times \mathbf{V}_2 =
       \begin{vmatrix}
        \mathbf{i} &amp; \mathbf{j} &amp; \mathbf{k} \\
        \frac{\partial X}{\partial u} &amp; \frac{\partial Y}{\partial u} &amp; 0 \\
        \frac{\partial X}{\partial v} &amp; \frac{\partial Y}{\partial v} &amp; 0 \\
       \end{vmatrix}
    \]</p>

    <h2>The probability of getting \(k\) heads when flipping \(n\) coins is:</h2>

    <p>\[P(E) = {n \choose k} p^k (1-p)^{ n-k} \]</p>

    <h2>An Identity of Ramanujan</h2>

    <p>\[
       \frac{1}{(\sqrt{\phi \sqrt{5}}-\phi) e^{\frac25 \pi}} =
         1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}}
          {1+\frac{e^{-8\pi}} {1+\ldots} } } }
    \]</p>

    <h2>A Rogers-Ramanujan Identity</h2>

    <p>\[
      1 +  \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots =
        \prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})},
         \quad\quad \text{for $|q| &lt; 1$}.
    \]</p>

    <h2>Maxwell's Equations</h2>

    <p>
    \begin{align}
      \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &amp; = \frac{4\pi}{c}\vec{\mathbf{j}} \\
      \nabla \cdot \vec{\mathbf{E}} &amp; = 4 \pi \rho \\
      \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} &amp; = \vec{\mathbf{0}} \\
      \nabla \cdot \vec{\mathbf{B}} &amp; = 0
    \end{align}
    </p>

    <h2>In-line Mathematics</h2>

    <p>Finally, while display equations look good for a page of samples, the
    ability to mix math and text in a paragraph is also important.  This
    expression $\sqrt{3x-1}+(1+x)^2$ is an example of an inline equation.  As
    you see, MathJax equations can be used this way as well, without unduly
    disturbing the spacing between lines.</p>

</body>
</html>

2、事件触发渲染

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <meta name="viewport" content="width=device-width">
  <title>MathJax v3 with interactive TeX input and HTML output</title>
  <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
  <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
  <script>
    function convert() {
      //
      //  Get the TeX input
      //
      var input = document.getElementById("input").value.trim();
      //
      //  Disable the display and render buttons until MathJax is done
      //
      var display = document.getElementById("display");
      var button = document.getElementById("render");
      button.disabled = display.disabled = true;
      //
      //  Clear the old output
      //
      output = document.getElementById('output');
      output.innerHTML = '';
      //
      //  Reset the tex labels (and automatic equation numbers, though there aren't any here).
      //  Get the conversion options (metrics and display settings)
      //  Convert the input to CommonHTML output and use a promise to wait for it to be ready
      //    (in case an extension needs to be loaded dynamically).
      //
      MathJax.texReset();
      var options = MathJax.getMetricsFor(output);
      options.display = display.checked;
      MathJax.tex2chtmlPromise(input, options).then(function (node) {
        //
        //  The promise returns the typeset node, which we add to the output
        //  Then update the document to include the adjusted CSS for the
        //    content of the new equation.
        //
        output.appendChild(node);
        MathJax.startup.document.clear();
        MathJax.startup.document.updateDocument();
      }).catch(function (err) {
        //
        //  If there was an error, put the message into the output instead
        //
        output.appendChild(document.createElement('pre')).appendChild(document.createTextNode(err.message));
      }).then(function () {
        //
        //  Error or not, re-enable the display and render buttons
        //
        button.disabled = display.disabled = false;
      });
    }
  </script>
  <style>
  #frame {
    max-width: 40em;
    margin: auto;
  }
  #input {
    border: 1px solid grey;
    margin: 0 0 .25em;
    width: 100%;
    font-size: 120%;
    box-sizing: border-box;
  }
  #output {
    font-size: 120%;
    margin-top: .75em;
    border: 1px solid grey;
    padding: .25em;
    min-height: 2em;
  }
  #output > pre {
    margin-left: 5px;
  }
  .left {
    float: left;
  }
  .right {
    float: right;
  }
  </style>
</head>

<body>
<div id="frame">

<h1>MathJax v3: TeX to HTML</h1>

<textarea id="input" rows="15" cols="10">
%
% Enter TeX commands below
%
x = {-b \pm \sqrt{b^2-4ac} \over 2a}.
</textarea>
<br />
<div class="left">
<input type="checkbox" id="display" checked onchange="convert()"> <label for="display">Display style</label>
</div>
<div class="right">
<input type="button" value="Render TeX" id="render" onclick="convert()" />
</div>
<br clear="all" />
<div id="output"></div>
</div>

</body>

</html>

3、动态数据解析

// v-html 加载动态数据
<div v-html="contnt">

// 之后调用MathJax重新渲染
this.$nextTick(() => {
     if (this.$mathjax.isMathjaxConfig) {
         this.$mathjax.initMathjaxConfig();
     }
     this.$mathjax.MathQueue("app");
});

3、更多例子,见 MathJax

参考:

基于vue渲染Latex数学公式(simplemde-editor)

Vue使用MathJax动态识别数学公式

MathJax的基本使用

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KWMax

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值