UNPKG

itutor-mathlive

Version:

Beautifully typeset math made easy

1,199 lines (1,089 loc) 1.15 MB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("MathLive", [], factory); else if(typeof exports === 'object') exports["MathLive"] = factory(); else root["MathLive"] = factory(); })(typeof self !== 'undefined' ? self : this, function() { return /******/ (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, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // 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 = 14); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /*global require:false*/ /*global define:false*/ /** * * See {@linkcode MathAtom} * @module mathAtom * @private */ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(6), __webpack_require__(16), __webpack_require__(3), __webpack_require__(4), __webpack_require__(17)], __WEBPACK_AMD_DEFINE_RESULT__ = (function (Mathstyle, Context, FontMetricsModule, Span, Delimiters) { var makeSpan = Span.makeSpan; var makeOrd = Span.makeOrd; var makeInner = Span.makeInner; var makeHlist = Span.makeHlist; var makeVlist = Span.makeVlist; var FONTMETRICS = FontMetricsModule.metrics; var getCharacterMetrics = FontMetricsModule.getCharacterMetrics; /** * An atom is an object encapsulating an elementary mathematical unit, * independent of its graphical representation. * * It keeps track of the content, while the dimensions, position and style * are tracked by Span objects which are created by the `decompose()` functions. * * @param {string} mode * @param {string} type * @param {string|MathAtom[]} body * @param {?string} [fontFamily="main"] * @param {?Object} [extras=null] A set of additional properties to append to * the atom * @return {MathAtom} * @property {string} mode `'display'`, `'command'`, etc... * @property {string} type - Type can be one of: * - `mord`: ordinary symbol, e.g. `x`, `\alpha` * - `textord`: ordinary characters used in text mode * - `mop`: operators, including special functions, `\sin`, `\sum`, `\cap`. * - `mbin`: binary operator: `+`, `*`, etc... * - `mrel`: relational operator: `=`, `\ne`, etc... * - `mpunct`: punctuation: `,`, `:`, etc... * - `mopen`: opening fence: `(`, `\langle`, etc... * - `mclose`: closing fence: `)`, `\rangle`, etc... * - `minner`: special layout cases, overlap, `\left...\right` * * In addition to these basic types, which correspond to the TeX atom types, * some atoms represent more complex compounds, including: * - `space` and `spacing`: blank space between atoms * - `mathstyle`: to change the math style used: `display` or `text`. * The layout rules are different for each, the latter being more compact and * intended to be incorporated with surrounding non-math text. * - `root`: a group, which has no parent (only one per formula) * - `group`: a simple group of atoms, for example from a `{...}` * - `font`: set the font used. Used by `\mathbb`, `\mathbb`, etc... * - `sizing`: set the size of the font used * - `color`: set the foreground color * - `rule`: draw a line, for the `\rule` command * - `line`: used by `\overline` and `\underline` commands * - `box`: a border drawn around an expression and change its background color * - `overlap`: display a symbol _over_ another * - `overunder`: displays an annotation above or below a symbol * - `array`: a group, which has children arranged in rows. Used * by environments such as `matrix`, `cases`, etc... * - `genfrac`: a generalized fraction: a numerator and denominator, separated * by an optional line, and surrounded by optional fences * - `surd`: a surd, aka root * - `leftright`: used by the `\left` and `\right` commands * - `delim`: some delimiter * - `sizeddelim`: a delimiter that can grow * * The following types are used by the editor: * - `command` indicate a command being entered. The text is displayed in * blue in the editor. * - `error`: indicate a command that is unknown, for example `\xyzy`. The text * is displayed with a wavy red underline in the editor. * - `placeholder`: indicate a temporary item. Placeholders are displayed * as a dashed square in the editor. * - `first`: a special, empty, atom put as the first atom in math lists in * order to be able to position the caret before the first element. Aside from * the caret, they display nothing. * * @property {string} fontFamily * @property {string|MathAtom[]} body * @property {MathAtom[]} superscript * @property {MathAtom[]} subscript * @property {MathAtom[]} numer * @property {MathAtom[]} denom * @property {boolean} captureSelection if true, this atom does not let its * children be selected. Used by the `\enclose` annotations, for example. * @property {boolean} skipBoundary if true, when the caret reaches the * first position in this element's body, it automatically moves to the * outside of the element. Conversely, when the caret reaches the position * right after this element, it automatically moves to the last position * inside this element. * @class MathAtom * @global * @private */ function MathAtom(mode, type, body, fontFamily, extras) { this.mode = mode; this.type = type; this.body = body; this.fontFamily = fontFamily; // Append all the properties in extras to this // This can override the type, value, etc... if (extras) { for (var p in extras) { if (extras.hasOwnProperty(p)) { this[p] = extras[p]; } } } // Determine which font family to use. // Note that the type, fontFamily and body could have been overridden // by 'extras', so don't check against the parameter ('type') but // the value in the object ('this.type'). if (this.type !== 'textord' && this.fontFamily === 'main' && typeof this.body === 'string' && this.body.length === 1) { if (AUTO_ITALIC_REGEX.test(this.body)) { // Auto italicize alphabetic and lowercase greek symbols // in math mode (European style, American style would not // italicize greek letters, but it's TeX's default behavior) this.fontFamily = 'mathit'; } } if (this.type === 'textord' && this.fontFamily === 'main') { this.fontFamily = 'mathrm'; } // if (!italic && type === 'textord' && (mode === 'displaymath' || mode === 'inlinemath')) { // fontFamily = 'mathit'; // This is important to get \prime to render correctly // } if (this.fontFamily === 'main') { this.fontFamily = 'mathrm'; } else if (fontFamily === 'ams') { this.fontFamily = 'amsrm'; } } MathAtom.prototype.getInitialBaseElement = function () { // if (this.type === 'leftright') { // return this; // } var result = this; if (Array.isArray(this.body) && this.body.length > 0) { for (var i = 0; i < this.body.length; i++) { if (this.body[i].type !== 'first') { result = this.body[i].getInitialBaseElement(); break; } } } return result; }; MathAtom.prototype.getFinalBaseElement = function () { if (Array.isArray(this.body) && this.body.length > 0) { return this.body[this.body.length - 1].getFinalBaseElement(); } return this; }; MathAtom.prototype.isCharacterBox = function () { var base = this.getInitialBaseElement(); return base.type === 'mord' || base.type === 'minner' || base.type === 'mbin' || base.type === 'mrel' || base.type === 'mpunct' || base.type === 'mopen' || base.type === 'mclose' || base.type === 'textord'; }; MathAtom.prototype.forEach = function (cb) { cb(this); if (Array.isArray(this.body)) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this.body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var atom = _step.value; if (atom) atom.forEach(cb); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } else if (this.body && _typeof(this.body) === 'object') { cb(this.body); } if (this.superscript) { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = this.superscript[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _atom = _step2.value; if (_atom) _atom.forEach(cb); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } if (this.subscript) { var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = this.subscript[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _atom2 = _step3.value; if (_atom2) _atom2.forEach(cb); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } if (this.overscript) { var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = this.overscript[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var _atom3 = _step4.value; if (_atom3) _atom3.forEach(cb); } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } } if (this.underscript) { var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { for (var _iterator5 = this.underscript[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { var _atom4 = _step5.value; if (_atom4) _atom4.forEach(cb); } } catch (err) { _didIteratorError5 = true; _iteratorError5 = err; } finally { try { if (!_iteratorNormalCompletion5 && _iterator5.return) { _iterator5.return(); } } finally { if (_didIteratorError5) { throw _iteratorError5; } } } } if (this.numer) { var _iteratorNormalCompletion6 = true; var _didIteratorError6 = false; var _iteratorError6 = undefined; try { for (var _iterator6 = this.numer[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { var _atom5 = _step6.value; if (_atom5) _atom5.forEach(cb); } } catch (err) { _didIteratorError6 = true; _iteratorError6 = err; } finally { try { if (!_iteratorNormalCompletion6 && _iterator6.return) { _iterator6.return(); } } finally { if (_didIteratorError6) { throw _iteratorError6; } } } } if (this.denom) { var _iteratorNormalCompletion7 = true; var _didIteratorError7 = false; var _iteratorError7 = undefined; try { for (var _iterator7 = this.denom[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { var _atom6 = _step7.value; if (_atom6) _atom6.forEach(cb); } } catch (err) { _didIteratorError7 = true; _iteratorError7 = err; } finally { try { if (!_iteratorNormalCompletion7 && _iterator7.return) { _iterator7.return(); } } finally { if (_didIteratorError7) { throw _iteratorError7; } } } } if (this.index) { var _iteratorNormalCompletion8 = true; var _didIteratorError8 = false; var _iteratorError8 = undefined; try { for (var _iterator8 = this.index[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { var _atom7 = _step8.value; if (_atom7) _atom7.forEach(cb); } } catch (err) { _didIteratorError8 = true; _iteratorError8 = err; } finally { try { if (!_iteratorNormalCompletion8 && _iterator8.return) { _iterator8.return(); } } finally { if (_didIteratorError8) { throw _iteratorError8; } } } } if (this.array) { var _iteratorNormalCompletion9 = true; var _didIteratorError9 = false; var _iteratorError9 = undefined; try { for (var _iterator9 = this.array[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { var row = _step9.value; var _iteratorNormalCompletion10 = true; var _didIteratorError10 = false; var _iteratorError10 = undefined; try { for (var _iterator10 = row[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) { var cell = _step10.value; var _iteratorNormalCompletion11 = true; var _didIteratorError11 = false; var _iteratorError11 = undefined; try { for (var _iterator11 = cell[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) { var _atom8 = _step11.value; _atom8.forEach(cb); } } catch (err) { _didIteratorError11 = true; _iteratorError11 = err; } finally { try { if (!_iteratorNormalCompletion11 && _iterator11.return) { _iterator11.return(); } } finally { if (_didIteratorError11) { throw _iteratorError11; } } } } } catch (err) { _didIteratorError10 = true; _iteratorError10 = err; } finally { try { if (!_iteratorNormalCompletion10 && _iterator10.return) { _iterator10.return(); } } finally { if (_didIteratorError10) { throw _iteratorError10; } } } } } catch (err) { _didIteratorError9 = true; _iteratorError9 = err; } finally { try { if (!_iteratorNormalCompletion9 && _iterator9.return) { _iterator9.return(); } } finally { if (_didIteratorError9) { throw _iteratorError9; } } } } }; /** * Iterate over all the child atoms of this atom, this included, * and return an array of all the atoms for which the predicate callback * is true. * * @return {MathAtom[]} * @method MathAtom#filter */ MathAtom.prototype.filter = function (cb) { var result = []; if (cb(this)) result.push(this); var _arr = ['body', 'superscript', 'subscript', 'overscript', 'underscript', 'numer', 'denom', 'index']; for (var _i = 0; _i < _arr.length; _i++) { var relation = _arr[_i]; if (Array.isArray(this[relation])) { var _iteratorNormalCompletion14 = true; var _didIteratorError14 = false; var _iteratorError14 = undefined; try { for (var _iterator14 = this[relation][Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) { var atom = _step14.value; if (atom) result = result.concat(atom.filter(cb)); } } catch (err) { _didIteratorError14 = true; _iteratorError14 = err; } finally { try { if (!_iteratorNormalCompletion14 && _iterator14.return) { _iterator14.return(); } } finally { if (_didIteratorError14) { throw _iteratorError14; } } } } } if (Array.isArray(this.array)) { var _iteratorNormalCompletion12 = true; var _didIteratorError12 = false; var _iteratorError12 = undefined; try { for (var _iterator12 = this.array[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) { var row = _step12.value; var _iteratorNormalCompletion13 = true; var _didIteratorError13 = false; var _iteratorError13 = undefined; try { for (var _iterator13 = row[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) { var cell = _step13.value; if (cell) result = result.concat(cell.filter(cb)); } } catch (err) { _didIteratorError13 = true; _iteratorError13 = err; } finally { try { if (!_iteratorNormalCompletion13 && _iterator13.return) { _iterator13.return(); } } finally { if (_didIteratorError13) { throw _iteratorError13; } } } } } catch (err) { _didIteratorError12 = true; _iteratorError12 = err; } finally { try { if (!_iteratorNormalCompletion12 && _iterator12.return) { _iterator12.return(); } } finally { if (_didIteratorError12) { throw _iteratorError12; } } } } return result; }; MathAtom.prototype.decomposeGroup = function (context) { // The scope of the context is this group, so make a copy of it // so that any changes to it will be discarded when finished // with this group. // Note that the mathstyle property is optional and could be undefined // If that's the case, withMathstyle() returns a clone of the // context with the same mathstyle. var localContext = context.withMathstyle(this.mathstyle); return makeOrd(decompose(localContext, this.body)); }; /** * Used in `decomposeArray` to create a column separator span. * * @param {number} width * @memberof module:mathAtom * @private */ function makeColGap(width) { var separator = makeSpan('\u200B', 'arraycolsep'); separator.setWidth(width, 'em'); return separator; } /** * Used in decomposeArray to create a column of repeating elements. * @memberof module:mathAtom * @private */ function makeColOfRepeatingElements(context, body, offset, elem) { var col = []; var _iteratorNormalCompletion15 = true; var _didIteratorError15 = false; var _iteratorError15 = undefined; try { for (var _iterator15 = body[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) { var row = _step15.value; var cell = makeSpan(decompose(context, elem)); cell.depth = row.depth; cell.height = row.height; col.push(cell); col.push(row.pos - offset); } } catch (err) { _didIteratorError15 = true; _iteratorError15 = err; } finally { try { if (!_iteratorNormalCompletion15 && _iterator15.return) { _iterator15.return(); } } finally { if (_didIteratorError15) { throw _iteratorError15; } } } return makeVlist(context, col, 'individualShift'); } MathAtom.prototype.decomposeArray = function (context) { // See http://tug.ctan.org/macros/latex/base/ltfsstrc.dtx // and http://tug.ctan.org/macros/latex/base/lttab.dtx var colFormat = this.colFormat; if (colFormat && colFormat.length === 0) { colFormat = [{ align: 'l' }]; } if (!colFormat) { colFormat = [{ align: 'l' }, { align: 'l' }, { align: 'l' }, { align: 'l' }, { align: 'l' }, { align: 'l' }, { align: 'l' }, { align: 'l' }, { align: 'l' }, { align: 'l' }]; } // Fold the array so that there are no more columns of content than // there are columns prescribed by the column format. var array = []; var colMax = 0; // Maximum number of columns of content var _iteratorNormalCompletion16 = true; var _didIteratorError16 = false; var _iteratorError16 = undefined; try { for (var _iterator16 = colFormat[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) { var colSpec = _step16.value; if (colSpec.align) colMax++; } } catch (err) { _didIteratorError16 = true; _iteratorError16 = err; } finally { try { if (!_iteratorNormalCompletion16 && _iterator16.return) { _iterator16.return(); } } finally { if (_didIteratorError16) { throw _iteratorError16; } } } var _iteratorNormalCompletion17 = true; var _didIteratorError17 = false; var _iteratorError17 = undefined; try { for (var _iterator17 = this.array[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) { var _row = _step17.value; var _colIndex = 0; while (_colIndex < _row.length) { var newRow = []; var lastCol = Math.min(_row.length, _colIndex + colMax); while (_colIndex < lastCol) { newRow.push(_row[_colIndex++]); } array.push(newRow); } } // If the last row is empty, ignore it. } catch (err) { _didIteratorError17 = true; _iteratorError17 = err; } finally { try { if (!_iteratorNormalCompletion17 && _iterator17.return) { _iterator17.return(); } } finally { if (_didIteratorError17) { throw _iteratorError17; } } } if (array[array.length - 1].length === 1 && array[array.length - 1][0].length === 0) { array.pop(); } var mathstyle = Mathstyle.toMathstyle(this.mathstyle) || context.mathstyle; // Row spacing // Default \arraystretch from lttab.dtx var arraystretch = this.arraystretch || 1; var arrayskip = arraystretch * FONTMETRICS.baselineskip; var arstrutHeight = 0.7 * arrayskip; var arstrutDepth = 0.3 * arrayskip; // \@arstrutbox in lttab.dtx var totalHeight = 0; var nc = 0; var body = []; var nr = array.length; for (var r = 0; r < nr; ++r) { var inrow = array[r]; nc = Math.max(nc, inrow.length); var height = arstrutHeight; // \@array adds an \@arstrut var depth = arstrutDepth; // to each row (via the template) var outrow = []; for (var c = 0; c < inrow.length; ++c) { var localContext = context.withMathstyle(this.mathstyle || 'auto'); var cell = decompose(localContext, inrow[c]) || []; var elt = [makeOrd(null)].concat(cell); depth = Math.max(depth, Span.depth(elt)); height = Math.max(height, Span.height(elt)); outrow.push(elt); } var jot = r === nr - 1 ? 0 : this.jot || 0; if (this.rowGaps && this.rowGaps[r]) { jot = this.rowGaps[r]; if (jot > 0) { // \@argarraycr jot += arstrutDepth; if (depth < jot) { depth = jot; // \@xargarraycr } jot = 0; } } outrow.height = height; outrow.depth = depth; totalHeight += height; outrow.pos = totalHeight; totalHeight += depth + jot; // \@yargarraycr body.push(outrow); } var offset = totalHeight / 2 + mathstyle.metrics.axisHeight; var contentCols = []; for (var colIndex = 0; colIndex < nc; colIndex++) { var col = []; var _iteratorNormalCompletion18 = true; var _didIteratorError18 = false; var _iteratorError18 = undefined; try { for (var _iterator18 = body[Symbol.iterator](), _step18; !(_iteratorNormalCompletion18 = (_step18 = _iterator18.next()).done); _iteratorNormalCompletion18 = true) { var row = _step18.value; var elem = row[colIndex]; if (!elem) { continue; } elem.depth = row.depth; elem.height = row.height; col.push(elem); col.push(row.pos - offset); } } catch (err) { _didIteratorError18 = true; _iteratorError18 = err; } finally { try { if (!_iteratorNormalCompletion18 && _iterator18.return) { _iterator18.return(); } } finally { if (_didIteratorError18) { throw _iteratorError18; } } } if (col.length > 0) { contentCols.push(makeVlist(context, col, 'individualShift')); } } // Iterate over each column description. // Each `colDesc` will indicate whether to insert a gap, a rule or // a column from 'contentCols' var cols = []; var prevColContent = false; var prevColRule = false; var currentContentCol = 0; var firstColumn = !this.lFence; var _iteratorNormalCompletion19 = true; var _didIteratorError19 = false; var _iteratorError19 = undefined; try { for (var _iterator19 = colFormat[Symbol.iterator](), _step19; !(_iteratorNormalCompletion19 = (_step19 = _iterator19.next()).done); _iteratorNormalCompletion19 = true) { var colDesc = _step19.value; if (colDesc.align && currentContentCol >= contentCols.length) { break; } else if (colDesc.align && currentContentCol < contentCols.length) { // If an alignment is specified, insert a column of content if (prevColContent) { // If no gap was provided, insert a default gap between // consecutive columns of content cols.push(makeColGap(2 * FONTMETRICS.arraycolsep)); } else if (prevColRule || firstColumn) { // If the previous column was a rule or this is the first column // add a smaller gap cols.push(makeColGap(FONTMETRICS.arraycolsep)); } cols.push(makeSpan(contentCols[currentContentCol], 'col-align-' + colDesc.align)); currentContentCol++; prevColContent = true; prevColRule = false; firstColumn = false; } else if (typeof colDesc.gap !== 'undefined') { // Something to insert in between columns of content if (typeof colDesc.gap === 'number') { // It's a number, indicating how much space, in em, // to leave in between columns cols.push(makeColGap(colDesc.gap)); } else { // It's a mathlist // Create a column made up of the mathlist // as many times as there are rows. cols.push(makeColOfRepeatingElements(context, body, offset, colDesc.gap)); } prevColContent = false; prevColRule = false; firstColumn = false; } else if (colDesc.rule) { // It's a rule. var separator = makeSpan(null, 'vertical-separator'); separator.setStyle('height', totalHeight, 'em'); // result.setTop((1 - context.mathstyle.sizeMultiplier) * // context.mathstyle.metrics.axisHeight); separator.setStyle('margin-top', 3 * context.mathstyle.metrics.axisHeight - offset, 'em'); separator.setStyle('vertical-align', 'top'); // separator.setStyle('display', 'inline-block'); var gap = 0; if (prevColRule) { gap = FONTMETRICS.doubleRuleSep - FONTMETRICS.arrayrulewidth; } else if (prevColContent) { gap = FONTMETRICS.arraycolsep - FONTMETRICS.arrayrulewidth; } separator.setLeft(gap, 'em'); cols.push(separator); prevColContent = false; prevColRule = true; firstColumn = false; } } } catch (err) { _didIteratorError19 = true; _iteratorError19 = err; } finally { try { if (!_iteratorNormalCompletion19 && _iterator19.return) { _iterator19.return(); } } finally { if (_didIteratorError19) { throw _iteratorError19; } } } if (prevColContent && !this.rFence) { // If the last column was content, add a small gap cols.push(makeColGap(FONTMETRICS.arraycolsep)); } if ((!this.lFence || this.lFence === '.') && (!this.rFence || this.rFence === '.')) { // There are no delimiters around the array, just return what // we've built so far. return makeOrd(cols, 'mtable'); } // There is at least one delimiter. Wrap the core of the array with // appropriate left and right delimiters // const inner = makeSpan(makeSpan(cols, 'mtable'), 'mord'); var inner = makeSpan(cols, 'mtable'); var innerHeight = Span.height(inner); var innerDepth = Span.depth(inner); return makeOrd([this.bind(context, Delimiters.makeLeftRightDelim('mopen', this.lFence, innerHeight, innerDepth, context)), inner, this.bind(context, Delimiters.makeLeftRightDelim('mclose', this.rFence, innerHeight, innerDepth, context))]); }; /** * GENFRAC -- Generalized fraction * * Decompose fractions, binomials, and in general anything made * of two expressions on top of each other, optionally separated by a bar, * and optionally surrounded by fences (parentheses, brackets, etc...) * * Depending on the type of fraction the mathstyle is either * display math or inline math (which is indicated by 'textstyle'). This value can * also be set to 'auto', which indicates it should use the current mathstyle * * @method MathAtom#decomposeGenfrac */ MathAtom.prototype.decomposeGenfrac = function (context) { var mathstyle = this.mathstyle === 'auto' ? context.mathstyle : Mathstyle.toMathstyle(this.mathstyle); var newContext = context.withMathstyle(mathstyle); var numer = []; if (this.numerPrefix) { numer.push(makeOrd(this.numerPrefix, 'mathrm')); } var numeratorStyle = this.continuousFraction ? mathstyle : mathstyle.fracNum(); numer = numer.concat(decompose(newContext.withMathstyle(numeratorStyle), this.numer)); var numerReset = makeHlist(numer, context.mathstyle.adjustTo(numeratorStyle)); var denom = []; if (this.denomPrefix) { denom.push(makeOrd(this.denomPrefix, 'mathrm')); } var denominatorStyle = this.continuousFraction ? mathstyle : mathstyle.fracDen(); denom = denom.concat(decompose(newContext.withMathstyle(denominatorStyle), this.denom)); var denomReset = makeHlist(denom, context.mathstyle.adjustTo(denominatorStyle)); var ruleWidth = !this.hasBarLine ? 0 : FONTMETRICS.defaultRuleThickness / mathstyle.sizeMultiplier; // Rule 15b from Appendix G var numShift = void 0; var clearance = void 0; var denomShift = void 0; if (mathstyle.size === Mathstyle.DISPLAY.size) { numShift = mathstyle.metrics.num1; if (ruleWidth > 0) { clearance = 3 * ruleWidth; } else { clearance = 7 * FONTMETRICS.defaultRuleThickness; } denomShift = mathstyle.metrics.denom1; } else { if (ruleWidth > 0) { numShift = mathstyle.metrics.num2; clearance = ruleWidth; } else { numShift = mathstyle.metrics.num3; clearance = 3 * FONTMETRICS.defaultRuleThickness; } denomShift = mathstyle.metrics.denom2; } var numerDepth = numerReset ? numerReset.depth : 0; var denomHeight = denomReset ? denomReset.height : 0; var frac = void 0; if (ruleWidth === 0) { // Rule 15c from Appendix G // No bar line between numerator and denominator var candidateClearance = numShift - numerDepth - (denomHeight - denomShift); if (candidateClearance < clearance) { numShift += 0.5 * (clearance - candidateClearance); denomShift += 0.5 * (clearance - candidateClearance); } frac = makeVlist(newContext, [numerReset, -numShift, denomReset, denomShift], 'individualShift'); } else { // Rule 15d from Appendix G // There is a bar line between the numerator and the denominator var axisHeight = mathstyle.metrics.axisHeight; if (numShift - numerDepth - (axisHeight + 0.5 * ruleWidth) < clearance) { numShift += clearance - (numShift - numerDepth - (axisHeight + 0.5 * ruleWidth)); } if (axisHeight - 0.5 * ruleWidth - (denomHeight - denomShift) < clearance) { denomShift += clearance - (axisHeight - 0.5 * ruleWidth - (denomHeight - denomShift)); } var mid = makeSpan('', /* newContext.mathstyle.adjustTo(Mathstyle.TEXT) + */' frac-line'); // @todo: do we really need to reset the size? // Manually set the height of the line because its height is // created in CSS mid.height = ruleWidth; var elements = []; if (numerReset) { elements.push(numerReset); elements.push(-numShift); } elements.push(mid); elements.push(ruleWidth / 2 - axisHeight); if (denomReset) { elements.push(denomReset); elements.push(denomShift); } frac = makeVlist(newContext, elements, 'individualShift'); } // Add a 'mfrac' class to provide proper context for // other css selectors (such as 'frac-line') frac.classes += ' mfrac'; // Since we manually change the style sometimes (with \dfrac or \tfrac), // account for the possible size change here. frac.height *= mathstyle.sizeMultiplier / context.mathstyle.sizeMultiplier; frac.depth *= mathstyle.sizeMultiplier / context.mathstyle.sizeMultiplier; // if (!this.leftDelim && !this.rightDelim) { // return makeOrd(frac, // context.parentMathstyle.adjustTo(mathstyle) + // ((context.parentSize !== context.size) ? // (' sizing reset-' + context.parentSize + ' ' + context.size) : '')); // } // Rule 15e of Appendix G var delimSize = mathstyle.size === Mathstyle.DISPLAY.size ? mathstyle.metrics.delim1 : mathstyle.metrics.delim2; // Optional delimiters var leftDelim = Delimiters.makeCustomSizedDelim('mopen', this.leftDelim, delimSize, true, context.withMathstyle(mathstyle)); var rightDelim = Delimiters.makeCustomSizedDelim('mclose', this.rightDelim, delimSize, true, context.withMathstyle(mathstyle)); var result = makeOrd([leftDelim, frac, rightDelim], context.parentSize !== context.size ? 'sizing reset-' + context.parentSize + ' ' + context.size : 'genfrac'); return this.bind(context, result); }; /** * \left....\right * * Note that we can encounter malformed \left...\right, for example * a \left without a matching \right or vice versa. In that case, the * leftDelim (resp. rightDelim) will be undefined. We still need to handle * those cases. * * @method MathAtom#decomposeLeftright */ MathAtom.prototype.decomposeLeftright = function (context) { // The scope of the context is this group, so make a copy of it // so that any changes to it will be discarded when finished // with this group. var localContext = context.clone(); if (!this.body) { // No body, only a delimiter if (this.leftDelim) { return this.bind(localContext, new MathAtom('math', 'mopen', this.leftDelim).decompose(context)); } if (this.rightDelim) { return this.bind(localContext, new MathAtom('math', 'mclose', this.rightDelim).decompose(context)); } return null; } var inner = decompose(localContext, this.body); var mathstyle = localContext.mathstyle; var innerHeight = 0; var innerDepth = 0; var result = []; // Calculate its height and depth // The size of delimiters is the same, regardless of what mathstyle we are // in. Thus, to correctly calculate the size of delimiter we need around // a group, we scale down the inner size based on the size. innerHeight = Span.height(inner) * mathstyle.sizeMultiplier; innerDepth = Span.depth(inner) * mathstyle.sizeMultiplier; // Add the left delimiter to the beginning of the expression if (this.leftDelim) { result.push(this.bind(localContext, Delimiters.makeLeftRightDelim('mopen', this.leftDelim, innerHeight, innerDepth, localContext))); } if (inner) { // Replace the delim (\middle) spans with proper ones now that we know // the height/depth for (var i = 0; i < inner.length; i++) { if (inner[i].delim) { var hadCaret = inner[i].hasCaret; inner[i] = this.bind(localContext, Delimiters.makeLeftRightDelim('minner', inner[i].delim, innerHeight, innerDepth, localContext)); if (hadCaret) inner[i].hasCaret = true; } if (inner[i].classes && inner[i].classes.indexOf('ML__selected') >= 0) { for (var j = 0; j < inner[i].children.length; j++) { if (inner[i].children[j].delim) { var _hadCaret = inner[i].hasCaret; inner[i].children[j] = this.bind(localContext, Delimiters.makeLeftRightDelim('minner', inner[i].children[j].delim, innerHeight, innerDepth, localContext)); if (_hadCaret) inner[i].hasCaret = true; } } } } result = result.concat(inner); } // Add the right delimiter to the end of the expression. if (this.rightDelim) { var delim = this.rightDelim; if (delim === '?') { // Use a placeholder delimiter matching the open delimiter delim = { '(': ')', '\\{': '\\}', '\\[': '\\]', '\\lbrace': '\\rbrace', '\\langle': '\\rangle', '\\lfloor': '\\rfloor', '\\lceil': '\\rceil', '\\vert': '\\vert', '\\lvert': '\\rvert', '\\Vert': '\\Vert', '\\lVert': '\\rVert', '\\lbrack': '\\rbrack', '\\ulcorner': '\\urcorner', '\\llcorner': '\\lrcorner', '\\lgroup': '\\rgroup', '\\lmoustache': '\\rmoustache' }[this.leftDelim]; delim = delim || this.leftDelim; localContext.color = 'rgba(0, 0, 0, .3)'; } result.push(this.bind(localContext, Delimiters.makeLeftRightDelim('mclose', delim, innerHeight, innerDepth, localContext))); } // If the `inner` flag is set, return the `inner` element (th