-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Plotly cannot be loaded if Mathjax v3 is already loaded #4563
Comments
MathJax v3 and plotly.js can be loaded together as long as the following is set before loading Plotly:
For reference: |
Is there any advance on this bug? I would like to load Mathjax v3 in my project, but unfortunately it does work with plotly at the moment. Plotly is using the old Mathjax.Hub object. Thanks! |
Curious whether the MathJax power users out there know if v3 avoids the function constructors that v2 has, as noticed by @archmoj in #5383 (comment) - we're trying to improve our compatibility with strict CSP and ATM that means we need to consider MathJax "not our problem," but if the new one avoids that issue we may have more motivation to upgrade. Of course if anyone else is interested to make a PR upgrading MathJax in plotly.js we'd be happy to help whether or not it improves our CSP compliance :) In principle it would be nice if we can support both v2 and v3 so as to not require these upgrades to be synchronized, and given that MathJax calls in plotly.js are grouped in just a couple locations (essentially just fonts/mathjax_config.js and lib/svg_text_utils.js) that shouldn't be too hard. |
Since people seem to be relying on this recipe:
It doesn't seem to work. I see errors "can't read property Queue of underfined", the source contains references to nonexistent |
^This |
For what it's worth, I've made some progress along the lines of the compatibility patch outlined in MathJax docs. After defining all the shims, the figure does render, albeit I don't actually see any latex. This happens because of this line that expects for the mathjax output to have a class |
I got some promising results (math shows up) with this monstrosity. mathjax_shim.js
This page footer contains <script src="mathjax_shim.js"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-svg.js"></script>
<script src="https://cdn.plot.ly/plotly-latest.js"></script> Now I would only want to know how to switch between chtml and svg rendering modes... |
Great, I now have a functioning plotly on a site with chtml mathjax. Do get there I combined what I had before with the idea from mathjax/MathJax#2705 Page footer: <script src="scripts/mathjaxconfig.js"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<script src="https://cdn.plot.ly/plotly-latest.js"></script>
window.PlotlyConfig = {MathJaxConfig: "local"}
window.MathJax = {
startup: {
//
// Mapping of old extension names to new ones
//
requireMap: {
AMSmath: 'ams',
AMSsymbols: 'ams',
AMScd: 'amscd',
SVG: 'svg',
noErrors: 'noerrors',
noUndefined: 'noundefined'
},
ready() {
// Here and later using recipe from https://github.com/mathjax/MathJax/issues/2705
//
// Get the MathJax modules that we need.
//
const {mathjax} = MathJax._.mathjax;
const {SVG} = MathJax._.output.svg_ts;
// Now using https://docs.mathjax.org/en/v3.2-latest/upgrading/v2.html#version-2-compatibility-example
//
// Replace the require command map with a new one that checks for
// renamed extensions and converts them to the new names.
//
var CommandMap = MathJax._.input.tex.SymbolMap.CommandMap;
var requireMap = MathJax.config.startup.requireMap;
var RequireLoad = MathJax._.input.tex.require.RequireConfiguration.RequireLoad;
var RequireMethods = {
Require: function (parser, name) {
var required = parser.GetArgument(name);
if (required.match(/[^_a-zA-Z0-9]/) || required === '') {
throw new TexError('BadPackageName', 'Argument for %1 is not a valid package name', name);
}
if (requireMap.hasOwnProperty(required)) {
required = requireMap[required];
}
RequireLoad(parser, required);
}
};
new CommandMap('require', {require: 'Require'}, RequireMethods);
MathJax.Callback = function (args) {
if (Array.isArray(args)) {
if (args.length === 1 && typeof(args[0]) === 'function') {
return args[0];
} else if (typeof(args[0]) === 'string' && args[1] instanceof Object &&
typeof(args[1][args[0]]) === 'function') {
return Function.bind.apply(args[1][args[0]], args.slice(1));
} else if (typeof(args[0]) === 'function') {
return Function.bind.apply(args[0], [window].concat(args.slice(1)));
} else if (typeof(args[1]) === 'function') {
return Function.bind.apply(args[1], [args[0]].concat(args.slice(2)));
}
} else if (typeof(args) === 'function') {
return args;
}
throw Error("Can't make callback from given data");
};
//
// Add a replacement for MathJax.Hub commands
//
MathJax.Hub = {
Queue: function () {
for (var i = 0, m = arguments.length; i < m; i++) {
var fn = MathJax.Callback(arguments[i]);
MathJax.startup.promise = MathJax.startup.promise.then(fn);
}
return MathJax.startup.promise;
},
Typeset: function (element, callback) {
var promise = MathJax.typesetSVGPromise([element]).then(
() => {
element.firstElementChild.classList.add("MathJax_SVG");
}
);
if (callback) {
promise = promise.then(callback);
}
return promise;
},
Config: function () {console.log('MathJax configurations should be converted for version 3')},
Configured: function () {console.log('MathJax cannot be configured like this')},
config: {menuSettings: {renderer: "SVG"}}
};
MathJax.startup.defaultReady();
// Continuing from https://github.com/mathjax/MathJax/issues/2705
//
// Create an SVG output jax and a new MathDocument that uses it.
//
const svgOutput = new SVG(MathJax.config.svg);
const svgDocument = mathjax.document(document, {
...MathJax.config.options,
InputJax: MathJax.startup.input,
OutputJax: svgOutput
});
//
// Define the SVG-based conversion methods
//
MathJax.svgStylesheet = () => svgOutput.styleSheet(svgDocument);
MathJax.typesetSVGPromise = (elements) => {
svgDocument.options.elements = elements;
svgDocument.reset();
return mathjax.handleRetriesFor(() => {
svgDocument.render();
});
};
})
}
},
loader: {load: ["output/svg"]},
tex: {
inlineMath: [["\\(", "\\)"], ["$", "$"]],
displayMath: [["\\[", "\\]"], ["$$", "$$"]],
processEscapes: true,
processEnvironments: true,
autoload: {
color: [], // don't autoload the color extension
colorv2: ['color'], // do autoload the colorv2 extension
}
}
}; |
Finally, also to return to @alexcjohnson remark: MathJax3 doesn't seem to use |
Thanks for letting me know. Setting up a dev environment is a bit too much work for me, so I'm good on testing for now. I did give feedback though :) |
Resolved by #6073. |
Since MathJax v3,
Mathjax.Hub
does not exist anymore. This makes impossible to load PlotlyJS if Mathjax v3 has already been loaded. I get the following error:I believe the error comes from these lines
plotly.js
:A check on MathJax version should probably be made here to use
MathJax.Hub
or not?Here is a short example where plotly failed to be loaded: https://codepen.io/bthierry/pen/PoqwXzm
Many thanks!
The text was updated successfully, but these errors were encountered: