diff --git a/src/fonts/mathjax_config.js b/src/fonts/mathjax_config.js index 0fb1c2a6d2c..a810af204a0 100644 --- a/src/fonts/mathjax_config.js +++ b/src/fonts/mathjax_config.js @@ -16,16 +16,20 @@ if(typeof MathJax !== 'undefined') { exports.MathJax = true; - MathJax.Hub.Config({ - messageStyle: 'none', - skipStartupTypeset: true, - displayAlign: 'left', - tex2jax: { - inlineMath: [['$', '$'], ['\\(', '\\)']] - } - }); + var globalConfig = (window.PlotlyConfig || {}).MathJaxConfig !== 'local'; + + if(globalConfig) { + MathJax.Hub.Config({ + messageStyle: 'none', + skipStartupTypeset: true, + displayAlign: 'left', + tex2jax: { + inlineMath: [['$', '$'], ['\\(', '\\)']] + } + }); + MathJax.Hub.Configured(); + } - MathJax.Hub.Configured(); } else { exports.MathJax = false; } diff --git a/src/lib/svg_text_utils.js b/src/lib/svg_text_utils.js index b320c560183..54f0a660962 100644 --- a/src/lib/svg_text_utils.js +++ b/src/lib/svg_text_utils.js @@ -163,14 +163,48 @@ function cleanEscapesForTex(s) { } function texToSVG(_texString, _config, _callback) { - var randomID = 'math-output-' + Lib.randstr({}, 64); - var tmpDiv = d3.select('body').append('div') - .attr({id: randomID}) - .style({visibility: 'hidden', position: 'absolute'}) - .style({'font-size': _config.fontSize + 'px'}) - .text(cleanEscapesForTex(_texString)); - - MathJax.Hub.Queue(['Typeset', MathJax.Hub, tmpDiv.node()], function() { + + var originalRenderer, + originalConfig, + originalProcessSectionDelay, + tmpDiv; + + MathJax.Hub.Queue( + function() { + originalConfig = Lib.extendDeepAll({}, MathJax.Hub.config); + + originalProcessSectionDelay = MathJax.Hub.processSectionDelay; + if(MathJax.Hub.processSectionDelay !== undefined) { + // MathJax 2.5+ + MathJax.Hub.processSectionDelay = 0; + } + + return MathJax.Hub.Config({ + messageStyle: 'none', + tex2jax: { + inlineMath: [['$', '$'], ['\\(', '\\)']] + }, + displayAlign: 'left', + }); + }, + function() { + // Get original renderer + originalRenderer = MathJax.Hub.config.menuSettings.renderer; + if(originalRenderer !== 'SVG') { + return MathJax.Hub.setRenderer('SVG'); + } + }, + function() { + var randomID = 'math-output-' + Lib.randstr({}, 64); + tmpDiv = d3.select('body').append('div') + .attr({id: randomID}) + .style({visibility: 'hidden', position: 'absolute'}) + .style({'font-size': _config.fontSize + 'px'}) + .text(cleanEscapesForTex(_texString)); + + return MathJax.Hub.Typeset(tmpDiv.node()); + }, + function() { var glyphDefs = d3.select('body').select('#MathJax_SVG_glyphs'); if(tmpDiv.select('.MathJax_SVG').empty() || !tmpDiv.select('svg').node()) { @@ -183,6 +217,16 @@ function texToSVG(_texString, _config, _callback) { } tmpDiv.remove(); + + if(originalRenderer !== 'SVG') { + return MathJax.Hub.setRenderer(originalRenderer); + } + }, + function() { + if(originalProcessSectionDelay !== undefined) { + MathJax.Hub.processSectionDelay = originalProcessSectionDelay; + } + return MathJax.Hub.Config(originalConfig); }); } diff --git a/tasks/stats.js b/tasks/stats.js index da597ce71b9..c746f1c9a60 100644 --- a/tasks/stats.js +++ b/tasks/stats.js @@ -65,6 +65,19 @@ function getInfoContent() { '', 'You can grab the relevant MathJax files in `./dist/extras/mathjax/`.', '', + 'By default, plotly.js will modify the global MathJax configuration on load.', + 'This can lead to undesirable behavior if plotly.js is loaded alongside', + 'other libraries that also rely on MathJax. To disable this global configuration', + 'process, set the `MathJaxConfig` property to `\'local\'` in the `window.PlotlyConfig`', + 'object. This property must be set before the plotly.js script tag, for example:', + '', + '```html', + '', + '', + '```', + '', '### To include localization', '', 'Plotly.js defaults to US English (en-US) and includes British English (en) in the standard bundle.',