Skip to content

Support rendering tex even when global MathJax rendering mode is not SVG #2994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 1, 2018
3 changes: 2 additions & 1 deletion src/fonts/mathjax_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ if(typeof MathJax !== 'undefined') {
displayAlign: 'left',
tex2jax: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
}
},
SVG: {font: 'STIX-Web'},
});

MathJax.Hub.Configured();
Expand Down
14 changes: 13 additions & 1 deletion src/lib/svg_text_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,19 @@ function texToSVG(_texString, _config, _callback) {
.style({'font-size': _config.fontSize + 'px'})
.text(cleanEscapesForTex(_texString));

MathJax.Hub.Queue(['Typeset', MathJax.Hub, tmpDiv.node()], function() {
var originalRenderer;
MathJax.Hub.Queue(function() {
// Get original renderer
originalRenderer = MathJax.Hub.config.menuSettings.renderer;
},
['setRenderer', MathJax.Hub, 'SVG'],
['Typeset', MathJax.Hub, tmpDiv.node()],
function() {
// Restore original renderer if not SVG
if(originalRenderer !== 'SVG') {
MathJax.Hub.Queue(['setRenderer', MathJax.Hub, originalRenderer]);
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this decision synchronously?

function finalize() { ... /* all the stuff we do with the results */ }
var originalRenderer = MathJax.Hub.config.menuSettings.renderer;
if(originalRenderer !== 'SVG') {
    MathJax.Hub.Queue(['setRenderer', ...], ['Typeset', ...], ['setRenderer', ...], finalize);
}
else {
    MathJax.Hub.Queue(['Typeset', ...], finalize);
}

As is I'm concerned

  1. that it adds unnecessary overhead to the svg-only case
  2. there's a potential race condition if someone else adds to the queue before we reset the renderer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trouble is that MathJax.Hub.config.menuSettings.renderer isn't initialized right away, so if it's accessed outside of a Queue command it will be null in the beginning. Perhaps there's a better way to wait for the first initialization than putting the MathJax.Hub.config.menuSettings.renderer on the Queue, but I'm not sure at this point.

Let me know if you have any ideas, I'll try a few more experiments tonight...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trouble is that MathJax.Hub.config.menuSettings.renderer isn't initialized right away

Ah OK... I see it immediately but perhaps that's just due to how we loaded MathJax in the first place... but I guess even if it's present, there's a case where someone else has put something in the Queue that changes the renderer, so by the time our expression gets rendered we have a different value from the one we read synchronously.

OK, so perhaps we can't do anything about the overhead - MathJax has enough overhead anyway, this is probably the least of our problems - but the race condition is still there. Since we're already in a function being executed by the Queue, can we just call MathJax.Hub.setRenderer(originalRenderer) directly, right where you have it, rather than putting it in the Queue? Or I guess, to be even safer, move this to the end of our finalize function so we can return MathJax.Hub.setRenderer(originalRenderer) in the (presumably unlikely) event that this happens async.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I see what you mean about the race condition. I'll give that a try again, but for some reason when I was testing earlier the direct MathJax.Hub.setRenderer call (not through the Queue) wasn't working properly, but I don't remember in what context that was. I'll report back...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it does work fine to end with return MathJax.Hub.setRenderer(originalRenderer) and remove the extra Queue command. Done in 1dd4fd3.

var glyphDefs = d3.select('body').select('#MathJax_SVG_glyphs');

if(tmpDiv.select('.MathJax_SVG').empty() || !tmpDiv.select('svg').node()) {
Expand Down