File:  [LON-CAPA] / loncom / html / adm / jsMath / extensions / AMSmath.js
Revision 1.1: download - view: text, annotated - select for diffs
Tue Oct 9 21:29:22 2007 UTC (17 years, 1 month ago) by albertel
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_7_X, version_2_7_99_1, version_2_7_99_0, version_2_7_1, version_2_7_0, version_2_6_X, version_2_6_99_1, version_2_6_99_0, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_99_1, version_2_5_99_0, version_2_12_X, version_2_11_X, version_2_11_5_msu, version_2_11_5, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, bz6209-base, bz6209, bz5969, bz2851, PRINT_INCOMPLETE_base, PRINT_INCOMPLETE, HEAD, GCI_3, GCI_2, GCI_1, BZ5971-printing-apage, BZ5434-fox, BZ4492-merge, BZ4492-feature_horizontal_radioresponse
- jsMath 3.4e

    1: /*
    2:  *  extensions/AMSmath.js
    3:  *  
    4:  *  Part of the jsMath package for mathematics on the web.
    5:  *
    6:  *  This file defines most of the macros and environments from
    7:  *  the amsmath LaTeX package.  You can activate it by calling
    8:  *  
    9:  *    jsMath.Extension.Require('AMSmath');
   10:  *  
   11:  *  once jsMath.js has been loaded, or by adding "extensions/AMSmath.js"
   12:  *  to the loadFiles array in jsMath/easy/load.js.
   13:  *  
   14:  *  You may wish to load AMSsymbols.js as well, but note that it
   15:  *  requires the extra msam10 and msb10 fonts that you will have 
   16:  *  to install on your server first.
   17:  *  
   18:  *  ---------------------------------------------------------------------
   19:  *
   20:  *  Copyright 2007 by Davide P. Cervone
   21:  * 
   22:  *  Licensed under the Apache License, Version 2.0 (the "License");
   23:  *  you may not use this file except in compliance with the License.
   24:  *  You may obtain a copy of the License at
   25:  * 
   26:  *      http://www.apache.org/licenses/LICENSE-2.0
   27:  * 
   28:  *  Unless required by applicable law or agreed to in writing, software
   29:  *  distributed under the License is distributed on an "AS IS" BASIS,
   30:  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   31:  *  See the License for the specific language governing permissions and
   32:  *  limitations under the License.
   33:  */
   34: 
   35: /********************************************************************/
   36: 
   37: jsMath.Extension.Require("moreArrows");
   38: 
   39: jsMath.Package(jsMath.Parser,{
   40:   macros: {
   41:     intI:       ['Macro','\\mathchoice{\\!}{}{}{}\\!\\!\\int'],
   42:     iint:       ['Macro','\\!\\!\\!\\mathop{\\,\\,\\,\\int\\intI}'],
   43:     iiint:      ['Macro','\\!\\!\\!\\mathop{\\,\\,\\,\\int\\intI\\intI}'],
   44:     iiiint:     ['Macro','\\!\\!\\!\\mathop{\\,\\,\\,\\int\\intI\\intI\\intI}'],
   45:     idotsint:   ['Macro','\\!\\!\\mathop{\\,\\,\\int\\cdots\\int}'],
   46:     
   47:     dddot:      ['Macro','\\mathop{#1}\\limits^{\\textstyle ...}',1],
   48:     ddddot:     ['Macro','\\mathop{#1}\\limits^{\\textstyle ....}',1],
   49:     
   50:     sideset:    ['Macro','\\mathop{\\rlap{\\phantom{#3}}}#1\\!{#3}#2',3],
   51:     stackrel:   ['Macro','\\mathrel{\\mathop{#2}\\limits^{#1}}',2],
   52:     
   53:     boxed:      ['Macro','\\fbox{$\\displaystyle{#1}$}',1],
   54:     
   55:     tag:        'HandleTag',
   56:     notag:      ['Macro',''],
   57:     
   58:     substack:   ['Macro','\\begin{subarray}{c}#1\\end{subarray}',1],
   59:     
   60:     varliminf:  ['Macro','\\mathop{\\underline{\\raise1.5pt{\\rule{0pt}{.6em}{0pt}\\smash{\\lower1.5pt{\\rm lim}}}}}'],
   61:     varlimsup:  ['Macro','\\mathop{\\overline{\\rule{0pt}{.6em}{0pt}\\smash{\\rm lim}}}'],
   62:     varinjlim:  ['Macro','\\mathop{\\underrightarrow{\\rm lim}}'],
   63:     varprojlim: ['Macro','\\mathop{\\underleftarrow{\\rm lim}}'],
   64:     
   65:     DeclareMathOperator: 'HandleDeclareOp',
   66:     operatorname: 'HandleOperatorName',
   67: 
   68:     genfrac:    'Genfrac',
   69:     frac:       ['Genfrac',"","","",""],
   70:     tfrac:      ['Genfrac',"","","","1"],
   71:     dfrac:      ['Genfrac',"","","","0"],
   72:     binom:      ['Genfrac',"(",")","0pt",""],
   73:     tbinom:     ['Genfrac',"(",")","0pt","1"],
   74:     dbinom:     ['Genfrac',"(",")","0pt","0"],
   75:     
   76:     cfrac:      'CFrac',
   77:     
   78:     shoveleft:  ['HandleShove','left'],
   79:     shoveright: ['HandleShove','right']
   80:   },
   81:   
   82:   environments: {
   83:     align:         ['Array',null,null,'rlrlrlrlrlrl',[5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18],1,'D'],
   84:     'align*':      ['Array',null,null,'rlrlrlrlrlrl',[5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18],1,'D'],
   85:     multline:     'Multline',
   86:     'multline*':  'Multline',
   87:     split:         ['Array',null,null,'rl',[5/18],1,'D'],
   88:     gather:        ['Array',null,null,'c',null,1,'D'],
   89:     'gather*':     ['Array',null,null,'c',null,1,'D'],
   90:     subarray:      ['Array',null,null,null,[0,0,0,0],1,'S',0,.25],
   91:     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]
   92:   },
   93:   
   94:   delimiter: {
   95:     '\\lvert':     [4,2,0x6A,3,0x0C],
   96:     '\\rvert':     [5,2,0x6A,3,0x0C],
   97:     '\\lVert':     [4,2,0x6B,3,0x0D],
   98:     '\\rVert':     [5,2,0x6B,3,0x0D]
   99:   },
  100: 
  101:   /*
  102:    *  Ignore the tag for now
  103:    */
  104:   HandleTag: function (name) {
  105:     var arg = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
  106:     if (arg == "*") this.GetArgument(this.cmd+name);
  107:   },
  108:   
  109:   /*
  110:    *  Handle \DeclareMathOperator
  111:    */
  112:   HandleDeclareOp: function (name) {
  113:     var limits = "";
  114:     var cs = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
  115:     if (cs == "*") {
  116:       limits = "\\limits";
  117:       cs = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
  118:     }
  119:     if (cs.charAt(0) == "\\") {cs = cs.substr(1)}
  120:     var op = this.GetArgument(this.cmd+name); if (this.error) return;
  121:     op = op.replace(/\*/g,'\\char{cmr10}{0x2A}').replace(/-/g,'\\char{cmr10}{0x2D}');
  122:     jsMath.Parser.prototype.macros[cs] = ['Macro','\\mathop{\\rm '+op+'}'+limits];
  123:   },
  124:   
  125:   HandleOperatorName: function (name) {
  126:     var limits = "";
  127:     var op = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
  128:     if (op == "*") {
  129:       limits = "\\limits";
  130:       op = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
  131:     }
  132:     op = op.replace(/\*/g,'\\char{cmr10}{0x2A}').replace(/-/g,'\\char{cmr10}{0x2D}');
  133:     this.string = '\\mathop{\\rm '+op+'}'+limits+this.string.slice(this.i);
  134:     this.i = 0;
  135:   },
  136:   
  137:   /*
  138:    *  Record presence of \shoveleft and \shoveright
  139:    */
  140:   HandleShove: function (name,data) {
  141:     if (this.mlist.data.entry == null) {this.mlist.data.entry = {}}
  142:     this.mlist.data.entry.shove = data[0];
  143:   },
  144:   
  145:   /*
  146:    *  Handle \cfrac
  147:    */
  148:   CFrac: function (name) {
  149:     var lr = this.GetBrackets(this.cmd+name); if (this.error) return;
  150:     var num = this.GetArgument(this.cmd+name); if (this.error) return;
  151:     var den = this.GetArgument(this.cmd+name); if (this.error) return;
  152:     
  153:     num = this.Process('\\strut\\textstyle{'+num+'}'); if (this.error) return;
  154:     den = this.Process('\\strut\\textstyle{'+den+'}'); if (this.error) return;
  155:     var data = this.mlist.data;
  156:     var TeX = jsMath.Typeset.TeX(data.style,data.size);
  157:     
  158:     if (lr != "") {
  159:       if (lr != 'l' && lr != 'r') {this.Error("Illegal alignment specified in "+this.cmd+name); return}
  160:       num = jsMath.Box.Set(num,data.style,data.size);
  161:       den = jsMath.Box.Set(den,data.style,data.size);
  162:       if (num.w > den.w) {
  163:         if (lr == 'l') {den.html += jsMath.HTML.Spacer(num.w-den.w)}
  164:                   else {den.html = jsMath.HTML.Spacer(num.w-den.w) + den.html}
  165:         den.w = num.w;
  166:       } else if (num.w < den.w) {
  167:         if (lr == 'l') {num.html += jsMath.HTML.Spacer(den.w-num.w)}
  168:                   else {num.html = jsMath.HTML.Spacer(den.w-num.w) + num.html}
  169:         num.w = den.w;
  170:       }
  171:     }
  172:     
  173:     this.mlist.Add(jsMath.mItem.Fraction(name,num,den,TeX.default_rule_thickness));
  174:   },
  175:   
  176:   /*
  177:    *  Implement AMS generalizes fraction
  178:    */
  179:   Genfrac: function (name,data) {
  180:     var left = data[0]; var right = data[1];
  181:     var thickness = data[2]; var style = data[3];
  182:     
  183:     if (left != null) {left = this.delimiter[left]} else
  184:       {left = this.GetDelimiterArg(this.cmd+name); if (this.error) return}
  185:     if (right != null) {right = this.delimiter[right]} else 
  186:       {right = this.GetDelimiterArg(this.cmd+name); if (this.error) return}
  187:     if (thickness == null) {thickness = this.GetArgument(this.cmd+name); if (this.error) return}
  188:     if (style == null) {style = this.GetArgument(this.cmd+name); if (this.error) return}
  189: 
  190:     var num = this.ProcessArg(this.cmd+name); if (this.error) return;
  191:     var den = this.ProcessArg(this.cmd+name); if (this.error) return;
  192:     
  193:     if (left == "") {left = null}; if (right == "") {right = null}
  194:     if (thickness == "") {
  195:       var TeX =jsMath.Typeset.TeX(this.mlist.data.style,this.mlist.data.size);
  196:       thickness = TeX.default_rule_thickness;
  197:     } else {
  198:       thickness = this.ParseDimen(thickness,this.cmd+name,0,0);
  199:     }
  200:     
  201:     var frac = jsMath.mItem.Fraction(name,num,den,thickness,left,right);
  202: 
  203:     if (style != "") {
  204:       style = (["D","T","S","SS"])[style];
  205:       if (style == null) {this.Error("Bad math style for "+this.cmd+name); return}
  206:       var mlist = new jsMath.mList([new jsMath.mItem('style',{style:style}),frac]);
  207:       this.mlist.Add(jsMath.mItem.Atom('inner',{type:'mlist',mlist: mlist}));
  208:     } else {
  209:       this.mlist.Add(frac);
  210:     }
  211:   },
  212:   
  213:   /*
  214:    *  Implements the multline environment
  215:    */
  216:   Multline: function (name,delim) {
  217:     var data = this.mlist.data;
  218:     var width = this.GetBrackets(this.cmd+'begin{'+name+'}'); if (this.error) return;
  219:     var arg = this.GetEnd(name); if (this.error) return;
  220: 
  221:     var parse = new jsMath.Parser(arg+this.cmd+'\\',null,data.size,'D');
  222:     parse.matrix = name; parse.row = []; parse.table = []; parse.rspacing = [];
  223:     parse.Parse(); if (parse.error) {this.Error(parse); return}
  224:     parse.HandleRow(name,1);  // be sure the last row is recorded
  225:     
  226:     //
  227:     // check rows for extra columns and maximum width
  228:     // 
  229:     var i; var row; var W = 0;
  230:     for (i = 0; i < parse.table.length; i++) {
  231:       row = parse.table[i];
  232:       if (row.length > 1) {
  233:         this.Error("Rows can contain only one equation in '"+name+"' environment");
  234:         return;
  235:       }
  236:       if (row[0].w > W) {W = row[0].w}
  237:     }
  238: 
  239:     //
  240:     //  Determine width of display
  241:     //
  242:     if (width == "") {width = W+2} else {
  243:       width = this.ParseDimen(width,name,0,0);
  244:       if (width < W) {width = W}
  245:     }
  246:     
  247:     //
  248:     //  Shove the top and bottom lines
  249:     //
  250:     if (parse.table.length > 1) {
  251:       parse.table[0][0].entry.shove = 'left';
  252:       row = parse.table[parse.table.length-1];
  253:       if (!row[0].entry.shove) {row[0].entry.shove = 'right'}
  254:     }
  255:     //
  256:     //  Adjust widths of shoved lines
  257:     //
  258:     for (i = 0; i < parse.table.length; i++) {
  259:       row = parse.table[i][0];
  260:       if (row.entry.shove && row.w < width) {
  261:         switch (row.entry.shove) {
  262:           case 'left':
  263:             row.html += jsMath.HTML.Spacer(width-row.w);
  264:             break;
  265:             
  266:           case 'right':
  267:             row.html = jsMath.HTML.Spacer(width-row.w)+row.html;
  268:             break;
  269:         }
  270:         row.w = width;
  271:       }
  272:     }
  273:     
  274:     //
  275:     //  Do the layout
  276:     //
  277:     var box = jsMath.Box.Layout(data.size,parse.table);
  278:     this.mlist.Add(jsMath.mItem.Atom('ord',box));
  279:   },
  280: 
  281:   /*
  282:    *  Get a delimiter or empty argument
  283:    */
  284:   GetDelimiterArg: function (name) {
  285:     var c = this.trimSpaces(this.GetArgument(name)); if (this.error) return null;
  286:     if (c == "") return null;
  287:     if (this.delimiter[c]) return this.delimiter[c];
  288:     this.Error("Missing or unrecognized delimiter for "+name);
  289:     return null;
  290:   }
  291: });

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>