-
Notifications
You must be signed in to change notification settings - Fork 231
Accessing the generated MathML of a formula programmatically through javascript
Dear MathJax developers,
first of all, thanks for your work.
Please forgive me if my question will be exceedingly naive: I’ve searched through the documentation and the group, but I couldn’t find any precise pointer to an answer.
I’d like to access programmatically, through javascript on my page, to the MathML underlying a specific rendered formula (the one you can see right-clicking on a formula and choosing Show Math As > MathML Code).
Is there a safe way to do it?
Thanks again,
Enrico
Are you after a string representation, or actual DOM elements? The Show Math As -> MathML Code
produces a string for display. It is possible to obtain that string, but it is a bit delicate, because the command that creates it can operate asynchronously. (That is because it may cause files to be loaded, depending on the math that is in the expression. If it has already been displayed, chances are that it won't need to do that, but it is still possible.)
You should add "toMathML.js"
to your extensions array if you are doing your own configuration (it is already included in the standard combined configuration files). Then define
function toMathML(jax,callback) {
var mml;
try {
//
// Try to produce the MathML (if an asynchronous
// action occurs, a reset error is thrown)
// Otherwise we got the MathML and call the
// user's callback passing the MathML.
//
mml = jax.root.toMathML("");
} catch(err) {
if (!err.restart) {throw err} // an actual error
//
// For a delay due to file loading
// call this routine again after waiting for the
// the asynchronous action to finish.
//
return MathJax.Callback.After([toMathML,jax,callback],err.restart);
}
//
// Pass the MathML to the user's callback
MathJax.Callback(callback)(mml);
}
This will give you a function that you can pass an Element Jax and a callback function to. The callback will be called with the MathML from the element.
Here is a complete example:
<!DOCTYPE html>
<html>
<head>
<title>MathJax TeX to MathML Page</title>
<script>
function toMathML(jax,callback) {
var mml;
try {
mml = jax.root.toMathML("");
} catch(err) {
if (!err.restart) {throw err} // an actual error
return MathJax.Callback.After([toMathML,jax,callback],err.restart);
}
MathJax.Callback(callback)(mml);
}
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {inlineMath: [["$","$"],["\\\\(","\\\\)"]]}
});
MathJax.Hub.Queue(
function () {
var jax = MathJax.Hub.getAllJax();
for (var i = 0; i < jax.length; i++) {
toMathML(jax[i],function (mml) {
alert(jax[i].originalText + "\n\n=>\n\n"+ mml);
});
}
}
);
</script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full"></script>
</head>
<body>
<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>
</body>
</html>
This example loops through the math elements on the page and displays the original TeX and the resulting MathML.
Note that using the callbacks is the only safe way to do this, as the jax.root.toMathML()
call may signal that it needs to load a file by throwing the reset error. If you don't take that into account, you code may work most of the time, but will cause errors in isolated circumstances.
Davide
Dear Davide,
Thanks a lot – I admire how thoughtful you always are in your answers.
I’m still not quite sure I will be able to use MathJax both for rendering LaTeX and for storing the rendered MathML for further processing uses - it will be probably turn out I’d better use a separate, server-side library for that, but the idea of using the same engine and so storing just the same code that get rendered (and, so, checked by a human being) is appealing and I confess I’m wooing it.
But, as far as you could reasonably assist me, your answer solves my problem – thanks again!
Enrico
Thanks for the kind comments. Yes, using a server-side library to translate to the MathML that you are storing is probably easier. It might be possible to use a server-side javascript interpreter to have MathJax do it, however.
Best of luck with the project.
Davide