Annotation of loncom/html/adm/jsMath/plugins/mimeTeX.js, revision 1.3

1.1       albertel    1: /*
1.2       albertel    2:  *  mimeTeX.js
                      3:  *  
                      4:  *  Part of the jsMath package for mathematics on the web.
                      5:  *
                      6:  *  This file makes jsMath more compatible with the mimeTeX program.
                      7:  *  It does not make everything work, but it goes a long way.
                      8:  *
                      9:  *  ---------------------------------------------------------------------
                     10:  *
                     11:  *  Copyright 2004-2006 by Davide P. Cervone
                     12:  * 
                     13:  *  Licensed under the Apache License, Version 2.0 (the "License");
                     14:  *  you may not use this file except in compliance with the License.
                     15:  *  You may obtain a copy of the License at
                     16:  * 
                     17:  *      http://www.apache.org/licenses/LICENSE-2.0
                     18:  * 
                     19:  *  Unless required by applicable law or agreed to in writing, software
                     20:  *  distributed under the License is distributed on an "AS IS" BASIS,
                     21:  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                     22:  *  See the License for the specific language governing permissions and
                     23:  *  limitations under the License.
                     24:  */
                     25: 
                     26: 
                     27: /*
1.1       albertel   28:  *  Treat ~ as space
                     29:  */
                     30: jsMath.Parser.prototype.nextIsSpace = function () {
                     31:   return this.string.charAt(this.i) == ' ' ||
                     32:          this.string.charAt(this.i) == '~';
                     33: }
                     34: jsMath.Parser.prototype.special['~'] = 'Space';
                     35: 
                     36: /*
                     37:  *  Implement \[ ... \], \( ... \), etc.
                     38:  */
                     39: jsMath.Macro('[','\\left[');  jsMath.Macro(']','\\right]');
                     40: jsMath.Macro('(','\\left(');  jsMath.Macro(')','\\right)');
                     41: jsMath.Macro('<','\\left<');  jsMath.Macro('>','\\right>');
                     42: // can't do \. in a reasonable way
                     43: jsMath.Parser.prototype.macros['|'] = ['HandleLR','|','|'];
                     44: jsMath.Parser.prototype.macros['='] = ['HandleLR','\\|','\\|'];
                     45: 
                     46: /*
                     47:  *  Make non-standard \left{ and \right} work
                     48:  */
                     49: jsMath.Parser.prototype.delimiter['}'] = [5,2,0x67,3,0x09];
                     50: jsMath.Parser.prototype.delimiter['{'] = [4,2,0x66,3,0x08];
                     51: 
                     52: 
                     53: /*
                     54:  *  Immitate mimeTeX \big... and \Big... ops
                     55:  */
                     56: 
                     57: // make the normal ones in text mode
                     58: jsMath.Macro('int','\\intop\\nolimits');
                     59: jsMath.Macro('oint','\\ointop\\nolimits');
                     60: jsMath.Macro('sum','\\sumop\\nolimits');
                     61: jsMath.Macro('prod','\\prodop\\nolimits');
                     62: jsMath.Macro('coprod','\\coprodop\\nolimits');
                     63: 
                     64: jsMath.Macro('bigint','\\bigintop\\nolimits'); 
                     65: jsMath.Macro('bigoint','\\bigointop\\nolimits');
                     66: jsMath.Macro('bigsum','\\bigsumop\\nolimits');
                     67: jsMath.Macro('bigprod','\\bigprodop\\nolimits');
                     68: jsMath.Macro('bigcoprod','\\bigcoprodop\\nolimits');
                     69: 
                     70: jsMath.Macro('Bigint','\\bigintop\\limits');
                     71: jsMath.Macro('Bigoint','\\bigointop\\limits');
                     72: jsMath.Macro('Bigsum','\\bigsumop\\limits');
                     73: jsMath.Macro('Bigprod','\\bigprodop\\limits');
                     74: jsMath.Macro('Bigcoprod','\\bigcoprod\\limits');
                     75: 
                     76: /*
                     77:  *  The characters needed for the macros above
                     78:  */
                     79: jsMath.Parser.prototype.mathchardef['coprodop'] = [1,3,0x60];
                     80: jsMath.Parser.prototype.mathchardef['prodop']   = [1,3,0x51];
                     81: jsMath.Parser.prototype.mathchardef['sumop']    = [1,3,0x50];
                     82: 
                     83: jsMath.Parser.prototype.mathchardef['bigintop']    = [1,3,0x5A];
                     84: jsMath.Parser.prototype.mathchardef['bigointop']   = [1,3,0x49];
                     85: jsMath.Parser.prototype.mathchardef['bigcoprodop'] = [1,3,0x61];
                     86: jsMath.Parser.prototype.mathchardef['bigprodop']   = [1,3,0x59];
                     87: jsMath.Parser.prototype.mathchardef['bigsumop']    = [1,3,0x58];
                     88: 
                     89: /*
                     90:  * Unlink the small versions so they don't enlarge in display mode
                     91:  */
                     92: jsMath.TeX['cmex10'][0x48].n = null;
                     93: jsMath.TeX['cmex10'][0x50].n = null;
                     94: jsMath.TeX['cmex10'][0x51].n = null;
                     95: jsMath.TeX['cmex10'][0x52].n = null;
                     96: jsMath.TeX['cmex10'][0x60].n = null;
                     97: 
                     98: 
                     99: /*
                    100:  *  Some other missing items
                    101:  */
                    102: jsMath.Macro('/','{}'); // insert an empty box \/
                    103: jsMath.Macro('raisebox','\\raise #1px ',1); // convert to \raise
                    104: jsMath.Macro('hfill','\\quad ',1); // punt
                    105: jsMath.Macro('fbox','\\oldfbox{$#1$}',1); // do fbox in math mode
                    106: 
                    107: /*
                    108:  *  These get new JavaScript routines
                    109:  */
                    110: jsMath.Parser.prototype.macros['unitlength'] = 'unitlength';
                    111: jsMath.Parser.prototype.macros['hspace']     = 'hspace';
                    112: jsMath.Parser.prototype.macros['fs']         = 'fs';
                    113: jsMath.Parser.prototype.macros['oldfbox']    = 'FBox';
                    114: 
                    115: /*
                    116:  *  Add some JavaScript functions to the parser
                    117:  */
                    118: jsMath.Package(jsMath.Parser,{
                    119:   
                    120:   /*
                    121:    *  Implement \left x ... \right x
                    122:    */
                    123:   HandleLR: function (name,data) {
                    124:     var arg = this.GetUpto(name,name); if (this.error) return;
                    125:     this.string = '\\left'+data[0]+arg+'\\right'+data[1];
                    126:     this.i = 0;
                    127:   },
                    128: 
                    129:   /*
                    130:    *  Hold the unit length in mlist.data
                    131:    */
                    132:   unitlength: function (name) {
                    133:     var n = this.GetArgument(this.cmd+name); if (this.error) return;
                    134:     if (!n.match(/^-?(\d+(\.\d*)?|\.\d+)$/)) {
                    135:       this.Error("Argument for "+this.cmd+name+" must be a number");
                    136:       return;
                    137:     }
                    138:     this.mlist.data['unitlength'] = n;
                    139:   },
                    140: 
                    141:   /*
                    142:    *  Get the length (converted to ems) and multiply by the unit length
                    143:    */
                    144:   hspace: function (name) {
                    145:     var w = this.GetArgument(this.cmd+name); if (this.error) return;
                    146:     if (!w.match(/^-?(\d+(\.\d*)?|\.\d+)$/)) {
                    147:       this.Error("Argument for "+this.cmd+name+" must be a number");
                    148:       return;
                    149:     }
                    150:     w /= jsMath.em
                    151:     if (this.mlist.data['unitlength']) {w *= this.mlist.data['unitlength']}
                    152:     this.mlist.Add(jsMath.mItem.Space(w));
                    153:   },
                    154:   
                    155:   /*
                    156:    *  Implement \fs{...} for font-size changing
                    157:    */
                    158:   fs: function (name) {
                    159:     var n = this.GetArgument(this.cmd+name); if (this.error) return;
                    160:     if (!n.match(/^[-+]?\d+$/)) {
                    161:       this.Error("Argument for "+this.cmd+name+" must be an integer");
                    162:       return;
                    163:     }
                    164:     if (n.match(/[-+]/)) {n = n - 0; n += this.mlist.data.size}
                    165:     this.mlist.data.size = n = Math.max(0,Math.min(9,n));
                    166:     this.mlist.Add(new jsMath.mItem('size',{size: n}));
                    167:   },
                    168: 
                    169:   /*
                    170:    *  Repalce the Array function by one that accepts an optional
                    171:    *  parameter for the column types, and that handle's mimeTeX's
                    172:    *  "preamble" format.
                    173:    */
                    174:   Array: function (name,delim) {
                    175:     var columns = delim[2]; var cspacing = delim[3];
                    176:     if (!columns && this.GetNext() == '{') {
                    177:       columns = this.GetArgument(this.cmd+'begin{'+name+'}');
                    178:       if (this.error) return;
                    179:     } else {
                    180:       columns = '';
                    181:     }
                    182:     columns = columns.replace(/[^clr]/g,'');
                    183:     columns = columns.split('');
1.3     ! albertel  184:     var data = this.mlist.data; var style = delim[5] || 'T';
1.1       albertel  185:     var arg = this.GetEnd(name); if (this.error) return;
                    186:     if (arg.match(/\$/)) {arg = arg.replace(/^([^$]*)\$/,''); columns = RegExp.$1}
1.3     ! albertel  187:     var parse = new jsMath.Parser(arg+this.cmd+'\\',null,data.size,style);
        !           188:     parse.matrix = name; parse.row = []; parse.table = []; parse.rspacing = [];
1.1       albertel  189:     parse.Parse(); if (parse.error) {this.Error(parse); return}
                    190:     parse.HandleRow(name,1);  // be sure the last row is recorded
1.3     ! albertel  191:     var box = jsMath.Box.Layout(data.size,parse.table,columns,cspacing,parse.rspacing,delim[4]||null);
1.1       albertel  192:     // Add parentheses, if needed
                    193:     if (delim[0] && delim[1]) {
1.3     ! albertel  194:       var left  = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[0]],'T');
        !           195:       var right = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[1]],'T');
1.1       albertel  196:       box = jsMath.Box.SetList([left,box,right],data.style,data.size);
                    197:     }
                    198:     this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box));
                    199:   },
                    200: 
                    201:   /*
                    202:    *  Similarly for Matrix (used by \matrix and \array)
                    203:    */
                    204:   Matrix: function (name,delim) {
                    205:     var data = this.mlist.data;
                    206:     var arg = this.GetArgument(this.cmd+name); if (this.error) return;
                    207:     if (arg.match(/\$/)) {arg = arg.replace(/^([^$]*)\$/,''); delim[2] = RegExp.$1}
1.3     ! albertel  208:     var parse = new jsMath.Parser(arg+this.cmd+'\\',null,data.size,delim[5] || 'T');
        !           209:     parse.matrix = name; parse.row = []; parse.table = []; parse.rspacing = [];
1.1       albertel  210:     parse.Parse(); if (parse.error) {this.Error(parse); return}
                    211:     parse.HandleRow(name,1);  // be sure the last row is recorded
1.3     ! albertel  212:     var box = jsMath.Box.Layout(data.size,parse.table,delim[2]||null,delim[3]||null,parse.rspacing,delim[4]||null);
1.1       albertel  213:     // Add parentheses, if needed
                    214:     if (delim[0] && delim[1]) {
1.3     ! albertel  215:       var left  = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[0]],'T');
        !           216:       var right = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[1]],'T');
1.1       albertel  217:       box = jsMath.Box.SetList([left,box,right],data.style,data.size);
                    218:     }
                    219:     this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box));
                    220:   }
1.2       albertel  221: });

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