Skip to content

Commit

Permalink
Anton Akhmerov's workaround to mock v2 API for pages with both chtml …
Browse files Browse the repository at this point in the history
…& svg outputs
  • Loading branch information
archmoj committed Jan 5, 2022
1 parent 1dd51fd commit 4ba005f
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 3 deletions.
2 changes: 1 addition & 1 deletion devtools/test_dashboard/index-mathjax3.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>Plotly.js Devtools</title>
<title>Plotly.js Devtools - MathJax v3 loaded with svg output</title>
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans:600,400,300,200|Droid+Sans|PT+Sans+Narrow|Gravitas+One|Droid+Sans+Mono|Droid+Serif|Raleway|Old+Standard+TT"/>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
Expand Down
159 changes: 159 additions & 0 deletions devtools/test_dashboard/index-mathjax3chtml.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<!DOCTYPE html>
<html>
<head>
<title>Plotly.js Devtools - MathJax v3 loaded with chtml output</title>
<p>MathJax $V^3$ with $chtml$ output on the page and <b>svg</b> output on the plotly graphs</p>
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans:600,400,300,200|Droid+Sans|PT+Sans+Narrow|Gravitas+One|Droid+Sans+Mono|Droid+Serif|Raleway|Old+Standard+TT"/>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
<header>
<img src="http://images.plot.ly/logo/plotlyjs-logo@2x.png" onClick="Tabs.reload();" />
<span id="reload-time"></span>

<input id="mocks-search" type="text" placeholder="mocks search" />
<input id="css-transform" type="text" placeholder="css transform" />
</header>

<section id="mocks-list"></section>
<div id="plots">
<div id="graph"></div>
</div>
<div id="snapshot"></div>

<script>
window.MathJax = window.MathJax || {
// mocking v2 API as suggested by https://github.com/akhmerov namely to handle both chtml output on the page as well as svg outputs for plotly

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 () {},
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
}
}
};
</script>
<script src="../../node_modules/mathjax-v3/es5/tex-mml-chtml.js"></script>
<script>
// let plotly.js know that v2 API is mocked
window.MathJax._mockedV2API = true;
</script>
<script charset="utf-8" id="source" type="module">import "../../build/plotly.js"</script>
<script charset="utf-8" src="../../build/test_dashboard-bundle.js"></script>
</body>
</html>
4 changes: 3 additions & 1 deletion devtools/test_dashboard/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var args = minimist(process.argv.slice(2), {});
var PORT = args.port || 3000;
var strict = args.strict;
var mathjax3 = args.mathjax3;
var mathjax3chtml = args.mathjax3chtml;

// Create server
var server = http.createServer(ecstatic({
Expand All @@ -28,7 +29,8 @@ var bundlePlotly = makeWatchifiedBundle(strict, function() {
// open up browser window on first bundle callback
open('http://localhost:' + PORT + '/devtools/test_dashboard/index' + (
strict ? '-strict' :
mathjax3 ? '-mathjax3' : ''
mathjax3 ? '-mathjax3' :
mathjax3chtml ? '-mathjax3chtml' : ''
) + '.html');
});

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"test-plain-obj": "node tasks/test_plain_obj.js",
"test": "npm run test-jasmine -- --nowatch && npm run test-bundle && npm run test-image && npm run test-export && npm run test-syntax && npm run lint",
"mathjax3": "node devtools/test_dashboard/server.js --mathjax3",
"mathjax3chtml": "node devtools/test_dashboard/server.js --mathjax3chtml",
"strict": "node devtools/test_dashboard/server.js --strict",
"start": "node devtools/test_dashboard/server.js",
"baseline": "node test/image/make_baseline.js",
Expand Down
11 changes: 10 additions & 1 deletion src/lib/svg_text_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,17 @@ function texToSVG(_texString, _config, _callback) {
(MathJax.version || '').split('.')[0]
) || -1;

if(MathJax._mockedV2API) {
MathJaxVersion = 2;
} else if(
MathJaxVersion === 3 &&
MathJax.config.startup.output === 'chtml'
) {
Lib.warn('To use both chtml and svg outputs on the page you may consider mocking MathJax-v2 API as illustrated in devtools/test_dashboard/index-mathjax3chtml.html');
}

if(!MathJaxVersion) {
Lib.log('No MathJax version:', MathJax.version);
Lib.warn('No MathJax version:', MathJax.version);
}

var originalRenderer,
Expand Down

0 comments on commit 4ba005f

Please sign in to comment.