aboutsummaryrefslogtreecommitdiff
path: root/js/mathjax/extensions/TeX
diff options
context:
space:
mode:
Diffstat (limited to 'js/mathjax/extensions/TeX')
-rw-r--r--js/mathjax/extensions/TeX/AMScd.js160
-rw-r--r--js/mathjax/extensions/TeX/AMSmath.js665
-rw-r--r--js/mathjax/extensions/TeX/AMSsymbols.js351
-rw-r--r--js/mathjax/extensions/TeX/HTML.js108
-rw-r--r--js/mathjax/extensions/TeX/action.js85
-rw-r--r--js/mathjax/extensions/TeX/autobold.js52
-rw-r--r--js/mathjax/extensions/TeX/autoload-all.js85
-rw-r--r--js/mathjax/extensions/TeX/bbox.js104
-rw-r--r--js/mathjax/extensions/TeX/begingroup.js294
-rw-r--r--js/mathjax/extensions/TeX/boldsymbol.js77
-rw-r--r--js/mathjax/extensions/TeX/cancel.js112
-rw-r--r--js/mathjax/extensions/TeX/color.js283
-rw-r--r--js/mathjax/extensions/TeX/enclose.js93
-rw-r--r--js/mathjax/extensions/TeX/extpfeil.js104
-rw-r--r--js/mathjax/extensions/TeX/mathchoice.js109
-rw-r--r--js/mathjax/extensions/TeX/mediawiki-texvc.js138
-rw-r--r--js/mathjax/extensions/TeX/mhchem.js522
-rw-r--r--js/mathjax/extensions/TeX/mhchem3/mhchem.js1776
-rw-r--r--js/mathjax/extensions/TeX/newcommand.js272
-rw-r--r--js/mathjax/extensions/TeX/noErrors.js407
-rw-r--r--js/mathjax/extensions/TeX/noUndefined.js74
-rw-r--r--js/mathjax/extensions/TeX/text-macros.js489
-rw-r--r--js/mathjax/extensions/TeX/unicode.js172
-rw-r--r--js/mathjax/extensions/TeX/verb.js63
24 files changed, 6595 insertions, 0 deletions
diff --git a/js/mathjax/extensions/TeX/AMScd.js b/js/mathjax/extensions/TeX/AMScd.js
new file mode 100644
index 0000000..d6bee02
--- /dev/null
+++ b/js/mathjax/extensions/TeX/AMScd.js
@@ -0,0 +1,160 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/AMScd.js
+ *
+ * Implements the CD environment for commutative diagrams.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2013-2020 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.Extension["TeX/AMScd"] = {
+ version: "2.7.9",
+ config: MathJax.Hub.CombineConfig("TeX.CD",{
+ colspace: "5pt",
+ rowspace: "5pt",
+ harrowsize: "2.75em",
+ varrowsize: "1.75em",
+ hideHorizontalLabels: false
+ })
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+ var MML = MathJax.ElementJax.mml,
+ TEX = MathJax.InputJax.TeX,
+ STACKITEM = TEX.Stack.Item,
+ TEXDEF = TEX.Definitions,
+ CONFIG = MathJax.Extension["TeX/AMScd"].config;
+
+ TEXDEF.environment.CD = "CD_env";
+ TEXDEF.special["@"] = "CD_arrow";
+ TEXDEF.macros.minCDarrowwidth = "CD_minwidth";
+ TEXDEF.macros.minCDarrowheight = "CD_minheight";
+
+ TEX.Parse.Augment({
+ //
+ // Implements \begin{CD}...\end{CD}
+ //
+ CD_env: function (begin) {
+ this.Push(begin);
+ return STACKITEM.array().With({
+ arraydef: {
+ columnalign: "center",
+ columnspacing: CONFIG.colspace,
+ rowspacing: CONFIG.rowspace,
+ displaystyle: true
+ },
+ minw: this.stack.env.CD_minw || CONFIG.harrowsize,
+ minh: this.stack.env.CD_minh || CONFIG.varrowsize
+ });
+ },
+
+ CD_arrow: function (name) {
+ var c = this.string.charAt(this.i);
+ if (!c.match(/[><VA.|=]/)) {return this.Other(name)} else {this.i++}
+
+ var top = this.stack.Top();
+ if (!top.isa(STACKITEM.array) || top.data.length) {
+ this.CD_cell(name);
+ top = this.stack.Top();
+ }
+ //
+ // Add enough cells to place the arrow correctly
+ //
+ var arrowRow = ((top.table.length % 2) === 1);
+ var n = (top.row.length + (arrowRow ? 0 : 1)) % 2;
+ while (n) {this.CD_cell(name); n--}
+
+ var mml;
+ var hdef = {minsize: top.minw, stretchy:true},
+ vdef = {minsize: top.minh, stretchy:true, symmetric:true, lspace:0, rspace:0};
+
+ if (c === ".") {}
+ else if (c === "|") {mml = this.mmlToken(MML.mo("\u2225").With(vdef))}
+ else if (c === "=") {mml = this.mmlToken(MML.mo("=").With(hdef))}
+ else {
+ //
+ // for @>>> @<<< @VVV and @AAA, get the arrow and labels
+ //
+ var arrow = {">":"\u2192", "<":"\u2190", V:"\u2193", A:"\u2191"}[c];
+ var a = this.GetUpTo(name+c,c),
+ b = this.GetUpTo(name+c,c);
+
+ if (c === ">" || c === "<") {
+ //
+ // Lay out horizontal arrows with munderover if it has labels
+ //
+ mml = MML.mo(arrow).With(hdef);
+ if (!a) {a = "\\kern "+top.minw} // minsize needs work
+ if (a || b) {
+ var pad = {width:"+11mu", lspace:"6mu"};
+ mml = MML.munderover(this.mmlToken(mml));
+ if (a) {
+ a = TEX.Parse(a,this.stack.env).mml();
+ mml.SetData(mml.over,MML.mpadded(a).With(pad).With({voffset:".1em"}));
+ }
+ if (b) {
+ b = TEX.Parse(b,this.stack.env).mml();
+ mml.SetData(mml.under,MML.mpadded(b).With(pad));
+ }
+ if (CONFIG.hideHorizontalLabels)
+ {mml = MML.mpadded(mml).With({depth:0, height:".67em"})}
+ }
+ } else {
+ //
+ // Lay out vertical arrows with mrow if there are labels
+ //
+ mml = arrow = this.mmlToken(MML.mo(arrow).With(vdef));
+ if (a || b) {
+ mml = MML.mrow();
+ if (a) {mml.Append(TEX.Parse("\\scriptstyle\\llap{"+a+"}",this.stack.env).mml())}
+ mml.Append(arrow.With({texClass: MML.TEXCLASS.ORD}));
+ if (b) {mml.Append(TEX.Parse("\\scriptstyle\\rlap{"+b+"}",this.stack.env).mml())}
+ }
+ }
+ }
+ if (mml) {this.Push(mml)};
+ this.CD_cell(name);
+ },
+ CD_cell: function (name) {
+ var top = this.stack.Top();
+ if ((top.table||[]).length % 2 === 0 && (top.row||[]).length === 0) {
+ //
+ // Add a strut to the first cell in even rows to get
+ // better spacing of arrow rows.
+ //
+ this.Push(MML.mpadded().With({height:"8.5pt",depth:"2pt"}));
+ }
+ this.Push(STACKITEM.cell().With({isEntry:true, name:name}));
+ },
+
+ CD_minwidth: function (name) {
+ this.stack.env.CD_minw = this.GetDimen(name);
+ },
+ CD_minheight: function (name) {
+ this.stack.env.CD_minh = this.GetDimen(name);
+ }
+
+ });
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/AMScd.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/AMSmath.js b/js/mathjax/extensions/TeX/AMSmath.js
new file mode 100644
index 0000000..70d5183
--- /dev/null
+++ b/js/mathjax/extensions/TeX/AMSmath.js
@@ -0,0 +1,665 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/AMSmath.js
+ *
+ * Implements AMS math environments and macros.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2020 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.Extension["TeX/AMSmath"] = {
+ version: "2.7.9",
+
+ number: 0, // current equation number
+ startNumber: 0, // current starting equation number (for when equation is restarted)
+ IDs: {}, // IDs used in previous equations
+ eqIDs: {}, // IDs used in this equation
+ labels: {}, // the set of labels
+ eqlabels: {}, // labels in the current equation
+ refs: [] // array of jax with unresolved references
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+
+ var MML = MathJax.ElementJax.mml,
+ TEX = MathJax.InputJax.TeX,
+ AMS = MathJax.Extension["TeX/AMSmath"];
+
+ var TEXDEF = TEX.Definitions,
+ STACKITEM = TEX.Stack.Item,
+ CONFIG = TEX.config.equationNumbers;
+
+ var COLS = function (W) {
+ var WW = [];
+ for (var i = 0, m = W.length; i < m; i++)
+ {WW[i] = TEX.Parse.prototype.Em(W[i])}
+ return WW.join(" ");
+ };
+
+ //
+ // Get the URL of the page (for use with formatURL) when there
+ // is a <base> element on the page.
+ //
+ var baseURL = (document.getElementsByTagName("base").length === 0) ? "" :
+ String(document.location).replace(/#.*$/,"");
+
+
+ /******************************************************************************/
+
+ TEXDEF.Add({
+ mathchar0mo: {
+ iiiint: ['2A0C',{texClass: MML.TEXCLASS.OP}]
+ },
+
+ macros: {
+ mathring: ['Accent','2DA'], // or 0x30A
+
+ nobreakspace: 'Tilde',
+ negmedspace: ['Spacer',MML.LENGTH.NEGATIVEMEDIUMMATHSPACE],
+ negthickspace: ['Spacer',MML.LENGTH.NEGATIVETHICKMATHSPACE],
+
+// intI: ['Macro','\\mathchoice{\\!}{}{}{}\\!\\!\\int'],
+// iint: ['MultiIntegral','\\int\\intI'], // now in core TeX input jax
+// iiint: ['MultiIntegral','\\int\\intI\\intI'], // now in core TeX input jax
+// iiiint: ['MultiIntegral','\\int\\intI\\intI\\intI'], // now in mathchar0mo above
+ idotsint: ['MultiIntegral','\\int\\cdots\\int'],
+
+// dddot: ['Macro','\\mathop{#1}\\limits^{\\textstyle \\mathord{.}\\mathord{.}\\mathord{.}}',1],
+// ddddot: ['Macro','\\mathop{#1}\\limits^{\\textstyle \\mathord{.}\\mathord{.}\\mathord{.}\\mathord{.}}',1],
+ dddot: ['Accent','20DB'],
+ ddddot: ['Accent','20DC'],
+
+ sideset: ['Macro','\\mathop{\\mathop{\\rlap{\\phantom{#3}}}\\nolimits#1\\!\\mathop{#3}\\nolimits#2}',3],
+
+ boxed: ['Macro','\\fbox{$\\displaystyle{#1}$}',1],
+
+ tag: 'HandleTag',
+ notag: 'HandleNoTag',
+ label: 'HandleLabel',
+ ref: 'HandleRef',
+ eqref: ['HandleRef',true],
+
+ substack: ['Macro','\\begin{subarray}{c}#1\\end{subarray}',1],
+
+ injlim: ['NamedOp','inj&thinsp;lim'],
+ projlim: ['NamedOp','proj&thinsp;lim'],
+ varliminf: ['Macro','\\mathop{\\underline{\\mmlToken{mi}{lim}}}'],
+ varlimsup: ['Macro','\\mathop{\\overline{\\mmlToken{mi}{lim}}}'],
+ varinjlim: ['Macro','\\mathop{\\underrightarrow{\\mmlToken{mi}{lim}}}'],
+ varprojlim: ['Macro','\\mathop{\\underleftarrow{\\mmlToken{mi}{lim}}}'],
+
+ DeclareMathOperator: 'HandleDeclareOp',
+ operatorname: 'HandleOperatorName',
+ SkipLimits: 'SkipLimits',
+
+ genfrac: 'Genfrac',
+ frac: ['Genfrac',"","","",""],
+ tfrac: ['Genfrac',"","","",1],
+ dfrac: ['Genfrac',"","","",0],
+ binom: ['Genfrac',"(",")","0",""],
+ tbinom: ['Genfrac',"(",")","0",1],
+ dbinom: ['Genfrac',"(",")","0",0],
+
+ cfrac: 'CFrac',
+
+ shoveleft: ['HandleShove',MML.ALIGN.LEFT],
+ shoveright: ['HandleShove',MML.ALIGN.RIGHT],
+
+ xrightarrow: ['xArrow',0x2192,5,6],
+ xleftarrow: ['xArrow',0x2190,7,3]
+ },
+
+ environment: {
+ align: ['AMSarray',null,true,true, 'rlrlrlrlrlrl',COLS([0,2,0,2,0,2,0,2,0,2,0])],
+ 'align*': ['AMSarray',null,false,true, 'rlrlrlrlrlrl',COLS([0,2,0,2,0,2,0,2,0,2,0])],
+ multline: ['Multline',null,true],
+ 'multline*': ['Multline',null,false],
+ split: ['AMSarray',null,false,false,'rl',COLS([0])],
+ gather: ['AMSarray',null,true,true, 'c'],
+ 'gather*': ['AMSarray',null,false,true, 'c'],
+
+ alignat: ['AlignAt',null,true,true],
+ 'alignat*': ['AlignAt',null,false,true],
+ alignedat: ['AlignAt',null,false,false],
+
+ aligned: ['AlignedAMSArray',null,null,null,'rlrlrlrlrlrl',COLS([0,2,0,2,0,2,0,2,0,2,0]),".5em",'D'],
+ gathered: ['AlignedAMSArray',null,null,null,'c',null,".5em",'D'],
+
+ subarray: ['Array',null,null,null,null,COLS([0]),"0.1em",'S',1],
+ smallmatrix: ['Array',null,null,null,'c',COLS([1/3]),".2em",'S',1],
+
+ 'equation': ['EquationBegin','Equation',true],
+ 'equation*': ['EquationBegin','EquationStar',false],
+
+ eqnarray: ['AMSarray',null,true,true, 'rcl',"0 "+MML.LENGTH.THICKMATHSPACE,".5em"],
+ 'eqnarray*': ['AMSarray',null,false,true,'rcl',"0 "+MML.LENGTH.THICKMATHSPACE,".5em"]
+ },
+
+ delimiter: {
+ '\\lvert': ['007C',{texClass:MML.TEXCLASS.OPEN}],
+ '\\rvert': ['007C',{texClass:MML.TEXCLASS.CLOSE}],
+ '\\lVert': ['2016',{texClass:MML.TEXCLASS.OPEN}],
+ '\\rVert': ['2016',{texClass:MML.TEXCLASS.CLOSE}]
+ }
+ },null,true);
+
+
+ /******************************************************************************/
+
+ TEX.Parse.Augment({
+
+ /*
+ * Add the tag to the environment (to be added to the table row later)
+ */
+ HandleTag: function (name) {
+ var star = this.GetStar();
+ var arg = this.trimSpaces(this.GetArgument(name)), tag = arg;
+ if (!star) {arg = CONFIG.formatTag(arg)}
+ var global = this.stack.global; global.tagID = tag;
+ if (global.notags) {
+ TEX.Error(["CommandNotAllowedInEnv",
+ "%1 not allowed in %2 environment",
+ name,global.notags]
+ );
+ }
+ if (global.tag) {TEX.Error(["MultipleCommand","Multiple %1",name])}
+ global.tag = MML.mtd.apply(MML,this.InternalMath(arg)).With({id:CONFIG.formatID(tag)});
+ },
+ HandleNoTag: function (name) {
+ if (this.stack.global.tag) {delete this.stack.global.tag}
+ this.stack.global.notag = true; // prevent auto-tagging
+ },
+
+ /*
+ * Record a label name for a tag
+ */
+ HandleLabel: function (name) {
+ var global = this.stack.global, label = this.GetArgument(name);
+ if (label === "") return;
+ if (!AMS.refUpdate) {
+ if (global.label) {TEX.Error(["MultipleCommand","Multiple %1",name])}
+ global.label = label;
+ if (AMS.labels[label] || AMS.eqlabels[label])
+ {TEX.Error(["MultipleLabel","Label '%1' multiply defined",label])}
+ AMS.eqlabels[label] = {tag:"???", id:""}; // will be replaced by tag value later
+ }
+ },
+
+ /*
+ * Handle a label reference
+ */
+ HandleRef: function (name,eqref) {
+ var label = this.GetArgument(name);
+ var ref = AMS.labels[label] || AMS.eqlabels[label];
+ if (!ref) {ref = {tag:"???",id:""}; AMS.badref = !AMS.refUpdate}
+ var tag = ref.tag; if (eqref) {tag = CONFIG.formatTag(tag)}
+ this.Push(MML.mrow.apply(MML,this.InternalMath(tag)).With({
+ href:CONFIG.formatURL(ref.id,baseURL), "class":"MathJax_ref"
+ }));
+ },
+
+ /*
+ * Handle \DeclareMathOperator
+ */
+ HandleDeclareOp: function (name) {
+ var limits = (this.GetStar() ? "" : "\\nolimits\\SkipLimits");
+ var cs = this.trimSpaces(this.GetArgument(name));
+ if (cs.charAt(0) == "\\") {cs = cs.substr(1)}
+ var op = this.GetArgument(name);
+ if (!op.match(/\\text/)) op = op.replace(/\*/g,'\\text{*}').replace(/-/g,'\\text{-}');
+ this.setDef(cs, ['Macro', '\\mathop{\\rm '+op+'}'+limits]);
+ },
+
+ HandleOperatorName: function (name) {
+ var limits = (this.GetStar() ? "" : "\\nolimits\\SkipLimits");
+ var op = this.trimSpaces(this.GetArgument(name));
+ if (!op.match(/\\text/)) op = op.replace(/\*/g,'\\text{*}').replace(/-/g,'\\text{-}');
+ this.string = '\\mathop{\\rm '+op+'}'+limits+" "+this.string.slice(this.i);
+ this.i = 0;
+ },
+
+ SkipLimits: function (name) {
+ var c = this.GetNext(), i = this.i;
+ if (c === "\\" && ++this.i && this.GetCS() !== "limits") this.i = i;
+ },
+
+ /*
+ * Record presence of \shoveleft and \shoveright
+ */
+ HandleShove: function (name,shove) {
+ var top = this.stack.Top();
+ if (top.type !== "multline") {
+ TEX.Error(["CommandInMultline",
+ "%1 can only appear within the multline environment",name]);
+ }
+ if (top.data.length) {
+ TEX.Error(["CommandAtTheBeginingOfLine",
+ "%1 must come at the beginning of the line",name]);
+ }
+ top.data.shove = shove;
+ },
+
+ /*
+ * Handle \cfrac
+ */
+ CFrac: function (name) {
+ var lr = this.trimSpaces(this.GetBrackets(name,"")),
+ num = this.GetArgument(name),
+ den = this.GetArgument(name);
+ var frac = MML.mfrac(TEX.Parse('\\strut\\textstyle{'+num+'}',this.stack.env).mml(),
+ TEX.Parse('\\strut\\textstyle{'+den+'}',this.stack.env).mml());
+ lr = ({l:MML.ALIGN.LEFT, r:MML.ALIGN.RIGHT,"":""})[lr];
+ if (lr == null)
+ {TEX.Error(["IllegalAlign","Illegal alignment specified in %1",name])}
+ if (lr) {frac.numalign = frac.denomalign = lr}
+ this.Push(frac);
+ },
+
+ /*
+ * Implement AMS generalized fraction
+ */
+ Genfrac: function (name,left,right,thick,style) {
+ if (left == null) {left = this.GetDelimiterArg(name)}
+ if (right == null) {right = this.GetDelimiterArg(name)}
+ if (thick == null) {thick = this.GetArgument(name)}
+ if (style == null) {style = this.trimSpaces(this.GetArgument(name))}
+ var num = this.ParseArg(name);
+ var den = this.ParseArg(name);
+ var frac = MML.mfrac(num,den);
+ if (thick !== "") {frac.linethickness = thick}
+ if (left || right) {frac = TEX.fixedFence(left,frac.With({texWithDelims:true}),right)}
+ if (style !== "") {
+ var STYLE = (["D","T","S","SS"])[style];
+ if (STYLE == null)
+ {TEX.Error(["BadMathStyleFor","Bad math style for %1",name])}
+ frac = MML.mstyle(frac);
+ if (STYLE === "D") {frac.displaystyle = true; frac.scriptlevel = 0}
+ else {frac.displaystyle = false; frac.scriptlevel = style - 1}
+ }
+ this.Push(frac);
+ },
+
+ /*
+ * Implements multline environment (mostly handled through STACKITEM below)
+ */
+ Multline: function (begin,numbered) {
+ this.Push(begin); this.checkEqnEnv();
+ return STACKITEM.multline(numbered,this.stack).With({
+ arraydef: {
+ displaystyle: true,
+ rowspacing: ".5em",
+ width: TEX.config.MultLineWidth, columnwidth:"100%",
+ side: TEX.config.TagSide,
+ minlabelspacing: TEX.config.TagIndent
+ }
+ });
+ },
+
+ /*
+ * Handle AMS aligned environments
+ */
+ AMSarray: function (begin,numbered,taggable,align,spacing) {
+ this.Push(begin); if (taggable) {this.checkEqnEnv()}
+ align = align.replace(/[^clr]/g,'').split('').join(' ');
+ align = align.replace(/l/g,'left').replace(/r/g,'right').replace(/c/g,'center');
+ return STACKITEM.AMSarray(begin.name,numbered,taggable,this.stack).With({
+ arraydef: {
+ displaystyle: true,
+ rowspacing: ".5em",
+ columnalign: align,
+ columnspacing: (spacing||"1em"),
+ rowspacing: "3pt",
+ side: TEX.config.TagSide,
+ minlabelspacing: TEX.config.TagIndent
+ }
+ });
+ },
+
+ AlignedAMSArray: function (begin) {
+ var align = this.GetBrackets("\\begin{"+begin.name+"}");
+ return this.setArrayAlign(this.AMSarray.apply(this,arguments),align);
+ },
+
+ /*
+ * Handle alignat environments
+ */
+ AlignAt: function (begin,numbered,taggable) {
+ var n, valign, align = "", spacing = [];
+ if (!taggable) {valign = this.GetBrackets("\\begin{"+begin.name+"}")}
+ n = this.GetArgument("\\begin{"+begin.name+"}");
+ if (n.match(/[^0-9]/)) {
+ TEX.Error(["PositiveIntegerArg","Argument to %1 must me a positive integer",
+ "\\begin{"+begin.name+"}"]);
+ }
+ while (n > 0) {align += "rl"; spacing.push("0em 0em"); n--}
+ spacing = spacing.join(" ");
+ if (taggable) {return this.AMSarray(begin,numbered,taggable,align,spacing)}
+ var array = this.AMSarray(begin,numbered,taggable,align,spacing);
+ return this.setArrayAlign(array,valign);
+ },
+
+ /*
+ * Handle equation environment
+ */
+ EquationBegin: function (begin,force) {
+ this.checkEqnEnv();
+ this.stack.global.forcetag = (force && CONFIG.autoNumber !== "none");
+ return begin;
+ },
+ EquationStar: function (begin,row) {
+ this.stack.global.tagged = true; // prevent automatic tagging
+ return row;
+ },
+
+ /*
+ * Check for bad nesting of equation environments
+ */
+ checkEqnEnv: function () {
+ if (this.stack.global.eqnenv)
+ {TEX.Error(["ErroneousNestingEq","Erroneous nesting of equation structures"])}
+ this.stack.global.eqnenv = true;
+ },
+
+ /*
+ * Handle multiple integrals (make a mathop if followed by limits)
+ */
+ MultiIntegral: function (name,integral) {
+ var next = this.GetNext();
+ if (next === "\\") {
+ var i = this.i; next = this.GetArgument(name); this.i = i;
+ if (next === "\\limits") {
+ if (name === "\\idotsint") {integral = "\\!\\!\\mathop{\\,\\,"+integral+"}"}
+ else {integral = "\\!\\!\\!\\mathop{\\,\\,\\,"+integral+"}"}
+ }
+ }
+ this.string = integral + " " + this.string.slice(this.i);
+ this.i = 0;
+ },
+
+ /*
+ * Handle stretchable arrows
+ */
+ xArrow: function (name,chr,l,r) {
+ var def = {width: "+"+(l+r)+"mu", lspace: l+"mu"};
+ var bot = this.GetBrackets(name),
+ top = this.ParseArg(name);
+ var arrow = MML.mo(MML.chars(String.fromCharCode(chr))).With({
+ stretchy: true, texClass: MML.TEXCLASS.REL
+ });
+ var mml = MML.munderover(arrow);
+ mml.SetData(mml.over,MML.mpadded(top).With(def).With({voffset:".15em"}));
+ if (bot) {
+ bot = TEX.Parse(bot,this.stack.env).mml()
+ mml.SetData(mml.under,MML.mpadded(bot).With(def).With({voffset:"-.24em"}));
+ }
+ this.Push(mml.With({subsupOK:true}));
+ },
+
+ /*
+ * Get a delimiter or empty argument
+ */
+ GetDelimiterArg: function (name) {
+ var c = this.trimSpaces(this.GetArgument(name));
+ if (c == "") return null;
+ if (c in TEXDEF.delimiter) return c;
+ TEX.Error(["MissingOrUnrecognizedDelim","Missing or unrecognized delimiter for %1",name]);
+ },
+
+ /*
+ * Get a star following a control sequence name, if any
+ */
+ GetStar: function () {
+ var star = (this.GetNext() === "*");
+ if (star) {this.i++}
+ return star;
+ }
+
+ });
+
+ /******************************************************************************/
+
+ STACKITEM.Augment({
+ /*
+ * Increment equation number and form tag mtd element
+ */
+ autoTag: function () {
+ var global = this.global;
+ if (!global.notag) {
+ AMS.number++; global.tagID = CONFIG.formatNumber(AMS.number.toString());
+ var mml = TEX.Parse("\\text{"+CONFIG.formatTag(global.tagID)+"}",{}).mml();
+ global.tag = MML.mtd(mml).With({id:CONFIG.formatID(global.tagID)});
+ }
+ },
+
+ /*
+ * Get the tag and record the label, if any
+ */
+ getTag: function () {
+ var global = this.global, tag = global.tag; global.tagged = true;
+ if (global.label) {
+ if (CONFIG.useLabelIds) {tag.id = CONFIG.formatID(global.label)}
+ AMS.eqlabels[global.label] = {tag:global.tagID, id:tag.id};
+ }
+ //
+ // Check for repeated ID's (either in the document or as
+ // a previous tag) and find a unique related one. (#240)
+ //
+ if (document.getElementById(tag.id) || AMS.IDs[tag.id] || AMS.eqIDs[tag.id]) {
+ var i = 0, ID;
+ do {i++; ID = tag.id+"_"+i}
+ while (document.getElementById(ID) || AMS.IDs[ID] || AMS.eqIDs[ID]);
+ tag.id = ID; if (global.label) {AMS.eqlabels[global.label].id = ID}
+ }
+ AMS.eqIDs[tag.id] = 1;
+ this.clearTag();
+ return tag;
+ },
+ clearTag: function () {
+ var global = this.global;
+ delete global.tag; delete global.tagID; delete global.label;
+ },
+
+ /*
+ * If the initial child, skipping any initial space or
+ * empty braces (TeXAtom with child being an empty inferred row),
+ * is an <mo>, precede it by an empty <mi> to force the <mo> to
+ * be infix.
+ */
+ fixInitialMO: function (data) {
+ for (var i = 0, m = data.length; i < m; i++) {
+ if (data[i] && (data[i].type !== "mspace" &&
+ (data[i].type !== "texatom" || (data[i].data[0] && data[i].data[0].data.length)))) {
+ if (data[i].isEmbellished() ||
+ (data[i].type === "texatom" && data[i].texClass === MML.TEXCLASS.REL)) data.unshift(MML.mi());
+ break;
+ }
+ }
+ }
+ });
+
+ /*
+ * Implement multline environment via a STACKITEM
+ */
+ STACKITEM.multline = STACKITEM.array.Subclass({
+ type: "multline",
+ Init: function (numbered,stack) {
+ this.SUPER(arguments).Init.apply(this);
+ this.numbered = (numbered && CONFIG.autoNumber !== "none");
+ this.save = {notag: stack.global.notag};
+ stack.global.tagged = !numbered && !stack.global.forcetag; // prevent automatic tagging in starred environments
+ },
+ EndEntry: function () {
+ if (this.table.length) {this.fixInitialMO(this.data)}
+ var mtd = MML.mtd.apply(MML,this.data);
+ if (this.data.shove) {mtd.columnalign = this.data.shove}
+ this.row.push(mtd);
+ this.data = [];
+ },
+ EndRow: function () {
+ if (this.row.length != 1) {
+ TEX.Error(["MultlineRowsOneCol",
+ "The rows within the %1 environment must have exactly one column",
+ "multline"]);
+ }
+ this.table.push(this.row); this.row = [];
+ },
+ EndTable: function () {
+ this.SUPER(arguments).EndTable.call(this);
+ if (this.table.length) {
+ var m = this.table.length-1, i, label = -1;
+ if (!this.table[0][0].columnalign) {this.table[0][0].columnalign = MML.ALIGN.LEFT}
+ if (!this.table[m][0].columnalign) {this.table[m][0].columnalign = MML.ALIGN.RIGHT}
+ if (!this.global.tag && this.numbered) {this.autoTag()}
+ if (this.global.tag && !this.global.notags) {
+ label = (this.arraydef.side === "left" ? 0 : this.table.length - 1);
+ this.table[label] = [this.getTag()].concat(this.table[label]);
+ }
+ for (i = 0, m = this.table.length; i < m; i++) {
+ var mtr = (i === label ? MML.mlabeledtr : MML.mtr);
+ this.table[i] = mtr.apply(MML,this.table[i]);
+ }
+ }
+ this.global.notag = this.save.notag;
+ }
+ });
+
+ /*
+ * Save data about numbering and taging equations, and add
+ * tags at the ends of rows.
+ */
+ STACKITEM.AMSarray = STACKITEM.array.Subclass({
+ type: "AMSarray",
+ Init: function (name,numbered,taggable,stack) {
+ this.SUPER(arguments).Init.apply(this);
+ this.numbered = (numbered && CONFIG.autoNumber !== "none");
+ this.save = {notags: stack.global.notags, notag: stack.global.notag};
+ stack.global.notags = (taggable ? null : name);
+ stack.global.tagged = !numbered && taggable && !stack.global.forcetag; // prevent automatic tagging in starred environments
+ },
+ EndEntry: function () {
+ if (this.row.length % 2 === 1) {this.fixInitialMO(this.data)}
+ this.row.push(MML.mtd.apply(MML,this.data));
+ this.data = [];
+ },
+ EndRow: function () {
+ var mtr = MML.mtr;
+ if (!this.global.tag && this.numbered) {this.autoTag()}
+ if (!this.global.notags) {
+ if (this.global.tag) {
+ this.row = [this.getTag()].concat(this.row);
+ mtr = MML.mlabeledtr;
+ } else {
+ this.clearTag();
+ }
+ }
+ if (this.numbered) {delete this.global.notag}
+ this.table.push(mtr.apply(MML,this.row)); this.row = [];
+ },
+ EndTable: function () {
+ this.SUPER(arguments).EndTable.call(this);
+ this.global.notags = this.save.notags;
+ this.global.notag = this.save.notag;
+ }
+ });
+
+ //
+ // Look for \tag on a formula and make an mtable to include it
+ //
+ STACKITEM.start.Augment({
+ oldCheckItem: STACKITEM.start.prototype.checkItem,
+ checkItem: function (item) {
+ if (item.type === "stop") {
+ var mml = this.mmlData(), global = this.global;
+ if (AMS.display && !global.tag && !global.tagged && !global.isInner &&
+ (CONFIG.autoNumber === "all" || global.forcetag)) {this.autoTag()}
+ if (global.tag) {
+ var row = [this.getTag(),MML.mtd(mml)];
+ var def = {
+ side: TEX.config.TagSide,
+ minlabelspacing: TEX.config.TagIndent,
+ displaystyle: "inherit" // replaced by TeX input jax Translate() function with actual value
+ };
+ mml = MML.mtable(MML.mlabeledtr.apply(MML,row)).With(def);
+ }
+ return STACKITEM.mml(mml);
+ }
+ return this.oldCheckItem.call(this,item);
+ }
+ });
+
+ /******************************************************************************/
+
+ /*
+ * Add pre- and post-filters to handle the equation number maintenance.
+ */
+ TEX.prefilterHooks.Add(function (data) {
+ AMS.display = data.display;
+ AMS.number = AMS.startNumber; // reset equation numbers (in case the equation restarted)
+ AMS.eqlabels = {};
+ AMS.eqIDs = {};
+ AMS.badref = false;
+ if (AMS.refUpdate) {AMS.number = data.script.MathJax.startNumber}
+ });
+ TEX.postfilterHooks.Add(function (data) {
+ data.script.MathJax.startNumber = AMS.startNumber;
+ AMS.startNumber = AMS.number; // equation numbers for next equation
+ MathJax.Hub.Insert(AMS.IDs,AMS.eqIDs); // save IDs from this equation
+ MathJax.Hub.Insert(AMS.labels,AMS.eqlabels); // save labels from this equation
+ if (AMS.badref && !data.math.texError) {AMS.refs.push(data.script)} // reprocess later
+ },100);
+
+ MathJax.Hub.Register.MessageHook("Begin Math Input",function () {
+ AMS.refs = []; // array of jax with bad references
+ AMS.refUpdate = false;
+ });
+ MathJax.Hub.Register.MessageHook("End Math Input",function (message) {
+ if (AMS.refs.length) {
+ AMS.refUpdate = true;
+ for (var i = 0, m = AMS.refs.length; i < m; i++)
+ {AMS.refs[i].MathJax.state = MathJax.ElementJax.STATE.UPDATE}
+ return MathJax.Hub.processInput({
+ scripts:AMS.refs,
+ start: new Date().getTime(),
+ i:0, j:0, jax:{}, jaxIDs:[]
+ });
+ }
+ return null;
+ });
+
+ //
+ // Clear the equation numbers and labels
+ //
+ TEX.resetEquationNumbers = function (n,keepLabels) {
+ AMS.startNumber = (n || 0);
+ if (!keepLabels) {
+ AMS.labels = {};
+ AMS.IDs = {};
+ }
+ }
+
+ /******************************************************************************/
+
+ MathJax.Hub.Startup.signal.Post("TeX AMSmath Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/AMSmath.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/AMSsymbols.js b/js/mathjax/extensions/TeX/AMSsymbols.js
new file mode 100644
index 0000000..ef7ae5f
--- /dev/null
+++ b/js/mathjax/extensions/TeX/AMSsymbols.js
@@ -0,0 +1,351 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/AMSsymbols.js
+ *
+ * Implements macros for accessing the AMS symbol fonts.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2020 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.Extension["TeX/AMSsymbols"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+ var MML = MathJax.ElementJax.mml,
+ TEXDEF = MathJax.InputJax.TeX.Definitions;
+
+ TEXDEF.Add({
+
+ mathchar0mi: {
+ // Lowercase Greek letters
+ digamma: '03DD',
+ varkappa: '03F0',
+
+ // Uppercase Greek letters
+ varGamma: ['0393',{mathvariant: MML.VARIANT.ITALIC}],
+ varDelta: ['0394',{mathvariant: MML.VARIANT.ITALIC}],
+ varTheta: ['0398',{mathvariant: MML.VARIANT.ITALIC}],
+ varLambda: ['039B',{mathvariant: MML.VARIANT.ITALIC}],
+ varXi: ['039E',{mathvariant: MML.VARIANT.ITALIC}],
+ varPi: ['03A0',{mathvariant: MML.VARIANT.ITALIC}],
+ varSigma: ['03A3',{mathvariant: MML.VARIANT.ITALIC}],
+ varUpsilon: ['03A5',{mathvariant: MML.VARIANT.ITALIC}],
+ varPhi: ['03A6',{mathvariant: MML.VARIANT.ITALIC}],
+ varPsi: ['03A8',{mathvariant: MML.VARIANT.ITALIC}],
+ varOmega: ['03A9',{mathvariant: MML.VARIANT.ITALIC}],
+
+ // Hebrew letters
+ beth: '2136',
+ gimel: '2137',
+ daleth: '2138',
+
+ // Miscellaneous symbols
+// hbar: '0127', // in TeX/jax.js
+ backprime: ['2035',{variantForm: true}],
+ hslash: '210F',
+ varnothing: ['2205',{variantForm: true}],
+ blacktriangle: '25B4',
+ triangledown: ['25BD',{variantForm: true}],
+ blacktriangledown: '25BE',
+ square: '25FB',
+ Box: '25FB',
+ blacksquare: '25FC',
+ lozenge: '25CA',
+ Diamond: '25CA',
+ blacklozenge: '29EB',
+ circledS: ['24C8',{mathvariant: MML.VARIANT.NORMAL}],
+ bigstar: '2605',
+// angle: '2220', // in TeX/jax.js
+ sphericalangle: '2222',
+ measuredangle: '2221',
+ nexists: '2204',
+ complement: '2201',
+ mho: '2127',
+ eth: ['00F0',{mathvariant: MML.VARIANT.NORMAL}],
+ Finv: '2132',
+ diagup: '2571',
+ Game: '2141',
+ diagdown: '2572',
+ Bbbk: ['006B',{mathvariant: MML.VARIANT.DOUBLESTRUCK}],
+
+ yen: '00A5',
+ circledR: '00AE',
+ checkmark: '2713',
+ maltese: '2720'
+ },
+
+ mathchar0mo: {
+ // Binary operators
+ dotplus: '2214',
+ ltimes: '22C9',
+ smallsetminus: '2216',
+ rtimes: '22CA',
+ Cap: '22D2',
+ doublecap: '22D2',
+ leftthreetimes: '22CB',
+ Cup: '22D3',
+ doublecup: '22D3',
+ rightthreetimes: '22CC',
+ barwedge: '22BC',
+ curlywedge: '22CF',
+ veebar: '22BB',
+ curlyvee: '22CE',
+ doublebarwedge: '2A5E',
+ boxminus: '229F',
+ circleddash: '229D',
+ boxtimes: '22A0',
+ circledast: '229B',
+ boxdot: '22A1',
+ circledcirc: '229A',
+ boxplus: '229E',
+ centerdot: ['22C5',{variantForm: true}],
+ divideontimes: '22C7',
+ intercal: '22BA',
+
+ // Binary relations
+ leqq: '2266',
+ geqq: '2267',
+ leqslant: '2A7D',
+ geqslant: '2A7E',
+ eqslantless: '2A95',
+ eqslantgtr: '2A96',
+ lesssim: '2272',
+ gtrsim: '2273',
+ lessapprox: '2A85',
+ gtrapprox: '2A86',
+ approxeq: '224A',
+ lessdot: '22D6',
+ gtrdot: '22D7',
+ lll: '22D8',
+ llless: '22D8',
+ ggg: '22D9',
+ gggtr: '22D9',
+ lessgtr: '2276',
+ gtrless: '2277',
+ lesseqgtr: '22DA',
+ gtreqless: '22DB',
+ lesseqqgtr: '2A8B',
+ gtreqqless: '2A8C',
+ doteqdot: '2251',
+ Doteq: '2251',
+ eqcirc: '2256',
+ risingdotseq: '2253',
+ circeq: '2257',
+ fallingdotseq: '2252',
+ triangleq: '225C',
+ backsim: '223D',
+ thicksim: ['223C',{variantForm: true}],
+ backsimeq: '22CD',
+ thickapprox: ['2248',{variantForm: true}],
+ subseteqq: '2AC5',
+ supseteqq: '2AC6',
+ Subset: '22D0',
+ Supset: '22D1',
+ sqsubset: '228F',
+ sqsupset: '2290',
+ preccurlyeq: '227C',
+ succcurlyeq: '227D',
+ curlyeqprec: '22DE',
+ curlyeqsucc: '22DF',
+ precsim: '227E',
+ succsim: '227F',
+ precapprox: '2AB7',
+ succapprox: '2AB8',
+ vartriangleleft: '22B2',
+ lhd: '22B2',
+ vartriangleright: '22B3',
+ rhd: '22B3',
+ trianglelefteq: '22B4',
+ unlhd: '22B4',
+ trianglerighteq: '22B5',
+ unrhd: '22B5',
+ vDash: '22A8',
+ Vdash: '22A9',
+ Vvdash: '22AA',
+ smallsmile: ['2323',{variantForm: true}],
+ shortmid: ['2223',{variantForm: true}],
+ smallfrown: ['2322',{variantForm: true}],
+ shortparallel: ['2225',{variantForm: true}],
+ bumpeq: '224F',
+ between: '226C',
+ Bumpeq: '224E',
+ pitchfork: '22D4',
+ varpropto: '221D',
+ backepsilon: '220D',
+ blacktriangleleft: '25C2',
+ blacktriangleright: '25B8',
+ therefore: '2234',
+ because: '2235',
+ eqsim: '2242',
+ vartriangle: ['25B3',{variantForm: true}],
+ Join: '22C8',
+
+ // Negated relations
+ nless: '226E',
+ ngtr: '226F',
+ nleq: '2270',
+ ngeq: '2271',
+ nleqslant: ['2A87',{variantForm: true}],
+ ngeqslant: ['2A88',{variantForm: true}],
+ nleqq: ['2270',{variantForm: true}],
+ ngeqq: ['2271',{variantForm: true}],
+ lneq: '2A87',
+ gneq: '2A88',
+ lneqq: '2268',
+ gneqq: '2269',
+ lvertneqq: ['2268',{variantForm: true}],
+ gvertneqq: ['2269',{variantForm: true}],
+ lnsim: '22E6',
+ gnsim: '22E7',
+ lnapprox: '2A89',
+ gnapprox: '2A8A',
+ nprec: '2280',
+ nsucc: '2281',
+ npreceq: ['22E0',{variantForm: true}],
+ nsucceq: ['22E1',{variantForm: true}],
+ precneqq: '2AB5',
+ succneqq: '2AB6',
+ precnsim: '22E8',
+ succnsim: '22E9',
+ precnapprox: '2AB9',
+ succnapprox: '2ABA',
+ nsim: '2241',
+ ncong: '2246',
+ nshortmid: ['2224',{variantForm: true}],
+ nshortparallel: ['2226',{variantForm: true}],
+ nmid: '2224',
+ nparallel: '2226',
+ nvdash: '22AC',
+ nvDash: '22AD',
+ nVdash: '22AE',
+ nVDash: '22AF',
+ ntriangleleft: '22EA',
+ ntriangleright: '22EB',
+ ntrianglelefteq: '22EC',
+ ntrianglerighteq: '22ED',
+ nsubseteq: '2288',
+ nsupseteq: '2289',
+ nsubseteqq: ['2288',{variantForm: true}],
+ nsupseteqq: ['2289',{variantForm: true}],
+ subsetneq: '228A',
+ supsetneq: '228B',
+ varsubsetneq: ['228A',{variantForm: true}],
+ varsupsetneq: ['228B',{variantForm: true}],
+ subsetneqq: '2ACB',
+ supsetneqq: '2ACC',
+ varsubsetneqq: ['2ACB',{variantForm: true}],
+ varsupsetneqq: ['2ACC',{variantForm: true}],
+
+
+ // Arrows
+ leftleftarrows: '21C7',
+ rightrightarrows: '21C9',
+ leftrightarrows: '21C6',
+ rightleftarrows: '21C4',
+ Lleftarrow: '21DA',
+ Rrightarrow: '21DB',
+ twoheadleftarrow: '219E',
+ twoheadrightarrow: '21A0',
+ leftarrowtail: '21A2',
+ rightarrowtail: '21A3',
+ looparrowleft: '21AB',
+ looparrowright: '21AC',
+ leftrightharpoons: '21CB',
+ rightleftharpoons: ['21CC',{variantForm: true}],
+ curvearrowleft: '21B6',
+ curvearrowright: '21B7',
+ circlearrowleft: '21BA',
+ circlearrowright: '21BB',
+ Lsh: '21B0',
+ Rsh: '21B1',
+ upuparrows: '21C8',
+ downdownarrows: '21CA',
+ upharpoonleft: '21BF',
+ upharpoonright: '21BE',
+ downharpoonleft: '21C3',
+ restriction: '21BE',
+ multimap: '22B8',
+ downharpoonright: '21C2',
+ leftrightsquigarrow: '21AD',
+ rightsquigarrow: '21DD',
+ leadsto: '21DD',
+ dashrightarrow: '21E2',
+ dashleftarrow: '21E0',
+
+ // Negated arrows
+ nleftarrow: '219A',
+ nrightarrow: '219B',
+ nLeftarrow: '21CD',
+ nRightarrow: '21CF',
+ nleftrightarrow: '21AE',
+ nLeftrightarrow: '21CE'
+ },
+
+ delimiter: {
+ // corners
+ "\\ulcorner": '231C',
+ "\\urcorner": '231D',
+ "\\llcorner": '231E',
+ "\\lrcorner": '231F'
+ },
+
+ macros: {
+ implies: ['Macro','\\;\\Longrightarrow\\;'],
+ impliedby: ['Macro','\\;\\Longleftarrow\\;']
+ }
+
+ },null,true);
+
+ var REL = MML.mo.OPTYPES.REL;
+
+ MathJax.Hub.Insert(MML.mo.prototype,{
+ OPTABLE: {
+ infix: {
+ '\u2322': REL, // smallfrown
+ '\u2323': REL, // smallsmile
+ '\u25B3': REL, // vartriangle
+ '\uE006': REL, // nshortmid
+ '\uE007': REL, // nshortparallel
+ '\uE00C': REL, // lvertneqq
+ '\uE00D': REL, // gvertneqq
+ '\uE00E': REL, // ngeqq
+ '\uE00F': REL, // ngeqslant
+ '\uE010': REL, // nleqslant
+ '\uE011': REL, // nleqq
+ '\uE016': REL, // nsubseteqq
+ '\uE017': REL, // varsubsetneqq
+ '\uE018': REL, // nsupseteqq
+ '\uE019': REL, // varsupsetneqq
+ '\uE01A': REL, // varsubsetneq
+ '\uE01B': REL, // varsupsetneq
+ '\uE04B': REL, // npreceq
+ '\uE04F': REL // nsucceq
+ }
+ }
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX AMSsymbols Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/AMSsymbols.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/HTML.js b/js/mathjax/extensions/TeX/HTML.js
new file mode 100644
index 0000000..75e4e45
--- /dev/null
+++ b/js/mathjax/extensions/TeX/HTML.js
@@ -0,0 +1,108 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/HTML.js
+ *
+ * Implements the \href, \class, \style, \cssId macros.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2010-2020 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.Extension["TeX/HTML"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+
+ var TEX = MathJax.InputJax.TeX;
+ var TEXDEF = TEX.Definitions;
+
+ TEXDEF.Add({
+ macros: {
+ href: 'HREF_attribute',
+ "class": 'CLASS_attribute',
+ style: 'STYLE_attribute',
+ cssId: 'ID_attribute'
+ }
+ },null,true);
+
+ TEX.Parse.Augment({
+
+ //
+ // Implements \href{url}{math}
+ //
+ HREF_attribute: function (name) {
+ var url = this.GetArgument(name),
+ arg = this.GetArgumentMML(name);
+ this.Push(arg.With({href:url}));
+ },
+
+ //
+ // Implements \class{name}{math}
+ //
+ CLASS_attribute: function (name) {
+ var CLASS = this.GetArgument(name),
+ arg = this.GetArgumentMML(name);
+ if (arg["class"] != null) {CLASS = arg["class"] + " " + CLASS}
+ this.Push(arg.With({"class":CLASS}));
+ },
+
+ //
+ // Implements \style{style-string}{math}
+ //
+ STYLE_attribute: function (name) {
+ var style = this.GetArgument(name),
+ arg = this.GetArgumentMML(name);
+ // check that it looks like a style string
+ if (arg.style != null) {
+ if (style.charAt(style.length-1) !== ";") {style += ";"}
+ style = arg.style + " " + style;
+ }
+ this.Push(arg.With({style: style}));
+ },
+
+ //
+ // Implements \cssId{id}{math}
+ //
+ ID_attribute: function (name) {
+ var ID = this.GetArgument(name),
+ arg = this.GetArgumentMML(name);
+ this.Push(arg.With({id:ID}));
+ },
+
+ //
+ // returns an argument that is a single MathML element
+ // (in an mrow if necessary)
+ //
+ GetArgumentMML: function (name) {
+ var arg = this.ParseArg(name);
+ if (arg.inferred && arg.data.length == 1)
+ {arg = arg.data[0]} else {delete arg.inferred}
+ return arg;
+ }
+
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX HTML Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/HTML.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/action.js b/js/mathjax/extensions/TeX/action.js
new file mode 100644
index 0000000..5ef06fd
--- /dev/null
+++ b/js/mathjax/extensions/TeX/action.js
@@ -0,0 +1,85 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/action.js
+ *
+ * Implements the \mathtip, \texttip, and \toggle macros, which give
+ * access from TeX to the <maction> tag in the MathML that underlies
+ * MathJax's internal format.
+ *
+ * Usage:
+ *
+ * \mathtip{math}{tip} % use "tip" (in math mode) as tooltip for "math"
+ * \texttip{math}{tip} % use "tip" (in text mode) as tooltip for "math"
+ * \toggle{math1}{math2}...\endtoggle
+ * % show math1, and when clicked, show math2, and so on.
+ * % When the last one is clicked, go back to math1.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2011-2020 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.Extension["TeX/action"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+ var TEX = MathJax.InputJax.TeX,
+ MML = MathJax.ElementJax.mml;
+
+ //
+ // Set up control sequenecs
+ //
+ TEX.Definitions.Add({
+ macros: {
+ toggle: 'Toggle',
+ mathtip: 'Mathtip',
+ texttip: ['Macro','\\mathtip{#1}{\\text{#2}}',2]
+ }
+ },null,true);
+
+ TEX.Parse.Augment({
+
+ //
+ // Implement \toggle {math1} {math2} ... \endtoggle
+ // (as an <maction actiontype="toggle">)
+ //
+ Toggle: function (name) {
+ var data = [], arg;
+ while ((arg = this.GetArgument(name)) !== "\\endtoggle")
+ {data.push(TEX.Parse(arg,this.stack.env).mml())}
+ this.Push(MML.maction.apply(MML,data).With({actiontype: MML.ACTIONTYPE.TOGGLE}));
+ },
+
+ //
+ // Implement \mathtip{math}{tip}
+ // (an an <maction actiontype="tooltip">)
+ //
+ Mathtip: function(name) {
+ var arg = this.ParseArg(name), tip = this.ParseArg(name);
+ this.Push(MML.maction(arg,tip).With({actiontype: MML.ACTIONTYPE.TOOLTIP}));
+ }
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX action Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/action.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/autobold.js b/js/mathjax/extensions/TeX/autobold.js
new file mode 100644
index 0000000..1d058ee
--- /dev/null
+++ b/js/mathjax/extensions/TeX/autobold.js
@@ -0,0 +1,52 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/autobold.js
+ *
+ * Adds \boldsymbol around mathematics that appears in a section
+ * of an HTML page that is in bold.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2020 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.Extension["TeX/autobold"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+ var TEX = MathJax.InputJax.TeX;
+
+ TEX.prefilterHooks.Add(function (data) {
+ var span = data.script.parentNode.insertBefore(document.createElement("span"),data.script);
+ span.visibility = "hidden";
+ span.style.fontFamily = "Times, serif";
+ span.appendChild(document.createTextNode("ABCXYZabcxyz"));
+ var W = span.offsetWidth;
+ span.style.fontWeight = "bold";
+ if (W && span.offsetWidth === W) {data.math = "\\boldsymbol{"+data.math+"}"}
+ span.parentNode.removeChild(span);
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX autobold Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/autobold.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/autoload-all.js b/js/mathjax/extensions/TeX/autoload-all.js
new file mode 100644
index 0000000..6032aad
--- /dev/null
+++ b/js/mathjax/extensions/TeX/autoload-all.js
@@ -0,0 +1,85 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/autoload-all.js
+ *
+ * Provides pre-defined macros to autoload all the extensions
+ * so that all macros that MathJax knows about are available.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2013-2020 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.Extension["TeX/autoload-all"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+
+ var EXTENSIONS = {
+ action: ["mathtip","texttip","toggle"],
+ AMSmath: ["mathring","nobreakspace","negmedspace","negthickspace","intI",
+ "iiiint","idotsint","dddot","ddddot","sideset","boxed",
+ "substack","injlim","projlim","varliminf","varlimsup",
+ "varinjlim","varprojlim","DeclareMathOperator","operatorname",
+ "genfrac","tfrac","dfrac","binom","tbinom","dbinom","cfrac",
+ "shoveleft","shoveright","xrightarrow","xleftarrow"],
+ begingroup: ["begingroup","endgroup","gdef","global"],
+ cancel: ["cancel","bcancel","xcancel","cancelto"],
+ color: ["color","textcolor","colorbox","fcolorbox","definecolor"],
+ enclose: ["enclose"],
+ extpfeil: ["Newextarrow","xlongequal","xmapsto","xtofrom",
+ "xtwoheadleftarrow","xtwoheadrightarrow"],
+ mhchem: ["ce","cee","cf"]
+ };
+
+ var ENVIRONMENTS = {
+ AMSmath: ["subarray","smallmatrix","equation","equation*"],
+ AMScd: ["CD"]
+ };
+
+ var name, i, m, defs = {macros:{}, environment:{}};
+
+ for (name in EXTENSIONS) {if (EXTENSIONS.hasOwnProperty(name)) {
+ if (!MathJax.Extension["TeX/"+name]) {
+ var macros = EXTENSIONS[name];
+ for (i = 0, m = macros.length; i < m; i++)
+ {defs.macros[macros[i]] = ["Extension",name]}
+ }
+ }}
+
+ for (name in ENVIRONMENTS) {if (ENVIRONMENTS.hasOwnProperty(name)) {
+ if (!MathJax.Extension["TeX/"+name]) {
+ var envs = ENVIRONMENTS[name];
+ for (i = 0, m = envs.length; i < m; i++)
+ {defs.environment[envs[i]] = ["ExtensionEnv",null,name]}
+ }
+ }}
+
+ MathJax.InputJax.TeX.Definitions.Add(defs);
+
+ MathJax.Hub.Startup.signal.Post("TeX autoload-all Ready");
+
+});
+
+MathJax.Callback.Queue(
+ ["Require",MathJax.Ajax,"[MathJax]/extensions/TeX/AMSsymbols.js"],
+ ["loadComplete",MathJax.Ajax,"[MathJax]/extensions/TeX/autoload-all.js"]
+);
+// @license-end
diff --git a/js/mathjax/extensions/TeX/bbox.js b/js/mathjax/extensions/TeX/bbox.js
new file mode 100644
index 0000000..cc5440a
--- /dev/null
+++ b/js/mathjax/extensions/TeX/bbox.js
@@ -0,0 +1,104 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/bbox.js
+ *
+ * This file implements the \bbox macro, which creates an box that
+ * can be styled (for background colors, and so on). You can include
+ * an optional dimension that tells how much extra padding to include
+ * around the bounding box for the mathematics, or a color specification
+ * for the background color to use, or both. E.g.,
+ *
+ * \bbox[2pt]{x+y} % an invisible box around x+y with 2pt of extra space
+ * \bbox[green]{x+y} % a green box around x+y
+ * \bbox[green,2pt]{x+y} % a green box with 2pt of extra space
+ *
+ * You can also specify style attributes, for example
+ *
+ * \bbox[red,border:3px solid blue,5px]{x+y}
+ *
+ * would give a red background with a 3px solid blue border that has 5px
+ * of padding between the border and the mathematics. Note that not all
+ * output formats support the style specifications. In particular, the
+ * NativeMML output depends on the browser to render the attributes, and
+ * not all MathML renderers will honor them (e.g., MathPlayer2 doesn't
+ * render border styles).
+ *
+ * This file will be loaded automatically when \bbox is first used.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2011-2020 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.Extension["TeX/bbox"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+
+ var TEX = MathJax.InputJax.TeX,
+ MML = MathJax.ElementJax.mml;
+
+ TEX.Definitions.Add({macros: {bbox: "BBox"}},null,true);
+
+ TEX.Parse.Augment({
+ BBox: function (name) {
+ var bbox = this.GetBrackets(name,""),
+ math = this.ParseArg(name);
+ var parts = bbox.split(/,/), def, background, style;
+ for (var i = 0, m = parts.length; i < m; i++) {
+ var part = parts[i].replace(/^\s+/,'').replace(/\s+$/,'');
+ var match = part.match(/^(\.\d+|\d+(\.\d*)?)(pt|em|ex|mu|px|in|cm|mm)$/);
+ if (match) {
+ if (def)
+ {TEX.Error(["MultipleBBoxProperty","%1 specified twice in %2","Padding",name])}
+ var pad = this.BBoxPadding(match[1]+match[3]);
+ if (pad) def = {height:"+"+pad, depth:"+"+pad, lspace:pad, width:"+"+(2*match[1])+match[3]};
+ } else if (part.match(/^([a-z0-9]+|\#[0-9a-f]{6}|\#[0-9a-f]{3})$/i)) {
+ if (background)
+ {TEX.Error(["MultipleBBoxProperty","%1 specified twice in %2","Background",name])}
+ background = part;
+ } else if (part.match(/^[-a-z]+:/i)) {
+ if (style)
+ {TEX.Error(["MultipleBBoxProperty","%1 specified twice in %2", "Style",name])}
+ style = this.BBoxStyle(part);
+ } else if (part !== "") {
+ TEX.Error(
+ ["InvalidBBoxProperty",
+ "'%1' doesn't look like a color, a padding dimension, or a style",
+ part]
+ );
+ }
+ }
+ if (def) {math = MML.mpadded(math).With(def)}
+ if (background || style) {
+ math = MML.mstyle(math).With({mathbackground:background, style:style});
+ }
+ this.Push(math);
+ },
+ BBoxStyle: function (styles) {return styles},
+ BBoxPadding: function (pad) {return pad}
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX bbox Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/bbox.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/begingroup.js b/js/mathjax/extensions/TeX/begingroup.js
new file mode 100644
index 0000000..f750fc5
--- /dev/null
+++ b/js/mathjax/extensions/TeX/begingroup.js
@@ -0,0 +1,294 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/begingroup.js
+ *
+ * Implements \begingroup and \endgroup commands that make local
+ * definitions possible and are removed when the \endgroup occurs.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2011-2020 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.Extension["TeX/begingroup"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+
+ var TEX = MathJax.InputJax.TeX,
+ TEXDEF = TEX.Definitions;
+
+ /****************************************************/
+
+ //
+ // A namespace for localizing macros and environments
+ // (\begingroup and \endgroup create and destroy these)
+ //
+ var NSFRAME = MathJax.Object.Subclass({
+ macros: null, // the local macro definitions
+ environments: null, // the local environments
+ Init: function (macros,environments) {
+ this.macros = (macros || {});
+ this.environments = (environments || {});
+ },
+ //
+ // Find a macro or environment by name
+ //
+ Find: function (name,type) {if (this[type].hasOwnProperty(name)) {return this[type][name]}},
+ //
+ // Define or remove a macro or environment
+ //
+ Def: function (name,value,type) {this[type][name] = value},
+ Undef: function (name,type) {delete this[type][name]},
+ //
+ // Merge two namespaces (used when the equation namespace is combined with the root one)
+ //
+ Merge: function (frame) {
+ MathJax.Hub.Insert(this.macros,frame.macros);
+ MathJax.Hub.Insert(this.environments,frame.environments);
+ },
+ //
+ // Move global macros to the stack (globally) and remove from the frame
+ //
+ MergeGlobals: function (stack) {
+ var macros = this.macros;
+ for (var cs in macros) {if (macros.hasOwnProperty(cs) && macros[cs].global) {
+ stack.Def(cs,macros[cs],"macros",true);
+ delete macros[cs].global; delete macros[cs];
+ }}
+ },
+ //
+ // Clear the macro and environment lists
+ // (but not global macros unless "all" is true)
+ //
+ Clear: function (all) {
+ this.environments = {};
+ if (all) {this.macros = {}} else {
+ var macros = this.macros;
+ for (var cs in macros) {
+ if (macros.hasOwnProperty(cs) && !macros[cs].global) {delete macros[cs]}
+ }
+ }
+ return this;
+ }
+ });
+
+ /****************************************************/
+
+ //
+ // A Stack of namespace frames
+ //
+ var NSSTACK = TEX.nsStack = MathJax.Object.Subclass({
+ stack: null, // the namespace frames
+ top: 0, // the current top one (we don't pop for real until the equation completes)
+ isEqn: false, // true if this is the equation stack (not the global one)
+ //
+ // Set up the initial stack frame
+ //
+ Init: function (eqn) {
+ this.isEqn = eqn; this.stack = [];
+ if (!eqn) {this.Push(NSFRAME(TEXDEF.macros,TEXDEF.environment))}
+ else {this.Push(NSFRAME())}
+ },
+ //
+ // Define a macro or environment in the top frame
+ //
+ Def: function (name,value,type,global) {
+ var n = this.top-1;
+ if (global) {
+ //
+ // Define global macros in the base frame and remove that cs
+ // from all other frames. Mark the global ones in equations
+ // so they can be made global when merged with the root stack.
+ //
+ while (n > 0) {this.stack[n].Undef(name,type); n--}
+ if (!MathJax.Object.isArray(value)) {value = [value]}
+ if (this.isEqn) {value.global = true}
+ }
+ this.stack[n].Def(name,value,type);
+ },
+ //
+ // Push a new namespace frame on the stack
+ //
+ Push: function (frame) {
+ this.stack.push(frame);
+ this.top = this.stack.length;
+ },
+ //
+ // Pop the top stack frame
+ // (if it is the root, just keep track of the pop so we can
+ // reset it if the equation is reprocessed)
+ //
+ Pop: function () {
+ var top;
+ if (this.top > 1) {
+ top = this.stack[--this.top];
+ if (this.isEqn) {this.stack.pop()}
+ } else if (this.isEqn) {
+ this.Clear();
+ }
+ return top;
+ },
+ //
+ // Search the stack from top to bottom for the first
+ // definition of the given control sequence in the given type
+ //
+ Find: function (name,type) {
+ for (var i = this.top-1; i >= 0; i--) {
+ var def = this.stack[i].Find(name,type);
+ if (def) {return def}
+ }
+ return null;
+ },
+ //
+ // Combine the equation stack with the global one
+ // (The bottom frame of the equation goes with the top frame of the global one,
+ // and the remainder are pushed on the global stack, truncated to the
+ // position where items were poped from it.)
+ //
+ Merge: function (stack) {
+ stack.stack[0].MergeGlobals(this);
+ this.stack[this.top-1].Merge(stack.stack[0]);
+ var data = [this.top,this.stack.length-this.top].concat(stack.stack.slice(1));
+ this.stack.splice.apply(this.stack,data);
+ this.top = this.stack.length;
+ },
+ //
+ // Put back the temporarily poped items
+ //
+ Reset: function () {this.top = this.stack.length},
+ //
+ // Clear the stack and start with a blank frame
+ //
+ Clear: function (all) {
+ this.stack = [this.stack[0].Clear()];
+ this.top = this.stack.length;
+ }
+ },{
+ nsFrame: NSFRAME
+ });
+
+ /****************************************************/
+
+ //
+ // Define the new macros
+ //
+ TEXDEF.Add({
+ macros: {
+ begingroup: "BeginGroup",
+ endgroup: "EndGroup",
+ global: "Global",
+ gdef: ["Macro","\\global\\def"]
+ }
+ },null,true);
+
+ TEX.Parse.Augment({
+ //
+ // Implement \begingroup
+ //
+ BeginGroup: function (name) {
+ TEX.eqnStack.Push(NSFRAME());
+ },
+ //
+ // Implements \endgroup
+ //
+ EndGroup: function (name) {
+ //
+ // If the equation has pushed frames, pop one,
+ // Otherwise clear the equation stack and pop the top global one
+ //
+ if (TEX.eqnStack.top > 1) {
+ TEX.eqnStack.Pop();
+ } else if (TEX.rootStack.top === 1) {
+ TEX.Error(["ExtraEndMissingBegin","Extra %1 or missing \\begingroup",name]);
+ } else {
+ TEX.eqnStack.Clear();
+ TEX.rootStack.Pop();
+ }
+ },
+
+ //
+ // Replace the original routines with ones that looks through the
+ // equation and root stacks for the given name
+ //
+ csFindMacro: function (name) {
+ return (TEX.eqnStack.Find(name,"macros") || TEX.rootStack.Find(name,"macros"));
+ },
+ envFindName: function (name) {
+ return (TEX.eqnStack.Find(name,"environments") || TEX.rootStack.Find(name,"environments"));
+ },
+
+ //
+ // Modify the way macros and environments are defined
+ // to make them go into the equation namespace stack
+ //
+ setDef: function (name,value) {
+ value.isUser = true;
+ TEX.eqnStack.Def(name,value,"macros",this.stack.env.isGlobal);
+ delete this.stack.env.isGlobal;
+ },
+ setEnv: function (name,value) {
+ value.isUser = true;
+ TEX.eqnStack.Def(name,value,"environments")
+ },
+
+ //
+ // Implement \global (for \global\let, \global\def and \global\newcommand)
+ //
+ Global: function (name) {
+ var i = this.i; var cs = this.GetCSname(name); this.i = i;
+ if (cs !== "let" && cs !== "def" && cs !== "newcommand" &&
+ cs !== "DeclareMathOperator" && cs !== "Newextarrow") {
+ TEX.Error(["GlobalNotFollowedBy",
+ "%1 not followed by \\let, \\def, or \\newcommand",name]);
+ }
+ this.stack.env.isGlobal = true;
+ }
+ });
+
+ /****************************************************/
+
+ TEX.rootStack = NSSTACK(); // the global namespace stack
+ TEX.eqnStack = NSSTACK(true); // the equation stack
+
+ //
+ // Reset the global stack and clear the equation stack
+ // (this gets us back to the initial stack state as it was
+ // before the equation was first processed, in case the equation
+ // get restarted due to an autoloaded file)
+ //
+ TEX.prefilterHooks.Add(function () {TEX.rootStack.Reset(); TEX.eqnStack.Clear(true)});
+
+ //
+ // We only get here if there were no errors and the equation is fully
+ // processed (all restarts are complete). So we merge the equation
+ // stack into the global stack, thus making the changes from this
+ // equation permanent.
+ //
+ TEX.postfilterHooks.Add(function () {TEX.rootStack.Merge(TEX.eqnStack)});
+
+ /*********************************************************/
+
+ MathJax.Hub.Startup.signal.Post("TeX begingroup Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/begingroup.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/boldsymbol.js b/js/mathjax/extensions/TeX/boldsymbol.js
new file mode 100644
index 0000000..e25fff0
--- /dev/null
+++ b/js/mathjax/extensions/TeX/boldsymbol.js
@@ -0,0 +1,77 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/boldsymbol.js
+ *
+ * Implements the \boldsymbol{...} command to make bold
+ * versions of all math characters (not just variables).
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2020 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.Extension["TeX/boldsymbol"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+
+ var MML = MathJax.ElementJax.mml;
+ var TEX = MathJax.InputJax.TeX;
+ var TEXDEF = TEX.Definitions;
+
+ var BOLDVARIANT = {};
+ BOLDVARIANT[MML.VARIANT.NORMAL] = MML.VARIANT.BOLD;
+ BOLDVARIANT[MML.VARIANT.ITALIC] = MML.VARIANT.BOLDITALIC;
+ BOLDVARIANT[MML.VARIANT.FRAKTUR] = MML.VARIANT.BOLDFRAKTUR;
+ BOLDVARIANT[MML.VARIANT.SCRIPT] = MML.VARIANT.BOLDSCRIPT;
+ BOLDVARIANT[MML.VARIANT.SANSSERIF] = MML.VARIANT.BOLDSANSSERIF;
+ BOLDVARIANT["-tex-caligraphic"] = "-tex-caligraphic-bold";
+ BOLDVARIANT["-tex-oldstyle"] = "-tex-oldstyle-bold";
+
+ TEXDEF.Add({macros: {boldsymbol: 'Boldsymbol'}},null,true);
+
+ TEX.Parse.Augment({
+ mmlToken: function (token) {
+ if (this.stack.env.boldsymbol) {
+ var variant = token.Get("mathvariant");
+ if (variant == null) {token.mathvariant = MML.VARIANT.BOLD}
+ else {token.mathvariant = (BOLDVARIANT[variant]||variant)}
+ }
+ return token;
+ },
+
+ Boldsymbol: function (name) {
+ var boldsymbol = this.stack.env.boldsymbol,
+ font = this.stack.env.font;
+ this.stack.env.boldsymbol = true;
+ this.stack.env.font = null;
+ var mml = this.ParseArg(name);
+ this.stack.env.font = font;
+ this.stack.env.boldsymbol = boldsymbol;
+ this.Push(mml);
+ }
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX boldsymbol Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/boldsymbol.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/cancel.js b/js/mathjax/extensions/TeX/cancel.js
new file mode 100644
index 0000000..9f2afe8
--- /dev/null
+++ b/js/mathjax/extensions/TeX/cancel.js
@@ -0,0 +1,112 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/cancel.js
+ *
+ * Implements the \cancel, \bcancel, \xcancel, and \cancelto macros.
+ *
+ * Usage:
+ *
+ * \cancel{math} % strikeout math from lower left to upper right
+ * \bcancel{math} % strikeout from upper left to lower right
+ * \xcancel{math} % strikeout with an X
+ * \cancelto{value}{math} % strikeout with arrow going to value
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2011-2020 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.Extension["TeX/cancel"] = {
+ version: "2.7.9",
+
+ //
+ // The attributes allowed in \enclose{notation}[attributes]{math}
+ //
+ ALLOWED: {
+ color: 1, mathcolor: 1,
+ background: 1, mathbackground: 1,
+ padding: 1,
+ thickness: 1
+ }
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+ var TEX = MathJax.InputJax.TeX,
+ MML = MathJax.ElementJax.mml,
+ CANCEL = MathJax.Extension["TeX/cancel"];
+
+ CANCEL.setAttributes = function (def,attr) {
+ if (attr !== "") {
+ attr = attr.replace(/ /g,"").split(/,/);
+ for (var i = 0, m = attr.length; i < m; i++) {
+ var keyvalue = attr[i].split(/[:=]/);
+ if (CANCEL.ALLOWED[keyvalue[0]]) {
+ if (keyvalue[1] === "true") {keyvalue[1] = true}
+ if (keyvalue[1] === "false") {keyvalue[1] = false}
+ def[keyvalue[0]] = keyvalue[1];
+ }
+ }
+ }
+ return def;
+ };
+
+ //
+ // Set up macros
+ //
+ TEX.Definitions.Add({
+ macros: {
+ cancel: ['Cancel',MML.NOTATION.UPDIAGONALSTRIKE],
+ bcancel: ['Cancel',MML.NOTATION.DOWNDIAGONALSTRIKE],
+ xcancel: ['Cancel',MML.NOTATION.UPDIAGONALSTRIKE+" "+MML.NOTATION.DOWNDIAGONALSTRIKE],
+ cancelto: 'CancelTo'
+ }
+ },null,true);
+
+ TEX.Parse.Augment({
+ //
+ // Implement \cancel[attributes]{math},
+ // \bcancel[attributes]{math}, and
+ // \xcancel[attributes]{math}
+ //
+ Cancel: function(name,notation) {
+ var attr = this.GetBrackets(name,""), math = this.ParseArg(name);
+ var def = CANCEL.setAttributes({notation: notation},attr);
+ this.Push(MML.menclose(math).With(def));
+ },
+
+ //
+ // Implement \cancelto{value}[attributes]{math}
+ //
+ CancelTo: function(name,notation) {
+ var value = this.ParseArg(name),
+ attr = this.GetBrackets(name,""),
+ math = this.ParseArg(name);
+ var def = CANCEL.setAttributes({notation: MML.NOTATION.UPDIAGONALSTRIKE+" "+MML.NOTATION.UPDIAGONALARROW},attr);
+ value = MML.mpadded(value).With({depth:"-.1em",height:"+.1em",voffset:".1em"});
+ this.Push(MML.msup(MML.menclose(math).With(def),value));
+ }
+
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX cancel Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/cancel.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/color.js b/js/mathjax/extensions/TeX/color.js
new file mode 100644
index 0000000..45c9b9e
--- /dev/null
+++ b/js/mathjax/extensions/TeX/color.js
@@ -0,0 +1,283 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/color.js
+ *
+ * Implements LaTeX-compatible \color macro rather than MathJax's original
+ * (non-standard) version. It includes the rgb, RGB, gray, and named color
+ * models, and the \textcolor, \definecolor, \colorbox, and \fcolorbox
+ * macros.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2011-2020 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.
+ */
+
+//
+// The configuration defaults, augmented by the user settings
+//
+MathJax.Extension["TeX/color"] = {
+ version: "2.7.9",
+
+ config: MathJax.Hub.CombineConfig("TeX.color",{
+ padding: "5px",
+ border: "2px"
+ }),
+
+ colors: {
+ Apricot: "#FBB982",
+ Aquamarine: "#00B5BE",
+ Bittersweet: "#C04F17",
+ Black: "#221E1F",
+ Blue: "#2D2F92",
+ BlueGreen: "#00B3B8",
+ BlueViolet: "#473992",
+ BrickRed: "#B6321C",
+ Brown: "#792500",
+ BurntOrange: "#F7921D",
+ CadetBlue: "#74729A",
+ CarnationPink: "#F282B4",
+ Cerulean: "#00A2E3",
+ CornflowerBlue: "#41B0E4",
+ Cyan: "#00AEEF",
+ Dandelion: "#FDBC42",
+ DarkOrchid: "#A4538A",
+ Emerald: "#00A99D",
+ ForestGreen: "#009B55",
+ Fuchsia: "#8C368C",
+ Goldenrod: "#FFDF42",
+ Gray: "#949698",
+ Green: "#00A64F",
+ GreenYellow: "#DFE674",
+ JungleGreen: "#00A99A",
+ Lavender: "#F49EC4",
+ LimeGreen: "#8DC73E",
+ Magenta: "#EC008C",
+ Mahogany: "#A9341F",
+ Maroon: "#AF3235",
+ Melon: "#F89E7B",
+ MidnightBlue: "#006795",
+ Mulberry: "#A93C93",
+ NavyBlue: "#006EB8",
+ OliveGreen: "#3C8031",
+ Orange: "#F58137",
+ OrangeRed: "#ED135A",
+ Orchid: "#AF72B0",
+ Peach: "#F7965A",
+ Periwinkle: "#7977B8",
+ PineGreen: "#008B72",
+ Plum: "#92268F",
+ ProcessBlue: "#00B0F0",
+ Purple: "#99479B",
+ RawSienna: "#974006",
+ Red: "#ED1B23",
+ RedOrange: "#F26035",
+ RedViolet: "#A1246B",
+ Rhodamine: "#EF559F",
+ RoyalBlue: "#0071BC",
+ RoyalPurple: "#613F99",
+ RubineRed: "#ED017D",
+ Salmon: "#F69289",
+ SeaGreen: "#3FBC9D",
+ Sepia: "#671800",
+ SkyBlue: "#46C5DD",
+ SpringGreen: "#C6DC67",
+ Tan: "#DA9D76",
+ TealBlue: "#00AEB3",
+ Thistle: "#D883B7",
+ Turquoise: "#00B4CE",
+ Violet: "#58429B",
+ VioletRed: "#EF58A0",
+ White: "#FFFFFF",
+ WildStrawberry: "#EE2967",
+ Yellow: "#FFF200",
+ YellowGreen: "#98CC70",
+ YellowOrange: "#FAA21A"
+ },
+
+ /*
+ * Look up a color based on its model and definition
+ */
+ getColor: function (model,def) {
+ if (!model) {model = "named"}
+ var fn = this["get_"+model];
+ if (!fn) {this.TEX.Error(["UndefinedColorModel","Color model '%1' not defined",model])}
+ return fn.call(this,def);
+ },
+
+ /*
+ * Get an rgb color
+ */
+ get_rgb: function (rgb) {
+ rgb = rgb.replace(/^\s+/,"").replace(/\s+$/,"").split(/\s*,\s*/); var RGB = "#";
+ if (rgb.length !== 3)
+ {this.TEX.Error(["ModelArg1","Color values for the %1 model require 3 numbers","rgb"])}
+ for (var i = 0; i < 3; i++) {
+ if (!rgb[i].match(/^(\d+(\.\d*)?|\.\d+)$/))
+ {this.TEX.Error(["InvalidDecimalNumber","Invalid decimal number"])}
+ var n = parseFloat(rgb[i]);
+ if (n < 0 || n > 1) {
+ this.TEX.Error(["ModelArg2",
+ "Color values for the %1 model must be between %2 and %3",
+ "rgb",0,1]);
+ }
+ n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n}
+ RGB += n;
+ }
+ return RGB;
+ },
+
+ /*
+ * Get an RGB color
+ */
+ get_RGB: function (rgb) {
+ rgb = rgb.replace(/^\s+/,"").replace(/\s+$/,"").split(/\s*,\s*/); var RGB = "#";
+ if (rgb.length !== 3)
+ {this.TEX.Error(["ModelArg1","Color values for the %1 model require 3 numbers","RGB"])}
+ for (var i = 0; i < 3; i++) {
+ if (!rgb[i].match(/^\d+$/))
+ {this.TEX.Error(["InvalidNumber","Invalid number"])}
+ var n = parseInt(rgb[i]);
+ if (n > 255) {
+ this.TEX.Error(["ModelArg2",
+ "Color values for the %1 model must be between %2 and %3",
+ "RGB",0,255]);
+ }
+ n = n.toString(16); if (n.length < 2) {n = "0"+n}
+ RGB += n;
+ }
+ return RGB;
+ },
+
+ /*
+ * Get a gray-scale value
+ */
+ get_gray: function (gray) {
+ if (!gray.match(/^\s*(\d+(\.\d*)?|\.\d+)\s*$/))
+ {this.TEX.Error(["InvalidDecimalNumber","Invalid decimal number"])}
+ var n = parseFloat(gray);
+ if (n < 0 || n > 1) {
+ this.TEX.Error(["ModelArg2",
+ "Color values for the %1 model must be between %2 and %3",
+ "gray",0,1]);
+ }
+ n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n}
+ return "#"+n+n+n;
+ },
+
+ /*
+ * Get a named value
+ */
+ get_named: function (name) {
+ if (this.colors.hasOwnProperty(name)) {return this.colors[name]}
+ return name;
+ },
+
+ padding: function () {
+ var pad = "+"+this.config.padding;
+ var unit = this.config.padding.replace(/^.*?([a-z]*)$/,"$1");
+ var pad2 = "+"+(2*parseFloat(pad))+unit;
+ return {width:pad2, height:pad, depth:pad, lspace:this.config.padding};
+ }
+
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+ var TEX = MathJax.InputJax.TeX,
+ MML = MathJax.ElementJax.mml;
+ var STACKITEM = TEX.Stack.Item;
+ var COLOR = MathJax.Extension["TeX/color"];
+
+ COLOR.TEX = TEX; // for reference in getColor above
+
+ TEX.Definitions.Add({
+ macros: {
+ color: "Color",
+ textcolor: "TextColor",
+ definecolor: "DefineColor",
+ colorbox: "ColorBox",
+ fcolorbox: "fColorBox"
+ }
+ },null,true);
+
+ TEX.Parse.Augment({
+
+ //
+ // Override \color macro definition
+ //
+ Color: function (name) {
+ var model = this.GetBrackets(name),
+ color = this.GetArgument(name);
+ color = COLOR.getColor(model,color);
+ var mml = STACKITEM.style().With({styles:{mathcolor:color}});
+ this.stack.env.color = color;
+ this.Push(mml);
+ },
+
+ TextColor: function (name) {
+ var model = this.GetBrackets(name),
+ color = this.GetArgument(name);
+ color = COLOR.getColor(model,color);
+ var old = this.stack.env.color; this.stack.env.color = color;
+ var math = this.ParseArg(name);
+ if (old) {this.stack.env.color} else {delete this.stack.env.color}
+ this.Push(MML.mstyle(math).With({mathcolor: color}));
+ },
+
+ //
+ // Define the \definecolor macro
+ //
+ DefineColor: function (name) {
+ var cname = this.GetArgument(name),
+ model = this.GetArgument(name),
+ def = this.GetArgument(name);
+ COLOR.colors[cname] = COLOR.getColor(model,def);
+ },
+
+ //
+ // Produce a text box with a colored background
+ //
+ ColorBox: function (name) {
+ var cname = this.GetArgument(name),
+ arg = this.InternalMath(this.GetArgument(name));
+ this.Push(MML.mpadded.apply(MML,arg).With({
+ mathbackground:COLOR.getColor("named",cname)
+ }).With(COLOR.padding()));
+ },
+
+ //
+ // Procude a framed text box with a colored background
+ //
+ fColorBox: function (name) {
+ var fname = this.GetArgument(name),
+ cname = this.GetArgument(name),
+ arg = this.InternalMath(this.GetArgument(name));
+ this.Push(MML.mpadded.apply(MML,arg).With({
+ mathbackground: COLOR.getColor("named",cname),
+ style: "border: "+COLOR.config.border+" solid "+COLOR.getColor("named",fname)
+ }).With(COLOR.padding()));
+ }
+
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX color Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/color.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/enclose.js b/js/mathjax/extensions/TeX/enclose.js
new file mode 100644
index 0000000..0976984
--- /dev/null
+++ b/js/mathjax/extensions/TeX/enclose.js
@@ -0,0 +1,93 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/enclose.js
+ *
+ * Implements the \enclose macros, which give access from TeX to the
+ * <menclose> tag in the MathML that underlies MathJax's internal format.
+ *
+ * Usage:
+ *
+ * \enclose{notation}{math} % enclose math using given notation
+ * \enclose{notation,notation,...}{math} % enclose with several notations
+ * \enclose{notation}[attributes]{math} % enclose with attributes
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2011-2020 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.Extension["TeX/enclose"] = {
+ version: "2.7.9",
+
+ //
+ // The attributes allowed in \enclose{notation}[attributes]{math}
+ //
+ ALLOWED: {
+ arrow: 1,
+ color: 1, mathcolor: 1,
+ background: 1, mathbackground: 1,
+ padding: 1,
+ thickness: 1
+ }
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+ var TEX = MathJax.InputJax.TeX,
+ MML = MathJax.ElementJax.mml,
+ ALLOW = MathJax.Extension["TeX/enclose"].ALLOWED;
+
+ //
+ // Set up macro
+ //
+ TEX.Definitions.Add({macros: {enclose: 'Enclose'}},null,true);
+
+ TEX.Parse.Augment({
+ //
+ // Implement \enclose{notation}[attr]{math}
+ // (create <menclose notation="notation">math</menclose>)
+ //
+ Enclose: function(name) {
+ var notation = this.GetArgument(name),
+ attr = this.GetBrackets(name),
+ math = this.ParseArg(name);
+ var def = {notation: notation.replace(/,/g," ")};
+ if (attr) {
+ attr = attr.replace(/ /g,"").split(/,/);
+ for (var i = 0, m = attr.length; i < m; i++) {
+ var keyvalue = attr[i].split(/[:=]/);
+ if (ALLOW[keyvalue[0]]) {
+ keyvalue[1] = keyvalue[1].replace(/^"(.*)"$/,"$1");
+ if (keyvalue[1] === "true") {keyvalue[1] = true}
+ if (keyvalue[1] === "false") {keyvalue[1] = false}
+ if (keyvalue[0] === "arrow" && keyvalue[1])
+ {def.notation = def.notation + " updiagonalarrow"} else
+ {def[keyvalue[0]] = keyvalue[1]}
+ }
+ }
+ }
+ this.Push(MML.menclose(math).With(def));
+ }
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX enclose Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/enclose.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/extpfeil.js b/js/mathjax/extensions/TeX/extpfeil.js
new file mode 100644
index 0000000..f07adac
--- /dev/null
+++ b/js/mathjax/extensions/TeX/extpfeil.js
@@ -0,0 +1,104 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/extpfeil.js
+ *
+ * Implements additional stretchy arrow macros.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2011-2020 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.Extension["TeX/extpfeil"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+
+ var TEX = MathJax.InputJax.TeX,
+ TEXDEF = TEX.Definitions;
+
+ //
+ // Define the arrows to load the AMSmath extension
+ // (since they need its xArrow method)
+ //
+ TEXDEF.Add({
+ macros: {
+ xtwoheadrightarrow: ['Extension','AMSmath'],
+ xtwoheadleftarrow: ['Extension','AMSmath'],
+ xmapsto: ['Extension','AMSmath'],
+ xlongequal: ['Extension','AMSmath'],
+ xtofrom: ['Extension','AMSmath'],
+ Newextarrow: ['Extension','AMSmath']
+ }
+ },null,true);
+
+ //
+ // Redefine the macros when AMSmath is loaded
+ //
+ MathJax.Hub.Register.StartupHook("TeX AMSmath Ready",function () {
+ MathJax.Hub.Insert(TEXDEF,{
+ macros: {
+ xtwoheadrightarrow: ['xArrow',0x21A0,12,16],
+ xtwoheadleftarrow: ['xArrow',0x219E,17,13],
+ xmapsto: ['xArrow',0x21A6,6,7],
+ xlongequal: ['xArrow',0x003D,7,7],
+ xtofrom: ['xArrow',0x21C4,12,12],
+ Newextarrow: 'NewExtArrow'
+ }
+ });
+ });
+
+ //
+ // Implements \Newextarrow to define a new arrow (not compatible with \newextarrow, but
+ // the equivalent for MathJax)
+ //
+ TEX.Parse.Augment({
+ NewExtArrow: function (name) {
+ var cs = this.GetArgument(name),
+ space = this.GetArgument(name),
+ chr = this.GetArgument(name);
+ if (!cs.match(/^\\([a-z]+|.)$/i)) {
+ TEX.Error(["NewextarrowArg1",
+ "First argument to %1 must be a control sequence name",name]);
+ }
+ if (!space.match(/^(\d+),(\d+)$/)) {
+ TEX.Error(
+ ["NewextarrowArg2",
+ "Second argument to %1 must be two integers separated by a comma",
+ name]
+ );
+ }
+ if (!chr.match(/^(\d+|0x[0-9A-F]+)$/i)) {
+ TEX.Error(
+ ["NewextarrowArg3",
+ "Third argument to %1 must be a unicode character number",
+ name]
+ );
+ }
+ cs = cs.substr(1); space = space.split(","); chr = parseInt(chr);
+ this.setDef(cs, ['xArrow', chr, parseInt(space[0]), parseInt(space[1])]);
+ }
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX extpfeil Ready");
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/extpfeil.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/mathchoice.js b/js/mathjax/extensions/TeX/mathchoice.js
new file mode 100644
index 0000000..7042395
--- /dev/null
+++ b/js/mathjax/extensions/TeX/mathchoice.js
@@ -0,0 +1,109 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/mathchoice.js
+ *
+ * Implements the \mathchoice macro (rarely used)
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2020 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.Hub.Register.StartupHook("TeX Jax Ready",function () {
+ var VERSION = "2.7.9";
+
+ var MML = MathJax.ElementJax.mml;
+ var TEX = MathJax.InputJax.TeX;
+ var TEXDEF = TEX.Definitions;
+
+ TEXDEF.Add({macros: {mathchoice: 'MathChoice'}},null,true);
+
+ TEX.Parse.Augment({
+ MathChoice: function (name) {
+ var D = this.ParseArg(name),
+ T = this.ParseArg(name),
+ S = this.ParseArg(name),
+ SS = this.ParseArg(name);
+ this.Push(MML.TeXmathchoice(D,T,S,SS));
+ }
+ });
+
+ MML.TeXmathchoice = MML.mbase.Subclass({
+ type: "TeXmathchoice", notParent: true,
+ choice: function () {
+ if (this.selection != null) return this.selection;
+ if (this.choosing) return 2; // prevent infinite loops: see issue #1151
+ this.choosing = true;
+ var selection = 0, values = this.getValues("displaystyle","scriptlevel");
+ if (values.scriptlevel > 0) {selection = Math.min(3,values.scriptlevel+1)}
+ else {selection = (values.displaystyle ? 0 : 1)}
+ // only cache the result if we are actually in place in a <math> tag.
+ var node = this.inherit; while (node && node.type !== "math") node = node.inherit;
+ if (node) this.selection = selection;
+ this.choosing = false;
+ return selection;
+ },
+ selected: function () {return this.data[this.choice()]},
+ setTeXclass: function (prev) {return this.selected().setTeXclass(prev)},
+ isSpacelike: function () {return this.selected().isSpacelike()},
+ isEmbellished: function () {return this.selected().isEmbellished()},
+ Core: function () {return this.selected()},
+ CoreMO: function () {return this.selected().CoreMO()},
+ toHTML: function (span) {
+ span = this.HTMLcreateSpan(span);
+ span.bbox = this.Core().toHTML(span).bbox;
+ // Firefox doesn't correctly handle a span with a negatively sized content,
+ // so move marginLeft to main span (this is a hack to get \iiiint to work).
+ // FIXME: This is a symptom of a more general problem with Firefox, and
+ // there probably needs to be a more general solution (e.g., modifying
+ // HTMLhandleSpace() to get the width and adjust the right margin to
+ // compensate for negative-width contents)
+ if (span.firstChild && span.firstChild.style.marginLeft) {
+ span.style.marginLeft = span.firstChild.style.marginLeft;
+ span.firstChild.style.marginLeft = "";
+ }
+ return span;
+ },
+ toSVG: function () {
+ var svg = this.Core().toSVG();
+ this.SVGsaveData(svg);
+ return svg;
+ },
+ toCommonHTML: function (node) {
+ node = this.CHTMLcreateNode(node);
+ this.CHTMLhandleStyle(node);
+ this.CHTMLhandleColor(node);
+ this.CHTMLaddChild(node,this.choice(),{});
+ return node;
+ },
+ toPreviewHTML: function(span) {
+ span = this.PHTMLcreateSpan(span);
+ this.PHTMLhandleStyle(span);
+ this.PHTMLhandleColor(span);
+ this.PHTMLaddChild(span,this.choice(),{});
+ return span;
+ }
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX mathchoice Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mathchoice.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/mediawiki-texvc.js b/js/mathjax/extensions/TeX/mediawiki-texvc.js
new file mode 100644
index 0000000..ab1ed42
--- /dev/null
+++ b/js/mathjax/extensions/TeX/mediawiki-texvc.js
@@ -0,0 +1,138 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/mediawiki-texvc.js
+ *
+ * Implements macros used by mediawiki with their texvc preprocessor.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2015-2020 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.Extension["TeX/mediawiki-texvc"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () {
+ MathJax.InputJax.TeX.Definitions.Add({
+ macros: {
+ AA: ["Macro", "\u00c5"],
+ alef: ["Macro", "\\aleph"],
+ alefsym: ["Macro", "\\aleph"],
+ Alpha: ["Macro", "\\mathrm{A}"],
+ and: ["Macro", "\\land"],
+ ang: ["Macro", "\\angle"],
+ Bbb: ["Macro", "\\mathbb"],
+ Beta: ["Macro", "\\mathrm{B}"],
+ bold: ["Macro", "\\mathbf"],
+ bull: ["Macro", "\\bullet"],
+ C: ["Macro", "\\mathbb{C}"],
+ Chi: ["Macro", "\\mathrm{X}"],
+ clubs: ["Macro", "\\clubsuit"],
+ cnums: ["Macro", "\\mathbb{C}"],
+ Complex: ["Macro", "\\mathbb{C}"],
+ coppa: ["Macro", "\u03D9"],
+ Coppa: ["Macro", "\u03D8"],
+ Dagger: ["Macro", "\\ddagger"],
+ Digamma: ["Macro", "\u03DC"],
+ darr: ["Macro", "\\downarrow"],
+ dArr: ["Macro", "\\Downarrow"],
+ Darr: ["Macro", "\\Downarrow"],
+ dashint: ["Macro", "\\unicodeInt{x2A0D}"],
+ ddashint: ["Macro", "\\unicodeInt{x2A0E}"],
+ diamonds: ["Macro", "\\diamondsuit"],
+ empty: ["Macro", "\\emptyset"],
+ Epsilon: ["Macro", "\\mathrm{E}"],
+ Eta: ["Macro", "\\mathrm{H}"],
+ euro: ["Macro", "\u20AC"],
+ exist: ["Macro", "\\exists"],
+ geneuro: ["Macro", "\u20AC"],
+ geneuronarrow: ["Macro", "\u20AC"],
+ geneurowide: ["Macro", "\u20AC"],
+ H: ["Macro", "\\mathbb{H}"],
+ hAar: ["Macro", "\\Leftrightarrow"],
+ harr: ["Macro", "\\leftrightarrow"],
+ Harr: ["Macro", "\\Leftrightarrow"],
+ hearts: ["Macro", "\\heartsuit"],
+ image: ["Macro", "\\Im"],
+ infin: ["Macro", "\\infty"],
+ Iota: ["Macro", "\\mathrm{I}"],
+ isin: ["Macro", "\\in"],
+ Kappa: ["Macro", "\\mathrm{K}"],
+ koppa: ["Macro", "\u03DF"],
+ Koppa: ["Macro", "\u03DE"],
+ lang: ["Macro", "\\langle"],
+ larr: ["Macro", "\\leftarrow"],
+ Larr: ["Macro", "\\Leftarrow"],
+ lArr: ["Macro", "\\Leftarrow"],
+ lrarr: ["Macro", "\\leftrightarrow"],
+ Lrarr: ["Macro", "\\Leftrightarrow"],
+ lrArr: ["Macro", "\\Leftrightarrow"],
+ Mu: ["Macro", "\\mathrm{M}"],
+ N: ["Macro", "\\mathbb{N}"],
+ natnums: ["Macro", "\\mathbb{N}"],
+ Nu: ["Macro", "\\mathrm{N}"],
+ O: ["Macro", "\\emptyset"],
+ oiint: ["Macro", "\\unicodeInt{x222F}"],
+ oiiint: ["Macro", "\\unicodeInt{x2230}"],
+ ointctrclockwise: ["Macro", "\\unicodeInt{x2233}"],
+ officialeuro: ["Macro", "\u20AC"],
+ Omicron: ["Macro", "\\mathrm{O}"],
+ or: ["Macro", "\\lor"],
+ P: ["Macro", "\u00B6"],
+ pagecolor: ['Macro','',1], // ignore \pagecolor{}
+ part: ["Macro", "\\partial"],
+ plusmn: ["Macro", "\\pm"],
+ Q: ["Macro", "\\mathbb{Q}"],
+ R: ["Macro", "\\mathbb{R}"],
+ rang: ["Macro", "\\rangle"],
+ rarr: ["Macro", "\\rightarrow"],
+ Rarr: ["Macro", "\\Rightarrow"],
+ rArr: ["Macro", "\\Rightarrow"],
+ real: ["Macro", "\\Re"],
+ reals: ["Macro", "\\mathbb{R}"],
+ Reals: ["Macro", "\\mathbb{R}"],
+ Rho: ["Macro", "\\mathrm{P}"],
+ sdot: ["Macro", "\\cdot"],
+ sampi: ["Macro", "\u03E1"],
+ Sampi: ["Macro", "\u03E0"],
+ sect: ["Macro", "\\S"],
+ spades: ["Macro", "\\spadesuit"],
+ stigma: ["Macro", "\u03DB"],
+ Stigma: ["Macro", "\u03DA"],
+ sub: ["Macro", "\\subset"],
+ sube: ["Macro", "\\subseteq"],
+ supe: ["Macro", "\\supseteq"],
+ Tau: ["Macro", "\\mathrm{T}"],
+ textvisiblespace: ["Macro", "\u2423"],
+ thetasym: ["Macro", "\\vartheta"],
+ uarr: ["Macro", "\\uparrow"],
+ uArr: ["Macro", "\\Uparrow"],
+ Uarr: ["Macro", "\\Uparrow"],
+ unicodeInt: ["Macro", "\\mathop{\\vcenter{\\mathchoice{\\huge\\unicode{#1}\\,}{\\unicode{#1}}{\\unicode{#1}}{\\unicode{#1}}}\\,}\\nolimits", 1],
+ varcoppa: ["Macro", "\u03D9"],
+ varstigma: ["Macro", "\u03DB"],
+ varointclockwise: ["Macro", "\\unicodeInt{x2232}"],
+ vline: ['Macro','\\smash{\\large\\lvert}',0],
+ weierp: ["Macro", "\\wp"],
+ Z: ["Macro", "\\mathbb{Z}"],
+ Zeta: ["Macro", "\\mathrm{Z}"]
+ }
+ });
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mediawiki-texvc.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/mhchem.js b/js/mathjax/extensions/TeX/mhchem.js
new file mode 100644
index 0000000..9d15876
--- /dev/null
+++ b/js/mathjax/extensions/TeX/mhchem.js
@@ -0,0 +1,522 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/mhchem.js
+ *
+ * Implements the \ce command for handling chemical formulas
+ * from the mhchem LaTeX package.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2011-2020 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.
+ */
+
+
+//
+// Don't replace [Contrib]/mhchem if it is already loaded
+//
+if (MathJax.Extension["TeX/mhchem"]) {
+ MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mhchem.js");
+} else {
+
+MathJax.Extension["TeX/mhchem"] = {
+ version: "2.7.9",
+ config: MathJax.Hub.CombineConfig("TeX.mhchem",{
+ legacy: true
+ })
+};
+
+//
+// Load [mhchem]/mhchem.js if not configured for legacy vesion
+//
+if (!MathJax.Extension["TeX/mhchem"].config.legacy) {
+ if (!MathJax.Ajax.config.path.mhchem) {
+ MathJax.Ajax.config.path.mhchem = MathJax.Hub.config.root + "/extensions/TeX/mhchem3";
+ }
+ MathJax.Callback.Queue(
+ ["Require",MathJax.Ajax,"[mhchem]/mhchem.js"],
+ ["loadComplete",MathJax.Ajax,"[MathJax]/extensions/TeX/mhchem.js"]
+ );
+} else {
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+
+ var TEX = MathJax.InputJax.TeX;
+
+ /*
+ * This is the main class for handing the \ce and related commands.
+ * Its main method is Parse() which takes the argument to \ce and
+ * returns the corresponding TeX string.
+ */
+
+ var CE = MathJax.Object.Subclass({
+ string: "", // the \ce string being parsed
+ i: 0, // the current position in the string
+ tex: "", // the partially processed TeX result
+ TEX: "", // the full TeX result
+ atom: false, // last processed token is an atom
+ sup: "", // pending superscript
+ sub: "", // pending subscript
+ presup: "", // pending pre-superscript
+ presub: "", // pending pre-subscript
+
+ //
+ // Store the string when a CE object is created
+ //
+ Init: function (string) {this.string = string},
+
+ //
+ // These are the special characters and the methods that
+ // handle them. All others are passed through verbatim.
+ //
+ ParseTable: {
+ '-': "Minus",
+ '+': "Plus",
+ '(': "Open",
+ ')': "Close",
+ '[': "Open",
+ ']': "Close",
+ '<': "Less",
+ '^': "Superscript",
+ '_': "Subscript",
+ '*': "Dot",
+ '.': "Dot",
+ '=': "Equal",
+ '#': "Pound",
+ '$': "Math",
+ '\\': "Macro",
+ ' ': "Space"
+ },
+ //
+ // Basic arrow names for reactions
+ //
+ Arrows: {
+ '->': "rightarrow",
+ '<-': "leftarrow",
+ '<->': "leftrightarrow",
+ '<=>': "rightleftharpoons",
+ '<=>>': "Rightleftharpoons",
+ '<<=>': "Leftrightharpoons",
+ '^': "uparrow",
+ 'v': "downarrow"
+ },
+
+ //
+ // Implementations for the various bonds
+ // (the ~ ones are hacks that don't work well in NativeMML)
+ //
+ Bonds: {
+ '-': "-",
+ '=': "=",
+ '#': "\\equiv",
+ '~': "\\tripledash",
+ '~-': "\\begin{CEstack}{}\\tripledash\\\\-\\end{CEstack}",
+ '~=': "\\raise2mu{\\begin{CEstack}{}\\tripledash\\\\-\\\\-\\end{CEstack}}",
+ '~--': "\\raise2mu{\\begin{CEstack}{}\\tripledash\\\\-\\\\-\\end{CEstack}}",
+ '-~-': "\\raise2mu{\\begin{CEstack}{}-\\\\\\tripledash\\\\-\\end{CEstack}}",
+ '...': "{\\cdot}{\\cdot}{\\cdot}",
+ '....': "{\\cdot}{\\cdot}{\\cdot}{\\cdot}",
+ '->': "\\rightarrow",
+ '<-': "\\leftarrow",
+ '??': "\\text{??}" // unknown bond
+ },
+
+ //
+ // This converts the CE string to a TeX string.
+ // It loops through the string and calls the proper
+ // method depending on the ccurrent character.
+ //
+ Parse: function () {
+ this.tex = ""; this.atom = false;
+ while (this.i < this.string.length) {
+ var c = this.string.charAt(this.i);
+ if (c.match(/[a-z]/i)) {this.ParseLetter()}
+ else if (c.match(/[0-9]/)) {this.ParseNumber()}
+ else {this["Parse"+(this.ParseTable[c]||"Other")](c)}
+ }
+ this.FinishAtom(true);
+ return this.TEX;
+ },
+
+ //
+ // Make an atom name or a down arrow
+ //
+ ParseLetter: function () {
+ this.FinishAtom();
+ if (this.Match(/^v( |$)/)) {
+ this.tex += "{\\"+this.Arrows["v"]+"}";
+ } else {
+ this.tex += "\\text{"+this.Match(/^[a-z]+/i)+"}";
+ this.atom = true;
+ }
+ },
+
+ //
+ // Make a number or fraction preceding an atom,
+ // or a subscript for an atom.
+ //
+ ParseNumber: function () {
+ var n = this.Match(/^\d+/);
+ if (this.atom && !this.sub) {
+ this.sub = n;
+ } else {
+ this.FinishAtom();
+ var match = this.Match(/^\/\d+/);
+ if (match) {
+ var frac = "\\frac{"+n+"}{"+match.substr(1)+"}";
+ this.tex += "\\mathchoice{\\textstyle"+frac+"}{"+frac+"}{"+frac+"}{"+frac+"}";
+ } else {
+ this.tex += n;
+ if (this.i < this.string.length) {this.tex += "\\,"}
+ }
+ }
+ },
+
+ //
+ // Make a superscript minus, or an arrow, or a single bond.
+ //
+ ParseMinus: function (c) {
+ if (this.atom && (this.i === this.string.length-1 || this.string.charAt(this.i+1) === " ")) {
+ this.sup += c;
+ } else {
+ this.FinishAtom();
+ if (this.string.substr(this.i,2) === "->") {this.i += 2; this.AddArrow("->"); return}
+ else {this.tex += "{-}"}
+ }
+ this.i++;
+ },
+
+ //
+ // Make a superscript plus, or pass it through
+ //
+ ParsePlus: function (c) {
+ if (this.atom) {this.sup += c} else {this.FinishAtom(); this.tex += c}
+ this.i++;
+ },
+
+ //
+ // Handle dots and double or triple bonds
+ //
+ ParseDot: function (c) {this.FinishAtom(); this.tex += "\\cdot "; this.i++},
+ ParseEqual: function (c) {this.FinishAtom(); this.tex += "{=}"; this.i++},
+ ParsePound: function (c) {this.FinishAtom(); this.tex += "{\\equiv}"; this.i++},
+
+ //
+ // Look for (v) or (^), or pass it through
+ //
+ ParseOpen: function (c) {
+ this.FinishAtom();
+ var match = this.Match(/^\([v^]\)/);
+ if (match) {this.tex += "{\\"+this.Arrows[match.charAt(1)]+"}"}
+ else {this.tex += "{"+c; this.i++}
+ },
+ //
+ // Allow ) and ] to get super- and subscripts
+ //
+ ParseClose: function (c) {this.FinishAtom(); this.atom = true; this.tex += c+"}"; this.i++},
+
+ //
+ // Make the proper arrow
+ //
+ ParseLess: function (c) {
+ this.FinishAtom();
+ var arrow = this.Match(/^(<->?|<=>>?|<<=>)/);
+ if (!arrow) {this.tex += c; this.i++} else {this.AddArrow(arrow)}
+ },
+
+ //
+ // Look for a superscript, or an up arrow
+ //
+ ParseSuperscript: function (c) {
+ c = this.string.charAt(++this.i);
+ if (c === "{") {
+ this.i++; var m = this.Find("}");
+ if (m === "-.") {this.sup += "{-}{\\cdot}"}
+ else if (m) {this.sup += CE(m).Parse().replace(/^\{-\}/,"-")}
+ } else if (c === " " || c === "") {
+ this.tex += "{\\"+this.Arrows["^"]+"}"; this.i++;
+ } else {
+ var n = this.Match(/^(\d+|-\.)/);
+ if (n) {this.sup += n}
+ }
+ },
+ //
+ // Look for subscripts
+ //
+ ParseSubscript: function (c) {
+ if (this.string.charAt(++this.i) == "{") {
+ this.i++; this.sub += CE(this.Find("}")).Parse().replace(/^\{-\}/,"-");
+ } else {
+ var n = this.Match(/^\d+/);
+ if (n) {this.sub += n}
+ }
+ },
+
+ //
+ // Look for raw TeX code to include
+ //
+ ParseMath: function (c) {
+ this.FinishAtom();
+ this.i++; this.tex += this.Find(c);
+ },
+
+ //
+ // Look for specific macros for bonds
+ // and allow \} to have subscripts
+ //
+ ParseMacro: function (c) {
+ this.FinishAtom();
+ this.i++; var match = this.Match(/^([a-z]+|.)/i)||" ";
+ if (match === "sbond") {this.tex += "{-}"}
+ else if (match === "dbond") {this.tex += "{=}"}
+ else if (match === "tbond") {this.tex += "{\\equiv}"}
+ else if (match === "bond") {
+ var bond = (this.Match(/^\{.*?\}/)||"");
+ bond = bond.substr(1,bond.length-2);
+ this.tex += "{"+(this.Bonds[bond]||"\\text{??}")+"}";
+ }
+ else if (match === "{") {this.tex += "{\\{"}
+ else if (match === "}") {this.tex += "\\}}"; this.atom = true}
+ else {this.tex += c+match}
+ },
+
+ //
+ // Ignore spaces
+ //
+ ParseSpace: function (c) {this.FinishAtom(); this.i++},
+
+ //
+ // Pass anything else on verbatim
+ //
+ ParseOther: function (c) {this.FinishAtom(); this.tex += c; this.i++},
+
+ //
+ // Process an arrow (looking for brackets for above and below)
+ //
+ AddArrow: function (arrow) {
+ var c = this.Match(/^[CT]\[/);
+ if (c) {this.i--; c = c.charAt(0)}
+ var above = this.GetBracket(c), below = this.GetBracket(c);
+ arrow = this.Arrows[arrow];
+ if (above || below) {
+ if (below) {arrow += "["+below+"]"}
+ arrow += "{"+above+"}";
+ arrow = "\\mathrel{\\x"+arrow+"}";
+ } else {
+ arrow = "\\long"+arrow+" ";
+ }
+ this.tex += arrow;
+ },
+
+ //
+ // Handle the super and subscripts for an atom
+ //
+ FinishAtom: function (force) {
+ if (this.sup || this.sub || this.presup || this.presub) {
+ if (!force && !this.atom) {
+ if (this.tex === "" && !this.sup && !this.sub) return;
+ if (!this.presup && !this.presub &&
+ (this.tex === "" || this.tex === "{" ||
+ (this.tex === "}" && this.TEX.substr(-1) === "{"))) {
+ this.presup = this.sup, this.presub = this.sub; // save for later
+ this.sub = this.sup = "";
+ this.TEX += this.tex; this.tex = "";
+ return;
+ }
+ }
+ if (this.sub && !this.sup) {this.sup = "\\Space{0pt}{0pt}{.2em}"} // forces subscripts to align properly
+ if ((this.presup || this.presub) && this.tex !== "{") {
+ if (!this.presup && !this.sup) {this.presup = "\\Space{0pt}{0pt}{.2em}"}
+ this.tex = "\\CEprescripts{"+(this.presub||"\\CEnone")+"}{"+(this.presup||"\\CEnone")+"}"
+ + "{"+(this.tex !== "}" ? this.tex : "")+"}"
+ + "{"+(this.sub||"\\CEnone")+"}{"+(this.sup||"\\CEnone")+"}"
+ + (this.tex === "}" ? "}" : "");
+ this.presub = this.presup = "";
+ } else {
+ if (this.sup) this.tex += "^{"+this.sup+"}";
+ if (this.sub) this.tex += "_{"+this.sub+"}";
+ }
+ this.sup = this.sub = "";
+ }
+ this.TEX += this.tex; this.tex = "";
+ this.atom = false;
+ },
+
+ //
+ // Find a bracket group and handle C and T prefixes
+ //
+ GetBracket: function (c) {
+ if (this.string.charAt(this.i) !== "[") {return ""}
+ this.i++; var bracket = this.Find("]");
+ if (c === "C") {bracket = "\\ce{"+bracket+"}"} else
+ if (c === "T") {
+ if (!bracket.match(/^\{.*\}$/)) {bracket = "{"+bracket+"}"}
+ bracket = "\\text"+bracket;
+ };
+ return bracket;
+ },
+
+ //
+ // Check if the string matches a regular expression
+ // and move past it if so, returning the match
+ //
+ Match: function (regex) {
+ var match = regex.exec(this.string.substr(this.i));
+ if (match) {match = match[0]; this.i += match.length}
+ return match;
+ },
+
+ //
+ // Find a particular character, skipping over braced groups
+ //
+ Find: function (c) {
+ var m = this.string.length, i = this.i, braces = 0;
+ while (this.i < m) {
+ var C = this.string.charAt(this.i++);
+ if (C === c && braces === 0) {return this.string.substr(i,this.i-i-1)}
+ if (C === "{") {braces++} else
+ if (C === "}") {
+ if (braces) {braces--}
+ else {
+ TEX.Error(["ExtraCloseMissingOpen","Extra close brace or missing open brace"])
+ }
+ }
+ }
+ if (braces) {TEX.Error(["MissingCloseBrace","Missing close brace"])}
+ TEX.Error(["NoClosingChar","Can't find closing %1",c]);
+ }
+
+ });
+
+ MathJax.Extension["TeX/mhchem"].CE = CE;
+
+ /***************************************************************************/
+
+ TEX.Definitions.Add({
+ macros: {
+ //
+ // Set up the macros for chemistry
+ //
+ ce: 'CE',
+ cf: 'CE',
+ cee: 'CE',
+
+ //
+ // Make these load AMSmath package (redefined below when loaded)
+ //
+ xleftrightarrow: ['Extension','AMSmath'],
+ xrightleftharpoons: ['Extension','AMSmath'],
+ xRightleftharpoons: ['Extension','AMSmath'],
+ xLeftrightharpoons: ['Extension','AMSmath'],
+
+ // FIXME: These don't work well in FF NativeMML mode
+ longrightleftharpoons: ["Macro","\\stackrel{\\textstyle{{-}\\!\\!{\\rightharpoonup}}}{\\smash{{\\leftharpoondown}\\!\\!{-}}}"],
+ longRightleftharpoons: ["Macro","\\stackrel{\\textstyle{-}\\!\\!{\\rightharpoonup}}{\\small\\smash\\leftharpoondown}"],
+ longLeftrightharpoons: ["Macro","\\stackrel{\\rightharpoonup}{{{\\leftharpoondown}\\!\\!\\textstyle{-}}}"],
+
+ //
+ // Add \hyphen used in some mhchem examples
+ //
+ hyphen: ["Macro","\\text{-}"],
+
+ //
+ // Handle prescripts and none
+ //
+ CEprescripts: "CEprescripts",
+ CEnone: "CEnone",
+
+ //
+ // Needed for \bond for the ~ forms
+ //
+ tripledash: ["Macro","\\raise3mu{\\tiny\\text{-}\\kern2mu\\text{-}\\kern2mu\\text{-}}"]
+ },
+
+ //
+ // Needed for \bond for the ~ forms
+ //
+ environment: {
+ CEstack: ['Array',null,null,null,'r',null,"0.001em",'T',1]
+ }
+ },null,true);
+
+ if (!MathJax.Extension["TeX/AMSmath"]) {
+ TEX.Definitions.Add({
+ macros: {
+ xrightarrow: ['Extension','AMSmath'],
+ xleftarrow: ['Extension','AMSmath']
+ }
+ },null,true);
+ }
+
+ //
+ // These arrows need to wait until AMSmath is loaded
+ //
+ MathJax.Hub.Register.StartupHook("TeX AMSmath Ready",function () {
+ TEX.Definitions.Add({
+ macros: {
+ //
+ // Some of these are hacks for now
+ //
+ xleftrightarrow: ['xArrow',0x2194,6,6],
+ xrightleftharpoons: ['xArrow',0x21CC,5,7], // FIXME: doesn't stretch in HTML-CSS output
+ xRightleftharpoons: ['xArrow',0x21CC,5,7], // FIXME: how should this be handled?
+ xLeftrightharpoons: ['xArrow',0x21CC,5,7]
+ }
+ },null,true);
+ });
+
+ TEX.Parse.Augment({
+
+ //
+ // Implements \ce and friends
+ //
+ CE: function (name) {
+ var arg = this.GetArgument(name);
+ var tex = CE(arg).Parse();
+ this.string = tex + this.string.substr(this.i); this.i = 0;
+ },
+
+ //
+ // Implements \CEprescripts{presub}{presup}{base}{sub}{sup}
+ //
+ CEprescripts: function (name) {
+ var presub = this.ParseArg(name),
+ presup = this.ParseArg(name),
+ base = this.ParseArg(name),
+ sub = this.ParseArg(name),
+ sup = this.ParseArg(name);
+ var MML = MathJax.ElementJax.mml;
+ this.Push(MML.mmultiscripts(base,sub,sup,MML.mprescripts(),presub,presup));
+ },
+ CEnone: function (name) {
+ this.Push(MathJax.ElementJax.mml.none());
+ }
+
+ });
+
+ //
+ // Indicate that the extension is ready
+ //
+ MathJax.Hub.Startup.signal.Post("TeX mhchem Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mhchem.js");
+
+}}
+// @license-end
diff --git a/js/mathjax/extensions/TeX/mhchem3/mhchem.js b/js/mathjax/extensions/TeX/mhchem3/mhchem.js
new file mode 100644
index 0000000..2caa810
--- /dev/null
+++ b/js/mathjax/extensions/TeX/mhchem3/mhchem.js
@@ -0,0 +1,1776 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/mhchem.js
+ *
+ * Implements the \ce command for handling chemical formulas
+ * from the mhchem LaTeX package.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2011-2015 The MathJax Consortium
+ * Copyright (c) 2015-2019 Martin Hensel
+ *
+ * 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.
+ */
+
+//
+// Coding Style
+// - use '' for identifiers that can by minified/uglified
+// - use "" for strings that need to stay untouched
+
+
+MathJax.Extension["TeX/mhchem"] = {
+ version: "3.3.2"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () {
+
+ var TEX = MathJax.InputJax.TeX;
+
+ //
+ // This is the main class for handing the \ce and related commands.
+ // Its main method is Parse() which takes the argument to \ce and
+ // returns the corresponding TeX string.
+ //
+
+ var CE = MathJax.Object.Subclass({
+ string: "", // the \ce string being parsed
+
+ //
+ // Store the string when a CE object is created
+ //
+ Init: function (string) { this.string = string; },
+
+ //
+ // This converts the CE string to a TeX string.
+ //
+ Parse: function (stateMachine) {
+ try {
+ return texify.go(mhchemParser.go(this.string, stateMachine));
+ } catch (ex) {
+ TEX.Error(ex);
+ }
+ }
+ });
+
+ //
+ // Core parser for mhchem syntax (recursive)
+ //
+ /** @type {MhchemParser} */
+ var mhchemParser = {
+ //
+ // Parses mchem \ce syntax
+ //
+ // Call like
+ // go("H2O");
+ //
+ go: function (input, stateMachine) {
+ if (!input) { return []; }
+ if (stateMachine === undefined) { stateMachine = 'ce'; }
+ var state = '0';
+
+ //
+ // String buffers for parsing:
+ //
+ // buffer.a == amount
+ // buffer.o == element
+ // buffer.b == left-side superscript
+ // buffer.p == left-side subscript
+ // buffer.q == right-side subscript
+ // buffer.d == right-side superscript
+ //
+ // buffer.r == arrow
+ // buffer.rdt == arrow, script above, type
+ // buffer.rd == arrow, script above, content
+ // buffer.rqt == arrow, script below, type
+ // buffer.rq == arrow, script below, content
+ //
+ // buffer.text_
+ // buffer.rm
+ // etc.
+ //
+ // buffer.parenthesisLevel == int, starting at 0
+ // buffer.sb == bool, space before
+ // buffer.beginsWithBond == bool
+ //
+ // These letters are also used as state names.
+ //
+ // Other states:
+ // 0 == begin of main part (arrow/operator unlikely)
+ // 1 == next entity
+ // 2 == next entity (arrow/operator unlikely)
+ // 3 == next atom
+ // c == macro
+ //
+ /** @type {Buffer} */
+ var buffer = {};
+ buffer['parenthesisLevel'] = 0;
+
+ input = input.replace(/\n/g, " ");
+ input = input.replace(/[\u2212\u2013\u2014\u2010]/g, "-");
+ input = input.replace(/[\u2026]/g, "...");
+
+ //
+ // Looks through mhchemParser.transitions, to execute a matching action
+ // (recursive)
+ //
+ var lastInput;
+ var watchdog = 10;
+ /** @type {ParserOutput[]} */
+ var output = [];
+ while (true) {
+ if (lastInput !== input) {
+ watchdog = 10;
+ lastInput = input;
+ } else {
+ watchdog--;
+ }
+ //
+ // Find actions in transition table
+ //
+ var machine = mhchemParser.stateMachines[stateMachine];
+ var t = machine.transitions[state] || machine.transitions['*'];
+ iterateTransitions:
+ for (var i=0; i<t.length; i++) {
+ var matches = mhchemParser.patterns.match_(t[i].pattern, input);
+ if (matches) {
+ //
+ // Execute actions
+ //
+ var task = t[i].task;
+ for (var iA=0; iA<task.action_.length; iA++) {
+ var o;
+ //
+ // Find and execute action
+ //
+ if (machine.actions[task.action_[iA].type_]) {
+ o = machine.actions[task.action_[iA].type_](buffer, matches.match_, task.action_[iA].option);
+ } else if (mhchemParser.actions[task.action_[iA].type_]) {
+ o = mhchemParser.actions[task.action_[iA].type_](buffer, matches.match_, task.action_[iA].option);
+ } else {
+ throw ["MhchemBugA", "mhchem bug A. Please report. (" + task.action_[iA].type_ + ")"]; // Trying to use non-existing action
+ }
+ //
+ // Add output
+ //
+ mhchemParser.concatArray(output, o);
+ }
+ //
+ // Set next state,
+ // Shorten input,
+ // Continue with next character
+ // (= apply only one transition per position)
+ //
+ state = task.nextState || state;
+ if (input.length > 0) {
+ if (!task.revisit) {
+ input = matches.remainder;
+ }
+ if (!task.toContinue) {
+ break iterateTransitions;
+ }
+ } else {
+ return output;
+ }
+ }
+ }
+ //
+ // Prevent infinite loop
+ //
+ if (watchdog <= 0) {
+ throw ["MhchemBugU", "mhchem bug U. Please report."]; // Unexpected character
+ }
+ }
+ },
+ concatArray: function (a, b) {
+ if (b) {
+ if (Object.prototype.toString.call(b) === "[object Array]") { // Array.isArray(b)
+ for (var iB=0; iB<b.length; iB++) {
+ a.push(b[iB]);
+ }
+ } else {
+ a.push(b);
+ }
+ }
+ },
+
+ patterns: {
+ //
+ // Matching patterns
+ // either regexps or function that return null or {match_:"a", remainder:"bc"}
+ //
+ patterns: {
+ // property names must not look like integers ("2") for correct property traversal order, later on
+ 'empty': /^$/,
+ 'else': /^./,
+ 'else2': /^./,
+ 'space': /^\s/,
+ 'space A': /^\s(?=[A-Z\\$])/,
+ 'space$': /^\s$/,
+ 'a-z': /^[a-z]/,
+ 'x': /^x/,
+ 'x$': /^x$/,
+ 'i$': /^i$/,
+ 'letters': /^(?:[a-zA-Z\u03B1-\u03C9\u0391-\u03A9?@]|(?:\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\s+|\{\}|(?![a-zA-Z]))))+/,
+ '\\greek': /^\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\s+|\{\}|(?![a-zA-Z]))/,
+ 'one lowercase latin letter $': /^(?:([a-z])(?:$|[^a-zA-Z]))$/,
+ '$one lowercase latin letter$ $': /^\$(?:([a-z])(?:$|[^a-zA-Z]))\$$/,
+ 'one lowercase greek letter $': /^(?:\$?[\u03B1-\u03C9]\$?|\$?\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega)\s*\$?)(?:\s+|\{\}|(?![a-zA-Z]))$/,
+ 'digits': /^[0-9]+/,
+ '-9.,9': /^[+\-]?(?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))/,
+ '-9.,9 no missing 0': /^[+\-]?[0-9]+(?:[.,][0-9]+)?/,
+ '(-)(9.,9)(e)(99)': function (input) {
+ var m = input.match(/^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))?(\((?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))\))?(?:(?:([eE])|\s*(\*|x|\\times|\u00D7)\s*10\^)([+\-]?[0-9]+|\{[+\-]?[0-9]+\}))?/);
+ if (m && m[0]) {
+ return { match_: m.slice(1), remainder: input.substr(m[0].length) };
+ }
+ return null;
+ },
+ '(-)(9)^(-9)': function (input) {
+ var m = input.match(/^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+)?)\^([+\-]?[0-9]+|\{[+\-]?[0-9]+\})/);
+ if (m && m[0]) {
+ return { match_: m.slice(1), remainder: input.substr(m[0].length) };
+ }
+ return null;
+ },
+ 'state of aggregation $': function (input) { // ... or crystal system
+ var a = mhchemParser.patterns.findObserveGroups(input, "", /^\([a-z]{1,3}(?=[\),])/, ")", ""); // (aq), (aq,$\infty$), (aq, sat)
+ if (a && a.remainder.match(/^($|[\s,;\)\]\}])/)) { return a; } // AND end of 'phrase'
+ var m = input.match(/^(?:\((?:\\ca\s?)?\$[amothc]\$\))/); // OR crystal system ($o$) (\ca$c$)
+ if (m) {
+ return { match_: m[0], remainder: input.substr(m[0].length) };
+ }
+ return null;
+ },
+ '_{(state of aggregation)}$': /^_\{(\([a-z]{1,3}\))\}/,
+ '{[(': /^(?:\\\{|\[|\()/,
+ ')]}': /^(?:\)|\]|\\\})/,
+ ', ': /^[,;]\s*/,
+ ',': /^[,;]/,
+ '.': /^[.]/,
+ '. ': /^([.\u22C5\u00B7\u2022])\s*/,
+ '...': /^\.\.\.(?=$|[^.])/,
+ '* ': /^([*])\s*/,
+ '^{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "^{", "", "", "}"); },
+ '^($...$)': function (input) { return mhchemParser.patterns.findObserveGroups(input, "^", "$", "$", ""); },
+ '^a': /^\^([0-9]+|[^\\_])/,
+ '^\\x{}{}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "^", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true); },
+ '^\\x{}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "^", /^\\[a-zA-Z]+\{/, "}", ""); },
+ '^\\x': /^\^(\\[a-zA-Z]+)\s*/,
+ '^(-1)': /^\^(-?\d+)/,
+ '\'': /^'/,
+ '_{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "_{", "", "", "}"); },
+ '_($...$)': function (input) { return mhchemParser.patterns.findObserveGroups(input, "_", "$", "$", ""); },
+ '_9': /^_([+\-]?[0-9]+|[^\\])/,
+ '_\\x{}{}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "_", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true); },
+ '_\\x{}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "_", /^\\[a-zA-Z]+\{/, "}", ""); },
+ '_\\x': /^_(\\[a-zA-Z]+)\s*/,
+ '^_': /^(?:\^(?=_)|\_(?=\^)|[\^_]$)/,
+ '{}': /^\{\}/,
+ '{...}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "", "{", "}", ""); },
+ '{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "{", "", "", "}"); },
+ '$...$': function (input) { return mhchemParser.patterns.findObserveGroups(input, "", "$", "$", ""); },
+ '${(...)}$': function (input) { return mhchemParser.patterns.findObserveGroups(input, "${", "", "", "}$"); },
+ '$(...)$': function (input) { return mhchemParser.patterns.findObserveGroups(input, "$", "", "", "$"); },
+ '=<>': /^[=<>]/,
+ '#': /^[#\u2261]/,
+ '+': /^\+/,
+ '-$': /^-(?=[\s_},;\]/]|$|\([a-z]+\))/, // -space -, -; -] -/ -$ -state-of-aggregation
+ '-9': /^-(?=[0-9])/,
+ '- orbital overlap': /^-(?=(?:[spd]|sp)(?:$|[\s,;\)\]\}]))/,
+ '-': /^-/,
+ 'pm-operator': /^(?:\\pm|\$\\pm\$|\+-|\+\/-)/,
+ 'operator': /^(?:\+|(?:[\-=<>]|<<|>>|\\approx|\$\\approx\$)(?=\s|$|-?[0-9]))/,
+ 'arrowUpDown': /^(?:v|\(v\)|\^|\(\^\))(?=$|[\s,;\)\]\}])/,
+ '\\bond{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\bond{", "", "", "}"); },
+ '->': /^(?:<->|<-->|->|<-|<=>>|<<=>|<=>|[\u2192\u27F6\u21CC])/,
+ 'CMT': /^[CMT](?=\[)/,
+ '[(...)]': function (input) { return mhchemParser.patterns.findObserveGroups(input, "[", "", "", "]"); },
+ '1st-level escape': /^(&|\\\\|\\hline)\s*/,
+ '\\,': /^(?:\\[,\ ;:])/, // \\x - but output no space before
+ '\\x{}{}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true); },
+ '\\x{}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", ""); },
+ '\\ca': /^\\ca(?:\s+|(?![a-zA-Z]))/,
+ '\\x': /^(?:\\[a-zA-Z]+\s*|\\[_&{}%])/,
+ 'orbital': /^(?:[0-9]{1,2}[spdfgh]|[0-9]{0,2}sp)(?=$|[^a-zA-Z])/, // only those with numbers in front, because the others will be formatted correctly anyway
+ 'others': /^[\/~|]/,
+ '\\frac{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\frac{", "", "", "}", "{", "", "", "}"); },
+ '\\overset{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\overset{", "", "", "}", "{", "", "", "}"); },
+ '\\underset{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\underset{", "", "", "}", "{", "", "", "}"); },
+ '\\underbrace{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\underbrace{", "", "", "}_", "{", "", "", "}"); },
+ '\\color{(...)}0': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}"); },
+ '\\color{(...)}{(...)}1': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}", "{", "", "", "}"); },
+ '\\color(...){(...)}2': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\color", "\\", "", /^(?=\{)/, "{", "", "", "}"); },
+ '\\ce{(...)}': function (input) { return mhchemParser.patterns.findObserveGroups(input, "\\ce{", "", "", "}"); },
+ 'oxidation$': /^(?:[+-][IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/,
+ 'd-oxidation$': /^(?:[+-]?\s?[IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/, // 0 could be oxidation or charge
+ 'roman numeral': /^[IVX]+/,
+ '1/2$': /^[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+(?:\$[a-z]\$|[a-z])?$/,
+ 'amount': function (input) {
+ var match;
+ // e.g. 2, 0.5, 1/2, -2, n/2, +; $a$ could be added later in parsing
+ match = input.match(/^(?:(?:(?:\([+\-]?[0-9]+\/[0-9]+\)|[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+|[+\-]?[0-9]+[.,][0-9]+|[+\-]?\.[0-9]+|[+\-]?[0-9]+)(?:[a-z](?=\s*[A-Z]))?)|[+\-]?[a-z](?=\s*[A-Z])|\+(?!\s))/);
+ if (match) {
+ return { match_: match[0], remainder: input.substr(match[0].length) };
+ }
+ var a = mhchemParser.patterns.findObserveGroups(input, "", "$", "$", "");
+ if (a) { // e.g. $2n-1$, $-$
+ match = a.match_.match(/^\$(?:\(?[+\-]?(?:[0-9]*[a-z]?[+\-])?[0-9]*[a-z](?:[+\-][0-9]*[a-z]?)?\)?|\+|-)\$$/);
+ if (match) {
+ return { match_: match[0], remainder: input.substr(match[0].length) };
+ }
+ }
+ return null;
+ },
+ 'amount2': function (input) { return this['amount'](input); },
+ '(KV letters),': /^(?:[A-Z][a-z]{0,2}|i)(?=,)/,
+ 'formula$': function (input) {
+ if (input.match(/^\([a-z]+\)$/)) { return null; } // state of aggregation = no formula
+ var match = input.match(/^(?:[a-z]|(?:[0-9\ \+\-\,\.\(\)]+[a-z])+[0-9\ \+\-\,\.\(\)]*|(?:[a-z][0-9\ \+\-\,\.\(\)]+)+[a-z]?)$/);
+ if (match) {
+ return { match_: match[0], remainder: input.substr(match[0].length) };
+ }
+ return null;
+ },
+ 'uprightEntities': /^(?:pH|pOH|pC|pK|iPr|iBu)(?=$|[^a-zA-Z])/,
+ '/': /^\s*(\/)\s*/,
+ '//': /^\s*(\/\/)\s*/,
+ '*': /^\s*[*.]\s*/
+ },
+ findObserveGroups: function (input, begExcl, begIncl, endIncl, endExcl, beg2Excl, beg2Incl, end2Incl, end2Excl, combine) {
+ /** @type {{(input: string, pattern: string | RegExp): string | string[] | null;}} */
+ var _match = function (input, pattern) {
+ if (typeof pattern === "string") {
+ if (input.indexOf(pattern) !== 0) { return null; }
+ return pattern;
+ } else {
+ var match = input.match(pattern);
+ if (!match) { return null; }
+ return match[0];
+ }
+ };
+ /** @type {{(input: string, i: number, endChars: string | RegExp): {endMatchBegin: number, endMatchEnd: number} | null;}} */
+ var _findObserveGroups = function (input, i, endChars) {
+ var braces = 0;
+ while (i < input.length) {
+ var a = input.charAt(i);
+ var match = _match(input.substr(i), endChars);
+ if (match !== null && braces === 0) {
+ return { endMatchBegin: i, endMatchEnd: i + match.length };
+ } else if (a === "{") {
+ braces++;
+ } else if (a === "}") {
+ if (braces === 0) {
+ throw ["ExtraCloseMissingOpen", "Extra close brace or missing open brace"];
+ } else {
+ braces--;
+ }
+ }
+ i++;
+ }
+ if (braces > 0) {
+ return null;
+ }
+ return null;
+ };
+ var match = _match(input, begExcl);
+ if (match === null) { return null; }
+ input = input.substr(match.length);
+ match = _match(input, begIncl);
+ if (match === null) { return null; }
+ var e = _findObserveGroups(input, match.length, endIncl || endExcl);
+ if (e === null) { return null; }
+ var match1 = input.substring(0, (endIncl ? e.endMatchEnd : e.endMatchBegin));
+ if (!(beg2Excl || beg2Incl)) {
+ return {
+ match_: match1,
+ remainder: input.substr(e.endMatchEnd)
+ };
+ } else {
+ var group2 = this.findObserveGroups(input.substr(e.endMatchEnd), beg2Excl, beg2Incl, end2Incl, end2Excl);
+ if (group2 === null) { return null; }
+ /** @type {string[]} */
+ var matchRet = [match1, group2.match_];
+ return {
+ match_: (combine ? matchRet.join("") : matchRet),
+ remainder: group2.remainder
+ };
+ }
+ },
+
+ //
+ // Matching function
+ // e.g. match("a", input) will look for the regexp called "a" and see if it matches
+ // returns null or {match_:"a", remainder:"bc"}
+ //
+ match_: function (m, input) {
+ var pattern = mhchemParser.patterns.patterns[m];
+ if (pattern === undefined) {
+ throw ["MhchemBugP", "mhchem bug P. Please report. (" + m + ")"]; // Trying to use non-existing pattern
+ } else if (typeof pattern === "function") {
+ return mhchemParser.patterns.patterns[m](input); // cannot use cached var pattern here, because some pattern functions need this===mhchemParser
+ } else { // RegExp
+ var match = input.match(pattern);
+ if (match) {
+ var mm;
+ if (match[2]) {
+ mm = [ match[1], match[2] ];
+ } else if (match[1]) {
+ mm = match[1];
+ } else {
+ mm = match[0];
+ }
+ return { match_: mm, remainder: input.substr(match[0].length) };
+ }
+ return null;
+ }
+ }
+ },
+
+ //
+ // Generic state machine actions
+ //
+ actions: {
+ 'a=': function (buffer, m) { buffer.a = (buffer.a || "") + m; },
+ 'b=': function (buffer, m) { buffer.b = (buffer.b || "") + m; },
+ 'p=': function (buffer, m) { buffer.p = (buffer.p || "") + m; },
+ 'o=': function (buffer, m) { buffer.o = (buffer.o || "") + m; },
+ 'q=': function (buffer, m) { buffer.q = (buffer.q || "") + m; },
+ 'd=': function (buffer, m) { buffer.d = (buffer.d || "") + m; },
+ 'rm=': function (buffer, m) { buffer.rm = (buffer.rm || "") + m; },
+ 'text=': function (buffer, m) { buffer.text_ = (buffer.text_ || "") + m; },
+ 'insert': function (buffer, m, a) { return { type_: a }; },
+ 'insert+p1': function (buffer, m, a) { return { type_: a, p1: m }; },
+ 'insert+p1+p2': function (buffer, m, a) { return { type_: a, p1: m[0], p2: m[1] }; },
+ 'copy': function (buffer, m) { return m; },
+ 'rm': function (buffer, m) { return { type_: 'rm', p1: m || ""}; },
+ 'text': function (buffer, m) { return mhchemParser.go(m, 'text'); },
+ '{text}': function (buffer, m) {
+ var ret = [ "{" ];
+ mhchemParser.concatArray(ret, mhchemParser.go(m, 'text'));
+ ret.push("}");
+ return ret;
+ },
+ 'tex-math': function (buffer, m) { return mhchemParser.go(m, 'tex-math'); },
+ 'tex-math tight': function (buffer, m) { return mhchemParser.go(m, 'tex-math tight'); },
+ 'bond': function (buffer, m, k) { return { type_: 'bond', kind_: k || m }; },
+ 'color0-output': function (buffer, m) { return { type_: 'color0', color: m[0] }; },
+ 'ce': function (buffer, m) { return mhchemParser.go(m); },
+ '1/2': function (buffer, m) {
+ /** @type {ParserOutput[]} */
+ var ret = [];
+ if (m.match(/^[+\-]/)) {
+ ret.push(m.substr(0, 1));
+ m = m.substr(1);
+ }
+ var n = m.match(/^([0-9]+|\$[a-z]\$|[a-z])\/([0-9]+)(\$[a-z]\$|[a-z])?$/);
+ n[1] = n[1].replace(/\$/g, "");
+ ret.push({ type_: 'frac', p1: n[1], p2: n[2] });
+ if (n[3]) {
+ n[3] = n[3].replace(/\$/g, "");
+ ret.push({ type_: 'tex-math', p1: n[3] });
+ }
+ return ret;
+ },
+ '9,9': function (buffer, m) { return mhchemParser.go(m, '9,9'); }
+ },
+ //
+ // createTransitions
+ // convert { 'letter': { 'state': { action_: 'output' } } } to { 'state' => [ { pattern: 'letter', task: { action_: [{type_: 'output'}] } } ] }
+ // with expansion of 'a|b' to 'a' and 'b' (at 2 places)
+ //
+ createTransitions: function (o) {
+ var pattern, state;
+ /** @type {string[]} */
+ var stateArray;
+ var i;
+ //
+ // 1. Collect all states
+ //
+ /** @type {Transitions} */
+ var transitions = {};
+ for (pattern in o) {
+ for (state in o[pattern]) {
+ stateArray = state.split("|");
+ o[pattern][state].stateArray = stateArray;
+ for (i=0; i<stateArray.length; i++) {
+ transitions[stateArray[i]] = [];
+ }
+ }
+ }
+ //
+ // 2. Fill states
+ //
+ for (pattern in o) {
+ for (state in o[pattern]) {
+ stateArray = o[pattern][state].stateArray || [];
+ for (i=0; i<stateArray.length; i++) {
+ //
+ // 2a. Normalize actions into array: 'text=' ==> [{type_:'text='}]
+ // (Note to myself: Resolving the function here would be problematic. It would need .bind (for *this*) and currying (for *option*).)
+ //
+ /** @type {any} */
+ var p = o[pattern][state];
+ if (p.action_) {
+ p.action_ = [].concat(p.action_);
+ for (var k=0; k<p.action_.length; k++) {
+ if (typeof p.action_[k] === "string") {
+ p.action_[k] = { type_: p.action_[k] };
+ }
+ }
+ } else {
+ p.action_ = [];
+ }
+ //
+ // 2.b Multi-insert
+ //
+ var patternArray = pattern.split("|");
+ for (var j=0; j<patternArray.length; j++) {
+ if (stateArray[i] === '*') { // insert into all
+ for (var t in transitions) {
+ transitions[t].push({ pattern: patternArray[j], task: p });
+ }
+ } else {
+ transitions[stateArray[i]].push({ pattern: patternArray[j], task: p });
+ }
+ }
+ }
+ }
+ }
+ return transitions;
+ },
+ stateMachines: {}
+ };
+
+ //
+ // Definition of state machines
+ //
+ mhchemParser.stateMachines = {
+ //
+ // \ce state machines
+ //
+ //#region ce
+ 'ce': { // main parser
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': { action_: 'output' } },
+ 'else': {
+ '0|1|2': { action_: 'beginsWithBond=false', revisit: true, toContinue: true } },
+ 'oxidation$': {
+ '0': { action_: 'oxidation-output' } },
+ 'CMT': {
+ 'r': { action_: 'rdt=', nextState: 'rt' },
+ 'rd': { action_: 'rqt=', nextState: 'rdt' } },
+ 'arrowUpDown': {
+ '0|1|2|as': { action_: [ 'sb=false', 'output', 'operator' ], nextState: '1' } },
+ 'uprightEntities': {
+ '0|1|2': { action_: [ 'o=', 'output' ], nextState: '1' } },
+ 'orbital': {
+ '0|1|2|3': { action_: 'o=', nextState: 'o' } },
+ '->': {
+ '0|1|2|3': { action_: 'r=', nextState: 'r' },
+ 'a|as': { action_: [ 'output', 'r=' ], nextState: 'r' },
+ '*': { action_: [ 'output', 'r=' ], nextState: 'r' } },
+ '+': {
+ 'o': { action_: 'd= kv', nextState: 'd' },
+ 'd|D': { action_: 'd=', nextState: 'd' },
+ 'q': { action_: 'd=', nextState: 'qd' },
+ 'qd|qD': { action_: 'd=', nextState: 'qd' },
+ 'dq': { action_: [ 'output', 'd=' ], nextState: 'd' },
+ '3': { action_: [ 'sb=false', 'output', 'operator' ], nextState: '0' } },
+ 'amount': {
+ '0|2': { action_: 'a=', nextState: 'a' } },
+ 'pm-operator': {
+ '0|1|2|a|as': { action_: [ 'sb=false', 'output', { type_: 'operator', option: '\\pm' } ], nextState: '0' } },
+ 'operator': {
+ '0|1|2|a|as': { action_: [ 'sb=false', 'output', 'operator' ], nextState: '0' } },
+ '-$': {
+ 'o|q': { action_: [ 'charge or bond', 'output' ], nextState: 'qd' },
+ 'd': { action_: 'd=', nextState: 'd' },
+ 'D': { action_: [ 'output', { type_: 'bond', option: "-" } ], nextState: '3' },
+ 'q': { action_: 'd=', nextState: 'qd' },
+ 'qd': { action_: 'd=', nextState: 'qd' },
+ 'qD|dq': { action_: [ 'output', { type_: 'bond', option: "-" } ], nextState: '3' } },
+ '-9': {
+ '3|o': { action_: [ 'output', { type_: 'insert', option: 'hyphen' } ], nextState: '3' } },
+ '- orbital overlap': {
+ 'o': { action_: [ 'output', { type_: 'insert', option: 'hyphen' } ], nextState: '2' },
+ 'd': { action_: [ 'output', { type_: 'insert', option: 'hyphen' } ], nextState: '2' } },
+ '-': {
+ '0|1|2': { action_: [ { type_: 'output', option: 1 }, 'beginsWithBond=true', { type_: 'bond', option: "-" } ], nextState: '3' },
+ '3': { action_: { type_: 'bond', option: "-" } },
+ 'a': { action_: [ 'output', { type_: 'insert', option: 'hyphen' } ], nextState: '2' },
+ 'as': { action_: [ { type_: 'output', option: 2 }, { type_: 'bond', option: "-" } ], nextState: '3' },
+ 'b': { action_: 'b=' },
+ 'o': { action_: { type_: '- after o/d', option: false }, nextState: '2' },
+ 'q': { action_: { type_: '- after o/d', option: false }, nextState: '2' },
+ 'd|qd|dq': { action_: { type_: '- after o/d', option: true }, nextState: '2' },
+ 'D|qD|p': { action_: [ 'output', { type_: 'bond', option: "-" } ], nextState: '3' } },
+ 'amount2': {
+ '1|3': { action_: 'a=', nextState: 'a' } },
+ 'letters': {
+ '0|1|2|3|a|as|b|p|bp|o': { action_: 'o=', nextState: 'o' },
+ 'q|dq': { action_: ['output', 'o='], nextState: 'o' },
+ 'd|D|qd|qD': { action_: 'o after d', nextState: 'o' } },
+ 'digits': {
+ 'o': { action_: 'q=', nextState: 'q' },
+ 'd|D': { action_: 'q=', nextState: 'dq' },
+ 'q': { action_: [ 'output', 'o=' ], nextState: 'o' },
+ 'a': { action_: 'o=', nextState: 'o' } },
+ 'space A': {
+ 'b|p|bp': {} },
+ 'space': {
+ 'a': { nextState: 'as' },
+ '0': { action_: 'sb=false' },
+ '1|2': { action_: 'sb=true' },
+ 'r|rt|rd|rdt|rdq': { action_: 'output', nextState: '0' },
+ '*': { action_: [ 'output', 'sb=true' ], nextState: '1'} },
+ '1st-level escape': {
+ '1|2': { action_: [ 'output', { type_: 'insert+p1', option: '1st-level escape' } ] },
+ '*': { action_: [ 'output', { type_: 'insert+p1', option: '1st-level escape' } ], nextState: '0' } },
+ '[(...)]': {
+ 'r|rt': { action_: 'rd=', nextState: 'rd' },
+ 'rd|rdt': { action_: 'rq=', nextState: 'rdq' } },
+ '...': {
+ 'o|d|D|dq|qd|qD': { action_: [ 'output', { type_: 'bond', option: "..." } ], nextState: '3' },
+ '*': { action_: [ { type_: 'output', option: 1 }, { type_: 'insert', option: 'ellipsis' } ], nextState: '1' } },
+ '. |* ': {
+ '*': { action_: [ 'output', { type_: 'insert', option: 'addition compound' } ], nextState: '1' } },
+ 'state of aggregation $': {
+ '*': { action_: [ 'output', 'state of aggregation' ], nextState: '1' } },
+ '{[(': {
+ 'a|as|o': { action_: [ 'o=', 'output', 'parenthesisLevel++' ], nextState: '2' },
+ '0|1|2|3': { action_: [ 'o=', 'output', 'parenthesisLevel++' ], nextState: '2' },
+ '*': { action_: [ 'output', 'o=', 'output', 'parenthesisLevel++' ], nextState: '2' } },
+ ')]}': {
+ '0|1|2|3|b|p|bp|o': { action_: [ 'o=', 'parenthesisLevel--' ], nextState: 'o' },
+ 'a|as|d|D|q|qd|qD|dq': { action_: [ 'output', 'o=', 'parenthesisLevel--' ], nextState: 'o' } },
+ ', ': {
+ '*': { action_: [ 'output', 'comma' ], nextState: '0' } },
+ '^_': { // ^ and _ without a sensible argument
+ '*': { } },
+ '^{(...)}|^($...$)': {
+ '0|1|2|as': { action_: 'b=', nextState: 'b' },
+ 'p': { action_: 'b=', nextState: 'bp' },
+ '3|o': { action_: 'd= kv', nextState: 'D' },
+ 'q': { action_: 'd=', nextState: 'qD' },
+ 'd|D|qd|qD|dq': { action_: [ 'output', 'd=' ], nextState: 'D' } },
+ '^a|^\\x{}{}|^\\x{}|^\\x|\'': {
+ '0|1|2|as': { action_: 'b=', nextState: 'b' },
+ 'p': { action_: 'b=', nextState: 'bp' },
+ '3|o': { action_: 'd= kv', nextState: 'd' },
+ 'q': { action_: 'd=', nextState: 'qd' },
+ 'd|qd|D|qD': { action_: 'd=' },
+ 'dq': { action_: [ 'output', 'd=' ], nextState: 'd' } },
+ '_{(state of aggregation)}$': {
+ 'd|D|q|qd|qD|dq': { action_: [ 'output', 'q=' ], nextState: 'q' } },
+ '_{(...)}|_($...$)|_9|_\\x{}{}|_\\x{}|_\\x': {
+ '0|1|2|as': { action_: 'p=', nextState: 'p' },
+ 'b': { action_: 'p=', nextState: 'bp' },
+ '3|o': { action_: 'q=', nextState: 'q' },
+ 'd|D': { action_: 'q=', nextState: 'dq' },
+ 'q|qd|qD|dq': { action_: [ 'output', 'q=' ], nextState: 'q' } },
+ '=<>': {
+ '0|1|2|3|a|as|o|q|d|D|qd|qD|dq': { action_: [ { type_: 'output', option: 2 }, 'bond' ], nextState: '3' } },
+ '#': {
+ '0|1|2|3|a|as|o': { action_: [ { type_: 'output', option: 2 }, { type_: 'bond', option: "#" } ], nextState: '3' } },
+ '{}': {
+ '*': { action_: { type_: 'output', option: 1 }, nextState: '1' } },
+ '{...}': {
+ '0|1|2|3|a|as|b|p|bp': { action_: 'o=', nextState: 'o' },
+ 'o|d|D|q|qd|qD|dq': { action_: [ 'output', 'o=' ], nextState: 'o' } },
+ '$...$': {
+ 'a': { action_: 'a=' }, // 2$n$
+ '0|1|2|3|as|b|p|bp|o': { action_: 'o=', nextState: 'o' }, // not 'amount'
+ 'as|o': { action_: 'o=' },
+ 'q|d|D|qd|qD|dq': { action_: [ 'output', 'o=' ], nextState: 'o' } },
+ '\\bond{(...)}': {
+ '*': { action_: [ { type_: 'output', option: 2 }, 'bond' ], nextState: "3" } },
+ '\\frac{(...)}': {
+ '*': { action_: [ { type_: 'output', option: 1 }, 'frac-output' ], nextState: '3' } },
+ '\\overset{(...)}': {
+ '*': { action_: [ { type_: 'output', option: 2 }, 'overset-output' ], nextState: '3' } },
+ '\\underset{(...)}': {
+ '*': { action_: [ { type_: 'output', option: 2 }, 'underset-output' ], nextState: '3' } },
+ '\\underbrace{(...)}': {
+ '*': { action_: [ { type_: 'output', option: 2 }, 'underbrace-output' ], nextState: '3' } },
+ '\\color{(...)}{(...)}1|\\color(...){(...)}2': {
+ '*': { action_: [ { type_: 'output', option: 2 }, 'color-output' ], nextState: '3' } },
+ '\\color{(...)}0': {
+ '*': { action_: [ { type_: 'output', option: 2 }, 'color0-output' ] } },
+ '\\ce{(...)}': {
+ '*': { action_: [ { type_: 'output', option: 2 }, 'ce' ], nextState: '3' } },
+ '\\,': {
+ '*': { action_: [ { type_: 'output', option: 1 }, 'copy' ], nextState: '1' } },
+ '\\x{}{}|\\x{}|\\x': {
+ '0|1|2|3|a|as|b|p|bp|o|c0': { action_: [ 'o=', 'output' ], nextState: '3' },
+ '*': { action_: ['output', 'o=', 'output' ], nextState: '3' } },
+ 'others': {
+ '*': { action_: [ { type_: 'output', option: 1 }, 'copy' ], nextState: '3' } },
+ 'else2': {
+ 'a': { action_: 'a to o', nextState: 'o', revisit: true },
+ 'as': { action_: [ 'output', 'sb=true' ], nextState: '1', revisit: true },
+ 'r|rt|rd|rdt|rdq': { action_: [ 'output' ], nextState: '0', revisit: true },
+ '*': { action_: [ 'output', 'copy' ], nextState: '3' } }
+ }),
+ actions: {
+ 'o after d': function (buffer, m) {
+ var ret;
+ if ((buffer.d || "").match(/^[0-9]+$/)) {
+ var tmp = buffer.d;
+ buffer.d = undefined;
+ ret = this['output'](buffer);
+ buffer.b = tmp;
+ } else {
+ ret = this['output'](buffer);
+ }
+ mhchemParser.actions['o='](buffer, m);
+ return ret;
+ },
+ 'd= kv': function (buffer, m) {
+ buffer.d = m;
+ buffer.dType = 'kv';
+ },
+ 'charge or bond': function (buffer, m) {
+ if (buffer['beginsWithBond']) {
+ /** @type {ParserOutput[]} */
+ var ret = [];
+ mhchemParser.concatArray(ret, this['output'](buffer));
+ mhchemParser.concatArray(ret, mhchemParser.actions['bond'](buffer, m, "-"));
+ return ret;
+ } else {
+ buffer.d = m;
+ }
+ },
+ '- after o/d': function (buffer, m, isAfterD) {
+ var c1 = mhchemParser.patterns.match_('orbital', buffer.o || "");
+ var c2 = mhchemParser.patterns.match_('one lowercase greek letter $', buffer.o || "");
+ var c3 = mhchemParser.patterns.match_('one lowercase latin letter $', buffer.o || "");
+ var c4 = mhchemParser.patterns.match_('$one lowercase latin letter$ $', buffer.o || "");
+ var hyphenFollows = m==="-" && ( c1 && c1.remainder==="" || c2 || c3 || c4 );
+ if (hyphenFollows && !buffer.a && !buffer.b && !buffer.p && !buffer.d && !buffer.q && !c1 && c3) {
+ buffer.o = '$' + buffer.o + '$';
+ }
+ /** @type {ParserOutput[]} */
+ var ret = [];
+ if (hyphenFollows) {
+ mhchemParser.concatArray(ret, this['output'](buffer));
+ ret.push({ type_: 'hyphen' });
+ } else {
+ c1 = mhchemParser.patterns.match_('digits', buffer.d || "");
+ if (isAfterD && c1 && c1.remainder==='') {
+ mhchemParser.concatArray(ret, mhchemParser.actions['d='](buffer, m));
+ mhchemParser.concatArray(ret, this['output'](buffer));
+ } else {
+ mhchemParser.concatArray(ret, this['output'](buffer));
+ mhchemParser.concatArray(ret, mhchemParser.actions['bond'](buffer, m, "-"));
+ }
+ }
+ return ret;
+ },
+ 'a to o': function (buffer) {
+ buffer.o = buffer.a;
+ buffer.a = undefined;
+ },
+ 'sb=true': function (buffer) { buffer.sb = true; },
+ 'sb=false': function (buffer) { buffer.sb = false; },
+ 'beginsWithBond=true': function (buffer) { buffer['beginsWithBond'] = true; },
+ 'beginsWithBond=false': function (buffer) { buffer['beginsWithBond'] = false; },
+ 'parenthesisLevel++': function (buffer) { buffer['parenthesisLevel']++; },
+ 'parenthesisLevel--': function (buffer) { buffer['parenthesisLevel']--; },
+ 'state of aggregation': function (buffer, m) {
+ return { type_: 'state of aggregation', p1: mhchemParser.go(m, 'o') };
+ },
+ 'comma': function (buffer, m) {
+ var a = m.replace(/\s*$/, '');
+ var withSpace = (a !== m);
+ if (withSpace && buffer['parenthesisLevel'] === 0) {
+ return { type_: 'comma enumeration L', p1: a };
+ } else {
+ return { type_: 'comma enumeration M', p1: a };
+ }
+ },
+ 'output': function (buffer, m, entityFollows) {
+ // entityFollows:
+ // undefined = if we have nothing else to output, also ignore the just read space (buffer.sb)
+ // 1 = an entity follows, never omit the space if there was one just read before (can only apply to state 1)
+ // 2 = 1 + the entity can have an amount, so output a\, instead of converting it to o (can only apply to states a|as)
+ /** @type {ParserOutput | ParserOutput[]} */
+ var ret;
+ if (!buffer.r) {
+ ret = [];
+ if (!buffer.a && !buffer.b && !buffer.p && !buffer.o && !buffer.q && !buffer.d && !entityFollows) {
+ //ret = [];
+ } else {
+ if (buffer.sb) {
+ ret.push({ type_: 'entitySkip' });
+ }
+ if (!buffer.o && !buffer.q && !buffer.d && !buffer.b && !buffer.p && entityFollows!==2) {
+ buffer.o = buffer.a;
+ buffer.a = undefined;
+ } else if (!buffer.o && !buffer.q && !buffer.d && (buffer.b || buffer.p)) {
+ buffer.o = buffer.a;
+ buffer.d = buffer.b;
+ buffer.q = buffer.p;
+ buffer.a = buffer.b = buffer.p = undefined;
+ } else {
+ if (buffer.o && buffer.dType==='kv' && mhchemParser.patterns.match_('d-oxidation$', buffer.d || "")) {
+ buffer.dType = 'oxidation';
+ } else if (buffer.o && buffer.dType==='kv' && !buffer.q) {
+ buffer.dType = undefined;
+ }
+ }
+ ret.push({
+ type_: 'chemfive',
+ a: mhchemParser.go(buffer.a, 'a'),
+ b: mhchemParser.go(buffer.b, 'bd'),
+ p: mhchemParser.go(buffer.p, 'pq'),
+ o: mhchemParser.go(buffer.o, 'o'),
+ q: mhchemParser.go(buffer.q, 'pq'),
+ d: mhchemParser.go(buffer.d, (buffer.dType === 'oxidation' ? 'oxidation' : 'bd')),
+ dType: buffer.dType
+ });
+ }
+ } else { // r
+ /** @type {ParserOutput[]} */
+ var rd;
+ if (buffer.rdt === 'M') {
+ rd = mhchemParser.go(buffer.rd, 'tex-math');
+ } else if (buffer.rdt === 'T') {
+ rd = [ { type_: 'text', p1: buffer.rd || "" } ];
+ } else {
+ rd = mhchemParser.go(buffer.rd);
+ }
+ /** @type {ParserOutput[]} */
+ var rq;
+ if (buffer.rqt === 'M') {
+ rq = mhchemParser.go(buffer.rq, 'tex-math');
+ } else if (buffer.rqt === 'T') {
+ rq = [ { type_: 'text', p1: buffer.rq || ""} ];
+ } else {
+ rq = mhchemParser.go(buffer.rq);
+ }
+ ret = {
+ type_: 'arrow',
+ r: buffer.r,
+ rd: rd,
+ rq: rq
+ };
+ }
+ for (var p in buffer) {
+ if (p !== 'parenthesisLevel' && p !== 'beginsWithBond') {
+ delete buffer[p];
+ }
+ }
+ return ret;
+ },
+ 'oxidation-output': function (buffer, m) {
+ var ret = [ "{" ];
+ mhchemParser.concatArray(ret, mhchemParser.go(m, 'oxidation'));
+ ret.push("}");
+ return ret;
+ },
+ 'frac-output': function (buffer, m) {
+ return { type_: 'frac-ce', p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) };
+ },
+ 'overset-output': function (buffer, m) {
+ return { type_: 'overset', p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) };
+ },
+ 'underset-output': function (buffer, m) {
+ return { type_: 'underset', p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) };
+ },
+ 'underbrace-output': function (buffer, m) {
+ return { type_: 'underbrace', p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) };
+ },
+ 'color-output': function (buffer, m) {
+ return { type_: 'color', color1: m[0], color2: mhchemParser.go(m[1]) };
+ },
+ 'r=': function (buffer, m) { buffer.r = m; },
+ 'rdt=': function (buffer, m) { buffer.rdt = m; },
+ 'rd=': function (buffer, m) { buffer.rd = m; },
+ 'rqt=': function (buffer, m) { buffer.rqt = m; },
+ 'rq=': function (buffer, m) { buffer.rq = m; },
+ 'operator': function (buffer, m, p1) { return { type_: 'operator', kind_: (p1 || m) }; }
+ }
+ },
+ 'a': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': {} },
+ '1/2$': {
+ '0': { action_: '1/2' } },
+ 'else': {
+ '0': { nextState: '1', revisit: true } },
+ '$(...)$': {
+ '*': { action_: 'tex-math tight', nextState: '1' } },
+ ',': {
+ '*': { action_: { type_: 'insert', option: 'commaDecimal' } } },
+ 'else2': {
+ '*': { action_: 'copy' } }
+ }),
+ actions: {}
+ },
+ 'o': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': {} },
+ '1/2$': {
+ '0': { action_: '1/2' } },
+ 'else': {
+ '0': { nextState: '1', revisit: true } },
+ 'letters': {
+ '*': { action_: 'rm' } },
+ '\\ca': {
+ '*': { action_: { type_: 'insert', option: 'circa' } } },
+ '\\x{}{}|\\x{}|\\x': {
+ '*': { action_: 'copy' } },
+ '${(...)}$|$(...)$': {
+ '*': { action_: 'tex-math' } },
+ '{(...)}': {
+ '*': { action_: '{text}' } },
+ 'else2': {
+ '*': { action_: 'copy' } }
+ }),
+ actions: {}
+ },
+ 'text': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': { action_: 'output' } },
+ '{...}': {
+ '*': { action_: 'text=' } },
+ '${(...)}$|$(...)$': {
+ '*': { action_: 'tex-math' } },
+ '\\greek': {
+ '*': { action_: [ 'output', 'rm' ] } },
+ '\\,|\\x{}{}|\\x{}|\\x': {
+ '*': { action_: [ 'output', 'copy' ] } },
+ 'else': {
+ '*': { action_: 'text=' } }
+ }),
+ actions: {
+ 'output': function (buffer) {
+ if (buffer.text_) {
+ /** @type {ParserOutput} */
+ var ret = { type_: 'text', p1: buffer.text_ };
+ for (var p in buffer) { delete buffer[p]; }
+ return ret;
+ }
+ }
+ }
+ },
+ 'pq': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': {} },
+ 'state of aggregation $': {
+ '*': { action_: 'state of aggregation' } },
+ 'i$': {
+ '0': { nextState: '!f', revisit: true } },
+ '(KV letters),': {
+ '0': { action_: 'rm', nextState: '0' } },
+ 'formula$': {
+ '0': { nextState: 'f', revisit: true } },
+ '1/2$': {
+ '0': { action_: '1/2' } },
+ 'else': {
+ '0': { nextState: '!f', revisit: true } },
+ '${(...)}$|$(...)$': {
+ '*': { action_: 'tex-math' } },
+ '{(...)}': {
+ '*': { action_: 'text' } },
+ 'a-z': {
+ 'f': { action_: 'tex-math' } },
+ 'letters': {
+ '*': { action_: 'rm' } },
+ '-9.,9': {
+ '*': { action_: '9,9' } },
+ ',': {
+ '*': { action_: { type_: 'insert+p1', option: 'comma enumeration S' } } },
+ '\\color{(...)}{(...)}1|\\color(...){(...)}2': {
+ '*': { action_: 'color-output' } },
+ '\\color{(...)}0': {
+ '*': { action_: 'color0-output' } },
+ '\\ce{(...)}': {
+ '*': { action_: 'ce' } },
+ '\\,|\\x{}{}|\\x{}|\\x': {
+ '*': { action_: 'copy' } },
+ 'else2': {
+ '*': { action_: 'copy' } }
+ }),
+ actions: {
+ 'state of aggregation': function (buffer, m) {
+ return { type_: 'state of aggregation subscript', p1: mhchemParser.go(m, 'o') };
+ },
+ 'color-output': function (buffer, m) {
+ return { type_: 'color', color1: m[0], color2: mhchemParser.go(m[1], 'pq') };
+ }
+ }
+ },
+ 'bd': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': {} },
+ 'x$': {
+ '0': { nextState: '!f', revisit: true } },
+ 'formula$': {
+ '0': { nextState: 'f', revisit: true } },
+ 'else': {
+ '0': { nextState: '!f', revisit: true } },
+ '-9.,9 no missing 0': {
+ '*': { action_: '9,9' } },
+ '.': {
+ '*': { action_: { type_: 'insert', option: 'electron dot' } } },
+ 'a-z': {
+ 'f': { action_: 'tex-math' } },
+ 'x': {
+ '*': { action_: { type_: 'insert', option: 'KV x' } } },
+ 'letters': {
+ '*': { action_: 'rm' } },
+ '\'': {
+ '*': { action_: { type_: 'insert', option: 'prime' } } },
+ '${(...)}$|$(...)$': {
+ '*': { action_: 'tex-math' } },
+ '{(...)}': {
+ '*': { action_: 'text' } },
+ '\\color{(...)}{(...)}1|\\color(...){(...)}2': {
+ '*': { action_: 'color-output' } },
+ '\\color{(...)}0': {
+ '*': { action_: 'color0-output' } },
+ '\\ce{(...)}': {
+ '*': { action_: 'ce' } },
+ '\\,|\\x{}{}|\\x{}|\\x': {
+ '*': { action_: 'copy' } },
+ 'else2': {
+ '*': { action_: 'copy' } }
+ }),
+ actions: {
+ 'color-output': function (buffer, m) {
+ return { type_: 'color', color1: m[0], color2: mhchemParser.go(m[1], 'bd') };
+ }
+ }
+ },
+ 'oxidation': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': {} },
+ 'roman numeral': {
+ '*': { action_: 'roman-numeral' } },
+ '${(...)}$|$(...)$': {
+ '*': { action_: 'tex-math' } },
+ 'else': {
+ '*': { action_: 'copy' } }
+ }),
+ actions: {
+ 'roman-numeral': function (buffer, m) { return { type_: 'roman numeral', p1: m || "" }; }
+ }
+ },
+ 'tex-math': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': { action_: 'output' } },
+ '\\ce{(...)}': {
+ '*': { action_: [ 'output', 'ce' ] } },
+ '{...}|\\,|\\x{}{}|\\x{}|\\x': {
+ '*': { action_: 'o=' } },
+ 'else': {
+ '*': { action_: 'o=' } }
+ }),
+ actions: {
+ 'output': function (buffer) {
+ if (buffer.o) {
+ /** @type {ParserOutput} */
+ var ret = { type_: 'tex-math', p1: buffer.o };
+ for (var p in buffer) { delete buffer[p]; }
+ return ret;
+ }
+ }
+ }
+ },
+ 'tex-math tight': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': { action_: 'output' } },
+ '\\ce{(...)}': {
+ '*': { action_: [ 'output', 'ce' ] } },
+ '{...}|\\,|\\x{}{}|\\x{}|\\x': {
+ '*': { action_: 'o=' } },
+ '-|+': {
+ '*': { action_: 'tight operator' } },
+ 'else': {
+ '*': { action_: 'o=' } }
+ }),
+ actions: {
+ 'tight operator': function (buffer, m) { buffer.o = (buffer.o || "") + "{"+m+"}"; },
+ 'output': function (buffer) {
+ if (buffer.o) {
+ /** @type {ParserOutput} */
+ var ret = { type_: 'tex-math', p1: buffer.o };
+ for (var p in buffer) { delete buffer[p]; }
+ return ret;
+ }
+ }
+ }
+ },
+ '9,9': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': {} },
+ ',': {
+ '*': { action_: 'comma' } },
+ 'else': {
+ '*': { action_: 'copy' } }
+ }),
+ actions: {
+ 'comma': function () { return { type_: 'commaDecimal' }; }
+ }
+ },
+ //#endregion
+ //
+ // \pu state machines
+ //
+ //#region pu
+ 'pu': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': { action_: 'output' } },
+ 'space$': {
+ '*': { action_: [ 'output', 'space' ] } },
+ '{[(|)]}': {
+ '0|a': { action_: 'copy' } },
+ '(-)(9)^(-9)': {
+ '0': { action_: 'number^', nextState: 'a' } },
+ '(-)(9.,9)(e)(99)': {
+ '0': { action_: 'enumber', nextState: 'a' } },
+ 'space': {
+ '0|a': {} },
+ 'pm-operator': {
+ '0|a': { action_: { type_: 'operator', option: '\\pm' }, nextState: '0' } },
+ 'operator': {
+ '0|a': { action_: 'copy', nextState: '0' } },
+ '//': {
+ 'd': { action_: 'o=', nextState: '/' } },
+ '/': {
+ 'd': { action_: 'o=', nextState: '/' } },
+ '{...}|else': {
+ '0|d': { action_: 'd=', nextState: 'd' },
+ 'a': { action_: [ 'space', 'd=' ], nextState: 'd' },
+ '/|q': { action_: 'q=', nextState: 'q' } }
+ }),
+ actions: {
+ 'enumber': function (buffer, m) {
+ /** @type {ParserOutput[]} */
+ var ret = [];
+ if (m[0] === "+-" || m[0] === "+/-") {
+ ret.push("\\pm ");
+ } else if (m[0]) {
+ ret.push(m[0]);
+ }
+ if (m[1]) { // 1.2
+ mhchemParser.concatArray(ret, mhchemParser.go(m[1], 'pu-9,9'));
+ if (m[2]) {
+ if (m[2].match(/[,.]/)) { // 1.23456(0.01111)
+ mhchemParser.concatArray(ret, mhchemParser.go(m[2], 'pu-9,9'));
+ } else { // 1.23456(1111) - without spacings
+ ret.push(m[2]);
+ }
+ }
+ if (m[3] || m[4]) { // 1.2e7 1.2x10^7
+ if (m[3] === "e" || m[4] === "*") {
+ ret.push({ type_: 'cdot' });
+ } else {
+ ret.push({ type_: 'times' });
+ }
+ }
+ }
+ if (m[5]) { // 10^7
+ ret.push("10^{"+m[5]+"}");
+ }
+ return ret;
+ },
+ 'number^': function (buffer, m) {
+ /** @type {ParserOutput[]} */
+ var ret = [];
+ if (m[0] === "+-" || m[0] === "+/-") {
+ ret.push("\\pm ");
+ } else if (m[0]) {
+ ret.push(m[0]);
+ }
+ mhchemParser.concatArray(ret, mhchemParser.go(m[1], 'pu-9,9'));
+ ret.push("^{"+m[2]+"}");
+ return ret;
+ },
+ 'operator': function (buffer, m, p1) { return { type_: 'operator', kind_: (p1 || m) }; },
+ 'space': function () { return { type_: 'pu-space-1' }; },
+ 'output': function (buffer) {
+ /** @type {ParserOutput | ParserOutput[]} */
+ var ret;
+ var md = mhchemParser.patterns.match_('{(...)}', buffer.d || "");
+ if (md && md.remainder === '') { buffer.d = md.match_; }
+ var mq = mhchemParser.patterns.match_('{(...)}', buffer.q || "");
+ if (mq && mq.remainder === '') { buffer.q = mq.match_; }
+ if (buffer.d) {
+ buffer.d = buffer.d.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C");
+ buffer.d = buffer.d.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F");
+ }
+ if (buffer.q) { // fraction
+ buffer.q = buffer.q.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C");
+ buffer.q = buffer.q.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F");
+ var b5 = {
+ d: mhchemParser.go(buffer.d, 'pu'),
+ q: mhchemParser.go(buffer.q, 'pu')
+ };
+ if (buffer.o === '//') {
+ ret = { type_: 'pu-frac', p1: b5.d, p2: b5.q };
+ } else {
+ ret = b5.d;
+ if (b5.d.length > 1 || b5.q.length > 1) {
+ ret.push({ type_: ' / ' });
+ } else {
+ ret.push({ type_: '/' });
+ }
+ mhchemParser.concatArray(ret, b5.q);
+ }
+ } else { // no fraction
+ ret = mhchemParser.go(buffer.d, 'pu-2');
+ }
+ for (var p in buffer) { delete buffer[p]; }
+ return ret;
+ }
+ }
+ },
+ 'pu-2': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '*': { action_: 'output' } },
+ '*': {
+ '*': { action_: [ 'output', 'cdot' ], nextState: '0' } },
+ '\\x': {
+ '*': { action_: 'rm=' } },
+ 'space': {
+ '*': { action_: [ 'output', 'space' ], nextState: '0' } },
+ '^{(...)}|^(-1)': {
+ '1': { action_: '^(-1)' } },
+ '-9.,9': {
+ '0': { action_: 'rm=', nextState: '0' },
+ '1': { action_: '^(-1)', nextState: '0' } },
+ '{...}|else': {
+ '*': { action_: 'rm=', nextState: '1' } }
+ }),
+ actions: {
+ 'cdot': function () { return { type_: 'tight cdot' }; },
+ '^(-1)': function (buffer, m) { buffer.rm += "^{"+m+"}"; },
+ 'space': function () { return { type_: 'pu-space-2' }; },
+ 'output': function (buffer) {
+ /** @type {ParserOutput | ParserOutput[]} */
+ var ret = [];
+ if (buffer.rm) {
+ var mrm = mhchemParser.patterns.match_('{(...)}', buffer.rm || "");
+ if (mrm && mrm.remainder === '') {
+ ret = mhchemParser.go(mrm.match_, 'pu');
+ } else {
+ ret = { type_: 'rm', p1: buffer.rm };
+ }
+ }
+ for (var p in buffer) { delete buffer[p]; }
+ return ret;
+ }
+ }
+ },
+ 'pu-9,9': {
+ transitions: mhchemParser.createTransitions({
+ 'empty': {
+ '0': { action_: 'output-0' },
+ 'o': { action_: 'output-o' } },
+ ',': {
+ '0': { action_: [ 'output-0', 'comma' ], nextState: 'o' } },
+ '.': {
+ '0': { action_: [ 'output-0', 'copy' ], nextState: 'o' } },
+ 'else': {
+ '*': { action_: 'text=' } }
+ }),
+ actions: {
+ 'comma': function () { return { type_: 'commaDecimal' }; },
+ 'output-0': function (buffer) {
+ /** @type {ParserOutput[]} */
+ var ret = [];
+ buffer.text_ = buffer.text_ || "";
+ if (buffer.text_.length > 4) {
+ var a = buffer.text_.length % 3;
+ if (a === 0) { a = 3; }
+ for (var i=buffer.text_.length-3; i>0; i-=3) {
+ ret.push(buffer.text_.substr(i, 3));
+ ret.push({ type_: '1000 separator' });
+ }
+ ret.push(buffer.text_.substr(0, a));
+ ret.reverse();
+ } else {
+ ret.push(buffer.text_);
+ }
+ for (var p in buffer) { delete buffer[p]; }
+ return ret;
+ },
+ 'output-o': function (buffer) {
+ /** @type {ParserOutput[]} */
+ var ret = [];
+ buffer.text_ = buffer.text_ || "";
+ if (buffer.text_.length > 4) {
+ var a = buffer.text_.length - 3;
+ for (var i=0; i<a; i+=3) {
+ ret.push(buffer.text_.substr(i, 3));
+ ret.push({ type_: '1000 separator' });
+ }
+ ret.push(buffer.text_.substr(i));
+ } else {
+ ret.push(buffer.text_);
+ }
+ for (var p in buffer) { delete buffer[p]; }
+ return ret;
+ }
+ }
+ }
+ //#endregion
+ };
+
+ //
+ // texify: Take MhchemParser output and convert it to TeX
+ //
+ /** @type {Texify} */
+ var texify = {
+ go: function (input, isInner) { // (recursive, max 4 levels)
+ if (!input) { return ""; }
+ var res = "";
+ var cee = false;
+ for (var i=0; i < input.length; i++) {
+ var inputi = input[i];
+ if (typeof inputi === "string") {
+ res += inputi;
+ } else {
+ res += texify._go2(inputi);
+ if (inputi.type_ === '1st-level escape') { cee = true; }
+ }
+ }
+ if (!isInner && !cee && res) {
+ res = "{" + res + "}";
+ }
+ return res;
+ },
+ _goInner: function (input) {
+ if (!input) { return input; }
+ return texify.go(input, true);
+ },
+ _go2: function (buf) {
+ /** @type {undefined | string} */
+ var res;
+ switch (buf.type_) {
+ case 'chemfive':
+ res = "";
+ var b5 = {
+ a: texify._goInner(buf.a),
+ b: texify._goInner(buf.b),
+ p: texify._goInner(buf.p),
+ o: texify._goInner(buf.o),
+ q: texify._goInner(buf.q),
+ d: texify._goInner(buf.d)
+ };
+ //
+ // a
+ //
+ if (b5.a) {
+ if (b5.a.match(/^[+\-]/)) { b5.a = "{"+b5.a+"}"; }
+ res += b5.a + "\\,";
+ }
+ //
+ // b and p
+ //
+ if (b5.b || b5.p) {
+ res += "{\\vphantom{X}}";
+ res += "^{\\hphantom{"+(b5.b||"")+"}}_{\\hphantom{"+(b5.p||"")+"}}";
+ res += "{\\vphantom{X}}";
+ res += "^{\\smash[t]{\\vphantom{2}}\\llap{"+(b5.b||"")+"}}";
+ res += "_{\\vphantom{2}\\llap{\\smash[t]{"+(b5.p||"")+"}}}";
+ }
+ //
+ // o
+ //
+ if (b5.o) {
+ if (b5.o.match(/^[+\-]/)) { b5.o = "{"+b5.o+"}"; }
+ res += b5.o;
+ }
+ //
+ // q and d
+ //
+ if (buf.dType === 'kv') {
+ if (b5.d || b5.q) {
+ res += "{\\vphantom{X}}";
+ }
+ if (b5.d) {
+ res += "^{"+b5.d+"}";
+ }
+ if (b5.q) {
+ res += "_{\\smash[t]{"+b5.q+"}}";
+ }
+ } else if (buf.dType === 'oxidation') {
+ if (b5.d) {
+ res += "{\\vphantom{X}}";
+ res += "^{"+b5.d+"}";
+ }
+ if (b5.q) {
+ res += "{\\vphantom{X}}";
+ res += "_{\\smash[t]{"+b5.q+"}}";
+ }
+ } else {
+ if (b5.q) {
+ res += "{\\vphantom{X}}";
+ res += "_{\\smash[t]{"+b5.q+"}}";
+ }
+ if (b5.d) {
+ res += "{\\vphantom{X}}";
+ res += "^{"+b5.d+"}";
+ }
+ }
+ break;
+ case 'rm':
+ res = "\\mathrm{"+buf.p1+"}";
+ break;
+ case 'text':
+ if (buf.p1.match(/[\^_]/)) {
+ buf.p1 = buf.p1.replace(" ", "~").replace("-", "\\text{-}");
+ res = "\\mathrm{"+buf.p1+"}";
+ } else {
+ res = "\\text{"+buf.p1+"}";
+ }
+ break;
+ case 'roman numeral':
+ res = "\\mathrm{"+buf.p1+"}";
+ break;
+ case 'state of aggregation':
+ res = "\\mskip2mu "+texify._goInner(buf.p1);
+ break;
+ case 'state of aggregation subscript':
+ res = "\\mskip1mu "+texify._goInner(buf.p1);
+ break;
+ case 'bond':
+ res = texify._getBond(buf.kind_);
+ if (!res) {
+ throw ["MhchemErrorBond", "mhchem Error. Unknown bond type (" + buf.kind_ + ")"];
+ }
+ break;
+ case 'frac':
+ var c = "\\frac{" + buf.p1 + "}{" + buf.p2 + "}";
+ res = "\\mathchoice{\\textstyle"+c+"}{"+c+"}{"+c+"}{"+c+"}";
+ break;
+ case 'pu-frac':
+ var d = "\\frac{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
+ res = "\\mathchoice{\\textstyle"+d+"}{"+d+"}{"+d+"}{"+d+"}";
+ break;
+ case 'tex-math':
+ res = buf.p1 + " ";
+ break;
+ case 'frac-ce':
+ res = "\\frac{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
+ break;
+ case 'overset':
+ res = "\\overset{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
+ break;
+ case 'underset':
+ res = "\\underset{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
+ break;
+ case 'underbrace':
+ res = "\\underbrace{" + texify._goInner(buf.p1) + "}_{" + texify._goInner(buf.p2) + "}";
+ break;
+ case 'color':
+ res = "{\\color{" + buf.color1 + "}{" + texify._goInner(buf.color2) + "}}";
+ break;
+ case 'color0':
+ res = "\\color{" + buf.color + "}";
+ break;
+ case 'arrow':
+ var b6 = {
+ rd: texify._goInner(buf.rd),
+ rq: texify._goInner(buf.rq)
+ };
+ var arrow = texify._getArrow(buf.r);
+ if (b6.rd || b6.rq) {
+ if (buf.r === "<=>" || buf.r === "<=>>" || buf.r === "<<=>" || buf.r === "<-->") {
+ // arrows that cannot stretch correctly yet, https://github.com/mathjax/MathJax/issues/1491
+ arrow = "\\long"+arrow;
+ if (b6.rd) { arrow = "\\overset{"+b6.rd+"}{"+arrow+"}"; }
+ if (b6.rq) {
+ if (buf.r === "<-->") {
+ arrow = "\\underset{\\lower2mu{"+b6.rq+"}}{"+arrow+"}";
+ } else {
+ arrow = "\\underset{\\lower6mu{"+b6.rq+"}}{"+arrow+"}"; // align with ->[][under]
+ }
+ }
+ arrow = " {}\\mathrel{"+arrow+"}{} ";
+ } else {
+ if (b6.rq) { arrow += "[{"+b6.rq+"}]"; }
+ arrow += "{"+b6.rd+"}";
+ arrow = " {}\\mathrel{\\x"+arrow+"}{} ";
+ }
+ } else {
+ arrow = " {}\\mathrel{\\long"+arrow+"}{} ";
+ }
+ res = arrow;
+ break;
+ case 'operator':
+ res = texify._getOperator(buf.kind_);
+ break;
+ case '1st-level escape':
+ res = buf.p1+" "; // &, \\\\, \\hlin
+ break;
+ case 'space':
+ res = " ";
+ break;
+ case 'entitySkip':
+ res = "~";
+ break;
+ case 'pu-space-1':
+ res = "~";
+ break;
+ case 'pu-space-2':
+ res = "\\mkern3mu ";
+ break;
+ case '1000 separator':
+ res = "\\mkern2mu ";
+ break;
+ case 'commaDecimal':
+ res = "{,}";
+ break;
+ case 'comma enumeration L':
+ res = "{"+buf.p1+"}\\mkern6mu ";
+ break;
+ case 'comma enumeration M':
+ res = "{"+buf.p1+"}\\mkern3mu ";
+ break;
+ case 'comma enumeration S':
+ res = "{"+buf.p1+"}\\mkern1mu ";
+ break;
+ case 'hyphen':
+ res = "\\text{-}";
+ break;
+ case 'addition compound':
+ res = "\\,{\\cdot}\\,";
+ break;
+ case 'electron dot':
+ res = "\\mkern1mu \\bullet\\mkern1mu ";
+ break;
+ case 'KV x':
+ res = "{\\times}";
+ break;
+ case 'prime':
+ res = "\\prime ";
+ break;
+ case 'cdot':
+ res = "\\cdot ";
+ break;
+ case 'tight cdot':
+ res = "\\mkern1mu{\\cdot}\\mkern1mu ";
+ break;
+ case 'times':
+ res = "\\times ";
+ break;
+ case 'circa':
+ res = "{\\sim}";
+ break;
+ case '^':
+ res = "uparrow";
+ break;
+ case 'v':
+ res = "downarrow";
+ break;
+ case 'ellipsis':
+ res = "\\ldots ";
+ break;
+ case '/':
+ res = "/";
+ break;
+ case ' / ':
+ res = "\\,/\\,";
+ break;
+ default:
+ assertNever(buf);
+ throw ["MhchemBugT", "mhchem bug T. Please report."]; // Missing texify rule or unknown MhchemParser output
+ }
+ assertString(res);
+ return res;
+ },
+ _getArrow: function (a) {
+ switch (a) {
+ case "->": return "rightarrow";
+ case "\u2192": return "rightarrow";
+ case "\u27F6": return "rightarrow";
+ case "<-": return "leftarrow";
+ case "<->": return "leftrightarrow";
+ case "<-->": return "leftrightarrows";
+ case "<=>": return "rightleftharpoons";
+ case "\u21CC": return "rightleftharpoons";
+ case "<=>>": return "Rightleftharpoons";
+ case "<<=>": return "Leftrightharpoons";
+ default:
+ assertNever(a);
+ throw ["MhchemBugT", "mhchem bug T. Please report."];
+ }
+ },
+ _getBond: function (a) {
+ switch (a) {
+ case "-": return "{-}";
+ case "1": return "{-}";
+ case "=": return "{=}";
+ case "2": return "{=}";
+ case "#": return "{\\equiv}";
+ case "3": return "{\\equiv}";
+ case "~": return "{\\tripledash}";
+ case "~-": return "{\\rlap{\\lower.1em{-}}\\raise.1em{\\tripledash}}";
+ case "~=": return "{\\rlap{\\lower.2em{-}}\\rlap{\\raise.2em{\\tripledash}}-}";
+ case "~--": return "{\\rlap{\\lower.2em{-}}\\rlap{\\raise.2em{\\tripledash}}-}";
+ case "-~-": return "{\\rlap{\\lower.2em{-}}\\rlap{\\raise.2em{-}}\\tripledash}";
+ case "...": return "{{\\cdot}{\\cdot}{\\cdot}}";
+ case "....": return "{{\\cdot}{\\cdot}{\\cdot}{\\cdot}}";
+ case "->": return "{\\rightarrow}";
+ case "<-": return "{\\leftarrow}";
+ case "<": return "{<}";
+ case ">": return "{>}";
+ default:
+ assertNever(a);
+ throw ["MhchemBugT", "mhchem bug T. Please report."];
+ }
+ },
+ _getOperator: function (a) {
+ switch (a) {
+ case "+": return " {}+{} ";
+ case "-": return " {}-{} ";
+ case "=": return " {}={} ";
+ case "<": return " {}<{} ";
+ case ">": return " {}>{} ";
+ case "<<": return " {}\\ll{} ";
+ case ">>": return " {}\\gg{} ";
+ case "\\pm": return " {}\\pm{} ";
+ case "\\approx": return " {}\\approx{} ";
+ case "$\\approx$": return " {}\\approx{} ";
+ case "v": return " \\downarrow{} ";
+ case "(v)": return " \\downarrow{} ";
+ case "^": return " \\uparrow{} ";
+ case "(^)": return " \\uparrow{} ";
+ default:
+ assertNever(a);
+ throw ["MhchemBugT", "mhchem bug T. Please report."];
+ }
+ }
+ };
+
+ //
+ // Helpers for code anaylsis
+ // Will show type error at calling position
+ //
+ /** @param {number} a */
+ function assertNever(a) {}
+ /** @param {string} a */
+ function assertString(a) {}
+
+ //
+ // MathJax definitions
+ //
+ MathJax.Extension["TeX/mhchem"].CE = CE;
+
+ /***************************************************************************/
+
+ TEX.Definitions.Add({
+ macros: {
+ //
+ // Set up the macros for chemistry
+ //
+ ce: "CE",
+ pu: "PU",
+
+ //
+ // Make these load AMSmath package (redefined below when loaded)
+ //
+ xleftrightarrow: ["Extension", "AMSmath"],
+ xrightleftharpoons: ["Extension", "AMSmath"],
+ xRightleftharpoons: ["Extension", "AMSmath"],
+ xLeftrightharpoons: ["Extension", "AMSmath"],
+
+ // FIXME: These don't work well in FF NativeMML mode
+ longrightleftharpoons: ["Macro", "\\stackrel{\\textstyle{-}\\!\\!{\\rightharpoonup}}{\\smash{{\\leftharpoondown}\\!\\!{-}}}"],
+ longRightleftharpoons: ["Macro", "\\stackrel{\\textstyle{-}\\!\\!{\\rightharpoonup}}{\\smash{\\leftharpoondown}}"],
+ longLeftrightharpoons: ["Macro", "\\stackrel{\\textstyle\\vphantom{{-}}{\\rightharpoonup}}{\\smash{{\\leftharpoondown}\\!\\!{-}}}"],
+ longleftrightarrows: ["Macro", "\\raise-3mu{\\stackrel{\\longrightarrow}{\\raise2mu{\\smash{\\longleftarrow}}}}"],
+
+ //
+ // Needed for \bond for the ~ forms
+ // Not perfectly aligned when zoomed in, but on 100%
+ //
+ tripledash: ["Macro", "\\vphantom{-}\\raise2mu{\\kern2mu\\tiny\\text{-}\\kern1mu\\text{-}\\kern1mu\\text{-}\\kern2mu}"]
+ }
+ }, null, true);
+
+ if (!MathJax.Extension["TeX/AMSmath"]) {
+ TEX.Definitions.Add({
+ macros: {
+ xrightarrow: ["Extension", "AMSmath"],
+ xleftarrow: ["Extension", "AMSmath"]
+ }
+ }, null, true);
+ }
+
+ //
+ // These arrows need to wait until AMSmath is loaded
+ //
+ MathJax.Hub.Register.StartupHook("TeX AMSmath Ready", function () {
+ TEX.Definitions.Add({
+ macros: {
+ //
+ // Some of these are hacks for now
+ //
+ xleftrightarrow: ["xArrow", 0x2194, 6, 6],
+ xrightleftharpoons: ["xArrow", 0x21CC, 5, 7], // FIXME: doesn't stretch in HTML-CSS output
+ xRightleftharpoons: ["xArrow", 0x21CC, 5, 7], // FIXME: how should this be handled?
+ xLeftrightharpoons: ["xArrow", 0x21CC, 5, 7]
+ }
+ }, null, true);
+ });
+
+ TEX.Parse.Augment({
+
+ //
+ // Implements \ce and friends
+ //
+ CE: function (name) {
+ var arg = this.GetArgument(name);
+ var tex = CE(arg).Parse();
+ this.string = tex + this.string.substr(this.i); this.i = 0;
+ },
+
+ PU: function (name) {
+ var arg = this.GetArgument(name);
+ var tex = CE(arg).Parse('pu');
+ this.string = tex + this.string.substr(this.i); this.i = 0;
+ }
+
+ });
+
+ //
+ // Indicate that the extension is ready
+ //
+ MathJax.Hub.Startup.signal.Post("TeX mhchem Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[mhchem]/mhchem.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/newcommand.js b/js/mathjax/extensions/TeX/newcommand.js
new file mode 100644
index 0000000..d106811
--- /dev/null
+++ b/js/mathjax/extensions/TeX/newcommand.js
@@ -0,0 +1,272 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/newcommand.js
+ *
+ * Implements the \newcommand, \newenvironment and \def
+ * macros, and is loaded automatically when needed.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2020 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.Extension["TeX/newcommand"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+
+ var TEX = MathJax.InputJax.TeX;
+ var TEXDEF = TEX.Definitions;
+
+ TEXDEF.Add({
+ macros: {
+ newcommand: 'NewCommand',
+ renewcommand: 'NewCommand',
+ newenvironment: 'NewEnvironment',
+ renewenvironment: 'NewEnvironment',
+ def: 'MacroDef',
+ 'let': 'Let'
+ }
+ },null,true);
+
+ TEX.Parse.Augment({
+
+ /*
+ * Implement \newcommand{\name}[n][default]{...}
+ */
+ NewCommand: function (name) {
+ var cs = this.trimSpaces(this.GetArgument(name)),
+ n = this.GetBrackets(name),
+ opt = this.GetBrackets(name),
+ def = this.GetArgument(name);
+ if (cs.charAt(0) === "\\") {cs = cs.substr(1)}
+ if (!cs.match(/^(.|[a-z]+)$/i)) {
+ TEX.Error(["IllegalControlSequenceName",
+ "Illegal control sequence name for %1",name]);
+ }
+ if (n) {
+ n = this.trimSpaces(n);
+ if (!n.match(/^[0-9]+$/)) {
+ TEX.Error(["IllegalParamNumber",
+ "Illegal number of parameters specified in %1",name]);
+ }
+ }
+ this.setDef(cs,['Macro',def,n,opt]);
+ },
+
+ /*
+ * Implement \newenvironment{name}[n][default]{begincmd}{endcmd}
+ */
+ NewEnvironment: function (name) {
+ var env = this.trimSpaces(this.GetArgument(name)),
+ n = this.GetBrackets(name),
+ opt = this.GetBrackets(name),
+ bdef = this.GetArgument(name),
+ edef = this.GetArgument(name);
+ if (n) {
+ n = this.trimSpaces(n);
+ if (!n.match(/^[0-9]+$/)) {
+ TEX.Error(["IllegalParamNumber",
+ "Illegal number of parameters specified in %1",name]);
+ }
+ }
+ this.setEnv(env,['BeginEnv',[null,'EndEnv'],bdef,edef,n,opt]);
+ },
+
+ /*
+ * Implement \def command
+ */
+ MacroDef: function (name) {
+ var cs = this.GetCSname(name),
+ params = this.GetTemplate(name,"\\"+cs),
+ def = this.GetArgument(name);
+ if (!(params instanceof Array)) {this.setDef(cs,['Macro',def,params])}
+ else {this.setDef(cs,['MacroWithTemplate',def].concat(params))}
+ },
+
+ /*
+ * Implements the \let command
+ */
+ Let: function (name) {
+ var cs = this.GetCSname(name), macro;
+ var c = this.GetNext(); if (c === "=") {this.i++; c = this.GetNext()}
+ //
+ // All \let commands create entries in the macros array, but we
+ // have to look in the various mathchar and delimiter arrays if
+ // the source isn't a macro already, and attach the data to a
+ // macro with the proper routine to process it.
+ //
+ // A command of the form \let\cs=char produces a macro equivalent
+ // to \def\cs{char}, which is as close as MathJax can get for this.
+ // So \let\bgroup={ is possible, but doesn't work as it does in TeX.
+ //
+ if (c === "\\") {
+ name = this.GetCSname(name);
+ macro = this.csFindMacro(name);
+ if (!macro) {
+ if (TEXDEF.mathchar0mi.hasOwnProperty(name)) {macro = ["csMathchar0mi",TEXDEF.mathchar0mi[name]]} else
+ if (TEXDEF.mathchar0mo.hasOwnProperty(name)) {macro = ["csMathchar0mo",TEXDEF.mathchar0mo[name]]} else
+ if (TEXDEF.mathchar7.hasOwnProperty(name)) {macro = ["csMathchar7",TEXDEF.mathchar7[name]]} else
+ if (TEXDEF.delimiter.hasOwnProperty("\\"+name)) {macro = ["csDelimiter",TEXDEF.delimiter["\\"+name]]} else
+ return;
+ }
+ } else {macro = ["Macro",c]; this.i++}
+ this.setDef(cs,macro);
+ },
+
+ /*
+ * Get a CS name or give an error
+ */
+ GetCSname: function (cmd) {
+ var c = this.GetNext();
+ if (c !== "\\") {
+ TEX.Error(["MissingCS",
+ "%1 must be followed by a control sequence", cmd])
+ }
+ var cs = this.trimSpaces(this.GetArgument(cmd));
+ return cs.substr(1);
+ },
+
+ /*
+ * Get a \def parameter template
+ */
+ GetTemplate: function (cmd,cs) {
+ var c, params = [], n = 0;
+ c = this.GetNext(); var i = this.i;
+ while (this.i < this.string.length) {
+ c = this.GetNext();
+ if (c === '#') {
+ if (i !== this.i) {params[n] = this.string.substr(i,this.i-i)}
+ c = this.string.charAt(++this.i);
+ if (!c.match(/^[1-9]$/)) {
+ TEX.Error(["CantUseHash2",
+ "Illegal use of # in template for %1",cs]);
+ }
+ if (parseInt(c) != ++n) {
+ TEX.Error(["SequentialParam",
+ "Parameters for %1 must be numbered sequentially",cs]);
+ }
+ i = this.i+1;
+ } else if (c === '{') {
+ if (i !== this.i) {params[n] = this.string.substr(i,this.i-i)}
+ if (params.length > 0) {return [n,params]} else {return n}
+ }
+ this.i++;
+ }
+ TEX.Error(["MissingReplacementString",
+ "Missing replacement string for definition of %1",cmd]);
+ },
+
+ /*
+ * Process a macro with a parameter template
+ */
+ MacroWithTemplate: function (name,text,n,params) {
+ if (n) {
+ var args = []; this.GetNext();
+ if (params[0] && !this.MatchParam(params[0])) {
+ TEX.Error(["MismatchUseDef",
+ "Use of %1 doesn't match its definition",name]);
+ }
+ for (var i = 0; i < n; i++) {args.push(this.GetParameter(name,params[i+1]))}
+ text = this.SubstituteArgs(args,text);
+ }
+ this.string = this.AddArgs(text,this.string.slice(this.i));
+ this.i = 0;
+ if (++this.macroCount > TEX.config.MAXMACROS) {
+ TEX.Error(["MaxMacroSub1",
+ "MathJax maximum macro substitution count exceeded; " +
+ "is there a recursive macro call?"]);
+ }
+ },
+
+ /*
+ * Process a user-defined environment
+ */
+ BeginEnv: function (begin,bdef,edef,n,def) {
+ if (n) {
+ var args = [];
+ if (def != null) {
+ var optional = this.GetBrackets("\\begin{"+name+"}");
+ args.push(optional == null ? def : optional);
+ }
+ for (var i = args.length; i < n; i++) {args.push(this.GetArgument("\\begin{"+name+"}"))}
+ bdef = this.SubstituteArgs(args,bdef);
+ edef = this.SubstituteArgs([],edef); // no args, but get errors for #n in edef
+ }
+ this.string = this.AddArgs(bdef,this.string.slice(this.i)); this.i = 0;
+ return begin;
+ },
+ EndEnv: function (begin,bdef,edef,n) {
+ var end = "\\end{\\end\\"+begin.name+"}"; // special version of \end for after edef
+ this.string = this.AddArgs(edef,end+this.string.slice(this.i)); this.i = 0;
+ return null;
+ },
+
+ /*
+ * Find a single parameter delimited by a trailing template
+ */
+ GetParameter: function (name,param) {
+ if (param == null) {return this.GetArgument(name)}
+ var i = this.i, j = 0, hasBraces = 0;
+ while (this.i < this.string.length) {
+ var c = this.string.charAt(this.i);
+ if (c === '{') {
+ if (this.i === i) {hasBraces = 1}
+ this.GetArgument(name); j = this.i - i;
+ } else if (this.MatchParam(param)) {
+ if (hasBraces) {i++; j -= 2}
+ return this.string.substr(i,j);
+ } else if (c === "\\") {
+ this.i++; j++; hasBraces = 0;
+ var match = this.string.substr(this.i).match(/[a-z]+|./i);
+ if (match) {this.i += match[0].length; j = this.i - i}
+ } else {
+ this.i++; j++; hasBraces = 0;
+ }
+ }
+ TEX.Error(["RunawayArgument","Runaway argument for %1?",name]);
+ },
+
+ /*
+ * Check if a template is at the current location.
+ * (The match must be exact, with no spacing differences. TeX is
+ * a little more forgiving than this about spaces after macro names)
+ */
+ MatchParam: function (param) {
+ if (this.string.substr(this.i,param.length) !== param) {return 0}
+ if (param.match(/\\[a-z]+$/i) &&
+ this.string.charAt(this.i+param.length).match(/[a-z]/i)) {return 0}
+ this.i += param.length;
+ return 1;
+ }
+
+ });
+
+ TEX.Environment = function (name) {
+ TEXDEF.environment[name] = ['BeginEnv',[null,'EndEnv']].concat([].slice.call(arguments,1));
+ TEXDEF.environment[name].isUser = true;
+ }
+
+ MathJax.Hub.Startup.signal.Post("TeX newcommand Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/newcommand.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/noErrors.js b/js/mathjax/extensions/TeX/noErrors.js
new file mode 100644
index 0000000..ae3f7f0
--- /dev/null
+++ b/js/mathjax/extensions/TeX/noErrors.js
@@ -0,0 +1,407 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/noErrors.js
+ *
+ * Prevents the TeX error messages from being displayed and shows the
+ * original TeX code instead. You can configure whether the dollar signs
+ * are shown or not for in-line math, and whether to put all the TeX on
+ * one line or use multiple-lines.
+ *
+ * To configure this extension, use
+ *
+ * MathJax.Hub.Config({
+ * TeX: {
+ * noErrors: {
+ * inlineDelimiters: ["",""], // or ["$","$"] or ["\\(","\\)"]
+ * multiLine: true, // false for TeX on all one line
+ * style: {
+ * "font-size": "90%",
+ * "text-align": "left",
+ * "color": "black",
+ * "padding": "1px 3px",
+ * "border": "1px solid"
+ * // add any additional CSS styles that you want
+ * // (be sure there is no extra comma at the end of the last item)
+ * }
+ * }
+ * }
+ * });
+ *
+ * Display-style math is always shown in multi-line format, and without
+ * delimiters, as it will already be set off in its own centered
+ * paragraph, like standard display mathematics.
+ *
+ * The default settings place the invalid TeX in a multi-line box with a
+ * black border. If you want it to look as though the TeX is just part of
+ * the paragraph, use
+ *
+ * MathJax.Hub.Config({
+ * TeX: {
+ * noErrors: {
+ * inlineDelimiters: ["$","$"], // or ["",""] or ["\\(","\\)"]
+ * multiLine: false,
+ * style: {
+ * "font-size": "normal",
+ * "border": ""
+ * }
+ * }
+ * }
+ * });
+ *
+ * You may also wish to set the font family, as the default is "serif"
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2020 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.
+ */
+
+(function (HUB,HTML) {
+ var VERSION = "2.7.9";
+
+ var CONFIG = HUB.CombineConfig("TeX.noErrors",{
+ disabled: false, // set to true to return to original error messages
+ multiLine: true,
+ inlineDelimiters: ["",""], // or use ["$","$"] or ["\\(","\\)"]
+ style: {
+ "font-size": "90%",
+ "text-align": "left",
+ "color": "black",
+ "padding": "1px 3px",
+ "border": "1px solid"
+ }
+ });
+
+ var NBSP = "\u00A0";
+
+ //
+ // The configuration defaults, augmented by the user settings
+ //
+ MathJax.Extension["TeX/noErrors"] = {
+ version: VERSION,
+ config: CONFIG
+ };
+
+ HUB.Register.StartupHook("TeX Jax Ready",function () {
+ var FORMAT = MathJax.InputJax.TeX.formatError;
+
+ MathJax.InputJax.TeX.Augment({
+ //
+ // Make error messages be the original TeX code
+ // Mark them as errors and multi-line or not, and for
+ // multi-line TeX, make spaces non-breakable (to get formatting right)
+ //
+ formatError: function (err,math,displaystyle,script) {
+ if (CONFIG.disabled) {return FORMAT.apply(this,arguments)}
+ var message = err.message.replace(/\n.*/,"");
+ HUB.signal.Post(["TeX Jax - parse error",message,math,displaystyle,script]);
+ var delim = CONFIG.inlineDelimiters;
+ var multiLine = (displaystyle || CONFIG.multiLine);
+ if (!displaystyle) {math = delim[0] + math + delim[1]}
+ if (multiLine) {math = math.replace(/ /g,NBSP)} else {math = math.replace(/\n/g," ")}
+ return MathJax.ElementJax.mml.merror(math).With({isError:true, multiLine: multiLine});
+ }
+ });
+ });
+
+ /*******************************************************************
+ *
+ * Fix HTML-CSS output
+ */
+
+ HUB.Register.StartupHook("HTML-CSS Jax Config",function () {
+ HUB.Config({
+ "HTML-CSS": {
+ styles: {
+ ".MathJax .noError": HUB.Insert({
+ "vertical-align": (HUB.Browser.isMSIE && CONFIG.multiLine ? "-2px" : "")
+ },CONFIG.style)
+ }
+ }
+ });
+ });
+
+ HUB.Register.StartupHook("HTML-CSS Jax Ready",function () {
+ var MML = MathJax.ElementJax.mml;
+ var HTMLCSS = MathJax.OutputJax["HTML-CSS"];
+
+ var MATH = MML.math.prototype.toHTML,
+ MERROR = MML.merror.prototype.toHTML;
+
+ //
+ // Override math toHTML routine so that error messages
+ // don't have the clipping and other unneeded overhead
+ //
+ MML.math.Augment({
+ toHTML: function (span,node) {
+ var data = this.data[0];
+ if (data && data.data[0] && data.data[0].isError) {
+ span.style.fontSize = "";
+ span = this.HTMLcreateSpan(span);
+ span.bbox = data.data[0].toHTML(span).bbox;
+ } else {
+ span = MATH.apply(this,arguments);
+ }
+ return span;
+ }
+ });
+
+ //
+ // Override merror toHTML routine so that it puts out the
+ // TeX code in an inline-block with line breaks as in the original
+ //
+ MML.merror.Augment({
+ toHTML: function (span) {
+ if (!this.isError) {return MERROR.apply(this,arguments)}
+ span = this.HTMLcreateSpan(span); span.className = "noError"
+ if (this.multiLine) {span.style.display = "inline-block"}
+ var text = this.data[0].data[0].data.join("").split(/\n/);
+ for (var i = 0, m = text.length; i < m; i++) {
+ HTMLCSS.addText(span,text[i]);
+ if (i !== m-1) {HTMLCSS.addElement(span,"br",{isMathJax:true})}
+ }
+ var HD = HTMLCSS.getHD(span.parentNode), W = HTMLCSS.getW(span.parentNode);
+ if (m > 1) {
+ var H = (HD.h + HD.d)/2, x = HTMLCSS.TeX.x_height/2;
+ span.parentNode.style.verticalAlign = HTMLCSS.Em(HD.d+(x-H));
+ HD.h = x + H; HD.d = H - x;
+ }
+ span.bbox = {h: HD.h, d: HD.d, w: W, lw: 0, rw: W};
+ return span;
+ }
+ });
+
+ });
+
+ /*******************************************************************
+ *
+ * Fix SVG output
+ */
+
+ HUB.Register.StartupHook("SVG Jax Config",function () {
+ HUB.Config({
+ "SVG": {
+ styles: {
+ ".MathJax_SVG .noError": HUB.Insert({
+ "vertical-align": (HUB.Browser.isMSIE && CONFIG.multiLine ? "-2px" : "")
+ },CONFIG.style)
+ }
+ }
+ });
+ });
+
+ HUB.Register.StartupHook("SVG Jax Ready",function () {
+ var MML = MathJax.ElementJax.mml;
+
+ var MATH = MML.math.prototype.toSVG,
+ MERROR = MML.merror.prototype.toSVG;
+
+ //
+ // Override math toSVG routine so that error messages
+ // don't have the clipping and other unneeded overhead
+ //
+ MML.math.Augment({
+ toSVG: function (span,node) {
+ var data = this.data[0];
+ if (data && data.data[0] && data.data[0].isError)
+ {span = data.data[0].toSVG(span)} else {span = MATH.apply(this,arguments)}
+ return span;
+ }
+ });
+
+ //
+ // Override merror toSVG routine so that it puts out the
+ // TeX code in an inline-block with line breaks as in the original
+ //
+ MML.merror.Augment({
+ toSVG: function (span) {
+ if (!this.isError || this.Parent().type !== "math") {return MERROR.apply(this,arguments)}
+ span = HTML.addElement(span,"span",{className: "noError", isMathJax:true});
+ if (this.multiLine) {span.style.display = "inline-block"}
+ var text = this.data[0].data[0].data.join("").split(/\n/);
+ for (var i = 0, m = text.length; i < m; i++) {
+ HTML.addText(span,text[i]);
+ if (i !== m-1) {HTML.addElement(span,"br",{isMathJax:true})}
+ }
+ if (m > 1) {
+ var H = span.offsetHeight/2;
+ span.style.verticalAlign = (-H+(H/m))+"px";
+ }
+ return span;
+ }
+ });
+
+ });
+
+ /*******************************************************************
+ *
+ * Fix NativeMML output
+ */
+
+ HUB.Register.StartupHook("NativeMML Jax Ready",function () {
+ var MML = MathJax.ElementJax.mml;
+ var CONFIG = MathJax.Extension["TeX/noErrors"].config;
+
+ var MATH = MML.math.prototype.toNativeMML,
+ MERROR = MML.merror.prototype.toNativeMML;
+
+ //
+ // Override math toNativeMML routine so that error messages
+ // don't get placed inside math tags.
+ //
+ MML.math.Augment({
+ toNativeMML: function (span) {
+ var data = this.data[0];
+ if (data && data.data[0] && data.data[0].isError)
+ {span = data.data[0].toNativeMML(span)} else {span = MATH.apply(this,arguments)}
+ return span;
+ }
+ });
+
+ //
+ // Override merror toNativeMML routine so that it puts out the
+ // TeX code in an inline-block with line breaks as in the original
+ //
+ MML.merror.Augment({
+ toNativeMML: function (span) {
+ if (!this.isError) {return MERROR.apply(this,arguments)}
+ span = span.appendChild(document.createElement("span"));
+ var text = this.data[0].data[0].data.join("").split(/\n/);
+ for (var i = 0, m = text.length; i < m; i++) {
+ span.appendChild(document.createTextNode(text[i]));
+ if (i !== m-1) {span.appendChild(document.createElement("br"))}
+ }
+ if (this.multiLine) {
+ span.style.display = "inline-block";
+ if (m > 1) {span.style.verticalAlign = "middle"}
+ }
+ for (var id in CONFIG.style) {if (CONFIG.style.hasOwnProperty(id)) {
+ var ID = id.replace(/-./g,function (c) {return c.charAt(1).toUpperCase()});
+ span.style[ID] = CONFIG.style[id];
+ }}
+ return span;
+ }
+ });
+
+ });
+
+ /*******************************************************************
+ *
+ * Fix PreviewHTML output
+ */
+
+ HUB.Register.StartupHook("PreviewHTML Jax Config",function () {
+ HUB.Config({
+ PreviewHTML: {
+ styles: {
+ ".MathJax_PHTML .noError": HUB.Insert({
+ "vertical-align": (HUB.Browser.isMSIE && CONFIG.multiLine ? "-2px" : "")
+ },CONFIG.style)
+ }
+ }
+ });
+ });
+
+ HUB.Register.StartupHook("PreviewHTML Jax Ready",function () {
+ var MML = MathJax.ElementJax.mml;
+ var HTML = MathJax.HTML;
+
+ var MERROR = MML.merror.prototype.toPreviewHTML;
+
+ //
+ // Override merror toPreviewHTML routine so that it puts out the
+ // TeX code in an inline-block with line breaks as in the original
+ //
+ MML.merror.Augment({
+ toPreviewHTML: function (span) {
+ if (!this.isError) return MERROR.apply(this,arguments);
+ span = this.PHTMLcreateSpan(span); span.className = "noError"
+ if (this.multiLine) span.style.display = "inline-block";
+ var text = this.data[0].data[0].data.join("").split(/\n/);
+ for (var i = 0, m = text.length; i < m; i++) {
+ HTML.addText(span,text[i]);
+ if (i !== m-1) {HTML.addElement(span,"br",{isMathJax:true})}
+ }
+ return span;
+ }
+ });
+
+ });
+
+ /*******************************************************************
+ *
+ * Fix CommonHTML output
+ */
+
+ HUB.Register.StartupHook("CommonHTML Jax Config",function () {
+ HUB.Config({
+ CommonHTML: {
+ styles: {
+ ".mjx-chtml .mjx-noError": HUB.Insert({
+ "line-height": 1.2,
+ "vertical-align": (HUB.Browser.isMSIE && CONFIG.multiLine ? "-2px" : "")
+ },CONFIG.style)
+ }
+ }
+ });
+ });
+
+ HUB.Register.StartupHook("CommonHTML Jax Ready",function () {
+ var MML = MathJax.ElementJax.mml;
+ var CHTML = MathJax.OutputJax.CommonHTML;
+ var HTML = MathJax.HTML;
+
+ var MERROR = MML.merror.prototype.toCommonHTML;
+
+ //
+ // Override merror toCommonHTML routine so that it puts out the
+ // TeX code in an inline-block with line breaks as in the original
+ //
+ MML.merror.Augment({
+ toCommonHTML: function (node) {
+ if (!this.isError) return MERROR.apply(this,arguments);
+ node = CHTML.addElement(node,"mjx-noError");
+ var text = this.data[0].data[0].data.join("").split(/\n/);
+ for (var i = 0, m = text.length; i < m; i++) {
+ HTML.addText(node,text[i]);
+ if (i !== m-1) {CHTML.addElement(node,"br",{isMathJax:true})}
+ }
+ var bbox = this.CHTML = CHTML.BBOX.zero();
+ bbox.w = (node.offsetWidth)/CHTML.em;
+ if (m > 1) {
+ var H2 = 1.2*m/2;
+ bbox.h = H2+.25; bbox.d = H2-.25;
+ node.style.verticalAlign = CHTML.Em(.45-H2);
+ } else {
+ bbox.h = 1; bbox.d = .2 + 2/CHTML.em;
+ }
+ return node;
+ }
+ });
+
+ });
+
+ /*******************************************************************/
+
+ HUB.Startup.signal.Post("TeX noErrors Ready");
+
+})(MathJax.Hub,MathJax.HTML);
+
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/noErrors.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/noUndefined.js b/js/mathjax/extensions/TeX/noUndefined.js
new file mode 100644
index 0000000..463a446
--- /dev/null
+++ b/js/mathjax/extensions/TeX/noUndefined.js
@@ -0,0 +1,74 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/noUndefined.js
+ *
+ * This causes undefined control sequences to be shown as their macro
+ * names rather than producing an error message. So $X_{\xxx}$ would
+ * display as an X with a subscript consiting of the text "\xxx".
+ *
+ * To configure this extension, use for example
+ *
+ * MathJax.Hub.Config({
+ * TeX: {
+ * noUndefined: {
+ * attributes: {
+ * mathcolor: "red",
+ * mathbackground: "#FFEEEE",
+ * mathsize: "90%"
+ * }
+ * }
+ * }
+ * });
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2010-2020 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.
+ */
+
+//
+// The configuration defaults, augmented by the user settings
+//
+MathJax.Extension["TeX/noUndefined"] = {
+ version: "2.7.9",
+ config: MathJax.Hub.CombineConfig("TeX.noUndefined",{
+ disabled: false, // set to true to return to original error messages
+ attributes: {
+ mathcolor: "red"
+ }
+ })
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+ var CONFIG = MathJax.Extension["TeX/noUndefined"].config;
+ var MML = MathJax.ElementJax.mml;
+ var UNDEFINED = MathJax.InputJax.TeX.Parse.prototype.csUndefined;
+
+ MathJax.InputJax.TeX.Parse.Augment({
+ csUndefined: function (name) {
+ if (CONFIG.disabled) {return UNDEFINED.apply(this,arguments)}
+ MathJax.Hub.signal.Post(["TeX Jax - undefined control sequence",name]);
+ this.Push(MML.mtext(name).With(CONFIG.attributes));
+ }
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX noUndefined Ready");
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/noUndefined.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/text-macros.js b/js/mathjax/extensions/TeX/text-macros.js
new file mode 100644
index 0000000..447a853
--- /dev/null
+++ b/js/mathjax/extensions/TeX/text-macros.js
@@ -0,0 +1,489 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/text-macros.js
+ *
+ * Implements the processing of some text-mode macros inside
+ * \text{} and other text boxes.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2018-2020 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.Extension["TeX/text-macros"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () {
+ var MML = MathJax.ElementJax.mml;
+ var TEX = MathJax.InputJax.TeX;
+ var TEXDEF = TEX.Definitions;
+
+ TEX.Parse.Augment({
+ //
+ // Replace InternalMath with parser that handles some text macros
+ //
+ InternalMath: function(text,level) {
+ var mml = TextParser(text, {}).Parse();
+ if (level != null) {
+ mml = [MML.mstyle.apply(MML,mml).With({displaystyle:false, scriptlevel:level})];
+ } else if (mml.length > 1) {
+ mml = [MML.mrow.apply(MML,mml)];
+ }
+ return mml;
+ },
+
+ //
+ // Correctly skip newline as well as comment
+ //
+ Comment: function (c) {
+ while (this.i < this.string.length && this.string.charAt(this.i) != "\n") {this.i++}
+ this.i++;
+ },
+
+ //
+ // Correctly skip trailing space as well
+ //
+ GetCS: function () {
+ var CS = this.string.slice(this.i).match(/^([a-z]+|.) ?/i);
+ if (CS) {this.i += CS[0].length; return CS[1]} else {this.i++; return " "}
+ }
+
+ });
+
+ //
+ // The text parser is a subclass of the math parser, so we can use
+ // some of the existing methods (like GetArgument()), and some of the
+ // control sequence implementations (like Macro, Spacer, etc.)
+ //
+ var TextParser = TEX.TextParser = TEX.Parse.Subclass({
+
+ Init: function (text, env) {
+ this.env = MathJax.Hub.Insert({},env);
+ this.stack = {env: this.env};
+ this.string = text;
+ this.i = 0;
+ this.mml = []; // the accumulated MathML elements
+ this.text = ''; // the accumulated text so far
+ },
+
+ //
+ // These are the special characters in text mode
+ //
+ textSpecial: {
+ '\\': 'ControlSequence',
+ '$': 'Math',
+ '%': 'Comment',
+ '^': 'MathModeOnly',
+ '_': 'MathModeOnly',
+ '&': 'Misplaced',
+ '#': 'Misplaced',
+ '~': 'Tilde',
+ ' ': 'Space',
+ '\t': 'Space',
+ '\r': 'Space',
+ '\n': 'Space',
+ '\u00A0': 'Tilde',
+ '{': 'OpenBrace',
+ '}': 'CloseBrace',
+ '`': 'OpenQuote',
+ "'": 'CloseQuote'
+ },
+
+ //
+ // These are text-mode macros we support
+ //
+ textMacros: {
+ '(': 'Math',
+
+ '$': 'SelfQuote',
+ '_': 'SelfQuote',
+ '%': 'SelfQuote',
+ '{': 'SelfQuote',
+ '}': 'SelfQuote',
+ ' ': 'SelfQuote',
+ '&': 'SelfQuote',
+ '#': 'SelfQuote',
+ '\\': 'SelfQuote',
+
+ "'": ['Accent', '\u00B4'],
+ '`': ['Accent', '\u0060'],
+ '^': ['Accent', '^'],
+ '"': ['Accent', '\u00A8'],
+ '~': ['Accent', '~'],
+ '=': ['Accent', '\u00AF'],
+ '.': ['Accent', '\u02D9'],
+ 'u': ['Accent', '\u02D8'],
+ 'v': ['Accent', '\u02C7'],
+
+ emph: 'Emph',
+ rm: ['SetFont',MML.VARIANT.NORMAL],
+ mit: ['SetFont',MML.VARIANT.ITALIC],
+ oldstyle: ['SetFont',MML.VARIANT.OLDSTYLE],
+ cal: ['SetFont',MML.VARIANT.CALIGRAPHIC],
+ it: ['SetFont','-tex-mathit'], // needs special handling
+ bf: ['SetFont',MML.VARIANT.BOLD],
+ bbFont: ['SetFont',MML.VARIANT.DOUBLESTRUCK],
+ scr: ['SetFont',MML.VARIANT.SCRIPT],
+ frak: ['SetFont',MML.VARIANT.FRAKTUR],
+ sf: ['SetFont',MML.VARIANT.SANSSERIF],
+ tt: ['SetFont',MML.VARIANT.MONOSPACE],
+
+ tiny: ['SetSize',0.5],
+ Tiny: ['SetSize',0.6], // non-standard
+ scriptsize: ['SetSize',0.7],
+ small: ['SetSize',0.85],
+ normalsize: ['SetSize',1.0],
+ large: ['SetSize',1.2],
+ Large: ['SetSize',1.44],
+ LARGE: ['SetSize',1.73],
+ huge: ['SetSize',2.07],
+ Huge: ['SetSize',2.49],
+
+ mathcal: 'MathModeOnly',
+ mathscr: 'MathModeOnly',
+ mathrm: 'MathModeOnly',
+ mathbf: 'MathModeOnly',
+ mathbb: 'MathModeOnly',
+ mathit: 'MathModeOnly',
+ mathfrak: 'MathModeOnly',
+ mathsf: 'MathModeOnly',
+ mathtt: 'MathModeOnly',
+ Bbb: ['Macro','{\\bbFont #1}',1],
+ textrm: ['Macro','{\\rm #1}',1],
+ textit: ['Macro','{\\it #1}',1],
+ textbf: ['Macro','{\\bf #1}',1],
+ textsf: ['Macro','{\\sf #1}',1],
+ texttt: ['Macro','{\\tt #1}',1],
+
+ dagger: ['Insert', '\u2020'],
+ ddagger: ['Insert', '\u2021'],
+ S: ['Insert', '\u00A7']
+ },
+
+ //
+ // These are the original macros that are allowed in text mode
+ //
+ useMathMacros: {
+ ',': true,
+ ':': true,
+ '>': true,
+ ';': true,
+ '!': true,
+ enspace: true,
+ quad: true,
+ qquad: true,
+ thinspace: true,
+ negthinspace: true,
+
+ hskip: true,
+ hspace: true,
+ kern: true,
+ mskip: true,
+ mspace: true,
+ mkern: true,
+ rule: true,
+ Rule: true,
+ Space: true,
+
+ color: true,
+ href: true,
+ unicode: true,
+
+ ref: true,
+ eqref: true
+ },
+
+ //
+ // Look through the text for special characters and process them.
+ // Save any accumulated text aat the end and return the MathML
+ // elements produced.
+ //
+ Parse: function () {
+ var c;
+ while ((c = this.string.charAt(this.i++))) {
+ if (this.textSpecial.hasOwnProperty(c)) {
+ this[this.textSpecial[c]](c);
+ } else {
+ this.text += c;
+ }
+ }
+ this.SaveText();
+ return this.mml;
+ },
+
+ //
+ // Handle a control sequence name
+ // If it is a text-mode macro, use it.
+ // Otherwise look for it in the math-mode lists
+ // Report an error if it is not there
+ // Otherwise check if it is a macro or one of the allowed control sequences
+ // Run the macro (with arguments if given)
+ //
+ ControlSequence: function (c) {
+ var cs = this.GetCS(), name = c + cs, cmd;
+ if (this.textMacros.hasOwnProperty(cs)) {
+ cmd = this.textMacros[cs];
+ } else {
+ cmd = this.LookupCS(cs);
+ if (!cmd) {
+ this.Error(["UndefinedControlSequence","Undefined control sequence %1",name]);
+ }
+ if ((!(cmd instanceof Array) || cmd[0] !== 'Macro') &&
+ !this.useMathMacros.hasOwnProperty(cs)) {
+ this.Error(["MathMacro","'%1' is only supported in math mode",name]);
+ }
+ }
+ if (cmd instanceof Array) {
+ if (!this.hasOwnProperty[cmd[0]]) this.SaveText();
+ this[cmd[0]].apply(this,[name].concat(cmd.slice(1)));
+ } else {
+ if (!this.hasOwnProperty[cmd]) this.SaveText();
+ this[cmd].call(this,name);
+ }
+ },
+
+ //
+ // Lookup the CS as a math-mode macro
+ //
+ LookupCS: function(cs) {
+ if (TEXDEF.macros.hasOwnProperty(cs)) return TEXDEF.macros[cs];
+ if (TEXDEF.mathchar0mi.hasOwnProperty(cs)) return TEXDEF.mathchar0mi[cs];
+ if (TEXDEF.mathchar0mo.hasOwnProperty(cs)) return TEXDEF.mathchar0mo[cs];
+ if (TEXDEF.mathchar7.hasOwnProperty(cs)) return TEXDEF.mathchar7[cs];
+ if (TEXDEF.delimiter.hasOwnProperty('\\'+cs)) return TEXDEF.delimiter['\\'+cs];
+ return null;
+ },
+
+ //
+ // Handle internal math mode
+ // Look for the close delimiter and process the contents
+ //
+ Math: function (open) {
+ this.SaveText();
+ var i = this.i, j;
+ var braces = 0, c;
+ while ((c = this.GetNext())) {
+ j = this.i++;
+ switch(c) {
+ case '\\':
+ var cs = this.GetCS();
+ if (cs === ')') c = '\\(';
+ case '$':
+ if (braces === 0 && open === c) {
+ this.Push(TEX.Parse(this.string.substr(i, j-i),this.env).mml());
+ return;
+ }
+ break;
+
+ case '{':
+ braces++;
+ break;
+
+ case '}':
+ if (braces == 0) {
+ this.Error(["ExtraCloseMissingOpen","Extra close brace or missing open brace"]);
+ }
+ braces--;
+ break;
+ }
+ }
+ this.Error(["MathNotTerminated","Math not terminated in text box"]);
+ },
+
+ //
+ // Character can only be used in math mode
+ //
+ MathModeOnly: function (c) {
+ this.Error(["MathModeOnly","'%1' allowed only in math mode",c]);
+ },
+
+ //
+ // Character is being used out of place
+ //
+ Misplaced: function (c) {
+ this.Error(["Misplaced","'%1' can not be used here",c]);
+ },
+
+ //
+ // Braces start new environments
+ //
+ OpenBrace: function (c) {
+ var env = this.env;
+ this.env = MathJax.Hub.Insert({}, env);
+ this.env.oldEnv = env;
+ },
+ CloseBrace: function (c) {
+ if (this.env.oldEnv) {
+ this.SaveText();
+ this.env = this.env.oldEnv;
+ } else {
+ this.Error(["ExtraCloseMissingOpen","Extra close brace or missing open brace"]);
+ }
+ },
+
+ //
+ // Handle open and close quotes
+ //
+ OpenQuote: function (c) {
+ if (this.string.charAt(this.i) === c) {
+ this.text += "\u201C";
+ this.i++;
+ } else {
+ this.text += "\u2018"
+ }
+ },
+ CloseQuote: function (c) {
+ if (this.string.charAt(this.i) === c) {
+ this.text += "\u201D";
+ this.i++;
+ } else {
+ this.text += "\u2019"
+ }
+ },
+
+ //
+ // Handle non-breaking and regular spaces
+ //
+ Tilde: function (c) {
+ this.text += '\u00A0';
+ },
+ Space: function (c) {
+ this.text += ' ';
+ while (this.GetNext().match(/\s/)) this.i++;
+ },
+
+ //
+ // Insert the escaped characer
+ //
+ SelfQuote: function (name) {
+ this.text += name.substr(1);
+ },
+
+ //
+ // Insert a given character
+ //
+ Insert: function (name, c) {
+ this.text += c;
+ },
+
+ //
+ // Create an accented character using mover
+ //
+ Accent: function (name, c) {
+ this.SaveText();
+ var base = this.ParseArg(name);
+ var accent = MML.mo(MML.chars(c));
+ if (this.env.mathvariant) accent.mathvariant = this.env.mathvariant;
+ this.Push(MML.mover(base,accent));
+ },
+
+ //
+ // Switch to/from italics
+ //
+ Emph: function (name) {
+ this.UseFont(name, this.env.mathvariant === '-tex-mathit' ? 'normal' : '-tex-mathit');
+ },
+
+ //
+ // Use a given font on its argument
+ //
+ UseFont: function (name, variant) {
+ this.SaveText();
+ this.Push(this.ParseTextArg(name,{mathvariant: variant}));
+ },
+
+ //
+ // Set a font for the rest of the text
+ //
+ SetFont: function (name, variant) {
+ this.SaveText();
+ this.env.mathvariant = variant;
+ },
+
+ //
+ // Set the size to use
+ //
+ SetSize: function (name, size) {
+ this.SaveText();
+ this.env.mathsize = size;
+ },
+
+ //
+ // Process the argument as text with the given environment settings
+ //
+ ParseTextArg: function (name, env) {
+ var text = this.GetArgument(name);
+ env = MathJax.Hub.Insert(MathJax.Hub.Insert({}, this.env), env);
+ delete env.oldEnv;
+ return TextParser(text, env).Parse();
+ },
+
+ //
+ // Process an argument as text (overrides the math-mode version)
+ //
+ ParseArg: function (name) {
+ var mml = TextParser(this.GetArgument(name), this.env).Parse();
+ if (mml.length === 0) return mml[0];
+ return MML.mrow.apply(MML.mrow, mml);
+ },
+
+ //
+ // Create an mtext element with the accumulated text, if any
+ // and set it variant
+ //
+ SaveText: function () {
+ if (this.text) {
+ var text = MML.mtext(MML.chars(this.text));
+ if (this.env.mathvariant) text.mathvariant = this.env.mathvariant;
+ this.Push(text);
+ }
+ this.text = "";
+ },
+
+ //
+ // Save a MathML element or array, setting its size and color, if any
+ //
+ Push: function (mml) {
+ if (mml instanceof Array) {
+ if (this.env.mathsize || this.env.mathcolor) {
+ mml = MML.mstyle.apply(MML,mml);
+ if (this.env.mathsize) mml.mathsize = this.env.mathsize;
+ if (this.env.mathcolor) mml.mathcolor = this.env.mathcolor;
+ }
+ this.mml.push.apply(this.mml,mml);
+ } else {
+ if (this.env.mathsize && !mml.mathsize) mml.mathsize = this.env.mathsize;
+ if (this.env.mathcolor && !mml.mathcolor) mml.mathcolor = this.env.mathcolor;
+ this.mml.push(mml);
+ }
+ },
+
+ //
+ // Throw an error
+ //
+ Error: function (message) {
+ TEX.Error(message);
+ }
+
+ });
+
+ MathJax.Hub.Startup.signal.Post('TeX text-macros Ready');
+
+});
+
+MathJax.Ajax.loadComplete('[MathJax]/extensions/TeX/text-macros.js');
+// @license-end
diff --git a/js/mathjax/extensions/TeX/unicode.js b/js/mathjax/extensions/TeX/unicode.js
new file mode 100644
index 0000000..0c3e50a
--- /dev/null
+++ b/js/mathjax/extensions/TeX/unicode.js
@@ -0,0 +1,172 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/unicode.js
+ *
+ * Implements the \unicode extension to TeX to allow arbitrary unicode
+ * code points to be entered into the TeX file. You can specify
+ * the height and depth of the character (the width is determined by
+ * the browser), and the default font from which to take the character.
+ *
+ * Examples:
+ * \unicode{65} % the character 'A'
+ * \unicode{x41} % the character 'A'
+ * \unicode[.55,0.05]{x22D6} % less-than with dot, with height .55 and depth 0.05
+ * \unicode[.55,0.05][Geramond]{x22D6} % same taken from Geramond font
+ * \unicode[Garamond]{x22D6} % same, but with default height, depth of .8,.2
+ *
+ * Once a size and font are provided for a given code point, they need
+ * not be specified again in subsequent \unicode calls for that character.
+ * Note that a font list can be given, but Internet Explorer has a buggy
+ * implementation of font-family where it only looks in the first
+ * available font and if the glyph is not in that, it does not look at
+ * later fonts, but goes directly to the default font as set in the
+ * Internet-Options/Font panel. For this reason, the default font list is
+ * "STIXGeneral,'Arial Unicode MS'", so if the user has STIX fonts, the
+ * symbol will be taken from that (almost all the symbols are in
+ * STIXGeneral), otherwise Arial Unicode MS is tried.
+ *
+ * To configure the default font list, use
+ *
+ * MathJax.Hub.Config({
+ * TeX: {
+ * unicode: {
+ * fonts: "STIXGeneral,'Arial Unicode MS'"
+ * }
+ * }
+ * });
+ *
+ * The result of \unicode will have TeX class ORD (i.e., it will act like a
+ * variable). Use \mathbin, \mathrel, etc, to specify a different class.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2020 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.
+ */
+
+//
+// The configuration defaults, augmented by the user settings
+//
+MathJax.Extension["TeX/unicode"] = {
+ version: "2.7.9",
+ unicode: {},
+ config: MathJax.Hub.CombineConfig("TeX.unicode",{
+ fonts: "STIXGeneral,'Arial Unicode MS'"
+ })
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+ var TEX = MathJax.InputJax.TeX;
+ var MML = MathJax.ElementJax.mml;
+ var UNICODE = MathJax.Extension["TeX/unicode"].unicode;
+
+ //
+ // Add \unicode macro
+ //
+ TEX.Definitions.Add({macros: {unicode: 'Unicode'}},null,true);
+ //
+ // Implementation of \unicode in parser
+ //
+ TEX.Parse.Augment({
+ Unicode: function(name) {
+ var HD = this.GetBrackets(name), font;
+ if (HD) {
+ if (HD.replace(/ /g,"").match(/^(\d+(\.\d*)?|\.\d+),(\d+(\.\d*)?|\.\d+)$/))
+ {HD = HD.replace(/ /g,"").split(/,/); font = this.GetBrackets(name)}
+ else {font = HD; HD = null}
+ }
+ var n = this.trimSpaces(this.GetArgument(name)).replace(/^0x/,"x");
+ if (!n.match(/^(x[0-9A-Fa-f]+|[0-9]+)$/)) {
+ TEX.Error(["BadUnicode","Argument to \\unicode must be a number"]);
+ }
+ var N = parseInt(n.match(/^x/) ? "0"+n : n);
+ if (!UNICODE[N]) {UNICODE[N] = [800,200,font,N]}
+ else if (!font) {font = UNICODE[N][2]}
+ if (HD) {
+ UNICODE[N][0] = Math.floor(HD[0]*1000);
+ UNICODE[N][1] = Math.floor(HD[1]*1000);
+ }
+ var variant = this.stack.env.font, def = {};
+ if (font) {
+ UNICODE[N][2] = def.fontfamily = font.replace(/"/g,"'");
+ if (variant) {
+ if (variant.match(/bold/)) {def.fontweight = "bold"}
+ if (variant.match(/italic|-mathit/)) {def.fontstyle = "italic"}
+ }
+ } else if (variant) {def.mathvariant = variant}
+ def.unicode = [].concat(UNICODE[N]); // make a copy
+ this.Push(MML.mtext(MML.entity("#"+n)).With(def));
+ }
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX unicode Ready");
+
+});
+
+MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
+ var MML = MathJax.ElementJax.mml;
+ var FONTS = MathJax.Extension["TeX/unicode"].config.fonts;
+
+ //
+ // Override getVariant to make one that includes the font and size
+ //
+ var GETVARIANT = MML.mbase.prototype.HTMLgetVariant;
+ MML.mbase.Augment({
+ HTMLgetVariant: function () {
+ var variant = GETVARIANT.apply(this,arguments);
+ if (variant.unicode) {delete variant.unicode; delete variant.FONTS} // clear font cache in case of restart
+ if (!this.unicode) {return variant}
+ variant.unicode = true;
+ if (!variant.defaultFont) {
+ variant = MathJax.Hub.Insert({},variant); // make a copy
+ variant.defaultFont = {family:FONTS};
+ }
+ var family = this.unicode[2]; if (family) {family += ","+FONTS} else {family = FONTS}
+ variant.defaultFont[this.unicode[3]] = [
+ this.unicode[0],this.unicode[1],500,0,500,
+ {isUnknown:true, isUnicode:true, font:family}
+ ];
+ return variant;
+ }
+ });
+});
+
+MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
+ var MML = MathJax.ElementJax.mml;
+ var FONTS = MathJax.Extension["TeX/unicode"].config.fonts;
+
+ //
+ // Override getVariant to make one that includes the font and size
+ //
+ var GETVARIANT = MML.mbase.prototype.SVGgetVariant;
+ MML.mbase.Augment({
+ SVGgetVariant: function () {
+ var variant = GETVARIANT.call(this);
+ if (variant.unicode) {delete variant.unicode; delete variant.FONTS} // clear font cache in case of restart
+ if (!this.unicode) {return variant}
+ variant.unicode = true;
+ if (!variant.forceFamily) {variant = MathJax.Hub.Insert({},variant)} // make a copy
+ variant.defaultFamily = FONTS; variant.noRemap = true;
+ variant.h = this.unicode[0]; variant.d = this.unicode[1];
+ return variant;
+ }
+ });
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/unicode.js");
+// @license-end
diff --git a/js/mathjax/extensions/TeX/verb.js b/js/mathjax/extensions/TeX/verb.js
new file mode 100644
index 0000000..0f6f845
--- /dev/null
+++ b/js/mathjax/extensions/TeX/verb.js
@@ -0,0 +1,63 @@
+// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0
+/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/*************************************************************
+ *
+ * MathJax/extensions/TeX/verb.js
+ *
+ * Implements the \verb|...| command for including text verbatim
+ * (with no processing of macros or special characters).
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2020 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.Extension["TeX/verb"] = {
+ version: "2.7.9"
+};
+
+MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
+
+ var MML = MathJax.ElementJax.mml;
+ var TEX = MathJax.InputJax.TeX;
+ var TEXDEF = TEX.Definitions;
+
+ TEXDEF.Add({macros: {verb: 'Verb'}},null,true);
+
+ TEX.Parse.Augment({
+
+ /*
+ * Implement \verb|...|
+ */
+ Verb: function (name) {
+ var c = this.GetNext(); var start = ++this.i;
+ if (c == "" ) {TEX.Error(["MissingArgFor","Missing argument for %1",name])}
+ while (this.i < this.string.length && this.string.charAt(this.i) != c) {this.i++}
+ if (this.i == this.string.length)
+ {TEX.Error(["NoClosingDelim","Can't find closing delimiter for %1", name])}
+ var text = this.string.slice(start,this.i).replace(/ /g,"\u00A0"); this.i++;
+ this.Push(MML.mtext(text).With({mathvariant:MML.VARIANT.MONOSPACE}));
+ }
+
+ });
+
+ MathJax.Hub.Startup.signal.Post("TeX verb Ready");
+
+});
+
+MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/verb.js");
+// @license-end