使用 mathjax 或类似工具将 Latex/MathML 转换为 SVG 或图像?

Convert Latex/MathML to SVG or Image with mathjax or similar?

我正在构建一个库,它只允许对象将功能渲染到 return DOM 自身表示的元素,其中之一是数学,所以 <img><canvas><svg> 都可以,我更喜欢 svg.

Mathjax 以在这方面非常擅长而闻名,但我需要更多类似的东西:

Mathjax.Latex('\frac{2}{1}').toSVG(); //svg DOM node or string
Mathjax.Latex('\frac{2}{1}').toImage(); //Image, img node, or base64

我知道可以使用 mathjax-node,但可以使用 mathjax 客户端吗? https://github.com/mathjax/MathJax-node

没有内置方法。但是您显然可以构建一些东西。

这是一个简单粗暴的例子。 注意此示例将 MathJax 配置为不将其 globalCache 用于 SVG 路径;这使得 SVG 输出很容易重用。渲染分离的 DOM 节点也有一些注意事项; MathJax 将不得不猜测上下文(CSS、字体指标等)。

window.MathJax = {
  jax: ["input/TeX", "output/SVG"],
  extensions: ["tex2jax.js", "MathMenu.js", "MathZoom.js"],
  showMathMenu: false,
  showProcessingMessages: false,
  messageStyle: "none",
  SVG: {
    useGlobalCache: false
  },
  TeX: {
    extensions: ["AMSmath.js", "AMSsymbols.js", "autoload-all.js"]
  },
  AuthorInit: function() {
    MathJax.Hub.Register.StartupHook("End", function() {
      var mj2img = function(texstring, callback) {
        var input = texstring;
        var wrapper = document.createElement("div");
        wrapper.innerHTML = input;
        var output = { svg: "", img: ""};
        MathJax.Hub.Queue(["Typeset", MathJax.Hub, wrapper]);
        MathJax.Hub.Queue(function() {
          var mjOut = wrapper.getElementsByTagName("svg")[0];
          mjOut.setAttribute("xmlns", "http://www.w3.org/2000/svg");
          // thanks, https://spin.atomicobject.com/2014/01/21/convert-svg-to-png/
          output.svg = mjOut.outerHTML;
          var image = new Image();
          image.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(output.svg)));
          image.onload = function() {
            var canvas = document.createElement('canvas');
            canvas.width = image.width;
            canvas.height = image.height;
            var context = canvas.getContext('2d');
            context.drawImage(image, 0, 0);
            output.img = canvas.toDataURL('image/png');
            callback(output);
          };
        });
      }
      mj2img("\[f: X \to Y\]", function(output){
        document.getElementById("target").innerText = output.img + '\n' + output.svg;
      });
    });
  }
};

(function(d, script) {
  script = d.createElement('script');
  script.type = 'text/javascript';
  script.async = true;
  script.onload = function() {
    // remote script has loaded
  };
  script.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
  d.getElementsByTagName('head')[0].appendChild(script);
}(document));
<div id="target"></div>

对于 MathJax 3:

<script>
  window.MathJax = {
    // options
  };
</script>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>

代码:

const latexToImg = function (formula) {
  return new Promise((resolve, reject) => {
    let wrapper = MathJax.tex2svg(`${formula}`, {em: 10, ex: 5,display: true})
    let output = { svg: "", img: "" }
    let mjOut = wrapper.getElementsByTagName("svg")[0]
    // mjOut.setAttribute("xmlns", "http://www.w3.org/2000/svg")
    output.svg = mjOut.outerHTML
    var image = new Image()
    image.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(output.svg)));
    image.onload = function() {
      var canvas = document.createElement('canvas');
      canvas.width = image.width;
      canvas.height = image.height;
      var context = canvas.getContext('2d');
      context.drawImage(image, 0, 0);
      output.img = canvas.toDataURL('image/png');
      resolve(output.img)
    }
    image.onerror = function() {
      reject()
    }
  })
}