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

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

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