User:CBM2/jsMath/extensions/AMSmath.js

/* * extensions/AMSmath.js * * Part of the jsMath package for mathematics on the web. * * This file defines most of the macros and environments from * the amsmath LaTeX package. You can activate it by calling *  *    jsMath.Extension.Require('AMSmath'); *  *  once jsMath.js has been loaded, or by adding "extensions/AMSmath.js" * to the loadFiles array in jsMath/easy/load.js. *  *  You may wish to load AMSsymbols.js as well, but note that it *  requires the extra msam10 and msb10 fonts that you will have * to install on your server first. *  *  - * *  Copyright 2007 by Davide P. Cervone * *  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. */

/********************************************************************/

jsMath.Extension.Require("moreArrows");

jsMath.Package(jsMath.Parser,{ macros: {    intI:       ['Macro','\\mathchoice{\\!}{}{}{}\\!\\!\\int'],    iint:       ['Macro','\\!\\!\\!\\mathop{\\,\\,\\,\\int\\intI}'],    iiint:      ['Macro','\\!\\!\\!\\mathop{\\,\\,\\,\\int\\intI\\intI}'],    iiiint:     ['Macro','\\!\\!\\!\\mathop{\\,\\,\\,\\int\\intI\\intI\\intI}'],    idotsint:   ['Macro','\\!\\!\\mathop{\\,\\,\\int\\cdots\\int}'],    dddot:      ['Macro','\\mathop{#1}\\limits^{\\textstyle ...}',1],    ddddot:     ['Macro','\\mathop{#1}\\limits^{\\textstyle ....}',1],    sideset:    ['Macro','\\mathop{\\rlap{\\phantom{#3}}}#1\\!{#3}#2',3],    stackrel:   ['Macro','\\mathrel{\\mathop{#2}\\limits^{#1}}',2],    boxed:      ['Macro','\\fbox{$\\displaystyle{#1}$}',1],    tag:        'HandleTag',    notag:      ['Macro',''],    substack:   ['Macro','\\begin{subarray}{c}#1\\end{subarray}',1],    varliminf:  ['Macro','\\mathop{\\underline{\\raise1.5pt{\\rule{0pt}{.6em}{0pt}\\smash{\\lower1.5pt{\\rm lim}}}}}'], varlimsup: ['Macro','\\mathop{\\overline{\\rule{0pt}{.6em}{0pt}\\smash{\\rm lim}}}'], varinjlim: ['Macro','\\mathop{\\underrightarrow{\\rm lim}}'], varprojlim: ['Macro','\\mathop{\\underleftarrow{\\rm lim}}'], DeclareMathOperator: 'HandleDeclareOp', operatorname: 'HandleOperatorName',

genfrac:   'Genfrac', frac:      ['Genfrac',"","","",""], tfrac:     ['Genfrac',"","","","1"], dfrac:     ['Genfrac',"","","","0"], binom:     ['Genfrac',"(",")","0pt",""], tbinom:    ['Genfrac',"(",")","0pt","1"], dbinom:    ['Genfrac',"(",")","0pt","0"], cfrac:     'CFrac', shoveleft: ['HandleShove','left'], shoveright: ['HandleShove','right'] }, environments: { align:        ['Array',null,null,'rlrlrlrlrlrl',[5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18],1,'D'], 'align*':     ['Array',null,null,'rlrlrlrlrlrl',[5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18],1,'D'], aligned:      ['Array',null,null,'rlrlrlrlrlrl',[5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18],1,'D'], multline:    'Multline', 'multline*': 'Multline', split:        ['Array',null,null,'rl',[5/18],1,'D'], gather:       ['Array',null,null,'c',null,1,'D'], 'gather*':    ['Array',null,null,'c',null,1,'D'], gathered:     ['Array',null,null,'c',null,1,'D'], subarray:     ['Array',null,null,null,[0,0,0,0],1,'S',0,.25], smallmatrix:  ['Array',null,null,'cccccccccc',[1/3,1/3,1/3,1/3,1/3,1/3,1/3,1/3,1/3,1/3],1,'S',0] }, delimiter: { '\\lvert':    [4,2,0x6A,3,0x0C], '\\rvert':    [5,2,0x6A,3,0x0C], '\\lVert':    [4,2,0x6B,3,0x0D], '\\rVert':    [5,2,0x6B,3,0x0D] },

/*  *  Ignore the tag for now */ HandleTag: function (name) { var arg = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return; if (arg == "*") this.GetArgument(this.cmd+name); }, /*   *  Handle \DeclareMathOperator */ HandleDeclareOp: function (name) { var limits = ""; var cs = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return; if (cs == "*") { limits = "\\limits"; cs = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return; }   if (cs.charAt(0) == "\\") {cs = cs.substr(1)} var op = this.GetArgument(this.cmd+name); if (this.error) return; op = op.replace(/\*/g,'\\char{cmr10}{0x2A}').replace(/-/g,'\\char{cmr10}{0x2D}'); jsMath.Parser.prototype.macros[cs] = ['Macro','\\mathop{\\rm '+op+'}'+limits]; }, HandleOperatorName: function (name) { var limits = "\\nolimits"; var op = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return; if (op == "*") { limits = "\\limits"; op = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return; }   op = op.replace(/\*/g,'\\char{cmr10}{0x2A}').replace(/-/g,'\\char{cmr10}{0x2D}'); this.string = '\\mathop{\\rm '+op+'}'+limits+this.string.slice(this.i); this.i = 0; }, /*   *  Record presence of \shoveleft and \shoveright */ HandleShove: function (name,data) { if (this.mlist.data.entry == null) {this.mlist.data.entry = {}} this.mlist.data.entry.shove = data[0]; }, /*   *  Handle \cfrac */ CFrac: function (name) { var lr = this.GetBrackets(this.cmd+name); if (this.error) return; var num = this.GetArgument(this.cmd+name); if (this.error) return; var den = this.GetArgument(this.cmd+name); if (this.error) return; num = this.Process('\\strut\\textstyle{'+num+'}'); if (this.error) return; den = this.Process('\\strut\\textstyle{'+den+'}'); if (this.error) return; var data = this.mlist.data; var TeX = jsMath.Typeset.TeX(data.style,data.size); if (lr != "") { if (lr != 'l' && lr != 'r') {this.Error("Illegal alignment specified in "+this.cmd+name); return} num = jsMath.Box.Set(num,data.style,data.size); den = jsMath.Box.Set(den,data.style,data.size); if (num.w > den.w) { if (lr == 'l') {den.html += jsMath.HTML.Spacer(num.w-den.w)} else {den.html = jsMath.HTML.Spacer(num.w-den.w) + den.html} den.w = num.w;     } else if (num.w < den.w) { if (lr == 'l') {num.html += jsMath.HTML.Spacer(den.w-num.w)} else {num.html = jsMath.HTML.Spacer(den.w-num.w) + num.html} num.w = den.w;     } }   this.mlist.Add(jsMath.mItem.Fraction(name,num,den,TeX.default_rule_thickness)); }, /*   *  Implement AMS generalized fraction */ Genfrac: function (name,data) { var left = data[0]; var right = data[1]; var thickness = data[2]; var style = data[3]; if (left != null) {left = this.delimiter[left]} else {left = this.GetDelimiterArg(this.cmd+name); if (this.error) return} if (right != null) {right = this.delimiter[right]} else {right = this.GetDelimiterArg(this.cmd+name); if (this.error) return} if (thickness == null) {thickness = this.GetArgument(this.cmd+name); if (this.error) return} if (style == null) {style = this.GetArgument(this.cmd+name); if (this.error) return}

var num = this.ProcessArg(this.cmd+name); if (this.error) return; var den = this.ProcessArg(this.cmd+name); if (this.error) return; if (left == "") {left = null}; if (right == "") {right = null} if (thickness == "") { var TeX =jsMath.Typeset.TeX(this.mlist.data.style,this.mlist.data.size); thickness = TeX.default_rule_thickness; } else { thickness = this.ParseDimen(thickness,this.cmd+name,0,0); }   var frac = jsMath.mItem.Fraction(name,num,den,thickness,left,right);

if (style != "") { style = (["D","T","S","SS"])[style]; if (style == null) {this.Error("Bad math style for "+this.cmd+name); return} var mlist = new jsMath.mList([new jsMath.mItem('style',{style:style}),frac]); this.mlist.Add(jsMath.mItem.Atom('inner',{type:'mlist',mlist: mlist})); } else { this.mlist.Add(frac); } },  /*   *  Implements the multline environment */ Multline: function (name,delim) { var data = this.mlist.data; var width = this.GetBrackets(this.cmd+'begin{'+name+'}'); if (this.error) return; var arg = this.GetEnd(name); if (this.error) return;

var parse = new jsMath.Parser(arg+this.cmd+'\\',null,data.size,'D'); parse.matrix = name; parse.row = []; parse.table = []; parse.rspacing = []; parse.Parse; if (parse.error) {this.Error(parse); return} parse.HandleRow(name,1); // be sure the last row is recorded //   // check rows for extra columns and maximum width //    var i; var row; var W = 0; for (i = 0; i < parse.table.length; i++) { row = parse.table[i]; if (row.length > 1) { this.Error("Rows can contain only one equation in '"+name+"' environment"); return; }     if (row[0].w > W) {W = row[0].w}    }

//   //  Determine width of display //   if (width == "") {width = W+2} else { width = this.ParseDimen(width,name,0,0); if (width < W) {width = W}   } //   //  Shove the top and bottom lines //   if (parse.table.length > 1) { parse.table[0][0].entry.shove = 'left'; row = parse.table[parse.table.length-1]; if (!row[0].entry.shove) {row[0].entry.shove = 'right'} }   //    //  Adjust widths of shoved lines //   for (i = 0; i < parse.table.length; i++) { row = parse.table[i][0]; if (row.entry.shove && row.w < width) { switch (row.entry.shove) { case 'left': row.html += jsMath.HTML.Spacer(width-row.w); break; case 'right': row.html = jsMath.HTML.Spacer(width-row.w)+row.html; break; }       row.w = width; }   }    //    //  Do the layout //   var box = jsMath.Box.Layout(data.size,parse.table); this.mlist.Add(jsMath.mItem.Atom('ord',box)); },

/*  *  Get a delimiter or empty argument */ GetDelimiterArg: function (name) { var c = this.trimSpaces(this.GetArgument(name)); if (this.error) return null; if (c == "") return null; if (this.delimiter[c]) return this.delimiter[c]; this.Error("Missing or unrecognized delimiter for "+name); return null; } });