react-native-math-view
Version:
Math view for react-native
1,168 lines (1,075 loc) • 2.91 MB
JavaScript
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./MathJaxProvider/index.web.tsx");
/******/ })
/************************************************************************/
/******/ ({
/***/ "./MathJaxProvider/App.web.tsx":
/*!*************************************!*\
!*** ./MathJaxProvider/App.web.tsx ***!
\*************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _mathjax__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mathjax */ "./MathJaxProvider/mathjax.js");
/* harmony import */ var _mathjax__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_mathjax__WEBPACK_IMPORTED_MODULE_1__);
var __extends = (undefined && undefined.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (undefined && undefined.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var App = /** @class */ (function (_super) {
__extends(App, _super);
function App() {
return _super !== null && _super.apply(this, arguments) || this;
}
App.prototype.componentDidMount = function () {
var _this = this;
if (false) { var originalCallback, goodMath_1, badMath, devCallback; }
_mathjax__WEBPACK_IMPORTED_MODULE_1__["config"]({
MathJax: {
// traditional MathJax configuration
},
displayErrors: true,
logger: function (message) { return App.postMessage({ error: { message: message } }); }
});
_mathjax__WEBPACK_IMPORTED_MODULE_1__["start"]();
window.MathJaxProvider = function (config) {
return _this.mathjax(config)
.then(App.postMessage)
.catch(App.postError);
;
};
this.messageEventDisposer = this.addMessageListener();
};
App.prototype.componentWillUnmount = function () {
this.messageEventDisposer();
};
App.prototype.mathjax = function (options) {
return _mathjax__WEBPACK_IMPORTED_MODULE_1__["typeset"](__assign({ format: "TeX", svg: true }, options)).then(function (response) {
if (response.svg) {
var parsedSvgString = response.svg.replace(/\n|\n /g, '');
parsedSvgString = parsedSvgString.replace(/> </g, '><');
if (options.excludeTitle) {
// remove <title>
var startingTag = '<title';
var endingTag = 'title>';
parsedSvgString = parsedSvgString.substring(0, parsedSvgString.indexOf(startingTag)) + parsedSvgString.substring(parsedSvgString.indexOf(endingTag) + endingTag.length);
}
response.svg = parsedSvgString;
}
if (options.parseSize) {
var ex = 6;
response.apprxWidth = parseFloat(response.width) * ex;
response.apprxHeight = parseFloat(response.height) * ex;
}
return response;
});
};
App.prototype.addMessageListener = function () {
var _this = this;
var listener = function (e) {
//document.body.setAttribute("style", "background-color:red");
var _a = typeof e.data === 'string' ? JSON.parse(e.data) : e.data, data = _a.data, options = _a.options;
if (true)
console.log('received message', { data: data, options: options });
//document.body.setAttribute("style", "background-color:green");
var arr = Array.isArray(data) ? data : [data];
//document.body.setAttribute("style", "background-color:yellow");
return Promise.all(arr.map(function (math) { return _this.mathjax(__assign({}, options, { math: math })); }))
.then(App.postMessage)
.catch(App.postError);
};
window.addEventListener('message', listener);
return function () { return window.removeEventListener("message", listener); };
};
App.postError = function (error) {
//MathJax.start();
var arr = Array.isArray(error) ? error : [error];
arr.forEach(function (error) {
App.postMessage({
error: {
name: error.name,
message: error.message,
stack: error.stack
}
});
});
};
App.postMessage = function (data) {
/**
* see https://github.com/react-native-community/react-native-webview/blob/master/docs/Reference.md#onmessage
* */
//document.body.setAttribute("style", "background-color:blue");
if (data === void 0) { data = {}; }
window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify(data));
};
App.prototype.render = function () {
return null;
};
return App;
}(react__WEBPACK_IMPORTED_MODULE_0__["Component"]));
/* harmony default export */ __webpack_exports__["default"] = (App);
/***/ }),
/***/ "./MathJaxProvider/index.web.tsx":
/*!***************************************!*\
!*** ./MathJaxProvider/index.web.tsx ***!
\***************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ "./node_modules/react-dom/index.js");
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _App_web__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./App.web */ "./MathJaxProvider/App.web.tsx");
react_dom__WEBPACK_IMPORTED_MODULE_1__["render"](react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_App_web__WEBPACK_IMPORTED_MODULE_2__["default"], null), document.getElementById('root'));
/***/ }),
/***/ "./MathJaxProvider/mathjax.js":
/*!************************************!*\
!*** ./MathJaxProvider/mathjax.js ***!
\************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
/*********************************************************************
*
* main.js
*
* Implements an API to MathJax in Node.js so that MathJax can be
* used server-side to generate HTML+CSS, SVG, or MathML.
*
* This API converts single math expressions while giving control
* over the input format, the SVG font caching, and a number of other
* features.
*
* ----------------------------------------------------------------------
*
* Copyright (c) 2014--2016 The MathJax Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
__webpack_require__(/*! react */ "./node_modules/react/index.js");
__webpack_require__(/*! react-dom */ "./node_modules/react-dom/index.js");
var isFullwidthCodePoint = __webpack_require__(/*! is-fullwidth-code-point */ "./node_modules/is-fullwidth-code-point/index.js");
var displayMessages = false; // don't log Message.Set() calls
var displayErrors = true; // show error messages on the console
var logger = (message) => console.error(message);
var undefinedChar = false; // unknown characters are not saved in the error array
var extensions = ''; // no additional extensions used
var paths = {}; // additional paths (for third party extensions)
var fontURL = ''; // location of web fonts for CHTML
var defaults = {
ex: 6, // ex-size in pixels
width: 100, // width of container (in ex) for linebreaking and tags
useFontCache: true, // use <defs> and <use> in svg output?
useGlobalCache: false, // use common <defs> for all equations?
linebreaks: false, // do linebreaking?
equationNumbers: "none", // or "AMS" or "all"
cjkCharWidth: 13, // width of CJK character
math: "", // the math to typeset
format: "TeX", // the input format (TeX, inline-TeX, AsciiMath, or MathML)
xmlns: "mml", // the namespace to use for MathML
html: false, // return HTML output?
htmlNode: false, // DOM element for HTML output?
css: false, // return CSS for HTML output?
mml: false, // return mml output?
mmlNode: false, // DOM element for MML output?
svg: false, // return svg output?
svgNode: false, // DOM element for SVG output?
speakText: true, // add spoken annotations
timeout: 10 * 1000, // 10 second timeout before restarting MathJax
};
//
// The MathJax server states
//
var STATE = {
STOPPED: 1, // no DOM or MathJax available
STARTED: 2, // DOM loaded, MathJax starting up
READY: 3, // MathJax initialized and ready to process math
BUSY: 4, // MathJax currently processing math
RESTART: 5, // start() called while MathJax is starting up
};
//
// The MathJaxPath is normaized against file:/// so that Windows paths are correct
//
var url = __webpack_require__(/*! url */ "./node_modules/url/url.js");
var MathJaxPath = url.resolve("file:///", "file:" + /*require.resolve*/(/*! mathjax */ "./node_modules/mathjax/unpacked/MathJax.js"));
var MathJaxConfig; // configuration for when starting MathJax
var MathJax; // filled in once MathJax is loaded
var serverState = STATE.STOPPED; // nothing loaded yet
var timer; // used to reset MathJax if it runs too long
var content, htmlDOMElement; // the DOM elements
var queue = []; // queue of typesetting requests of the form [data,callback]
var data, callback, originalData; // the current queue item
var errors = []; // errors collected durring the typesetting
var sErrors = []; // errors collected durring MathJax startup
var ID = 0; // id for this SVG element
//
// The delimiters used for each of the input formats
//
var TYPES = {
TeX: "tex; mode=display",
"inline-TeX": "tex",
AsciiMath: "asciimath",
MathML: "mml"
};
var CHTMLSTYLES; // filled in when CommonHTML is loaded
/********************************************************************/
//
// Create the DOM window and set up the console wtihin it
// Add an error handler to trap unexpected errors (requires
// modifying jsdom)
// Add a <div> where we can put the math to be typeset
// and typeset math in the three formats we use (to force
// the jax to be loaded completely)
//
function GetWindow() {
htmlDOMElement = document.firstChild;
//window.addEventListener("error", function (event) { logger("Error: " + event.error) });
content = document.body.appendChild(document.createElement("div"));
content.id = "MathJax_Content";
content.innerHTML = '<script type="math/tex">x</script>' +
'<script type="math/asciimath">x</script>' +
'<script type="math/mml"><math><mi>x</mi></math></script>';
}
//
// Set up a Mathjax configuration within the window
//
function ConfigureMathJax() {
window.MathJax = {
//
// Load all input jax and preprocessors
// Load AMS extensions and the autoload extension for TeX
// Create stand-alone SVG elements with font caches by default
// (users can override that)
//
jax: ["input/TeX", "input/MathML", "input/AsciiMath", "output/SVG", "output/CommonHTML"],
extensions: ["toMathML.js"],
TeX: { extensions: window.Array("AMSmath.js", "AMSsymbols.js", "autoload-all.js") },
SVG: { useFontCache: true, useGlobalCache: false, EqnChunk: 1000000, EqnDelay: 0 },
CommonHTML: { EqnChunk: 1000000, EqnDelay: 0, undefinedFamily: "monospace" },
//
// This gets run before MathJax queues any actions
//
AuthorInit: function () {
MathJax = window.MathJax;//require('mathjax');
// Add custom paths to configuration
for (let key in paths) {
MathJax.Ajax.config.path[key] = paths[key];
}
delete MathJax.Hub.config.styles; // don't need any styles
MathJax.Hub.Startup.MenuZoom = function () { }; // don't load menu or zoom code
MathJax.Extension.MathEvents = {
Event: {}, Touch: {}, Hover: {} // fake structure to avid errors
};
MathJax.Ajax.loaded[MathJax.Ajax.fileURL("[MathJax]/extensions/MathEvents.js")] = true;
//
// When creating stylesheets, no need to wait for them
// to become active, so just do the callback
//
MathJax.Ajax.timer.create = function (callback, node) {
callback = MathJax.Callback(callback);
callback(this.STATUS.OK);
return callback;
};
//
// Use the console for messages, if we are requesting them
//
MathJax.Message.Set = function (text, n, delay) {
if (displayMessages && n !== 0) {
if (text instanceof window.Array) { text = MathJax.Localization._.apply(MathJax.Localization, text) }
logger(text);
}
};
MathJax.Message.Clear = function () { };
MathJax.Message.Remove = function () { };
MathJax.Message.Init = function () { };
//
// Trap Math Processing Errors
//
MathJax.Hub.Register.MessageHook("Math Processing Error", function (message) {
AddError("Math Processing Error: " + message[2].message);
});
MathJax.Hub.Register.MessageHook("SVG Jax - unknown char", function (message) {
AddError("SVG - Unknown character: U+" + message[1].toString(16).toUpperCase() +
" in " + (message[2].fonts || ["unknown"]).join(","), !undefinedChar);
});
MathJax.Hub.Register.MessageHook("CommonHTML Jax - unknown char", function (message) {
AddError("CHTML - Unknown character: U+" + message[1].toString(16).toUpperCase() +
" in " + (message[2].fonts || ["unknown"]).join(","), !undefinedChar);
});
MathJax.Hub.Register.MessageHook("MathML Jax - unknown node type", function (message) {
AddError("MathML - Unknown node type: " + message[1]);
});
MathJax.Hub.Register.MessageHook("MathML Jax - parse error", function (message) {
AddError("MathML - " + message[1]);
});
MathJax.Hub.Register.MessageHook("AsciiMath Jax - parse error", function (message) {
AddError("AsciiMath parse error: " + message[1]);
});
MathJax.Hub.Register.MessageHook("TeX Jax - parse error", function (message) {
AddError("TeX parse error: " + message[1]);
});
MathJax.Hub.Register.MessageHook("file load error", function (message) {
AddError("File load error: " + message[1]);
});
//
// Set the delays to 0 (we don't need to update the screen)
//
MathJax.Hub.processSectionDelay = 0;
MathJax.Hub.processUpdateTime = 10000000; // don't interrupt processing of output
MathJax.Hub.processUpdateDelay = 0;
//
// Adjust the SVG output jax
//
MathJax.Hub.Register.StartupHook("SVG Jax Config", function () {
var SVG = MathJax.OutputJax.SVG, HTML = MathJax.HTML;
//
// Don't need the styles
//
delete SVG.config.styles
SVG.Augment({
//
// Set up the default ex-size and width
//
InitializeSVG: function () {
this.pxPerInch = 96;
this.defaultEx = 6;
this.defaultWidth = 100;
},
//
// Adjust preTranslate() to not try to find the ex-size or
// the container widths.
//
preTranslate: function (state) {
var scripts = state.jax[this.id], i, m = scripts.length,
script, prev, span, div, jax, ex, em,
maxwidth = 100000, relwidth = false, cwidth,
linebreak = this.config.linebreaks.automatic,
width = this.config.linebreaks.width;
//
// Loop through the scripts
//
for (i = 0; i < m; i++) {
script = scripts[i]; if (!script.parentNode) continue;
//
// Remove any existing output
//
prev = script.previousSibling;
if (prev && String(prev.className).match(/^MathJax(_SVG)?(_Display)?( MathJax(_SVG)?_Processing)?$/)) { prev.parentNode.removeChild(prev) }
//
// Add the span, and a div if in display mode,
// then mark it as being processed
//
jax = script.MathJax.elementJax; if (!jax) continue;
jax.SVG = { display: (jax.root.Get("display") === "block") }
span = div = HTML.Element("span", {
style: { "font-size": this.config.scale + "%", display: "inline-block" },
className: "MathJax_SVG", id: jax.inputID + "-Frame", isMathJax: true, jaxID: this.id
});
if (jax.SVG.display) {
div = HTML.Element("div", { className: "MathJax_SVG_Display" });
div.appendChild(span);
}
div.className += " MathJax_SVG_Processing";
script.parentNode.insertBefore(div, script);
//
// Set SVG data for jax
//
jax.SVG.ex = ex = (data || defaults).ex;
jax.SVG.em = em = ex / SVG.TeX.x_height * 1000; // scale ex to x_height
jax.SVG.cwidth = width / em * 1000;
jax.SVG.lineWidth = (linebreak ? width / em * 1000 : SVG.BIGDIMEN);
}
//
// Set state variables used for displaying equations in chunks
//
state.SVGeqn = state.SVGlast = 0; state.SVGi = -1;
state.SVGchunk = this.config.EqnChunk;
state.SVGdelay = false;
}
});
//
// TEXT boxes use getBBox, which isn't implemented, so
// use a monspace font and fake the size. Since these
// are used only for error messages and undefined characters,
// this should be good enough for now.
//
SVG.BBOX.TEXT.Augment({
Init: function (scale, text, def) {
if (!def) { def = {} }; def.stroke = "none";
if (def["font-style"] === "") delete def["font-style"];
if (def["font-weight"] === "") delete def["font-weight"];
this.SUPER(arguments).Init.call(this, def);
SVG.addText(this.element, text);
// tweaking font fallback behavior: https://github.com/mathjax/MathJax-node/issues/299
var textWidth = text.split('')
.map(function (c) { return isFullwidthCodePoint(c.codePointAt()) ? data.cjkCharWidth : 8.5 })
.reduce(function (a, b) { return a + b }, 0);
var bbox = { width: textWidth, height: 18, y: -12 };
scale *= 1000 / SVG.em;
this.element.setAttribute("font-family", "monospace");
this.element.setAttribute("transform", "scale(" + scale + ") matrix(1 0 0 -1 0 0)");
this.w = this.r = bbox.width * scale; this.l = 0;
this.h = this.H = -bbox.y * scale;
this.d = this.D = (bbox.height + bbox.y) * scale;
}
});
//
// Don't have mglyph load images
//
MathJax.Hub.Register.StartupHook("SVG mglyph Ready", function () {
var MML = MathJax.ElementJax.mml;
var MGLYPH = MML.mglyph;
var TOSVG = MGLYPH.prototype.toSVG;
MGLYPH.Augment({
toSVG: function (variant, scale) {
var values = this.getValues("src", "width", "height");
if (values.src !== "" && !MGLYPH.GLYPH[values.src]) {
if (!values.width || !values.height) {
AddError("mglyphs must have explicit width and height in mathjax-node");
}
MGLYPH.GLYPH[values.src] = {
img: { SRC: values.src, width: 0, height: 0 },
status: "OK"
};
}
return TOSVG.apply(this, arguments);
}
});
});
});
//
// Adjust the CommonHTML output jax
//
MathJax.Hub.Register.StartupHook("CommonHTML Jax Config", function () {
var CHTML = MathJax.OutputJax.CommonHTML, HTML = MathJax.HTML;
//
// Don't need these styles
//
var STYLES = CHTML.config.styles;
delete STYLES["#MathJax_CHTML_Tooltip"];
delete STYLES[".MJXc-processing"];
delete STYLES[".MJXc-processed"];
delete STYLES[".mjx-chartest"];
delete STYLES[".mjx-chartest .mjx-char"];
delete STYLES[".mjx-chartest .mjx-box"];
delete STYLES[".mjx-test"];
delete STYLES[".mjx-ex-boxtest"];
// fontURL to current MathJax version
if (!fontURL) {
fontURL = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/' + MathJax.version + '/fonts/HTML-CSS';
}
CHTML.Augment({
webfontDir: fontURL,
//
// Set up the default ex-size and width
//
getDefaultExEm: function () {
var styles = document.head.getElementsByTagName("style");
CHTMLSTYLES = styles[styles.length - 1].innerHTML;
this.pxPerInch = 96;
this.defaultEx = 6;
this.defaultEm = 6 / CHTML.TEX.x_height * 1000;
this.defaultWidth = 100;
},
//
// Adjust preTranslate() to not try to find the ex-size or
// the container widths.
//
preTranslate: function (state) {
var scripts = state.jax[this.id], i, m = scripts.length,
script, prev, node, jax, ex, em,
maxwidth = 100000, relwidth = false, cwidth = 0,
linebreak = this.config.linebreaks.automatic,
width = this.config.linebreaks.width;
//
// Loop through the scripts
//
for (i = 0; i < m; i++) {
script = scripts[i]; if (!script.parentNode) continue;
//
// Remove any existing output
//
prev = script.previousSibling;
if (prev && prev.className && String(prev.className).substr(0, 9) === "mjx-chtml")
prev.parentNode.removeChild(prev);
//
// Add the node for the math and mark it as being processed
//
jax = script.MathJax.elementJax; if (!jax) continue;
jax.CHTML = { display: (jax.root.Get("display") === "block") }
node = CHTML.Element("mjx-chtml", {
id: jax.inputID + "-Frame", isMathJax: true, jaxID: this.id
});
if (jax.CHTML.display) {
//
// Zoom box requires an outer container to get the positioning right.
//
var NODE = CHTML.Element("mjx-chtml", { className: "MJXc-display", isMathJax: false });
NODE.appendChild(node); node = NODE;
}
node.className += " MJXc-processing";
script.parentNode.insertBefore(node, script);
//
// Set CHTML data for jax
//
jax.CHTML.ex = ex = (data || defaults).ex;
jax.CHTML.em = jax.CHTML.outerEm = em = ex / CHTML.TEX.x_height; // scale ex to x_height
jax.CHTML.cwidth = width / em;
jax.CHTML.lineWidth = (linebreak ? width / em : 1000000);
jax.CHTML.scale = 1; jax.CHTML.fontsize = "100%";
}
//
// Set state variables used for displaying equations in chunks
//
state.CHTMLeqn = state.CHTMLlast = 0; state.CHTMLi = -1;
state.CHTMLchunk = this.config.EqnChunk;
state.CHTMLdelay = false;
},
//
// We are using a monospaced font, so fake the size
//
getHDW: function (c, name, styles) {
return { h: .8, d: .2, w: c.length * .5 };
}
});
//
// Don't have mglyph load images
//
MathJax.Hub.Register.StartupHook("CommonHTML mglyph Ready", function () {
var MML = MathJax.ElementJax.mml;
var MGLYPH = MML.mglyph;
var TOCHTML = MGLYPH.prototype.toCommonHTML;
MGLYPH.Augment({
toCommonHTML: function (node, options) {
var values = this.getValues("src", "width", "height");
if (values.src !== "" && !MGLYPH.GLYPH[values.src]) {
if (!values.width || !values.height) {
AddError("mglyphs must have explicit width and height in mathjax-node");
}
MGLYPH.GLYPH[values.src] = {
img: { SRC: values.src, width: 0, height: 0 },
status: "OK"
};
}
return TOCHTML.apply(this, arguments);
}
});
});
});
//
// Set up None output jax (for when only MathML output is needed)
//
MathJax.Hub.Register.StartupHook("End Jax", function () {
MathJax.OutputJax.None = MathJax.OutputJax({
id: "None",
preTranslate: function () { },
Translate: function () { },
postTranslate: function () { }
});
MathJax.OutputJax.None.loadComplete("jax.js");
MathJax.OutputJax.None.Register("jax/mml");
});
//
// Reset the color extension after `autoload-all`
//
if (MathJax.AuthorConfig.extensions.indexOf("TeX/color.js") == -1 && MathJax.AuthorConfig.extensions.indexOf("TeX/autoload-all.js") == -1) {
MathJax.Hub.Register.StartupHook("TeX autoload-all Ready", function () {
var macros = MathJax.InputJax.TeX.Definitions.macros;
macros.color = "Color";
delete macros.textcolor;
delete macros.colorbox;
delete macros.fcolorbox;
delete macros.definecolor;
});
}
//
// Start the typesetting queue when MathJax is ready
// (reseting the counters so that the initial math doesn't affect them)
//
MathJax.Hub.Register.StartupHook("End", function () {
if (MathJax.OutputJax.SVG.resetGlyphs) MathJax.OutputJax.SVG.resetGlyphs(true);
MathJax.ElementJax.mml.ID = 0;
if (serverState === STATE.RESTART) {
setTimeout(RestartMathJax, 100);
} else {
serverState = STATE.READY;
MathJax.Hub.Queue(
function () { sErrors = errors },
StartQueue
);
}
});
}
};
if (extensions) {
//
// Parse added extensions list and add to standard ones
//
var extensionList = extensions.split(/\s*,\s*/);
for (var i = 0; i < extensionList.length; i++) {
var matches = extensionList[i].match(/^(.*?)(\.js)?$/);
window.MathJax.extensions.push(matches[1] + '.js');
}
}
//
// Turn arrays into jsdom window arrays
// (so "instanceof Array" will identify them properly)
//
var adjustArrays = function (obj) {
for (var id in obj) {
if (obj.hasOwnProperty(id)) {
if (obj[id] instanceof Array) {
var A = window.Array();
obj[id] = A.concat.apply(A, obj[id]);
} else if (typeof obj[id] === "object") {
adjustArrays(obj[id]);
}
}
}
}
if (MathJaxConfig) {
adjustArrays(MathJaxConfig);
// merge the defaults into the user configuration (to sanitize)
window.MathJax = Insert(Insert({}, MathJaxConfig), window.MathJax);
if (MathJaxConfig.extensions) {
window.MathJax.extensions = window.MathJax.extensions.concat(MathJaxConfig.extensions);
}
}
}
//
// Insert one objects into another
//
function Insert(dst, src) {
for (var id in src) {
if (src.hasOwnProperty(id)) {
// allow for concatenation of arrays?
if (typeof src[id] === 'object' && !(src[id] instanceof Array) &&
(typeof dst[id] === 'object' || typeof dst[id] === 'function')) { Insert(dst[id], src[id]) } else { dst[id] = src[id] }
}
}
return dst;
}
//
// Load MathJax into the DOM
//
function StartMathJax() {
serverState = STATE.STARTED;
return;
/*
var script = document.createElement("script");
script.src = MathJaxPath;
script.onerror = function () { AddError("Can't load MathJax.js from " + MathJaxPath) };
document.head.appendChild(script);
*/
}
/********************************************************************/
//
// Return an error value (and report it to console)
//
function ReportError(message, currentCallback) {
AddError(message);
(currentCallback || callback)({ errors: errors });
}
//
// Add an error to the error list and display it on the console
//
function AddError(message, nopush) {
if (displayErrors) logger(message);
if (!nopush) errors.push(message);
}
/********************************************************************/
//
// Creates the MathML output (taking MathJax resets
// into account)
//
function GetMML(result) {
if (!data.mml && !data.mmlNode) return;
var jax = MathJax.Hub.getAllJax()[0];
if (data.speakText && !jax.root.alttext) {
jax.root.alttext = result.speakText;
var attrNames = jax.root.attrNames;
if (attrNames && attrNames.indexOf("alttext") === -1) {
attrNames.push("alttext");
}
}
try {
var mml = jax.root.toMathML('', jax);
} catch (err) {
if (!err.restart) { throw err; } // an actual error
return MathJax.Callback.After(window.Array(GetMML, result), err.restart);
}
if (data.mml) result.mml = mml;
if (data.mmlNode) result.mmlNode = mml.firstChild; // unchecked change by @ShaMan123
}
//
// Creates speech string and updates the MathML to include it, if needed
//
function GetSpeech(result) {
if (!data.speakText) return;
result.speakText = "Equation";
if (data.format !== "MathML") result.speakText = data.math;
else {
var jax = MathJax.Hub.getAllJax()[0];
if (jax.root.alttext) result.speakText = jax.root.alttext;
}
}
//
// Create HTML and CSS output, if requested
//
function GetHTML(result) {
if (data.css) result.css = CHTMLSTYLES;
if (!data.html && !data.htmlNode) return;
var jax = MathJax.Hub.getAllJax()[0]; if (!jax) return;
var script = jax.SourceElement(), htmlDOMElement = script.previousSibling;
// add speech text if there isn't one
if (data.speakText) {
var labelTarget = htmlDOMElement.querySelector('.mjx-math');
for (child of labelTarget.childNodes) child.setAttribute("aria-hidden", true);
if (!labelTarget.getAttribute("aria-label")) {
labelTarget.setAttribute("aria-label", result.speakText);
}
}
// remove automatically generated IDs
var ids = htmlDOMElement.querySelectorAll('[id^="MJXc-Node-"]');
for (var i = 0; i < ids.length; i++) {
ids[i].removeAttribute("id");
}
// remove extreneous frame element
var frame = htmlDOMElement.querySelector('[id^="MathJax-Element-"]');
if (frame) {
// in display-mode, the frame is inside the display-style wrapper
htmlDOMElement.insertBefore(frame.firstChild, frame);
htmlDOMElement.removeChild(frame);
}
else {
// otherwise (inline-mode) the frame is the root element
htmlDOMElement.removeAttribute("id");
}
if (data.html) result.html = htmlDOMElement.outerHTML;
if (data.htmlNode) result.htmlNode = htmlDOMElement;
}
//
// Create SVG output, if requested
//
function GetSVG(result) {
if (!data.svg && !data.svgNode) return;
var jax = MathJax.Hub.getAllJax()[0]; if (!jax) return;
var script = jax.SourceElement(),
svg = script.previousSibling.getElementsByTagName("svg")[0];
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
//
// Add the speech text and mark the SVG appropriately
//
if (data.speakText) {
for (var i = 0, m = svg.childNodes.length; i < m; i++)
svg.childNodes[i].setAttribute("aria-hidden", true);
// Note: if aria-label exists, getSpeech preserved it in speakText
// remove aria-label since labelled-by title is preferred
svg.removeAttribute("aria-label");
ID++; var id = "MathJax-SVG-" + ID + "-Title";
svg.setAttribute("aria-labelledby", id);
var node = MathJax.HTML.Element("title", { id: id }, [result.speakText]);
svg.insertBefore(node, svg.firstChild);
}
if (data.svg) {
//
// SVG data is modified to add linebreaks for readability,
// and to put back the xlink namespace that is removed in HTML5
//
var svgdata = svg.outerHTML.replace(/><([^/])/g, ">\n<$1")
.replace(/(<\/[a-z]*>)(?=<\/)/g, "$1\n")
.replace(/(<(?:use|image) [^>]*)(href=)/g, ' $1xlink:$2');
//
// Add the requested data to the results
//
result.svg = svgdata;
}
if (data.svgNode) result.svgNode = svg;
result.width = svg.getAttribute("width");
result.height = svg.getAttribute("height");
result.style = svg.style.cssText;
const rect = svg.getBoundingClientRect();
result.measuredWidth = rect.width;
result.measuredHeight = rect.height;
}
/********************************************************************/
//
// Start typesetting the queued expressions
//
function StartQueue() {
data = callback = originalData = null; // clear existing equation, if any
errors = sErrors; sErrors = []; // clear any errors
if (!queue.length) return; // return if nothing to do
serverState = STATE.BUSY;
var result = {}, $$ = window.Array;
//
// Get the math data and callback
// and set the content with the proper script type
//
var item = queue.shift();
data = item[0]; callback = item[1]; originalData = item[2];
content.innerHTML = "";
MathJax.HTML.addElement(content, "script", { type: "math/" + TYPES[data.format] }, [data.math]);
//htmlDOMElement.setAttribute("xmlns:" + data.xmlns, "http://www.w3.org/1998/Math/MathML");
//
// Set the SVG and TeX parameters
// according to the requested data
//
var CHTML = MathJax.OutputJax.CommonHTML,
SVG = MathJax.OutputJax.SVG,
TEX = MathJax.InputJax.TeX,
HUB = MathJax.Hub;
SVG.defaultEx = CHTML.defaultEx = data.ex;
SVG.defaultWidth = CHTMLdefaultWidth = data.width * data.ex;
SVG.config.linebreaks.automatic = CHTML.config.linebreaks.automatic = data.linebreaks;
SVG.config.linebreaks.width = CHTML.config.linebreaks.width = data.width * data.ex;
SVG.config.useFontCache = data.useFontCache;
SVG.config.useGlobalCache = data.useGlobalCache;
TEX.config.equationNumbers.autoNumber = data.equationNumbers;
//
// Set the state from data.state or clear it
//
GetState(data.state);
//
// Get the renderer to use
//
var renderer = (
(data.html || data.htmlNode || data.css) ? "CommonHTML" :
(data.svg || data.svgNode) ? "SVG" : "None"
);
//
// Set up a timeout timer to restart MathJax if it runs too long,
// Then push the Typeset call, the MathML, speech, and SVG calls,
// and our TypesetDone routine
//
timer = setTimeout(RestartMathJax, data.timeout);
HUB.Queue(
$$(SetRenderer, renderer),
$$("Process", HUB),
$$(TypesetDone, result),
$$(GetSpeech, result),
$$(GetMML, result),
$$(GetHTML, result),
$$(RerenderSVG, result),
$$(GetSVG, result),
$$(ReturnResult, result)
);
}
//
// Update the MathJax values from the state,
// or clear them if there is no state.
//
function GetState(state) {
var SVG = MathJax.OutputJax.SVG,
TEX = MathJax.InputJax.TeX,
MML = MathJax.ElementJax.mml,
AMS = MathJax.Extension["TeX/AMSmath"],
HUB = MathJax.Hub, HTML = MathJax.HTML,
GLYPH = (SVG.BBOX || {}).GLYPH;
if (state && state.AMS) {
AMS.startNumber = state.AMS.startNumber;
AMS.labels = state.AMS.labels;
AMS.IDs = state.AMS.IDs;
MML.SUPER.ID = state.mmlID;
GLYPH.glyphs = state.glyphs;
GLYPH.defs = state.defs;
GLYPH.n = state.n;
ID = state.ID;
} else {
if (state) { state.AMS = {} }
if (SVG.resetGlyphs) SVG.resetGlyphs(true);
if (data.useGlobalCache) {
state.glyphs = {};
state.defs = HTML.Element("defs");
state.n = 0;
}
if (TEX.resetEquationNumbers) TEX.resetEquationNumbers();
MML.SUPER.ID = ID = 0;
MathJax.OutputJax.CommonHTML.ID = 0;
}
}
//
// When the expression is typeset,
// clear the timeout timer, if any,
// and update the MathJax state,
//
function TypesetDone(result) {
if (timer) { clearTimeout(timer); timer = null }
//htmlDOMElement.removeAttribute("xmlns:" + data.xmlns);
}
//
// Return the result object, and
// do the next queued expression
//
function ReturnResult(result) {
if (errors.length) {
result.errors = errors;
}
var state = data.state;
if (state) {
var AMS = MathJax.Extension["TeX/AMSmath"];
var GLYPH = (MathJax.OutputJax.SVG || {}).BBOX.GLYPH;
state.AMS.startNumber = AMS.startNumber;
state.AMS.labels = AMS.labels;
state.AMS.IDs = AMS.IDs;
state.mmlID = MathJax.ElementJax.mml.SUPER.ID;
state.glyphs = GLYPH.glyphs;
state.defs = GLYPH.defs;
state.n = GLYPH.n;
state.ID = ID;
}
serverState = STATE.READY;
callback(result, originalData);
if (serverState === STATE.READY) StartQueue();
}
//
// Set the MathJax renderer
//
function SetRenderer(renderer) {
return MathJax.Hub.setRenderer(renderer);
}
function RerenderSVG(result) {
if ((data.html || data.htmlNode || data.css) && (data.svg || data.svgNode)) {
timer = setTimeout(RestartMathJax, data.timeout);
var queue = MathJax.Callback.Queue(), $$ = window.Array;
return queue.Push(
$$(SetRenderer, "SVG"),
$$("Rerender", MathJax.Hub),
$$(TypesetDone, result)
);
}
}
/********************************************************************/
//
// If MathJax times out, discard the DOM
// and load a new one (get a fresh MathJax)
//
function RestartMathJax() {
if (timer) {
MathJax.Hub.queue.queue = []; // clear MathJax queue, so pending operations won't fire
window.MathJax = MathJax = timer = htmlDOMElement = content = null;
document.getElementById("MathJax_Content").remove();
ReportError("Timeout waiting for MathJax: restarting");
}
serverState = STATE.STOPPED;
GetWindow();
ConfigureMathJax();
StartMathJax();
}
/*******************************************