Math/modules/MathJax/jax/element/mml/jax.js

1606 lines
56 KiB
JavaScript

/*************************************************************
*
* 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-2012 Design Science, Inc.
*
* 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.0",
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}
}
}
}
},{
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",
VERTICALSTRIKE: "verticalstrike",
HORIZONTALSTRIKE: "horizontalstrike",
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"],
copyAttributes: {
fontfamily:true, fontsize:true, fontweight:true, fontstyle:true,
color:true, background:true,
id:true, "class":true, href:true, style:true
},
skipAttributes: {texClass: true, useHeight: true, texprimestyle: true},
copyAttributeNames: [
"fontfamily", "fontsize", "fontweight", "fontstyle",
"color", "background",
"id", "class", "href", "style"
]
});
(function (MML) {
MML.mbase = MathJax.Object.Subclass({
type: "base", isToken: false,
defaults: {
mathbackground: MML.INHERIT,
mathcolor: MML.INHERIT
},
noInherit: {},
noInheritAttribute: {
texClass: true
},
linebreakContainer: false,
Init: function () {
this.data = [];
if (this.inferRow && !(arguments.length === 1 && arguments[0].inferred))
{this.Append(MML.mrow().With({inferred: 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 ? 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.inferred) {parent = parent.parent}
return parent;
},
Get: function (name,nodefault) {
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])(parent.childPosition(this))}
var obj = this.inherit; var root = obj;
while (obj) {
var value = obj[name]; if (value == null && obj.attr) {value = obj.attr[name]}
if (value != null && !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) {return this.Get("scriptlevel")}, // always inherit from parent
adjustChild_displaystyle: function (i) {return this.Get("displaystyle")}, // always inherit from parent
adjustChild_texprimestyle: function (i) {return this.Get("texprimestyle")}, // always inherit from parent
childPosition: function (child) {
if (child.parent.inferred) {child = child.parent}
for (var i = 0, m = this.data.length; i < m; i++) {if (this.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},
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(",")+")"}
},{
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.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.isEmbellished()) {
prev = this.data[0].setTeXclass(prev);
this.updateTeXclass(this.Core());
} else {if (this.data[0]) {this.data[0].setTeXclass()}; 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
},
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 "";
}
});
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
}
});
MML.mo = MML.mbase.Subclass({
type: "mo", isToken: true,
defaults: {
mathvariant: MML.INHERIT,
mathsize: MML.INHERIT,
mathbackground: MML.INHERIT,
mathcolor: 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: true,
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)}
def.form = forms[0];
this.def = def;
}
}
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)},
setTeXclass: function (prev) {
this.getValues("lspace","rspace"); // sets useMMLspacing
if (this.useMMLspacing) {this.texClass = MML.TEXCLASS.NONE; return this}
this.texClass = this.Get("texClass"); if (this.texClass === MML.TEXCLASS.NONE) {return prev}
if (prev) {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;
}
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
}
});
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
},
hasNewline: function () {return (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,
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,
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) {
for (var i = 0, m = this.data.length; i < m; i++)
{if (this.data[i]) {prev = this.data[i].setTeXclass(prev)}}
if (this.data[0]) {this.updateTeXclass(this.data[0])}
return prev;
}
});
MML.mfrac = MML.mbase.Subclass({
type: "mfrac", num: 0, den: 1,
linebreakContainer: true,
texClass: MML.TEXCLASS.INNER,
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,
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(/^ *[-+]/)) {
delete this.scriptlevel;
var LEVEL = this.Get("scriptlevel");
this.scriptlevel = level;
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}
},
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: ','
},
texClass: MML.TEXCLASS.OPEN,
setTeXclass: function (prev) {
this.getPrevClass(prev);
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({stretchy:true, texClass:MML.TEXCLASS.OPEN}));
prev = this.data.open.setTeXclass(prev);
}
// get the separators
if (values.separators !== "") {
while (values.separators.length < this.data.length)
{values.separators += values.separators.charAt(values.separators.length-1)}
}
// handle the first item, if any
if (this.data[0]) {prev = this.data[0].setTeXclass(prev)}
// add fake nodes for separators and handle the following item
for (var i = 1, m = this.data.length; i < m; i++) {
if (this.data[i]) {
if (values.separators !== "") {
this.SetData("sep"+i,MML.mo(values.separators.charAt(i-1)));
prev = this.data["sep"+i].setTeXclass(prev);
}
prev = this.data[i].setTeXclass(prev);
}
}
// create fake node for the close item
if (values.close !== "") {
this.SetData("close",MML.mo(values.close).With({stretchy:true, texClass:MML.TEXCLASS.CLOSE}));
prev = this.data.close.setTeXclass(prev);
}
// get the data from the open item
this.updateTeXclass(this.data.open);
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,
linebreakContainer: true,
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
},
inheritFromMe: true,
noInherit: {
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,
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.mtd(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: "malign",
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) {return this.selected().setTeXclass(prev)}
});
MML.semantics = MML.mbase.Subclass({
type: "semantics",
isEmbellished: MML.mbase.childEmbellished,
Core: MML.mbase.childCore,
CoreMO: MML.mbase.childCoreMO,
defaults: {
definitionURL: null,
encoding: null
},
setTeXclass: MML.mbase.setChildTeXclass
});
MML.annotation = MML.mbase.Subclass({
type: "annotation", isToken: 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,
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
});
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)
+ String.fromCharCode((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);
if (node.className) {nNode.className=iNode.className}
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",
inferRow: true,
texClass: MML.TEXCLASS.ORD,
setTeXclass: function (prev) {
this.getPrevClass(prev);
this.data[0].setTeXclass();
return this;
}
});
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 <mo>
'%': [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
//
MML.mo.prototype.OPTABLE.infix["^"] = MO.WIDEREL;
MML.mo.prototype.OPTABLE.infix["_"] = MO.WIDEREL;
})(MathJax.ElementJax.mml);
MathJax.ElementJax.mml.loadComplete("jax.js");