I've recently started using MathJax in my application with the use of JQuery to try and make an editor for Intuitionistic/Constructive logic. The problem I'm facing is whenever the page loads and I inject MathML using JQuery it is not rendered properly. Here's the code
<math display="block" id="mathml-derivation">
<mrow class="beginning">
</mrow>
</math>
This is the javascript
setTimeout(function() {
console.log("Started");
var $frac = document.createElement('mfrac');
$frac.innerHTML = '<mrow id="children' + parseInt(1) + '" class="conclusion">\
<mrow>\
<mi>b</mi>\
</mrow>\
</mrow>\
<mrow class="assumption">\
<mo>' + "\u22A2" + '</mo>\
<mrow class="goal clickable">\
<mi>a</mi>\
</mrow>\
</mrow>';
$("#mathml-derivation").append($frac);
console.log($frac);
MathJax.Hub.Typeset("mathml-derivation");
}, 1000);
I'm not certain what the issue is. The reason I have a setTimeout function is to make sure this executes atleast a second after the page loads. When I load it immediately or through an event, MathML fails to render properly. I followed some other posts on StackOverflow and it said to use the '.Typeset' function but it's not working properly.
As a final note, I'm using Chrome to develop and I'm using MathJax for compatibility.
There are several problems with your jsfiddle example.
The erratic behavior you see using timeouts is due to a lack of synchronization between your MathJax and jQuery code. MathJax may or may not have been loaded completely before your jQuery code runs. So you end up with a race: when you set a low timeout, the jQuery part runs first and replaces the (not yet MathJax-processed) MathML in the page; then MathJax comes in and renders what it finds in the DOM.
With a longer timeout, you'll see what happens when MathJax runs first -- and you run into a second issue: MathJax removes the source MathML from the DOM but preserves the id
s from the source in its output. This means the jQuery part ends up appending a MathML fragment to MathJax's (HTML or SVG) output (thereby breaking it).
Now MathJax.Hub.Typeset("mathml-derivation");
(which is not ideal as you should always use MathJax's queue) will render only new math content. However, your code merely hacks around in the output without letting MathJax know that something changed. So queuing a plain typeset won't do anything to that particular node. If you asked MathJAx to rerender using MathJax.Hub.Queue(["Rerender", MathJax.Hub]);
you still won't see any effect because of the second issue of adding the MathML to the output instead of the source used internally by MathJax.
Long story short, you'll need to redesign the interaction between MathJax and jQuery. you probably want to use MathJax's queuing mechanism since it is highly asynchronous. The MathJax documentation also describes a few approaches to the problem of updating math on a page; the "MathJax way" would be to update the source via the text
method, though most developers will lazily remove the entire output node and insert the changed MathML and just queue a typeset
(since there's now new math in the DOM).
Note that MathJax does not provide APIs for the modification of sub-expressions, so you'll have to track that yourself, e.g., keep an internal DOM node that represents the state of your MathML expression, modify that, and then copy it to the DOM to update the visual output.