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>