I'm building a library that only allows objects render's functionality to to return DOM elements of the representation of themselves, one of those is math, so <img>
, <canvas>
or <svg>
will do it, I'll prefer svg.
Mathjax is known for being very good at this, but I need something more like:
Mathjax.Latex('\frac{2}{1}').toSVG(); //svg DOM node or string
Mathjax.Latex('\frac{2}{1}').toImage(); //Image, img node, or base64
I know it's possible with mathjax-node, but is it with mathjax client side? https://github.com/mathjax/MathJax-node
There is not built-in method for this. But you could obviously build something.
Here's a quick and dirty example. Note that this example configures MathJax to not use its globalCache for SVG paths; this makes the SVG output easily re-usable. There are also some caveats for rendering detached DOM nodes; MathJax will have to guess the context (CSS, font metrics etc).
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>
For 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>
code:
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()
}
})
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With