/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /************************************************************* * * MathJax/jax/element/mml/jax.js * * Implements the MML ElementJax that holds the internal represetation * of the mathematics on the page. Various InputJax will produce this * format, and the OutputJax will display it in various formats. * * --------------------------------------------------------------------- * * Copyright (c) 2009-2017 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. */ MathJax.ElementJax.mml = MathJax.ElementJax({ mimeType: "jax/mml" },{ id: "mml", version: "2.7.2", directory: MathJax.ElementJax.directory + "/mml", extensionDir: MathJax.ElementJax.extensionDir + "/mml", optableDir: MathJax.ElementJax.directory + "/mml/optable" }); MathJax.ElementJax.mml.Augment({ Init: function () { if (arguments.length === 1 && arguments[0].type === "math") {this.root = arguments[0]} else {this.root = MathJax.ElementJax.mml.math.apply(this,arguments)} if (this.root.attr && this.root.attr.mode) { if (!this.root.display && this.root.attr.mode === "display") { this.root.display = "block"; this.root.attrNames.push("display"); } delete this.root.attr.mode; for (var i = 0, m = this.root.attrNames.length; i < m; i++) { if (this.root.attrNames[i] === "mode") {this.root.attrNames.splice(i,1); break} } } } },{ // VS Q: These two do what? INHERIT: "_inherit_", AUTO: "_auto_", SIZE: { INFINITY: "infinity", SMALL: "small", NORMAL: "normal", BIG: "big" }, COLOR: { TRANSPARENT: "transparent" }, VARIANT: { NORMAL: "normal", BOLD: "bold", ITALIC: "italic", BOLDITALIC: "bold-italic", DOUBLESTRUCK: "double-struck", FRAKTUR: "fraktur", BOLDFRAKTUR: "bold-fraktur", SCRIPT: "script", BOLDSCRIPT: "bold-script", SANSSERIF: "sans-serif", BOLDSANSSERIF: "bold-sans-serif", SANSSERIFITALIC: "sans-serif-italic", SANSSERIFBOLDITALIC: "sans-serif-bold-italic", MONOSPACE: "monospace", INITIAL: "inital", TAILED: "tailed", LOOPED: "looped", STRETCHED: "stretched", CALIGRAPHIC: "-tex-caligraphic", OLDSTYLE: "-tex-oldstyle" }, FORM: { PREFIX: "prefix", INFIX: "infix", POSTFIX: "postfix" }, LINEBREAK: { AUTO: "auto", NEWLINE: "newline", NOBREAK: "nobreak", GOODBREAK: "goodbreak", BADBREAK: "badbreak" }, LINEBREAKSTYLE: { BEFORE: "before", AFTER: "after", DUPLICATE: "duplicate", INFIXLINBREAKSTYLE: "infixlinebreakstyle" }, INDENTALIGN: { LEFT: "left", CENTER: "center", RIGHT: "right", AUTO: "auto", ID: "id", INDENTALIGN: "indentalign" }, INDENTSHIFT: { INDENTSHIFT: "indentshift" }, LINETHICKNESS: { THIN: "thin", MEDIUM: "medium", THICK: "thick" }, NOTATION: { LONGDIV: "longdiv", ACTUARIAL: "actuarial", RADICAL: "radical", BOX: "box", ROUNDEDBOX: "roundedbox", CIRCLE: "circle", LEFT: "left", RIGHT: "right", TOP: "top", BOTTOM: "bottom", UPDIAGONALSTRIKE: "updiagonalstrike", DOWNDIAGONALSTRIKE: "downdiagonalstrike", UPDIAGONALARROW: "updiagonalarrow", VERTICALSTRIKE: "verticalstrike", HORIZONTALSTRIKE: "horizontalstrike", PHASORANGLE: "phasorangle", MADRUWB: "madruwb" }, ALIGN: { TOP: "top", BOTTOM: "bottom", CENTER: "center", BASELINE: "baseline", AXIS: "axis", LEFT: "left", RIGHT: "right" }, LINES: { NONE: "none", SOLID: "solid", DASHED: "dashed" }, SIDE: { LEFT: "left", RIGHT: "right", LEFTOVERLAP: "leftoverlap", RIGHTOVERLAP: "rightoverlap" }, WIDTH: { AUTO: "auto", FIT: "fit" }, ACTIONTYPE: { TOGGLE: "toggle", STATUSLINE: "statusline", TOOLTIP: "tooltip", INPUT: "input" }, LENGTH: { VERYVERYTHINMATHSPACE: "veryverythinmathspace", VERYTHINMATHSPACE: "verythinmathspace", THINMATHSPACE: "thinmathspace", MEDIUMMATHSPACE: "mediummathspace", THICKMATHSPACE: "thickmathspace", VERYTHICKMATHSPACE: "verythickmathspace", VERYVERYTHICKMATHSPACE: "veryverythickmathspace", NEGATIVEVERYVERYTHINMATHSPACE: "negativeveryverythinmathspace", NEGATIVEVERYTHINMATHSPACE: "negativeverythinmathspace", NEGATIVETHINMATHSPACE: "negativethinmathspace", NEGATIVEMEDIUMMATHSPACE: "negativemediummathspace", NEGATIVETHICKMATHSPACE: "negativethickmathspace", NEGATIVEVERYTHICKMATHSPACE: "negativeverythickmathspace", NEGATIVEVERYVERYTHICKMATHSPACE: "negativeveryverythickmathspace" }, OVERFLOW: { LINBREAK: "linebreak", SCROLL: "scroll", ELIDE: "elide", TRUNCATE: "truncate", SCALE: "scale" }, UNIT: { EM: "em", EX: "ex", PX: "px", IN: "in", CM: "cm", MM: "mm", PT: "pt", PC: "pc" }, TEXCLASS: { ORD: 0, OP: 1, BIN: 2, REL: 3, OPEN: 4, CLOSE: 5, PUNCT: 6, INNER: 7, VCENTER: 8, NONE: -1 }, TEXCLASSNAMES: ["ORD", "OP", "BIN", "REL", "OPEN", "CLOSE", "PUNCT", "INNER", "VCENTER"], skipAttributes: { texClass:true, useHeight:true, texprimestyle:true }, copyAttributes: { displaystyle:1, scriptlevel:1, open:1, close:1, form:1, actiontype: 1, fontfamily:true, fontsize:true, fontweight:true, fontstyle:true, color:true, background:true, id:true, "class":1, href:true, style:true }, copyAttributeNames: [ "displaystyle", "scriptlevel", "open", "close", "form", // force these to be copied "actiontype", "fontfamily", "fontsize", "fontweight", "fontstyle", "color", "background", "id", "class", "href", "style" ], nocopyAttributes: { fontfamily: true, fontsize: true, fontweight: true, fontstyle: true, color: true, background: true, id: true, 'class': true, href: true, style: true, xmlns: true }, Error: function (message,def) { var mml = this.merror(message), dir = MathJax.Localization.fontDirection(), font = MathJax.Localization.fontFamily(); if (def) {mml = mml.With(def)} if (dir || font) { mml = this.mstyle(mml); if (dir) {mml.dir = dir} if (font) {mml.style.fontFamily = "font-family: "+font} } return mml; } }); (function (MML) { MML.mbase = MathJax.Object.Subclass({ type: "base", isToken: false, defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, dir: MML.INHERIT }, noInherit: {}, noInheritAttribute: { texClass: true }, getRemoved: {}, linebreakContainer: false, Init: function () { this.data = []; if (this.inferRow && !(arguments.length === 1 && arguments[0].inferred)) {this.Append(MML.mrow().With({inferred: true, notParent: true}))} this.Append.apply(this,arguments); }, With: function (def) { for (var id in def) {if (def.hasOwnProperty(id)) {this[id] = def[id]}} return this; }, Append: function () { if (this.inferRow && this.data.length) { this.data[0].Append.apply(this.data[0],arguments); } else { for (var i = 0, m = arguments.length; i < m; i++) {this.SetData(this.data.length,arguments[i])} } }, SetData: function (i,item) { if (item != null) { if (!(item instanceof MML.mbase)) {item = (this.isToken || this.isChars ? MML.chars(item) : MML.mtext(item))} item.parent = this; item.setInherit(this.inheritFromMe ? this : this.inherit); } this.data[i] = item; }, Parent: function () { var parent = this.parent; while (parent && parent.notParent) {parent = parent.parent} return parent; }, Get: function (name,nodefault,noself) { if (!noself) { if (this[name] != null) {return this[name]} if (this.attr && this.attr[name] != null) {return this.attr[name]} } // FIXME: should cache these values and get from cache // (clear cache when appended to a new object?) var parent = this.Parent(); if (parent && parent["adjustChild_"+name] != null) { return (parent["adjustChild_"+name])(this.childPosition(),nodefault); } var obj = this.inherit; var root = obj; while (obj) { var value = obj[name]; if (value == null && obj.attr) {value = obj.attr[name]} if (obj.removedStyles && obj.getRemoved[name] && value == null) value = obj.removedStyles[obj.getRemoved[name]]; if (value != null && obj.noInheritAttribute && !obj.noInheritAttribute[name]) { var noInherit = obj.noInherit[this.type]; if (!(noInherit && noInherit[name])) {return value} } root = obj; obj = obj.inherit; } if (!nodefault) { if (this.defaults[name] === MML.AUTO) {return this.autoDefault(name)} if (this.defaults[name] !== MML.INHERIT && this.defaults[name] != null) {return this.defaults[name]} if (root) {return root.defaults[name]} } return null; }, hasValue: function (name) {return (this.Get(name,true) != null)}, getValues: function () { var values = {}; for (var i = 0, m = arguments.length; i < m; i++) {values[arguments[i]] = this.Get(arguments[i])} return values; }, adjustChild_scriptlevel: function (i,nodef) {return this.Get("scriptlevel",nodef)}, // always inherit from parent adjustChild_displaystyle: function (i,nodef) {return this.Get("displaystyle",nodef)}, // always inherit from parent adjustChild_texprimestyle: function (i,nodef) {return this.Get("texprimestyle",nodef)}, // always inherit from parent childPosition: function () { var child = this, parent = child.parent; while (parent.notParent) {child = parent; parent = child.parent} for (var i = 0, m = parent.data.length; i < m; i++) {if (parent.data[i] === child) {return i}} return null; }, setInherit: function (obj) { if (obj !== this.inherit && this.inherit == null) { this.inherit = obj; for (var i = 0, m = this.data.length; i < m; i++) { if (this.data[i] && this.data[i].setInherit) {this.data[i].setInherit(obj)} } } }, setTeXclass: function (prev) { this.getPrevClass(prev); return (typeof(this.texClass) !== "undefined" ? this : prev); }, getPrevClass: function (prev) { if (prev) { this.prevClass = prev.Get("texClass"); this.prevLevel = prev.Get("scriptlevel"); } }, updateTeXclass: function (core) { if (core) { this.prevClass = core.prevClass; delete core.prevClass; this.prevLevel = core.prevLevel; delete core.prevLevel; this.texClass = core.Get("texClass"); } }, texSpacing: function () { var prev = (this.prevClass != null ? this.prevClass : MML.TEXCLASS.NONE); var tex = (this.Get("texClass") || MML.TEXCLASS.ORD); if (prev === MML.TEXCLASS.NONE || tex === MML.TEXCLASS.NONE) {return ""} if (prev === MML.TEXCLASS.VCENTER) {prev = MML.TEXCLASS.ORD} if (tex === MML.TEXCLASS.VCENTER) {tex = MML.TEXCLASS.ORD} var space = this.TEXSPACE[prev][tex]; if ((this.prevLevel > 0 || this.Get("scriptlevel") > 0) && space >= 0) {return ""} return this.TEXSPACELENGTH[Math.abs(space)]; }, TEXSPACELENGTH:[ "", MML.LENGTH.THINMATHSPACE, MML.LENGTH.MEDIUMMATHSPACE, MML.LENGTH.THICKMATHSPACE ], // See TeXBook Chapter 18 (p. 170) TEXSPACE: [ [ 0,-1, 2, 3, 0, 0, 0, 1], // ORD [-1,-1, 0, 3, 0, 0, 0, 1], // OP [ 2, 2, 0, 0, 2, 0, 0, 2], // BIN [ 3, 3, 0, 0, 3, 0, 0, 3], // REL [ 0, 0, 0, 0, 0, 0, 0, 0], // OPEN [ 0,-1, 2, 3, 0, 0, 0, 1], // CLOSE [ 1, 1, 0, 1, 1, 1, 1, 1], // PUNCT [ 1,-1, 2, 3, 1, 0, 1, 1] // INNER ], autoDefault: function (name) {return ""}, isSpacelike: function () {return false}, isEmbellished: function () {return false}, Core: function () {return this}, CoreMO: function () {return this}, childIndex: function(child) { if (child == null) return; for (var i = 0, m = this.data.length; i < m; i++) if (child === this.data[i]) return i; }, CoreIndex: function () { return (this.inferRow ? this.data[0]||this : this).childIndex(this.Core()); }, hasNewline: function () { if (this.isEmbellished()) {return this.CoreMO().hasNewline()} if (this.isToken || this.linebreakContainer) {return false} for (var i = 0, m = this.data.length; i < m; i++) { if (this.data[i] && this.data[i].hasNewline()) {return true} } return false; }, array: function () {if (this.inferred) {return this.data} else {return [this]}}, toString: function () {return this.type+"("+this.data.join(",")+")"}, getAnnotation: function () {return null} },{ childrenSpacelike: function () { for (var i = 0, m = this.data.length; i < m; i++) {if (!this.data[i].isSpacelike()) {return false}} return true; }, childEmbellished: function () { return (this.data[0] && this.data[0].isEmbellished()); }, childCore: function () {return (this.inferRow && this.data[0] ? this.data[0].Core() : this.data[0])}, childCoreMO: function () {return (this.data[0] ? this.data[0].CoreMO() : null)}, setChildTeXclass: function (prev) { if (this.data[0]) { prev = this.data[0].setTeXclass(prev); this.updateTeXclass(this.data[0]); } return prev; }, setBaseTeXclasses: function (prev) { this.getPrevClass(prev); this.texClass = null; if (this.data[0]) { if (this.isEmbellished() || this.data[0].isa(MML.mi)) { prev = this.data[0].setTeXclass(prev); this.updateTeXclass(this.Core()); } else {this.data[0].setTeXclass(); prev = this} } else {prev = this} for (var i = 1, m = this.data.length; i < m; i++) {if (this.data[i]) {this.data[i].setTeXclass()}} return prev; }, setSeparateTeXclasses: function (prev) { this.getPrevClass(prev); for (var i = 0, m = this.data.length; i < m; i++) {if (this.data[i]) {this.data[i].setTeXclass()}} if (this.isEmbellished()) {this.updateTeXclass(this.Core())} return this; } }); MML.mi = MML.mbase.Subclass({ type: "mi", isToken: true, texClass: MML.TEXCLASS.ORD, defaults: { mathvariant: MML.AUTO, mathsize: MML.INHERIT, mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, dir: MML.INHERIT }, autoDefault: function (name) { if (name === "mathvariant") { var mi = (this.data[0]||"").toString(); return (mi.length === 1 || (mi.length === 2 && mi.charCodeAt(0) >= 0xD800 && mi.charCodeAt(0) < 0xDC00) ? MML.VARIANT.ITALIC : MML.VARIANT.NORMAL); } return ""; }, setTeXclass: function (prev) { this.getPrevClass(prev); var name = this.data.join(""); if (name.length > 1 && name.match(/^[a-z][a-z0-9]*$/i) && this.texClass === MML.TEXCLASS.ORD) { this.texClass = MML.TEXCLASS.OP; this.autoOP = true; } return this; } }); MML.mn = MML.mbase.Subclass({ type: "mn", isToken: true, texClass: MML.TEXCLASS.ORD, defaults: { mathvariant: MML.INHERIT, mathsize: MML.INHERIT, mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, dir: MML.INHERIT } }); MML.mo = MML.mbase.Subclass({ type: "mo", isToken: true, defaults: { mathvariant: MML.INHERIT, mathsize: MML.INHERIT, mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, dir: MML.INHERIT, form: MML.AUTO, fence: MML.AUTO, separator: MML.AUTO, lspace: MML.AUTO, rspace: MML.AUTO, stretchy: MML.AUTO, symmetric: MML.AUTO, maxsize: MML.AUTO, minsize: MML.AUTO, largeop: MML.AUTO, movablelimits: MML.AUTO, accent: MML.AUTO, linebreak: MML.LINEBREAK.AUTO, lineleading: MML.INHERIT, linebreakstyle: MML.AUTO, linebreakmultchar: MML.INHERIT, indentalign: MML.INHERIT, indentshift: MML.INHERIT, indenttarget: MML.INHERIT, indentalignfirst: MML.INHERIT, indentshiftfirst: MML.INHERIT, indentalignlast: MML.INHERIT, indentshiftlast: MML.INHERIT, texClass: MML.AUTO }, defaultDef: { form: MML.FORM.INFIX, fence: false, separator: false, lspace: MML.LENGTH.THICKMATHSPACE, rspace: MML.LENGTH.THICKMATHSPACE, stretchy: false, symmetric: false, maxsize: MML.SIZE.INFINITY, minsize: '0em', //'1em', largeop: false, movablelimits: false, accent: false, linebreak: MML.LINEBREAK.AUTO, lineleading: "1ex", linebreakstyle: "before", indentalign: MML.INDENTALIGN.AUTO, indentshift: "0", indenttarget: "", indentalignfirst: MML.INDENTALIGN.INDENTALIGN, indentshiftfirst: MML.INDENTSHIFT.INDENTSHIFT, indentalignlast: MML.INDENTALIGN.INDENTALIGN, indentshiftlast: MML.INDENTSHIFT.INDENTSHIFT, texClass: MML.TEXCLASS.REL // for MML, but TeX sets ORD explicitly }, SPACE_ATTR: {lspace: 0x01, rspace: 0x02, form: 0x04}, useMMLspacing: 0x07, autoDefault: function (name,nodefault) { var def = this.def; if (!def) { if (name === "form") {this.useMMLspacing &= ~this.SPACE_ATTR.form; return this.getForm()} var mo = this.data.join(""); var forms = [this.Get("form"),MML.FORM.INFIX,MML.FORM.POSTFIX,MML.FORM.PREFIX]; for (var i = 0, m = forms.length; i < m; i++) { var data = this.OPTABLE[forms[i]][mo]; if (data) {def = this.makeDef(data); break} } if (!def) {def = this.CheckRange(mo)} if (!def && nodefault) {def = {}} else { if (!def) {def = MathJax.Hub.Insert({},this.defaultDef)} if (this.parent) {this.def = def} else {def = MathJax.Hub.Insert({},def)} def.form = forms[0]; } } this.useMMLspacing &= ~(this.SPACE_ATTR[name] || 0); if (def[name] != null) {return def[name]} else if (!nodefault) {return this.defaultDef[name]} return ""; }, CheckRange: function (mo) { var n = mo.charCodeAt(0); if (n >= 0xD800 && n < 0xDC00) {n = (((n-0xD800)<<10)+(mo.charCodeAt(1)-0xDC00))+0x10000} for (var i = 0, m = this.RANGES.length; i < m && this.RANGES[i][0] <= n; i++) { if (n <= this.RANGES[i][1]) { if (this.RANGES[i][3]) { var file = MML.optableDir+"/"+this.RANGES[i][3]+".js"; this.RANGES[i][3] = null; MathJax.Hub.RestartAfter(MathJax.Ajax.Require(file)); } var data = MML.TEXCLASSNAMES[this.RANGES[i][2]]; data = this.OPTABLE.infix[mo] = MML.mo.OPTYPES[data === "BIN" ? "BIN3" : data]; return this.makeDef(data); } } return null; }, makeDef: function (data) { if (data[2] == null) {data[2] = this.defaultDef.texClass} if (!data[3]) {data[3] = {}} var def = MathJax.Hub.Insert({},data[3]); def.lspace = this.SPACE[data[0]]; def.rspace = this.SPACE[data[1]]; def.texClass = data[2]; if (def.texClass === MML.TEXCLASS.REL && (this.movablelimits || this.data.join("").match(/^[a-z]+$/i))) {def.texClass = MML.TEXCLASS.OP} // mark named operators as OP return def; }, getForm: function () { var core = this, parent = this.parent, Parent = this.Parent(); while (Parent && Parent.isEmbellished()) {core = parent; parent = Parent.parent; Parent = Parent.Parent()} if (parent && parent.type === "mrow" && parent.NonSpaceLength() !== 1) { if (parent.FirstNonSpace() === core) {return MML.FORM.PREFIX} if (parent.LastNonSpace() === core) {return MML.FORM.POSTFIX} } return MML.FORM.INFIX; }, isEmbellished: function () {return true}, hasNewline: function () {return (this.Get("linebreak") === MML.LINEBREAK.NEWLINE)}, CoreParent: function () { var parent = this; while (parent && parent.isEmbellished() && parent.CoreMO() === this && !parent.isa(MML.math)) {parent = parent.Parent()} return parent; }, CoreText: function (parent) { if (!parent) {return ""} if (parent.isEmbellished()) {return parent.CoreMO().data.join("")} while ((((parent.isa(MML.mrow) || parent.isa(MML.TeXAtom) || parent.isa(MML.mstyle) || parent.isa(MML.mphantom)) && parent.data.length === 1) || parent.isa(MML.munderover)) && parent.data[0]) {parent = parent.data[0]} if (!parent.isToken) {return ""} else {return parent.data.join("")} }, remapChars: { '*':"\u2217", '"':"\u2033", "\u00B0":"\u2218", "\u00B2":"2", "\u00B3":"3", "\u00B4":"\u2032", "\u00B9":"1" }, remap: function (text,map) { text = text.replace(/-/g,"\u2212"); if (map) { text = text.replace(/'/g,"\u2032").replace(/`/g,"\u2035"); if (text.length === 1) {text = map[text]||text} } return text; }, setTeXclass: function (prev) { var values = this.getValues("form","lspace","rspace","fence"); // sets useMMLspacing if (this.useMMLspacing) {this.texClass = MML.TEXCLASS.NONE; return this} if (values.fence && !this.texClass) { if (values.form === MML.FORM.PREFIX) {this.texClass = MML.TEXCLASS.OPEN} if (values.form === MML.FORM.POSTFIX) {this.texClass = MML.TEXCLASS.CLOSE} } this.texClass = this.Get("texClass"); if (this.data.join("") === "\u2061") { // force previous node to be texClass OP, and skip this node if (prev) {prev.texClass = MML.TEXCLASS.OP; prev.fnOP = true} this.texClass = this.prevClass = MML.TEXCLASS.NONE; return prev; } return this.adjustTeXclass(prev); }, adjustTeXclass: function (prev) { if (this.texClass === MML.TEXCLASS.NONE) {return prev} if (prev) { if (prev.autoOP && (this.texClass === MML.TEXCLASS.BIN || this.texClass === MML.TEXCLASS.REL)) {prev.texClass = MML.TEXCLASS.ORD} this.prevClass = prev.texClass || MML.TEXCLASS.ORD; this.prevLevel = prev.Get("scriptlevel") } else {this.prevClass = MML.TEXCLASS.NONE} if (this.texClass === MML.TEXCLASS.BIN && (this.prevClass === MML.TEXCLASS.NONE || this.prevClass === MML.TEXCLASS.BIN || this.prevClass === MML.TEXCLASS.OP || this.prevClass === MML.TEXCLASS.REL || this.prevClass === MML.TEXCLASS.OPEN || this.prevClass === MML.TEXCLASS.PUNCT)) { this.texClass = MML.TEXCLASS.ORD; } else if (this.prevClass === MML.TEXCLASS.BIN && (this.texClass === MML.TEXCLASS.REL || this.texClass === MML.TEXCLASS.CLOSE || this.texClass === MML.TEXCLASS.PUNCT)) { prev.texClass = this.prevClass = MML.TEXCLASS.ORD; } else if (this.texClass === MML.TEXCLASS.BIN) { // // Check if node is the last one in its container since the rule // above only takes effect if there is a node that follows. // var child = this, parent = this.parent; while (parent && parent.parent && parent.isEmbellished() && (parent.data.length === 1 || (parent.type !== "mrow" && parent.Core() === child))) // handles msubsup and munderover {child = parent; parent = parent.parent} if (parent.data[parent.data.length-1] === child) this.texClass = MML.TEXCLASS.ORD; } return this; } }); MML.mtext = MML.mbase.Subclass({ type: "mtext", isToken: true, isSpacelike: function () {return true}, texClass: MML.TEXCLASS.ORD, defaults: { mathvariant: MML.INHERIT, mathsize: MML.INHERIT, mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, dir: MML.INHERIT } }); MML.mspace = MML.mbase.Subclass({ type: "mspace", isToken: true, isSpacelike: function () {return true}, defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, width: "0em", height: "0ex", depth: "0ex", linebreak: MML.LINEBREAK.AUTO }, hasDimAttr: function () { return (this.hasValue("width") || this.hasValue("height") || this.hasValue("depth")); }, hasNewline: function () { // The MathML spec says that the linebreak attribute should be ignored // if any dimensional attribute is set. return (!this.hasDimAttr() && this.Get("linebreak") === MML.LINEBREAK.NEWLINE); } }); MML.ms = MML.mbase.Subclass({ type: "ms", isToken: true, texClass: MML.TEXCLASS.ORD, defaults: { mathvariant: MML.INHERIT, mathsize: MML.INHERIT, mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, dir: MML.INHERIT, lquote: '"', rquote: '"' } }); MML.mglyph = MML.mbase.Subclass({ type: "mglyph", isToken: true, texClass: MML.TEXCLASS.ORD, defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, alt: "", src: "", width: MML.AUTO, height: MML.AUTO, valign: "0em" } }); MML.mrow = MML.mbase.Subclass({ type: "mrow", isSpacelike: MML.mbase.childrenSpacelike, inferred: false, notParent: false, isEmbellished: function () { var isEmbellished = false; for (var i = 0, m = this.data.length; i < m; i++) { if (this.data[i] == null) continue; if (this.data[i].isEmbellished()) { if (isEmbellished) {return false} isEmbellished = true; this.core = i; } else if (!this.data[i].isSpacelike()) {return false} } return isEmbellished; }, NonSpaceLength: function () { var n = 0; for (var i = 0, m = this.data.length; i < m; i++) {if (this.data[i] && !this.data[i].isSpacelike()) {n++}} return n; }, FirstNonSpace: function () { for (var i = 0, m = this.data.length; i < m; i++) {if (this.data[i] && !this.data[i].isSpacelike()) {return this.data[i]}} return null; }, LastNonSpace: function () { for (var i = this.data.length-1; i >= 0; i--) {if (this.data[0] && !this.data[i].isSpacelike()) {return this.data[i]}} return null; }, Core: function () { if (!(this.isEmbellished()) || typeof(this.core) === "undefined") {return this} return this.data[this.core]; }, CoreMO: function () { if (!(this.isEmbellished()) || typeof(this.core) === "undefined") {return this} return this.data[this.core].CoreMO(); }, toString: function () { if (this.inferred) {return '[' + this.data.join(',') + ']'} return this.SUPER(arguments).toString.call(this); }, setTeXclass: function (prev) { var i, m = this.data.length; if ((this.open || this.close) && (!prev || !prev.fnOP)) { // // came from \left...\right // so treat as subexpression (tex class INNER) // this.getPrevClass(prev); prev = null; for (i = 0; i < m; i++) {if (this.data[i]) {prev = this.data[i].setTeXclass(prev)}} if (!this.hasOwnProperty("texClass")) this.texClass = MML.TEXCLASS.INNER; return this; } else { // // Normal , so treat as // thorugh mrow is not there // for (i = 0; i < m; i++) {if (this.data[i]) {prev = this.data[i].setTeXclass(prev)}} if (this.data[0]) {this.updateTeXclass(this.data[0])} return prev; } }, getAnnotation: function (name) { if (this.data.length != 1) return null; return this.data[0].getAnnotation(name); } }); MML.mfrac = MML.mbase.Subclass({ type: "mfrac", num: 0, den: 1, linebreakContainer: true, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, linethickness: MML.LINETHICKNESS.MEDIUM, numalign: MML.ALIGN.CENTER, denomalign: MML.ALIGN.CENTER, bevelled: false }, adjustChild_displaystyle: function (n) {return false}, adjustChild_scriptlevel: function (n) { var level = this.Get("scriptlevel"); if (!this.Get("displaystyle") || level > 0) {level++} return level; }, adjustChild_texprimestyle: function (n) { if (n == this.den) {return true} return this.Get("texprimestyle"); }, setTeXclass: MML.mbase.setSeparateTeXclasses }); MML.msqrt = MML.mbase.Subclass({ type: "msqrt", inferRow: true, linebreakContainer: true, texClass: MML.TEXCLASS.ORD, setTeXclass: MML.mbase.setSeparateTeXclasses, adjustChild_texprimestyle: function (n) {return true} }); MML.mroot = MML.mbase.Subclass({ type: "mroot", linebreakContainer: true, texClass: MML.TEXCLASS.ORD, adjustChild_displaystyle: function (n) { if (n === 1) {return false} return this.Get("displaystyle"); }, adjustChild_scriptlevel: function (n) { var level = this.Get("scriptlevel"); if (n === 1) {level += 2} return level; }, adjustChild_texprimestyle: function (n) { if (n === 0) {return true}; return this.Get("texprimestyle"); }, setTeXclass: MML.mbase.setSeparateTeXclasses }); MML.mstyle = MML.mbase.Subclass({ type: "mstyle", isSpacelike: MML.mbase.childrenSpacelike, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, inferRow: true, defaults: { scriptlevel: MML.INHERIT, displaystyle: MML.INHERIT, scriptsizemultiplier: Math.sqrt(1/2), scriptminsize: "8pt", mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, dir: MML.INHERIT, infixlinebreakstyle: MML.LINEBREAKSTYLE.BEFORE, decimalseparator: "." }, adjustChild_scriptlevel: function (n) { var level = this.scriptlevel; if (level == null) { level = this.Get("scriptlevel"); } else if (String(level).match(/^ *[-+]/)) { var LEVEL = this.Get("scriptlevel",null,true); level = LEVEL + parseInt(level); } return level; }, inheritFromMe: true, noInherit: { mpadded: {width: true, height: true, depth: true, lspace: true, voffset: true}, mtable: {width: true, height: true, depth: true, align: true} }, getRemoved: {fontfamily:"fontFamily", fontweight:"fontWeight", fontstyle:"fontStyle", fontsize:"fontSize"}, setTeXclass: MML.mbase.setChildTeXclass }); MML.merror = MML.mbase.Subclass({ type: "merror", inferRow: true, linebreakContainer: true, texClass: MML.TEXCLASS.ORD }); MML.mpadded = MML.mbase.Subclass({ type: "mpadded", inferRow: true, isSpacelike: MML.mbase.childrenSpacelike, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, width: "", height: "", depth: "", lspace: 0, voffset: 0 }, setTeXclass: MML.mbase.setChildTeXclass }); MML.mphantom = MML.mbase.Subclass({ type: "mphantom", texClass: MML.TEXCLASS.ORD, inferRow: true, isSpacelike: MML.mbase.childrenSpacelike, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, setTeXclass: MML.mbase.setChildTeXclass }); MML.mfenced = MML.mbase.Subclass({ type: "mfenced", defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, open: '(', close: ')', separators: ',' }, addFakeNodes: function () { var values = this.getValues("open","close","separators"); values.open = values.open.replace(/[ \t\n\r]/g,""); values.close = values.close.replace(/[ \t\n\r]/g,""); values.separators = values.separators.replace(/[ \t\n\r]/g,""); // // Create a fake node for the open item // if (values.open !== "") { this.SetData("open",MML.mo(values.open).With({ fence:true, form:MML.FORM.PREFIX, texClass:MML.TEXCLASS.OPEN })); // // Clear flag for using MML spacing even though form is specified // this.data.open.useMMLspacing = 0; } // // Create fake nodes for the separators // if (values.separators !== "") { while (values.separators.length < this.data.length) {values.separators += values.separators.charAt(values.separators.length-1)} for (var i = 1, m = this.data.length; i < m; i++) { if (this.data[i]) { this.SetData("sep"+i,MML.mo(values.separators.charAt(i-1)).With({separator:true})) this.data["sep"+i].useMMLspacing = 0; } } } // // Create fake node for the close item // if (values.close !== "") { this.SetData("close",MML.mo(values.close).With({ fence:true, form:MML.FORM.POSTFIX, texClass:MML.TEXCLASS.CLOSE })); // // Clear flag for using MML spacing even though form is specified // this.data.close.useMMLspacing = 0; } }, texClass: MML.TEXCLASS.OPEN, setTeXclass: function (prev) { this.addFakeNodes(); this.getPrevClass(prev); if (this.data.open) {prev = this.data.open.setTeXclass(prev)} if (this.data[0]) {prev = this.data[0].setTeXclass(prev)} for (var i = 1, m = this.data.length; i < m; i++) { if (this.data["sep"+i]) {prev = this.data["sep"+i].setTeXclass(prev)} if (this.data[i]) {prev = this.data[i].setTeXclass(prev)} } if (this.data.close) {prev = this.data.close.setTeXclass(prev)} this.updateTeXclass(this.data.open); this.texClass = MML.TEXCLASS.INNER; return prev; } }); MML.menclose = MML.mbase.Subclass({ type: "menclose", inferRow: true, linebreakContainer: true, defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, notation: MML.NOTATION.LONGDIV, texClass: MML.TEXCLASS.ORD }, setTeXclass: MML.mbase.setSeparateTeXclasses }); MML.msubsup = MML.mbase.Subclass({ type: "msubsup", base: 0, sub: 1, sup: 2, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, subscriptshift: "", superscriptshift: "", texClass: MML.AUTO }, autoDefault: function (name) { if (name === "texClass") {return (this.isEmbellished() ? this.CoreMO().Get(name) : MML.TEXCLASS.ORD)} return 0; }, adjustChild_displaystyle: function (n) { if (n > 0) {return false} return this.Get("displaystyle"); }, adjustChild_scriptlevel: function (n) { var level = this.Get("scriptlevel"); if (n > 0) {level++} return level; }, adjustChild_texprimestyle: function (n) { if (n === this.sub) {return true} return this.Get("texprimestyle"); }, setTeXclass: MML.mbase.setBaseTeXclasses }); MML.msub = MML.msubsup.Subclass({type: "msub"}); MML.msup = MML.msubsup.Subclass({type: "msup", sub:2, sup:1}); MML.mmultiscripts = MML.msubsup.Subclass({ type: "mmultiscripts", adjustChild_texprimestyle: function (n) { if (n % 2 === 1) {return true} return this.Get("texprimestyle"); } }); MML.mprescripts = MML.mbase.Subclass({type: "mprescripts"}); MML.none = MML.mbase.Subclass({type: "none"}); MML.munderover = MML.mbase.Subclass({ type: "munderover", base: 0, under: 1, over: 2, sub: 1, sup: 2, ACCENTS: ["", "accentunder", "accent"], linebreakContainer: true, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, accent: MML.AUTO, accentunder: MML.AUTO, align: MML.ALIGN.CENTER, texClass: MML.AUTO, subscriptshift: "", // when converted to msubsup by moveablelimits superscriptshift: "" // when converted to msubsup by moveablelimits }, autoDefault: function (name) { if (name === "texClass") {return (this.isEmbellished() ? this.CoreMO().Get(name) : MML.TEXCLASS.ORD)} if (name === "accent" && this.data[this.over]) {return this.data[this.over].CoreMO().Get("accent")} if (name === "accentunder" && this.data[this.under]) {return this.data[this.under].CoreMO().Get("accent")} return false; }, adjustChild_displaystyle: function (n) { if (n > 0) {return false} return this.Get("displaystyle"); }, adjustChild_scriptlevel: function (n) { var level = this.Get("scriptlevel"); var force = (this.data[this.base] && !this.Get("displaystyle") && this.data[this.base].CoreMO().Get("movablelimits")); if (n == this.under && (force || !this.Get("accentunder"))) {level++} if (n == this.over && (force || !this.Get("accent"))) {level++} return level; }, adjustChild_texprimestyle: function (n) { if (n === this.base && this.data[this.over]) {return true} return this.Get("texprimestyle"); }, setTeXclass: MML.mbase.setBaseTeXclasses }); MML.munder = MML.munderover.Subclass({type: "munder"}); MML.mover = MML.munderover.Subclass({ type: "mover", over: 1, under: 2, sup: 1, sub: 2, ACCENTS: ["", "accent", "accentunder"] }); MML.mtable = MML.mbase.Subclass({ type: "mtable", defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, align: MML.ALIGN.AXIS, rowalign: MML.ALIGN.BASELINE, columnalign: MML.ALIGN.CENTER, groupalign: "{left}", alignmentscope: true, columnwidth: MML.WIDTH.AUTO, width: MML.WIDTH.AUTO, rowspacing: "1ex", columnspacing: ".8em", rowlines: MML.LINES.NONE, columnlines: MML.LINES.NONE, frame: MML.LINES.NONE, framespacing: "0.4em 0.5ex", equalrows: false, equalcolumns: false, displaystyle: false, side: MML.SIDE.RIGHT, minlabelspacing: "0.8em", texClass: MML.TEXCLASS.ORD, useHeight: 1 }, adjustChild_displaystyle: function () { return (this.displaystyle != null ? this.displaystyle : this.defaults.displaystyle); }, inheritFromMe: true, noInherit: { mover: {align: true}, munder: {align: true}, munderover: {align: true}, mtable: { align: true, rowalign: true, columnalign: true, groupalign: true, alignmentscope: true, columnwidth: true, width: true, rowspacing: true, columnspacing: true, rowlines: true, columnlines: true, frame: true, framespacing: true, equalrows: true, equalcolumns: true, displaystyle: true, side: true, minlabelspacing: true, texClass: true, useHeight: 1 } }, linebreakContainer: true, Append: function () { for (var i = 0, m = arguments.length; i < m; i++) { if (!((arguments[i] instanceof MML.mtr) || (arguments[i] instanceof MML.mlabeledtr))) {arguments[i] = MML.mtr(arguments[i])} } this.SUPER(arguments).Append.apply(this,arguments); }, setTeXclass: MML.mbase.setSeparateTeXclasses }); MML.mtr = MML.mbase.Subclass({ type: "mtr", defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, rowalign: MML.INHERIT, columnalign: MML.INHERIT, groupalign: MML.INHERIT }, inheritFromMe: true, noInherit: { mrow: {rowalign: true, columnalign: true, groupalign: true}, mtable: {rowalign: true, columnalign: true, groupalign: true} }, linebreakContainer: true, Append: function () { for (var i = 0, m = arguments.length; i < m; i++) { if (!(arguments[i] instanceof MML.mtd)) {arguments[i] = MML.mtd(arguments[i])} } this.SUPER(arguments).Append.apply(this,arguments); }, setTeXclass: MML.mbase.setSeparateTeXclasses }); MML.mtd = MML.mbase.Subclass({ type: "mtd", inferRow: true, linebreakContainer: true, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, rowspan: 1, columnspan: 1, rowalign: MML.INHERIT, columnalign: MML.INHERIT, groupalign: MML.INHERIT }, setTeXclass: MML.mbase.setSeparateTeXclasses }); MML.maligngroup = MML.mbase.Subclass({ type: "maligngroup", isSpacelike: function () {return true}, defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, groupalign: MML.INHERIT }, inheritFromMe: true, noInherit: { mrow: {groupalign: true}, mtable: {groupalign: true} } }); MML.malignmark = MML.mbase.Subclass({ type: "malignmark", defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, edge: MML.SIDE.LEFT }, isSpacelike: function () {return true} }); MML.mlabeledtr = MML.mtr.Subclass({ type: "mlabeledtr" }); MML.maction = MML.mbase.Subclass({ type: "maction", defaults: { mathbackground: MML.INHERIT, mathcolor: MML.INHERIT, actiontype: MML.ACTIONTYPE.TOGGLE, selection: 1 }, selected: function () {return this.data[this.Get("selection")-1] || MML.NULL}, isEmbellished: function () {return this.selected().isEmbellished()}, isSpacelike: function () {return this.selected().isSpacelike()}, Core: function () {return this.selected().Core()}, CoreMO: function () {return this.selected().CoreMO()}, setTeXclass: function (prev) { if (this.Get("actiontype") === MML.ACTIONTYPE.TOOLTIP && this.data[1]) { // Make sure tooltip has proper spacing when typeset (see issue #412) this.data[1].setTeXclass(); } var selected = this.selected(); prev = selected.setTeXclass(prev); this.updateTeXclass(selected); return prev; } }); MML.semantics = MML.mbase.Subclass({ type: "semantics", notParent: true, isEmbellished: MML.mbase.childEmbellished, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, defaults: { definitionURL: null, encoding: null }, setTeXclass: MML.mbase.setChildTeXclass, getAnnotation: function (name) { var encodingList = MathJax.Hub.config.MathMenu.semanticsAnnotations[name]; if (encodingList) { for (var i = 0, m = this.data.length; i < m; i++) { var encoding = this.data[i].Get("encoding"); if (encoding) { for (var j = 0, n = encodingList.length; j < n; j++) { if (encodingList[j] === encoding) return this.data[i]; } } } } return null; } }); MML.annotation = MML.mbase.Subclass({ type: "annotation", isChars: true, linebreakContainer: true, defaults: { definitionURL: null, encoding: null, cd: "mathmlkeys", name: "", src: null } }); MML["annotation-xml"] = MML.mbase.Subclass({ type: "annotation-xml", linebreakContainer: true, defaults: { definitionURL: null, encoding: null, cd: "mathmlkeys", name: "", src: null } }); MML.math = MML.mstyle.Subclass({ type: "math", defaults: { mathvariant: MML.VARIANT.NORMAL, mathsize: MML.SIZE.NORMAL, mathcolor: "", // should be "black", but allow it to inherit from surrounding text mathbackground: MML.COLOR.TRANSPARENT, dir: "ltr", scriptlevel: 0, displaystyle: MML.AUTO, display: "inline", maxwidth: "", overflow: MML.OVERFLOW.LINEBREAK, altimg: "", 'altimg-width': "", 'altimg-height': "", 'altimg-valign': "", alttext: "", cdgroup: "", scriptsizemultiplier: Math.sqrt(1/2), scriptminsize: "8px", // should be 8pt, but that's too big infixlinebreakstyle: MML.LINEBREAKSTYLE.BEFORE, lineleading: "1ex", indentshift: "auto", // use user configuration indentalign: MML.INDENTALIGN.AUTO, indentalignfirst: MML.INDENTALIGN.INDENTALIGN, indentshiftfirst: MML.INDENTSHIFT.INDENTSHIFT, indentalignlast: MML.INDENTALIGN.INDENTALIGN, indentshiftlast: MML.INDENTSHIFT.INDENTSHIFT, decimalseparator: ".", texprimestyle: false // is it in TeX's C' style? }, autoDefault: function (name) { if (name === "displaystyle") {return this.Get("display") === "block"} return ""; }, linebreakContainer: true, setTeXclass: MML.mbase.setChildTeXclass, getAnnotation: function (name) { if (this.data.length != 1) return null; return this.data[0].getAnnotation(name); } }); MML.chars = MML.mbase.Subclass({ type: "chars", Append: function () {this.data.push.apply(this.data,arguments)}, value: function () {return this.data.join("")}, toString: function () {return this.data.join("")} }); MML.entity = MML.mbase.Subclass({ type: "entity", Append: function () {this.data.push.apply(this.data,arguments)}, value: function () { if (this.data[0].substr(0,2) === "#x") {return parseInt(this.data[0].substr(2),16)} else if (this.data[0].substr(0,1) === "#") {return parseInt(this.data[0].substr(1))} else {return 0} // FIXME: look up named entities from table }, toString: function () { var n = this.value(); if (n <= 0xFFFF) {return String.fromCharCode(n)} n -= 0x10000; return String.fromCharCode((n>>10)+0xD800, (n&0x3FF)+0xDC00); } }); MML.xml = MML.mbase.Subclass({ type: "xml", Init: function () { this.div = document.createElement("div"); return this.SUPER(arguments).Init.apply(this,arguments); }, Append: function () { for (var i = 0, m = arguments.length; i < m; i++) { var node = this.Import(arguments[i]); this.data.push(node); this.div.appendChild(node); } }, Import: function (node) { if (document.importNode) {return document.importNode(node,true)} // // IE < 9 doesn't have importNode, so fake it. // var nNode, i, m; if (node.nodeType === 1) { // ELEMENT_NODE nNode = document.createElement(node.nodeName); for (i = 0, m = node.attributes.length; i < m; i++) { var attribute = node.attributes[i]; if (attribute.specified && attribute.nodeValue != null && attribute.nodeValue != '') {nNode.setAttribute(attribute.nodeName,attribute.nodeValue)} if (attribute.nodeName === "style") {nNode.style.cssText = attribute.nodeValue} } if (node.className) {nNode.className = node.className} } else if (node.nodeType === 3 || node.nodeType === 4) { // TEXT_NODE or CDATA_SECTION_NODE nNode = document.createTextNode(node.nodeValue); } else if (node.nodeType === 8) { // COMMENT_NODE nNode = document.createComment(node.nodeValue); } else { return document.createTextNode(''); } for (i = 0, m = node.childNodes.length; i < m; i++) {nNode.appendChild(this.Import(node.childNodes[i]))} return nNode; }, value: function () {return this.div}, toString: function () {return this.div.innerHTML} }); MML.TeXAtom = MML.mbase.Subclass({ type: "texatom", linebreakContainer: true, inferRow: true, notParent: true, texClass: MML.TEXCLASS.ORD, Core: MML.mbase.childCore, CoreMO: MML.mbase.childCoreMO, isEmbellished: MML.mbase.childEmbellished, setTeXclass: function (prev) { this.data[0].setTeXclass(); return this.adjustTeXclass(prev); }, adjustTeXclass: MML.mo.prototype.adjustTeXclass }); MML.NULL = MML.mbase().With({type:"null"}); var TEXCLASS = MML.TEXCLASS; var MO = { ORD: [0,0,TEXCLASS.ORD], ORD11: [1,1,TEXCLASS.ORD], ORD21: [2,1,TEXCLASS.ORD], ORD02: [0,2,TEXCLASS.ORD], ORD55: [5,5,TEXCLASS.ORD], OP: [1,2,TEXCLASS.OP,{largeop: true, movablelimits: true, symmetric: true}], OPFIXED: [1,2,TEXCLASS.OP,{largeop: true, movablelimits: true}], INTEGRAL: [0,1,TEXCLASS.OP,{largeop: true, symmetric: true}], INTEGRAL2: [1,2,TEXCLASS.OP,{largeop: true, symmetric: true}], BIN3: [3,3,TEXCLASS.BIN], BIN4: [4,4,TEXCLASS.BIN], BIN01: [0,1,TEXCLASS.BIN], BIN5: [5,5,TEXCLASS.BIN], TALLBIN: [4,4,TEXCLASS.BIN,{stretchy: true}], BINOP: [4,4,TEXCLASS.BIN,{largeop: true, movablelimits: true}], REL: [5,5,TEXCLASS.REL], REL1: [1,1,TEXCLASS.REL,{stretchy: true}], REL4: [4,4,TEXCLASS.REL], RELSTRETCH: [5,5,TEXCLASS.REL,{stretchy: true}], RELACCENT: [5,5,TEXCLASS.REL,{accent: true}], WIDEREL: [5,5,TEXCLASS.REL,{accent: true, stretchy: true}], OPEN: [0,0,TEXCLASS.OPEN,{fence: true, stretchy: true, symmetric: true}], CLOSE: [0,0,TEXCLASS.CLOSE,{fence: true, stretchy: true, symmetric: true}], INNER: [0,0,TEXCLASS.INNER], PUNCT: [0,3,TEXCLASS.PUNCT], ACCENT: [0,0,TEXCLASS.ORD,{accent: true}], WIDEACCENT: [0,0,TEXCLASS.ORD,{accent: true, stretchy: true}] }; MML.mo.Augment({ SPACE: [ '0em', '0.1111em', '0.1667em', '0.2222em', '0.2667em', '0.3333em' ], RANGES: [ [0x20,0x7F,TEXCLASS.REL,"BasicLatin"], [0xA0,0xFF,TEXCLASS.ORD,"Latin1Supplement"], [0x100,0x17F,TEXCLASS.ORD], [0x180,0x24F,TEXCLASS.ORD], [0x2B0,0x2FF,TEXCLASS.ORD,"SpacingModLetters"], [0x300,0x36F,TEXCLASS.ORD,"CombDiacritMarks"], [0x370,0x3FF,TEXCLASS.ORD,"GreekAndCoptic"], [0x1E00,0x1EFF,TEXCLASS.ORD], [0x2000,0x206F,TEXCLASS.PUNCT,"GeneralPunctuation"], [0x2070,0x209F,TEXCLASS.ORD], [0x20A0,0x20CF,TEXCLASS.ORD], [0x20D0,0x20FF,TEXCLASS.ORD,"CombDiactForSymbols"], [0x2100,0x214F,TEXCLASS.ORD,"LetterlikeSymbols"], [0x2150,0x218F,TEXCLASS.ORD], [0x2190,0x21FF,TEXCLASS.REL,"Arrows"], [0x2200,0x22FF,TEXCLASS.BIN,"MathOperators"], [0x2300,0x23FF,TEXCLASS.ORD,"MiscTechnical"], [0x2460,0x24FF,TEXCLASS.ORD], [0x2500,0x259F,TEXCLASS.ORD], [0x25A0,0x25FF,TEXCLASS.ORD,"GeometricShapes"], [0x2700,0x27BF,TEXCLASS.ORD,"Dingbats"], [0x27C0,0x27EF,TEXCLASS.ORD,"MiscMathSymbolsA"], [0x27F0,0x27FF,TEXCLASS.REL,"SupplementalArrowsA"], [0x2900,0x297F,TEXCLASS.REL,"SupplementalArrowsB"], [0x2980,0x29FF,TEXCLASS.ORD,"MiscMathSymbolsB"], [0x2A00,0x2AFF,TEXCLASS.BIN,"SuppMathOperators"], [0x2B00,0x2BFF,TEXCLASS.ORD,"MiscSymbolsAndArrows"], [0x1D400,0x1D7FF,TEXCLASS.ORD] ], OPTABLE: { prefix: { '\u2200': MO.ORD21, // for all '\u2202': MO.ORD21, // partial differential '\u2203': MO.ORD21, // there exists '\u2207': MO.ORD21, // nabla '\u220F': MO.OP, // n-ary product '\u2210': MO.OP, // n-ary coproduct '\u2211': MO.OP, // n-ary summation '\u2212': MO.BIN01, // minus sign '\u2213': MO.BIN01, // minus-or-plus sign '\u221A': [1,1,TEXCLASS.ORD,{stretchy: true}], // square root '\u2220': MO.ORD, // angle '\u222B': MO.INTEGRAL, // integral '\u222E': MO.INTEGRAL, // contour integral '\u22C0': MO.OP, // n-ary logical and '\u22C1': MO.OP, // n-ary logical or '\u22C2': MO.OP, // n-ary intersection '\u22C3': MO.OP, // n-ary union '\u2308': MO.OPEN, // left ceiling '\u230A': MO.OPEN, // left floor '\u27E8': MO.OPEN, // mathematical left angle bracket '\u27EE': MO.OPEN, // mathematical left flattened parenthesis '\u2A00': MO.OP, // n-ary circled dot operator '\u2A01': MO.OP, // n-ary circled plus operator '\u2A02': MO.OP, // n-ary circled times operator '\u2A04': MO.OP, // n-ary union operator with plus '\u2A06': MO.OP, // n-ary square union operator '\u00AC': MO.ORD21, // not sign '\u00B1': MO.BIN01, // plus-minus sign '(': MO.OPEN, // left parenthesis '+': MO.BIN01, // plus sign '-': MO.BIN01, // hyphen-minus '[': MO.OPEN, // left square bracket '{': MO.OPEN, // left curly bracket '|': MO.OPEN // vertical line }, postfix: { '!': [1,0,TEXCLASS.CLOSE], // exclamation mark '&': MO.ORD, // ampersand '\u2032': MO.ORD02, // prime '\u203E': MO.WIDEACCENT, // overline '\u2309': MO.CLOSE, // right ceiling '\u230B': MO.CLOSE, // right floor '\u23DE': MO.WIDEACCENT, // top curly bracket '\u23DF': MO.WIDEACCENT, // bottom curly bracket '\u266D': MO.ORD02, // music flat sign '\u266E': MO.ORD02, // music natural sign '\u266F': MO.ORD02, // music sharp sign '\u27E9': MO.CLOSE, // mathematical right angle bracket '\u27EF': MO.CLOSE, // mathematical right flattened parenthesis '\u02C6': MO.WIDEACCENT, // modifier letter circumflex accent '\u02C7': MO.WIDEACCENT, // caron '\u02C9': MO.WIDEACCENT, // modifier letter macron '\u02CA': MO.ACCENT, // modifier letter acute accent '\u02CB': MO.ACCENT, // modifier letter grave accent '\u02D8': MO.ACCENT, // breve '\u02D9': MO.ACCENT, // dot above '\u02DC': MO.WIDEACCENT, // small tilde '\u0302': MO.WIDEACCENT, // combining circumflex accent '\u00A8': MO.ACCENT, // diaeresis '\u00AF': MO.WIDEACCENT, // macron ')': MO.CLOSE, // right parenthesis ']': MO.CLOSE, // right square bracket '^': MO.WIDEACCENT, // circumflex accent '_': MO.WIDEACCENT, // low line '`': MO.ACCENT, // grave accent '|': MO.CLOSE, // vertical line '}': MO.CLOSE, // right curly bracket '~': MO.WIDEACCENT // tilde }, infix: { '': MO.ORD, // empty '%': [3,3,TEXCLASS.ORD], // percent sign '\u2022': MO.BIN4, // bullet '\u2026': MO.INNER, // horizontal ellipsis '\u2044': MO.TALLBIN, // fraction slash '\u2061': MO.ORD, // function application '\u2062': MO.ORD, // invisible times '\u2063': [0,0,TEXCLASS.ORD,{linebreakstyle:"after", separator: true}], // invisible separator '\u2064': MO.ORD, // invisible plus '\u2190': MO.WIDEREL, // leftwards arrow '\u2191': MO.RELSTRETCH, // upwards arrow '\u2192': MO.WIDEREL, // rightwards arrow '\u2193': MO.RELSTRETCH, // downwards arrow '\u2194': MO.WIDEREL, // left right arrow '\u2195': MO.RELSTRETCH, // up down arrow '\u2196': MO.RELSTRETCH, // north west arrow '\u2197': MO.RELSTRETCH, // north east arrow '\u2198': MO.RELSTRETCH, // south east arrow '\u2199': MO.RELSTRETCH, // south west arrow '\u21A6': MO.WIDEREL, // rightwards arrow from bar '\u21A9': MO.WIDEREL, // leftwards arrow with hook '\u21AA': MO.WIDEREL, // rightwards arrow with hook '\u21BC': MO.WIDEREL, // leftwards harpoon with barb upwards '\u21BD': MO.WIDEREL, // leftwards harpoon with barb downwards '\u21C0': MO.WIDEREL, // rightwards harpoon with barb upwards '\u21C1': MO.WIDEREL, // rightwards harpoon with barb downwards '\u21CC': MO.WIDEREL, // rightwards harpoon over leftwards harpoon '\u21D0': MO.WIDEREL, // leftwards double arrow '\u21D1': MO.RELSTRETCH, // upwards double arrow '\u21D2': MO.WIDEREL, // rightwards double arrow '\u21D3': MO.RELSTRETCH, // downwards double arrow '\u21D4': MO.WIDEREL, // left right double arrow '\u21D5': MO.RELSTRETCH, // up down double arrow '\u2208': MO.REL, // element of '\u2209': MO.REL, // not an element of '\u220B': MO.REL, // contains as member '\u2212': MO.BIN4, // minus sign '\u2213': MO.BIN4, // minus-or-plus sign '\u2215': MO.TALLBIN, // division slash '\u2216': MO.BIN4, // set minus '\u2217': MO.BIN4, // asterisk operator '\u2218': MO.BIN4, // ring operator '\u2219': MO.BIN4, // bullet operator '\u221D': MO.REL, // proportional to '\u2223': MO.REL, // divides '\u2225': MO.REL, // parallel to '\u2227': MO.BIN4, // logical and '\u2228': MO.BIN4, // logical or '\u2229': MO.BIN4, // intersection '\u222A': MO.BIN4, // union '\u223C': MO.REL, // tilde operator '\u2240': MO.BIN4, // wreath product '\u2243': MO.REL, // asymptotically equal to '\u2245': MO.REL, // approximately equal to '\u2248': MO.REL, // almost equal to '\u224D': MO.REL, // equivalent to '\u2250': MO.REL, // approaches the limit '\u2260': MO.REL, // not equal to '\u2261': MO.REL, // identical to '\u2264': MO.REL, // less-than or equal to '\u2265': MO.REL, // greater-than or equal to '\u226A': MO.REL, // much less-than '\u226B': MO.REL, // much greater-than '\u227A': MO.REL, // precedes '\u227B': MO.REL, // succeeds '\u2282': MO.REL, // subset of '\u2283': MO.REL, // superset of '\u2286': MO.REL, // subset of or equal to '\u2287': MO.REL, // superset of or equal to '\u228E': MO.BIN4, // multiset union '\u2291': MO.REL, // square image of or equal to '\u2292': MO.REL, // square original of or equal to '\u2293': MO.BIN4, // square cap '\u2294': MO.BIN4, // square cup '\u2295': MO.BIN4, // circled plus '\u2296': MO.BIN4, // circled minus '\u2297': MO.BIN4, // circled times '\u2298': MO.BIN4, // circled division slash '\u2299': MO.BIN4, // circled dot operator '\u22A2': MO.REL, // right tack '\u22A3': MO.REL, // left tack '\u22A4': MO.ORD55, // down tack '\u22A5': MO.REL, // up tack '\u22A8': MO.REL, // true '\u22C4': MO.BIN4, // diamond operator '\u22C5': MO.BIN4, // dot operator '\u22C6': MO.BIN4, // star operator '\u22C8': MO.REL, // bowtie '\u22EE': MO.ORD55, // vertical ellipsis '\u22EF': MO.INNER, // midline horizontal ellipsis '\u22F1': [5,5,TEXCLASS.INNER], // down right diagonal ellipsis '\u25B3': MO.BIN4, // white up-pointing triangle '\u25B5': MO.BIN4, // white up-pointing small triangle '\u25B9': MO.BIN4, // white right-pointing small triangle '\u25BD': MO.BIN4, // white down-pointing triangle '\u25BF': MO.BIN4, // white down-pointing small triangle '\u25C3': MO.BIN4, // white left-pointing small triangle '\u2758': MO.REL, // light vertical bar '\u27F5': MO.WIDEREL, // long leftwards arrow '\u27F6': MO.WIDEREL, // long rightwards arrow '\u27F7': MO.WIDEREL, // long left right arrow '\u27F8': MO.WIDEREL, // long leftwards double arrow '\u27F9': MO.WIDEREL, // long rightwards double arrow '\u27FA': MO.WIDEREL, // long left right double arrow '\u27FC': MO.WIDEREL, // long rightwards arrow from bar '\u2A2F': MO.BIN4, // vector or cross product '\u2A3F': MO.BIN4, // amalgamation or coproduct '\u2AAF': MO.REL, // precedes above single-line equals sign '\u2AB0': MO.REL, // succeeds above single-line equals sign '\u00B1': MO.BIN4, // plus-minus sign '\u00B7': MO.BIN4, // middle dot '\u00D7': MO.BIN4, // multiplication sign '\u00F7': MO.BIN4, // division sign '*': MO.BIN3, // asterisk '+': MO.BIN4, // plus sign ',': [0,3,TEXCLASS.PUNCT,{linebreakstyle:"after", separator: true}], // comma '-': MO.BIN4, // hyphen-minus '.': [3,3,TEXCLASS.ORD], // full stop '/': MO.ORD11, // solidus ':': [1,2,TEXCLASS.REL], // colon ';': [0,3,TEXCLASS.PUNCT,{linebreakstyle:"after", separator: true}], // semicolon '<': MO.REL, // less-than sign '=': MO.REL, // equals sign '>': MO.REL, // greater-than sign '?': [1,1,TEXCLASS.CLOSE], // question mark '\\': MO.ORD, // reverse solidus '^': MO.ORD11, // circumflex accent '_': MO.ORD11, // low line '|': [2,2,TEXCLASS.ORD,{fence: true, stretchy: true, symmetric: true}], // vertical line '#': MO.ORD, // # '$': MO.ORD, // $ '\u002E': [0,3,TEXCLASS.PUNCT,{separator: true}], // \ldotp '\u02B9': MO.ORD, // prime '\u0300': MO.ACCENT, // \grave '\u0301': MO.ACCENT, // \acute '\u0303': MO.WIDEACCENT, // \tilde '\u0304': MO.ACCENT, // \bar '\u0306': MO.ACCENT, // \breve '\u0307': MO.ACCENT, // \dot '\u0308': MO.ACCENT, // \ddot '\u030C': MO.ACCENT, // \check '\u0332': MO.WIDEACCENT, // horizontal line '\u0338': MO.REL4, // \not '\u2015': [0,0,TEXCLASS.ORD,{stretchy: true}], // horizontal line '\u2017': [0,0,TEXCLASS.ORD,{stretchy: true}], // horizontal line '\u2020': MO.BIN3, // \dagger '\u2021': MO.BIN3, // \ddagger '\u20D7': MO.ACCENT, // \vec '\u2111': MO.ORD, // \Im '\u2113': MO.ORD, // \ell '\u2118': MO.ORD, // \wp '\u211C': MO.ORD, // \Re '\u2205': MO.ORD, // \emptyset '\u221E': MO.ORD, // \infty '\u2305': MO.BIN3, // barwedge '\u2306': MO.BIN3, // doublebarwedge '\u2322': MO.REL4, // \frown '\u2323': MO.REL4, // \smile '\u2329': MO.OPEN, // langle '\u232A': MO.CLOSE, // rangle '\u23AA': MO.ORD, // \bracevert '\u23AF': [0,0,TEXCLASS.ORD,{stretchy: true}], // \underline '\u23B0': MO.OPEN, // \lmoustache '\u23B1': MO.CLOSE, // \rmoustache '\u2500': MO.ORD, // horizontal line '\u25EF': MO.BIN3, // \bigcirc '\u2660': MO.ORD, // \spadesuit '\u2661': MO.ORD, // \heartsuit '\u2662': MO.ORD, // \diamondsuit '\u2663': MO.ORD, // \clubsuit '\u3008': MO.OPEN, // langle '\u3009': MO.CLOSE, // rangle '\uFE37': MO.WIDEACCENT, // horizontal brace down '\uFE38': MO.WIDEACCENT // horizontal brace up } } },{ OPTYPES: MO }); // // These are not in the W3C table, but FF works this way, // and it makes sense, so add it here // var OPTABLE = MML.mo.prototype.OPTABLE; OPTABLE.infix["^"] = MO.WIDEREL; OPTABLE.infix["_"] = MO.WIDEREL; OPTABLE.prefix["\u2223"] = MO.OPEN; OPTABLE.prefix["\u2225"] = MO.OPEN; OPTABLE.postfix["\u2223"] = MO.CLOSE; OPTABLE.postfix["\u2225"] = MO.CLOSE; })(MathJax.ElementJax.mml); MathJax.ElementJax.mml.loadComplete("jax.js");