【问题标题】:Convert Latex/MathML to SVG or Image with mathjax or similar?使用 mathjax 或类似工具将 Latex/MathML 转换为 SVG 或图像?
【发布时间】:2016-04-27 17:09:36
【问题描述】:

我正在构建一个库,它只允许对象渲染的功能返回其自身表示的 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

【问题讨论】:

    标签: javascript svg mathjax


    【解决方案1】:

    没有内置的方法。但你显然可以建造一些东西。

    这是一个快速而肮脏的例子。 注意,此示例将 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>

    【讨论】:

    • 为什么它返回 mjOut 对我来说是未定义的:x
    • 代码 sn-p 仍然适用于我,所以我不确定你指的是什么。
    • @PeterKrautzberger,它似乎在 Safari 中不起作用——onload 处理程序永远不会触发。不知道为什么。它确实适用于我的 Firefox 和 Chrome。没试过IE。从技术上讲,应该在设置src 属性之前安装 onload 处理程序,但这并不能解决 Safari 的问题。
    • 啊,谢谢@Davide。我之前没有发现这个评论。毕竟这是一个快速破解。我会尽量找时间看看 Safari。
    【解决方案2】:

    对于 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()
        }
      })
    }
    

    【讨论】:

    • 我试过了,第 3 行代码抛出错误:TypeError: MathJax.tex2svg is not a function
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    相关资源
    最近更新 更多