Annotation of loncom/html/adm/jsMath/uncompressed/jsMath.js, revision 1.2
1.1 albertel 1: /*****************************************************************************
2: *
3: * jsMath: Mathematics on the Web
4: *
5: * This jsMath package makes it possible to display mathematics in HTML pages
6: * that are viewable by a wide range of browsers on both the Mac and the IBM PC,
7: * including browsers that don't process MathML. See
8: *
9: * http://www.math.union.edu/locate/jsMath
10: *
11: * for the latest version, and for documentation on how to use jsMath.
12: *
13: * Copyright 2004-2006 by Davide P. Cervone
14: *
15: * Licensed under the Apache License, Version 2.0 (the "License");
16: * you may not use this file except in compliance with the License.
17: * You may obtain a copy of the License at
18: *
19: * http://www.apache.org/licenses/LICENSE-2.0
20: *
21: * Unless required by applicable law or agreed to in writing, software
22: * distributed under the License is distributed on an "AS IS" BASIS,
23: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24: * See the License for the specific language governing permissions and
25: * limitations under the License.
26: *
27: *****************************************************************************/
28:
29: /*
30: * Prevent running everything again if this file is loaded twice
31: */
32: if (!window.jsMath || !window.jsMath.loaded) {
33:
34: var jsMath_old = window.jsMath; // save user customizations
35:
36: //
37: // debugging routine
38: //
39: /*
40: * function ShowObject (obj,spaces) {
41: * var s = ''; if (!spaces) {spaces = ""}
42: * for (var i in obj) {
43: * if (obj[i] != null) {
44: * if (typeof(obj[i]) == "object") {
45: * s += spaces + i + ": {\n"
46: * + ShowObject(obj[i],spaces + ' ')
47: * + spaces + "}\n";
48: * } else if (typeof(obj[i]) != "function") {
49: * s += spaces + i + ': ' + obj[i] + "\n";
50: * }
51: * }
52: * }
53: * return s;
54: * }
55: */
56:
57: /***************************************************************************/
58: //
59: // Check for DOM support
60: //
61: if (!document.getElementById || !document.childNodes || !document.createElement) {
62: alert('The mathematics on this page requires W3C DOM support in its JavaScript. '
63: + 'Unfortunately, your browser doesn\'t seem to have this.');
64: } else {
65:
66: /***************************************************************************/
67:
1.2 ! albertel 68: window.jsMath = {
1.1 albertel 69:
1.2 ! albertel 70: version: "3.3", // change this if you edit the file, but don't edit this file
1.1 albertel 71:
72: document: document, // the document loading jsMath
73: window: window, // the window of the of loading document
74:
75: // Font sizes for \tiny, \small, etc. (must match styles below)
76: sizes: [50, 60, 70, 85, 100, 120, 144, 173, 207, 249],
77:
78: //
79: // The styles needed for the TeX fonts
80: //
81: styles: {
82: '.math': 'font-family: serif; font-style: normal; font-weight: normal',
83:
84: '.typeset': 'font-family: serif; font-style: normal; font-weight: normal',
85: 'div.typeset': 'text-align: center; margin: 1em 0px;',
86: 'span.typeset': 'text-align: left',
87: '.typeset span': 'text-align: left; border:0px; margin:0px; padding:0px',
88:
89: '.typeset .normal': 'font-family: serif; font-style: normal; font-weight: normal',
90:
91: '.typeset .size0': 'font-size: 50%', // tiny (\scriptscriptsize)
92: '.typeset .size1': 'font-size: 60%', // (50% of \large for consistency)
93: '.typeset .size2': 'font-size: 70%', // scriptsize
94: '.typeset .size3': 'font-size: 85%', // small (70% of \large for consistency)
95: '.typeset .size4': 'font-size: 100%', // normalsize
96: '.typeset .size5': 'font-size: 120%', // large
97: '.typeset .size6': 'font-size: 144%', // Large
98: '.typeset .size7': 'font-size: 173%', // LARGE
99: '.typeset .size8': 'font-size: 207%', // huge
100: '.typeset .size9': 'font-size: 249%', // Huge
101:
102: '.typeset .cmr10': 'font-family: jsMath-cmr10, serif',
103: '.typeset .cmbx10': 'font-family: jsMath-cmbx10, jsMath-cmr10',
104: '.typeset .cmti10': 'font-family: jsMath-cmti10, jsMath-cmr10',
105: '.typeset .cmmi10': 'font-family: jsMath-cmmi10',
106: '.typeset .cmsy10': 'font-family: jsMath-cmsy10',
107: '.typeset .cmex10': 'font-family: jsMath-cmex10',
108:
109: '.typeset .textit': 'font-family: serif; font-style:italic',
110: '.typeset .textbf': 'font-family: serif; font-weight:bold',
111:
112: '.typeset .link': 'text-decoration: none',
113: '.typeset .error': 'font-size: 10pt; font-style: italic; '
114: + 'background-color: #FFFFCC; padding: 1px; '
115: + 'border: 1px solid #CC0000',
116:
117: '.typeset .blank': 'display:inline-block; overflow:hidden; border:0px none; width:0px; height:0px;',
118: '.typeset .spacer': 'display:inline-block',
119:
1.2 ! albertel 120: '#jsMath_message': 'position:fixed; bottom:1px; left:2px; background-color:#E6E6E6; '
! 121: + 'border: solid 1px #959595; margin:0px; padding: 1px 8px; '
! 122: + 'z-index:102; color: black; font-size:small; width:auto;',
! 123: '#jsMath_panel': 'position:fixed; bottom:1.5em; right:1.5em; padding: .8em 1.6em; '
! 124: + 'background-color:#DDDDDD; border: outset 2px; '
! 125: + 'z-index:103; width:auto;',
! 126: '#jsMath_panel .disabled': 'color:#888888',
! 127: '#jsMath_panel .infoLink': 'font-size:85%',
! 128: '#jsMath_button': 'position:fixed; bottom:1px; right:2px; background-color:white; '
! 129: + 'border: solid 1px #959595; margin:0px; padding: 0px 3px 1px 3px; '
! 130: + 'z-index:102; color:black; text-decoration:none; font-size:x-small; '
! 131: + 'width:auto; cursor:hand;',
! 132: '#jsMath_global': 'font-style:italic;',
! 133: '#jsMath_float': 'position:absolute; top:0px; left:0px; max-width:80%; '
! 134: + 'z-index:101; width:auto; height:auto;',
! 135: '#jsMath_float .drag': 'background-color:#DDDDDD; border: outset 1px; height:12px; font-size: 1px;',
! 136: '#jsMath_float .close': 'background-color:#E6E6E6; border: inset 1px; width:8px; height:8px; margin: 1px 2px;',
! 137: '#jsMath_float .source': 'background-color:#E2E2E2; border: outset 1px; '
! 138: + 'width:auto; height:auto; padding: 8px 15px; '
! 139: + 'font-family: courier, fixed; font-size: 90%',
! 140:
! 141: '#jsMath_noFont .message': 'text-align: center; padding: .8em 1.6em; border: 3px solid #DD0000; '
! 142: + 'background-color: #FFF8F8; color: #AA0000; font-size:small; width:auto;',
! 143: '#jsMath_noFont .link': 'padding: 0px 5px 2px 5px; border: 2px outset; background-color:#E8E8E8; '
! 144: + 'color:black; font-size:80%; width:auto; cursor:hand;',
! 145:
! 146: '#jsMath_PrintWarning .message':
! 147: 'text-align: center; padding: .8em 1.6em; border: 3px solid #DD0000; '
! 148: + 'background-color: #FFF8F8; color: #AA0000; font-size:x-small; width:auto;',
! 149:
! 150: '@media print': '#jsMath_button {display:none}\n' +
! 151: '#jsMath_Warning {display:none}',
! 152:
! 153: '@media screen': '#jsMath_PrintWarning {display:none}'
1.1 albertel 154:
155: },
156:
157:
158: /***************************************************************************/
159:
160: /*
161: * Get a jsMath DOM element
162: */
163: Element: function (name) {return jsMath.document.getElementById('jsMath_'+name)},
164:
165: /*
166: * Get the width and height (in pixels) of an HTML string
167: */
168: BBoxFor: function (s) {
169: this.hidden.innerHTML =
170: '<nobr><span class="typeset"><span class="scale">'+s+'</span></span></nobr>';
171: var bbox = {w: this.hidden.offsetWidth, h: this.hidden.offsetHeight};
172: this.hidden.innerHTML = '';
173: return bbox;
174: },
175:
176: /*
1.2 ! albertel 177: * Get the width and height (in ems) of an HTML string.
! 178: * Check the cache first to see if we've already measured it.
1.1 albertel 179: */
180: EmBoxFor: function (s) {
1.2 ! albertel 181: var cache = jsMath.Global.cache.R;
! 182: if (!cache[this.em]) {cache[this.em] = {}}
! 183: if (!cache[this.em][s]) {
! 184: var bbox = this.BBoxFor(s);
! 185: cache[this.em][s] = {w: bbox.w/this.em, h: bbox.h/this.em};
! 186: }
! 187: return cache[this.em][s];
1.1 albertel 188: },
189:
190: /*
1.2 ! albertel 191: * For browsers that don't handle sizes of italics properly (MSIE).
! 192: * Check the cache first to see if we've already measured it.
1.1 albertel 193: */
194: EmBoxForItalics: function (s) {
1.2 ! albertel 195: var cache = jsMath.Global.cache.R;
! 196: if (!cache[this.em]) {cache[this.em] = {}}
! 197: if (!cache[this.em][s]) {
! 198: var bbox = this.BBoxFor(s);
! 199: if (s.match(/<i>|class=\"(icm|italic|igreek|iaccent)/i)) {
! 200: bbox.w = this.BBoxFor(s+jsMath.Browser.italicString).w
! 201: - jsMath.Browser.italicCorrection;
! 202: }
! 203: cache[this.em][s] = {w: bbox.w/this.em, h: bbox.h/this.em};
1.1 albertel 204: }
1.2 ! albertel 205: return cache[this.em][s];
1.1 albertel 206: },
207:
208: /*
209: * Initialize jsMath. This determines the em size, and a variety
210: * of other parameters used throughout jsMath.
211: */
212: Init: function () {
213: if (jsMath.Setup.inited != 1) {
1.2 ! albertel 214: if (!jsMath.Setup.inited) {jsMath.Setup.Body()}
! 215: if (jsMath.Setup.inited != 1) {
1.1 albertel 216: alert("It looks like jsMath failed to set up properly (error code "
217: + jsMath.Setup.inited + "). "
1.2 ! albertel 218: + "I will try to keep going, but it could get ugly.");
1.1 albertel 219: jsMath.Setup.inited = 1;
220: }
221: }
1.2 ! albertel 222: this.em = this.BBoxFor('<span style="'+jsMath.Browser.block+';width:13em;height:1em"></span>').w/13;
1.1 albertel 223: if (this.em == 0) {
224: // handle older browsers
1.2 ! albertel 225: this.em = this.BBoxFor('<img src="'+jsMath.blank+'" style="width:13em;height:1em"/>').w/13;
1.1 albertel 226: }
1.2 ! albertel 227: var cache = jsMath.Global.cache.B;
! 228: if (!cache[this.em]) {
! 229: cache[this.em] = {};
! 230: cache[this.em].bb = this.BBoxFor('x'); var hh = cache[this.em].bb.h;
! 231: cache[this.em].d = this.BBoxFor('x'+jsMath.HTML.Rule(1,hh/jsMath.em)).h - hh;
! 232: if (jsMath.Browser.italicString)
! 233: {cache[this.em].ic = jsMath.BBoxFor(jsMath.Browser.italicString).w}
! 234: }
! 235: jsMath.Browser.italicCorrection = cache[this.em].ic;
! 236: var bb = cache[this.em].bb; var h = bb.h; var d = cache[this.em].d
1.1 albertel 237: this.h = (h-d)/this.em; this.d = d/this.em;
238: this.hd = this.h + this.d;
239: this.xWidth = bb.w; // used to tell if scale has changed
240:
241: this.Setup.TeXfonts();
242:
243: var x_height = this.EmBoxFor('<span class="cmr10">M</span>').w/2;
244: this.TeX.M_height = x_height*(26/14);
245: this.TeX.h = this.h; this.TeX.d = this.d; this.TeX.hd = this.hd;
246:
247: this.Img.Scale();
248: if (!this.initialized) {
249: this.Setup.Sizes();
250: this.Img.UpdateFonts();
251: }
252:
253: // factor for \big and its brethren
254: this.p_height = (this.TeX.cmex10[0].h + this.TeX.cmex10[0].d) / .85;
255:
256: this.initialized = 1;
257: },
258:
259: /*
260: * Get the xWidth size and if it has changed, reinitialize the sizes
261: */
262: ReInit: function () {
263: var w = this.BBoxFor('x').w;
264: if (w != this.xWidth) {this.Init()}
265: },
266:
267: /*
268: * Mark jsMath as loaded and copy any user-provided overrides
269: */
270: Loaded: function () {
271: if (jsMath_old) {
272: var override = ['Process', 'ProcessBeforeShowing',
273: 'ConvertTeX','ConvertTeX2','ConvertLaTeX','ConvertCustom',
274: 'CustomSearch', 'Synchronize', 'Macro', 'document'];
275: for (var i = 0; i < override.length; i++) {
1.2 ! albertel 276: if (jsMath_old[override[i]]) {delete jsMath_old[override[i]]}
1.1 albertel 277: }
278: }
279: if (jsMath_old) {this.Insert(jsMath,jsMath_old)}
280: jsMath_old = null;
281: jsMath.loaded = 1;
282: },
283:
284: /*
285: * Manage JavaScript objects:
286: *
287: * Add: add/replace items in an object
288: * Insert: add items to an object
289: * Package: add items to an object prototype
290: */
291: Add: function (dst,src) {for (var id in src) {dst[id] = src[id]}},
292: Insert: function (dst,src) {
293: for (var id in src) {
294: if (dst[id] && typeof(src[id]) == 'object'
295: && (typeof(dst[id]) == 'object'
296: || typeof(dst[id]) == 'function')) {
297: this.Insert(dst[id],src[id]);
298: } else {
299: dst[id] = src[id];
300: }
301: }
302: },
303: Package: function (obj,def) {this.Insert(obj.prototype,def)}
304:
1.2 ! albertel 305: };
! 306:
! 307:
! 308: /***************************************************************************/
! 309:
! 310: /*
! 311: * Implements items associated with the global cache.
! 312: *
! 313: * This object will be replaced by a global version when
! 314: * (and if) jsMath-global.html is loaded.
! 315: */
! 316: jsMath.Global = {
! 317: isLocal: 1, // a local copy if jsMath-global.html hasn't been loaded
! 318: cache: {T: {}, D: {}, R: {}, B: {}},
! 319:
! 320: /*
! 321: * Clear the global (or local) cache
! 322: */
! 323: ClearCache: function () {jsMath.Global.cache = {T: {}, D: {}, R: {}, B: {}}},
! 324:
! 325: /*
! 326: * Initiate global mode
! 327: */
! 328: GoGlobal: function (cookie) {
! 329: var url = String(jsMath.window.location);
! 330: var c = (jsMath.window.location.protocol == 'mk:') ? '#' : '?';
! 331: if (cookie) {url = url.replace(/\?.*/,'') + '?' + cookie}
! 332: jsMath.Controls.Reload(jsMath.root + "jsMath-global.html" + c +escape(url));
! 333: },
! 334:
! 335: /*
! 336: * Check if we need to go to global mode
! 337: */
! 338: Init: function () {
! 339: if (jsMath.Controls.cookie.global == "always" && !jsMath.noGoGlobal) {
! 340: if (navigator.accentColorName) return; // OmniWeb craches on GoGlobal
! 341: if (!jsMath.window) {jsMath.window = window}
! 342: jsMath.Controls.loaded = 1;
! 343: jsMath.Controls.defaults.hiddenGlobal = null;
! 344: this.GoGlobal(jsMath.Controls.SetCookie(2));
! 345: }
! 346: },
! 347:
! 348: /*
! 349: * Try to register with a global.html window that contains us
! 350: */
! 351: Register: function () {
! 352: try {
! 353: this.Domain();
! 354: if (parent.jsMath && parent.jsMath.isGlobal)
! 355: {parent.jsMath.Register(jsMath.window)}
! 356: } catch (err) {}
! 357: },
! 358:
! 359: /*
! 360: * If we're not the parent window, try to set the domain to
! 361: * match the parent's domain (so we can use the Global data
! 362: * if the surrounding frame is a Global frame.
! 363: */
! 364: Domain: function () {
! 365: // MSIE/Mac can't do domain changes, so don't bother trying
! 366: if (navigator.appName == 'Microsoft Internet Explorer' &&
! 367: navigator.platform == 'MacPPC' && navigator.userProfile != null) return;
! 368: if (window == parent) return;
! 369: var oldDomain = jsMath.document.domain;
! 370: try {
! 371: while (true) {
! 372: try {if (parent.document.title != null) return} catch (err) {}
! 373: if (!document.domain.match(/\..*\./)) break;
! 374: jsMath.document.domain = jsMath.document.domain.replace(/^[^.]*\./,'');
! 375: }
! 376: } catch (err) {}
! 377: jsMath.document.domain = oldDomain;
! 378: }
! 379:
! 380: };
! 381:
! 382:
1.1 albertel 383:
384: /***************************************************************************/
385:
386: /*
387: *
388: * Implement loading of remote scripts using XMLHttpRequest, if
389: * possible, otherwise use a hidden IFRAME and fake it. That
390: * method runs asynchronously, which causes lots of headaches.
391: * Solve these using Push command, which queues actions
392: * until files have loaded.
393: */
394:
395: jsMath.Script = {
396:
397: request: null, // the XMLHttpRequest object
398:
399: /*
400: * Create the XMLHttpRequest object, if we can.
401: * Otherwise, use the iframe-based fallback method.
402: */
403: Init: function () {
404: if (!(jsMath.Controls.cookie.asynch && jsMath.Controls.cookie.progress)) {
405: if (window.XMLHttpRequest) {
406: this.request = new XMLHttpRequest;
407: } else if (window.ActiveXObject) {
408: try {this.request = new ActiveXObject("Microsoft.XMLHTTP")} catch (err) {}
409: }
410: }
411: //
412: // Use the delayed-script fallback for MSIE/Mac and old versions
413: // of several browsers (Opera 7.5, OmniWeb 4.5).
414: //
415: if (!this.request || jsMath.Setup.domainChanged)
416: {this.Load = this.delayedLoad; this.needsBody = 1}
417: },
418:
419: /*
420: * Load a script and evaluate it in the window's context
421: */
422: Load: function (url,show) {
423: if (show) {
424: jsMath.Message.Set("Loading "+url);
425: jsMath.Script.Delay(1);
426: jsMath.Script.Push(this,'xmlRequest',url);
427: jsMath.Script.Push(jsMath.Message,'Clear');
428: } else {
429: jsMath.Script.Push(this,'xmlRequest',url);
430: }
431: },
432:
433: /*
434: * Load a URL and run the contents of the file
435: */
436: xmlRequest: function (url) {
1.2 ! albertel 437: this.blocking = 1;
! 438: // this.debug('xmlRequest: '+url);
1.1 albertel 439: try {
440: this.request.open("GET",url,false);
441: this.request.send(null);
442: } catch (err) {
443: throw "jsMath can't load the file '"+url+"'\n"
444: + "Message: "+err.message;
445: }
446: if (this.request.status && this.request.status >= 400) {
447: // Do we need to deal with redirected links?
448: throw "jsMath can't load the file '"+url+"'\n"
449: + "Error status: "+this.request.status;
450: }
1.2 ! albertel 451: var tmpQueue = this.queue; this.queue = [];
! 452: // this.debug('xml Eval ['+tmpQueue.length+']');
1.1 albertel 453: jsMath.window.eval(this.request.responseText);
1.2 ! albertel 454: // this.debug('xml Done ['+this.queue.length+' + '+tmpQueue.length+']');
! 455: this.blocking = 0; this.queue = this.queue.concat(tmpQueue);
1.1 albertel 456: this.Process();
457: },
458:
459: /********************************************************************
460: *
461: * Implement asynchronous loading and execution of scripts
462: * (via hidden IFRAME) interleved with other JavaScript commands
463: * that must be synchronized with the file loading. (Basically, this
464: * is for MSIE/Mac and Opera 7.5, which don't have XMLHttpRequest.)
465: */
466:
467: cancelTimeout: 30*1000, // delay for canceling load (30 sec)
468:
469: iframe: null, // the hidden iframe
470: blocking: 0, // true when an asynchronous action is being performed
471: cancelTimer: null, // timer to cancel load if it takes too long
472: needsBody: 0, // true if loading files requires BODY to be present
473:
474: queue: [], // the stack of pending actions
475:
476: /*
477: * Provide mechanism for synchronizing with the asynchronous jsMath
478: * file-loading mechanism. 'code' can be a string or a function.
479: */
480: Synchronize: function (code,data) {
481: if (typeof(code) != 'string') {jsMath.Script.Push(null,code,data)}
482: else {jsMath.Script.Push(jsMath.window,'eval',code)}
483: },
484:
485: /*
486: * Queue a function to be processed.
487: * If nothing is being loaded, do the pending commands.
488: */
489: Push: function (object,method,data) {
1.2 ! albertel 490: // this.debug('Pushing: '+method+' at '+this.queue.length);
! 491: this.queue[this.queue.length] = [object,method,data];
1.1 albertel 492: if (!(this.blocking || (this.needsBody && !jsMath.document.body))) this.Process();
493: },
494:
495: /*
496: * Do any pending functions (stopping if a file load is started)
497: */
498: Process: function () {
499: while (this.queue.length && !this.blocking) {
1.2 ! albertel 500: var call = this.queue[0]; var tmpQueue = this.queue.slice(1); this.queue = [];
1.1 albertel 501: var object = call[0]; var method = call[1]; var data = call[2];
1.2 ! albertel 502: // this.debug('Calling: '+method+' ['+tmpQueue.length+']');
1.1 albertel 503: if (object) {object[method](data)} else if (method) {method(data)}
1.2 ! albertel 504: // this.debug('Done: '+method+' ['+this.queue.length+' + '+tmpQueue.length+']');
! 505: this.queue = this.queue.concat(tmpQueue);
1.1 albertel 506: }
507: },
508:
509: /*
510: * Handle loading of scripts that run asynchronously
511: */
512: delayedLoad: function (url) {
1.2 ! albertel 513: // this.debug('Loading: '+url);
1.1 albertel 514: this.Push(this,'startLoad',url);
515: },
516: startLoad: function (url) {
517: this.iframe = jsMath.document.createElement('iframe');
518: this.iframe.style.visibility = 'hidden';
519: this.iframe.style.position = 'absolute';
520: this.iframe.style.width = '0px';
521: this.iframe.style.height = '0px';
522: if (jsMath.document.body.firstChild) {
523: jsMath.document.body.insertBefore(this.iframe,jsMath.document.body.firstChild);
524: } else {
525: jsMath.document.body.appendChild(this.iframe);
526: }
527: this.blocking = 1; this.url = url;
528: if (!url.match(/\.js$/)) {this.iframe.src = url}
529: else {this.iframe.src = jsMath.root+"jsMath-loader.html"}
530: if (url.substr(0,jsMath.root.length) == jsMath.root)
531: {url = url.substr(jsMath.root.length)}
532: jsMath.Message.Set("Loading "+url);
533: this.cancelTimer = setTimeout('jsMath.Script.cancelLoad()',this.cancelTimeout);
534: },
535: endLoad: function (action) {
536: if (this.cancelTimer) {clearTimeout(this.cancelTimer); this.cancelTimer = null;}
537: jsMath.Message.Clear();
538: if (action != 'cancel') {this.blocking = 0; this.Process()}
539: },
1.2 ! albertel 540:
! 541: Start: function () {
! 542: // this.debug('Starting: ['+this.queue.length+'] '+this.url);
! 543: this.tmpQueue = this.queue; this.queue = [];
! 544: },
! 545: End: function () {
! 546: // this.debug('Ending: ['+this.queue.length+' + '+this.tmpQueue.length+'] '+this.url);
! 547: this.queue = this.queue.concat(this.tmpQueue); delete this.tmpQueue;
! 548: },
1.1 albertel 549:
550: /*
551: * If the loading takes too long, cancel it and end the load.
552: */
553: cancelLoad: function () {
554: this.cancelTimer = null;
555: jsMath.Message.Set("Can't load file");
556: this.endLoad("cancel");
557: },
558:
559: /*
560: * Perform a delay (to let the browser catch up)
561: */
562: Delay: function (time) {
563: this.blocking = 1;
564: setTimeout('jsMath.Script.endDelay()',time);
565: },
1.2 ! albertel 566: endDelay: function () {
! 567: // this.debug('endDelay');
! 568: this.blocking = 0;
! 569: this.Process();
! 570: },
1.1 albertel 571:
572: /*
573: * Load an image and wait for it
574: * (so MSIE won't load extra copies of it)
575: */
1.2 ! albertel 576: imageCount: 0,
1.1 albertel 577: WaitForImage: function (file) {
1.2 ! albertel 578: this.blocking = 1; this.imageCount++;
! 579: if (this.img == null) {this.img = []}
1.1 albertel 580: var img = new Image(); this.img[this.img.length] = img;
1.2 ! albertel 581: img.onload = function () {if (--jsMath.Script.imageCount == 0) jsMath.Script.endDelay()}
1.1 albertel 582: img.onerror = img.onload; img.onabort = img.onload;
583: img.src = file;
584: },
585:
586: /*
587: * The code uncompressor
588: */
589: Uncompress: function (data) {
590: for (var k = 0; k < data.length; k++) {
591: var d = data[k]; var n = d.length;
592: for (var i = 0; i < n; i++) {if (typeof(d[i]) == 'number') {d[i] = d[d[i]]}}
593: data[k] = d.join('');
594: }
595: window.eval(data.join(''));
1.2 ! albertel 596: }//,
1.1 albertel 597:
598: /*
599: * for debugging the event queue
600: */
1.2 ! albertel 601: // debug: function (message) {
1.1 albertel 602: // if (jsMath.document.body && jsMath.window.debug) {jsMath.window.debug(message)}
603: // else {alert(message)}
1.2 ! albertel 604: // }
1.1 albertel 605:
606: };
607:
608: /***************************************************************************/
609:
610: /*
611: * Message and screen blanking facility
612: */
613:
614: jsMath.Message = {
615:
616: blank: null, // the div to blank out the screen
617: message: null, // the div for the messages
618: text: null, // the text node for messages
619: clear: null, // timer for clearing message
620:
621: /*
622: * Create the elements needed for the message box
623: */
624: Init: function () {
625: if (!jsMath.document.body || !jsMath.Controls.cookie.progress) return;
626: if (jsMath.Setup.stylesReady) {
627: this.message = jsMath.Setup.DIV('message',{visibility:'hidden'});
628: } else {
629: this.message = jsMath.Setup.DIV('message',{
630: visibility:'hidden', position:'absolute', bottom:'1px', left:'2px',
631: backgroundColor:'#E6E6E6', border:'solid 1px #959595',
632: margin:'0px', padding:'1px 8px', zIndex:102,
633: color:'black', fontSize:'small', width:'auto'
634: });
635: }
636: this.text = jsMath.document.createTextNode('');
637: this.message.appendChild(this.text);
638: this.message.onmousedown = jsMath.Translate.Cancel;
639: },
640:
641: /*
642: * Set the contents of the message box, or use the window status line
643: */
644: Set: function (text,canCancel) {
645: if (this.clear) {clearTimeout(this.clear); this.clear = null}
646: if (jsMath.Controls.cookie.progress) {
647: if (!this.text) {this.Init(); if (!this.text) return}
648: if (jsMath.Browser.textNodeBug) {this.message.innerHTML = text}
649: else {this.text.nodeValue = text}
650: this.message.style.visibility = 'visible';
651: if (canCancel) {
652: this.message.style.cursor = 'pointer';
653: if (!this.message.style.cursor) {this.message.style.cursor = 'hand'}
654: this.message.title = ' Cancel Processing of Math ';
655: } else {
1.2 ! albertel 656: this.message.style.cursor = '';
1.1 albertel 657: this.message.title = '';
658: }
659: } else {
660: if (text.substr(0,8) != "Loading ") {jsMath.window.status = text}
661: }
662: },
663:
664: /*
665: * Clear the message box or status line
666: */
667: Clear: function () {
668: if (this.clear) {clearTimeout(this.clear)}
669: this.clear = setTimeout("jsMath.Message.doClear()",1000);
670: },
671: doClear: function () {
672: if (this.clear) {
673: this.clear = null;
674: jsMath.window.status = '';
675: if (this.text) {this.text.nodeValue = ''}
676: if (this.message) {this.message.style.visibility = 'hidden'}
677: }
678: },
679:
680:
681: /*
682: * Put up a DIV that covers the window so that the
683: * "flicker" of processing the mathematics will not be visible
684: */
685: Blank: function () {
686: if (this.blank || !jsMath.document.body) return;
687: this.blank = jsMath.Setup.DIV("blank",{
688: position:(jsMath.Browser.msiePositionFixedBug? 'absolute': 'fixed'),
689: top:'0px', left:'0px', bottom:'0px', right:'0px',
690: zIndex:101, backgroundColor:'white'
691: });
692: if (jsMath.Browser.msieBlankBug) {
693: this.blank.innerHTML = ' ';
694: this.blank.style.width = "110%";
695: this.blank.style.height = "110%";
696: }
697: },
698:
699: UnBlank: function () {
700: if (this.blank) {jsMath.document.body.removeChild(this.blank)}
701: this.blank = null;
702: }
703: };
704:
705:
706: /***************************************************************************/
707:
708: /*
709: * Miscellaneous setup and initialization
710: */
711: jsMath.Setup = {
712:
713: loaded: [], // array of files already loaded
714:
715: /*
716: * Insert a DIV at the top of the page with given ID,
717: * attributes, and style settings
718: */
719: DIV: function (id,styles) {
720: var div = jsMath.document.createElement('div');
721: div.id = 'jsMath_'+id;
722: for (var i in styles) {div.style[i]= styles[i]}
723: if (!jsMath.document.body.hasChildNodes) {jsMath.document.body.appendChild(div)}
724: else {jsMath.document.body.insertBefore(div,jsMath.document.body.firstChild)}
725: return div;
726: },
727:
728: /*
729: * Source a jsMath JavaScript file (only load any given file once)
730: */
731: Script: function (file,show) {
732: if (this.loaded[file]) {return} else {this.loaded[file] = 1}
1.2 ! albertel 733: if (!file.match('^([a-zA-Z]+:/?)?/')) {file = jsMath.root + file}
1.1 albertel 734: jsMath.Script.Load(file,show);
735: },
736:
737: /*
738: * Use a hidden <DIV> for measuring the BBoxes of things
739: */
740: Hidden: function () {
741: jsMath.hidden = this.DIV("Hidden",{
742: visibility: 'hidden', position:"absolute",
743: top:0, left:0, border:0, padding:0, margin:0
744: });
745: jsMath.hiddenTop = jsMath.hidden;
746: return;
747: },
748:
749: /*
750: * Find the root URL for the jsMath files (so we can load
751: * the other .js and .gif files)
752: */
753: Source: function () {
754: if (jsMath.Autoload && jsMath.Autoload.root) {
755: jsMath.root = jsMath.Autoload.root;
756: } else {
757: jsMath.root = '';
758: var script = jsMath.document.getElementsByTagName('script');
759: if (script) {
760: for (var i = 0; i < script.length; i++) {
761: var src = script[i].src;
762: if (src && src.match('(^|/)jsMath.js$')) {
763: jsMath.root = src.replace(/jsMath.js$/,'');
764: if (jsMath.root.charAt(0) == '/') {
765: jsMath.root = jsMath.document.location.protocol + '//'
766: + jsMath.document.location.host + jsMath.root;
767: } else if (!jsMath.root.match(/^[a-z]+:/i)) {
768: src = new String(jsMath.document.location);
769: jsMath.root = src.replace(new RegExp('[^/]*$'),'') + jsMath.root;
770: while (jsMath.root.match('/[^/]*/\\.\\./')) {
771: jsMath.root = jsMath.root.replace(new RegExp('/[^/]*/\\.\\./'),'/');
772: }
773: }
774: i = script.length;
775: }
776: }
777: }
778: }
779: jsMath.Img.root = jsMath.root + "fonts/";
780: jsMath.blank = jsMath.root + "blank.gif";
781: this.Domain();
782: },
783:
784: /*
785: * Find the most restricted common domain for the main
786: * page and jsMath. Report an error if jsMath is outside
787: * the domain of the calling page.
788: */
789: Domain: function () {
1.2 ! albertel 790: try {jsMath.document.domain} catch (err) {return}
1.1 albertel 791: var jsDomain = ''; var pageDomain = jsMath.document.domain;
792: if (jsMath.root.match('://([^/]*)/')) {jsDomain = RegExp.$1}
793: jsDomain = jsDomain.replace(/:\d+$/,'');
794: if (jsDomain == "" || jsDomain == pageDomain) return;
795: //
796: // MSIE on the Mac can't change jsMath.document.domain and 'try' won't
797: // catch the error (Grrr!), so exit for them.
798: //
799: if (navigator.appName == 'Microsoft Internet Explorer' &&
800: navigator.platform == 'MacPPC' && navigator.onLine &&
801: navigator.userProfile && jsMath.document.all) return;
802: jsDomain = jsDomain.split(/\./); pageDomain = pageDomain.split(/\./);
803: if (jsDomain.length < 2 || pageDomain.length < 2 ||
804: jsDomain[jsDomain.length-1] != pageDomain[pageDomain.length-1] ||
805: jsDomain[jsDomain.length-2] != pageDomain[pageDomain.length-2]) {
806: this.DomainWarning();
807: return;
808: }
809: var domain = jsDomain[jsDomain.length-2] + '.' + jsDomain[jsDomain.length-1];
810: for (var i = 3; i <= jsDomain.length && i <= pageDomain.length; i++) {
811: if (jsDomain[jsDomain.length-i] != pageDomain[pageDomain.length-i]) break;
812: domain = jsDomain[jsDomain.length-i] + '.' + domain;
813: }
814: jsMath.document.domain = domain;
815: this.domainChanged = 1;
816: },
817:
818: DomainWarning: function () {
819: alert("In order for jsMath to be able to load the additional "
820: + "components that it may need, the jsMath.js file must be "
821: + "loaded from a server in the same domain as the page that "
822: + "contains it. Because that is not the case for this page, "
823: + "the mathematics displayed here may not appear correctly.");
824: },
825:
826: /*
827: * Initialize a font's encoding array
828: */
829: EncodeFont: function (name) {
830: var font = jsMath.TeX[name];
831: if (font[0].c != null) return;
832: for (var k = 0; k < 128; k++) {
833: var data = font[k]; font[k] = data[3];
834: if (font[k] == null) {font[k] = {}};
835: font[k].w = data[0]; font[k].h = data[1];
836: if (data[2] != null) {font[k].d = data[2]}
837: font[k].c = jsMath.TeX.encoding[k];
838: }
839: },
840:
841: /*
842: * Initialize the encodings for all fonts
843: */
844: Fonts: function () {
845: for (var i = 0; i < jsMath.TeX.fam.length; i++) {
846: var name = jsMath.TeX.fam[i];
847: if (name) {this.EncodeFont(name)}
848: }
849: },
850:
851: /*
852: * Look up the default height and depth for a TeX font
853: * and set the skewchar
854: */
855: TeXfont: function (name) {
856: var font = jsMath.TeX[name]; if (font == null) return;
857: var WH = jsMath.EmBoxFor('<span class="'+name+'">'+font[65].c+'</span>');
858: font.hd = WH.h; font.dh = .05;
859: font.d = jsMath.EmBoxFor('<span class="'+name+'">'+ font[65].c +
860: jsMath.HTML.Rule(1,font.hd) + '</span>').h - font.hd;
861: font.h = font.hd - font.d;
862: if (name == 'cmmi10') {font.skewchar = 0177}
863: else if (name == 'cmsy10') {font.skewchar = 060}
864: },
865:
866: /*
867: * Init all the TeX fonts
868: */
869: TeXfonts: function () {
870: for (var i = 0; i < jsMath.TeX.fam.length; i++)
871: {if (jsMath.TeX.fam[i]) {this.TeXfont(jsMath.TeX.fam[i])}}
872: },
873:
874: /*
875: * Compute font parameters for various sizes
876: */
877: Sizes: function () {
878: jsMath.TeXparams = [];
879: for (var j=0; j < jsMath.sizes.length; j++) {jsMath.TeXparams[j] = {}}
880: for (var i in jsMath.TeX) {
881: if (typeof(jsMath.TeX[i]) != 'object') {
882: for (var j=0; j < jsMath.sizes.length; j++) {
883: jsMath.TeXparams[j][i] = jsMath.sizes[j]*jsMath.TeX[i]/100;
884: }
885: }
886: }
887: },
888:
889: /*
890: * Send the style definitions to the browser (these may be adjusted
891: * by the browser-specific code)
892: */
893: Styles: function (styles) {
894: if (!styles) {
895: styles = jsMath.styles;
896: styles['.typeset .scale'] = 'font-size:'+jsMath.Controls.cookie.scale+'%';
897: this.stylesReady = 1;
898: }
899: jsMath.Script.Push(this,'AddStyleSheet',styles);
900: if (jsMath.Browser.styleChangeDelay) {jsMath.Script.Push(jsMath.Script,'Delay',1)}
901: },
902:
903: AddStyleSheet: function (styles) {
904: var head = jsMath.document.getElementsByTagName('head')[0];
905: var string = ''; for (var id in styles) {string += id + ' {'+styles[id]+"}\n"}
906: if (jsMath.document.createStyleSheet) {// check for MSIE
907: head.insertAdjacentHTML('beforeEnd',
1.2 ! albertel 908: '<span style="display:none">x</span>' // MSIE needs this for some reason
! 909: + '<style type="text/css">'+string+'</style>');
1.1 albertel 910: } else {
911: var style = jsMath.document.createElement('style'); style.type = "text/css";
912: style.appendChild(jsMath.document.createTextNode(string));
913: head.appendChild(style);
914: }
915: },
916:
917: /*
918: * Do the initialization that requires the <body> to be in place.
919: */
920: Body: function () {
921: if (this.inited) return;
922:
923: this.inited = -1;
924:
925: jsMath.Setup.Hidden(); this.inited = -2;
926: jsMath.Browser.Init(); this.inited = -3;
927:
928: // blank screen if necessary
929: if (jsMath.Controls.cookie.blank) {jsMath.Message.Blank()}; this.inited = -4;
930:
931: jsMath.Setup.Styles(); this.inited = -5;
932: jsMath.Controls.Init(); this.inited = -6;
933:
934: // do user-specific initialization
935: jsMath.Script.Push(jsMath.Setup,'User','pre-font'); this.inited = -7;
936:
937: // make sure browser-specific loads are done before this
938: jsMath.Script.Push(jsMath.Font,'Check');
1.2 ! albertel 939: if (jsMath.Font.register.length)
! 940: {jsMath.Script.Push(jsMath.Font,'LoadRegistered')}
1.1 albertel 941:
942: this.inited = 1;
943: },
944:
945: /*
946: * Web page author can override this to do initialization
947: * that must be done before the font check is performed, or
948: * at other times (as indicated by the value of the parameter).
949: */
950: User: function (when) {}
951:
952: };
953:
954: jsMath.Update = {
955:
956: /*
957: * Update specific parameters for a limited number of font entries
958: */
959: TeXfonts: function (change) {
960: for (var font in change) {
961: for (var code in change[font]) {
962: for (var id in change[font][code]) {
963: jsMath.TeX[font][code][id] = change[font][code][id];
964: }
965: }
966: }
967: },
968:
969: /*
970: * Update the character code for every character in a list
971: * of fonts
972: */
973: TeXfontCodes: function (change) {
974: for (var font in change) {
975: for (var i = 0; i < change[font].length; i++) {
976: jsMath.TeX[font][i].c = change[font][i];
977: }
978: }
979: }
980:
981: };
982:
983: /***************************************************************************/
984:
985: /*
986: * Implement browser-specific checks
987: */
988:
989: jsMath.Browser = {
990:
991: allowAbsolute: 1, // tells if browser can nest absolutely positioned
992: // SPANs inside relative SPANs
993: allowAbsoluteDelim: 0, // OK to use absolute placement for building delims?
994: separateSkips: 0, // MSIE doesn't do negative left margins, and
995: // Netscape doesn't combine skips well
996:
997: valignBug: 0, // Konqueror doesn't nest vertical-align
998: operaHiddenFix: '', // for Opera to fix bug with math in tables
999: msieCenterBugFix: '', // for MSIE centering bug with image fonts
1000: msieInlineBlockFix: '', // for MSIE alignment bug in non-quirks mode
1.2 ! albertel 1001: msieSpaceFix: '', // for MSIE to avoid dropping empty spans
1.1 albertel 1002: imgScale: 1, // MSI scales images for 120dpi screens, so compensate
1003:
1004: renameOK: 1, // tells if brower will find a tag whose name
1005: // has been set via setAttributes
1006: styleChangeDelay: 0, // true if style changes need a delay in order
1007: // for them to be available
1008:
1009: delay: 1, // delay for asynchronous math processing
1010:
1011: version: 0, // browser version number (when needed)
1012:
1013: /*
1014: * Determine if the "top" of a <SPAN> is always at the same height
1015: * or varies with the height of the rest of the line (MSIE).
1016: */
1017: TestSpanHeight: function () {
1018: jsMath.hidden.innerHTML = '<span><span style="'+this.block+';height:2em;width:1px"></span></span>';
1019: var span = jsMath.hidden.firstChild;
1020: var img = span.firstChild;
1021: this.spanHeightVaries = (span.offsetHeight >= img.offsetHeight && span.offsetHeight > 0);
1022: this.spanHeightTooBig = (span.offsetHeight > img.offsetHeight);
1023: jsMath.hidden.innerHTML = '';
1024: },
1025:
1026: /*
1027: * Determine if an inline-block with 0 width is OK or not
1028: * and decide whether to use spans or images for spacing
1029: */
1030: TestInlineBlock: function () {
1.2 ! albertel 1031: this.block = "display:-moz-inline-box";
1.1 albertel 1032: this.hasInlineBlock = jsMath.BBoxFor('<span style="'+this.block+';width:10px;height:5px"></span>').w > 0;
1.2 ! albertel 1033: if (this.hasInlineBlock) {
! 1034: jsMath.styles['.typeset .blank'] = jsMath.styles['.typeset .blank'].replace(/display:inline-block/,this.block);
! 1035: jsMath.styles['.typeset .spacer'] = jsMath.styles['.typeset .spacer'].replace(/display:inline-block/,'');
! 1036: } else {
! 1037: this.block = "display:inline-block";
1.1 albertel 1038: this.hasInlineBlock = jsMath.BBoxFor('<span style="'+this.block+';width:10px;height:5px"></span>').w > 0;
1039: if (!this.hasInlineBlock) return;
1040: }
1041: this.block += ';overflow:hidden';
1042: var h = jsMath.BBoxFor('x').h;
1043: this.mozInlineBlockBug = jsMath.BBoxFor(
1044: '<span style="'+this.block+';height:'+h+'px;width:1px"></span>x'+
1045: '<span style="'+this.block+';height:'+h+'px;width:1px;vertical-align:-'+h+'px"></span>').h > 2*h;
1046: this.widthAddsBorder = jsMath.BBoxFor('<span style="'+this.block+
1047: ';overflow:hidden;height:1px;width:10px;border-left:10px solid"></span>').w > 10;
1048: this.msieBorderBug =
1049: jsMath.BBoxFor('<span style="'+this.block+';height:'+h+'px;width:1px"></span>x').h !=
1050: jsMath.BBoxFor('<span style="'+this.block+';height:'+h+'px;width:1px;border-left:1px solid"></span>x').h;
1051: this.blankWidthBug = this.msieBorderBug ||
1052: jsMath.BBoxFor('<span style="'+this.block+';height:2em;width:0px"></span>').h == 0;
1053: },
1054:
1055: /*
1056: * Determine if the NAME attribute of a tag can be changed
1057: * using the setAttribute function, and then be properly
1058: * returned by getElementByName.
1059: */
1060: TestRenameOK: function () {
1061: jsMath.hidden.innerHTML = '<span></span>';
1062: var test = jsMath.hidden.firstChild;
1063: test.setAttribute('name','jsMath_test');
1064: this.renameOK = (jsMath.document.getElementsByName('jsMath_test').length > 0);
1065: jsMath.hidden.innerHTML = '';
1066: },
1067:
1068: /*
1069: * See if style changes occur immediately, or if we need to delay
1070: * in order to let them take effect.
1071: */
1072: TestStyleChange: function () {
1073: jsMath.hidden.innerHTML = '<span ID="jsMath_test">x</span>';
1074: var span = jsMath.hidden.firstChild;
1075: var w = span.offsetWidth;
1076: jsMath.Setup.AddStyleSheet({'#jsMath_test': 'font-size:200%'});
1077: this.styleChangeDelay = (span.offsetWidth == w);
1078: jsMath.hidden.innerHTML = '';
1079: },
1080:
1081: /*
1082: * Perform a version check on a standard version string
1083: */
1084: VersionAtLeast: function (v) {
1085: var bv = new String(this.version).split('.');
1086: v = new String(v).split('.'); if (v[1] == null) {v[1] = '0'}
1087: return bv[0] > v[0] || (bv[0] == v[0] && bv[1] >= v[1]);
1088: },
1089:
1090: /*
1091: * Test for browser characteristics, and adjust things
1092: * to overcome specific browser bugs
1093: */
1094: Init: function () {
1095: jsMath.browser = 'unknown';
1096: this.TestInlineBlock();
1097: this.TestSpanHeight();
1098: this.TestRenameOK();
1099: this.TestStyleChange();
1100:
1101: this.MSIE();
1102: this.Mozilla();
1103: this.Opera();
1104: this.OmniWeb();
1105: this.Safari();
1106: this.Konqueror();
1107:
1108: //
1109: // Change some routines depending on the browser
1110: //
1111: if (this.allowAbsoluteDelim) {
1112: jsMath.Box.DelimExtend = jsMath.Box.DelimExtendAbsolute;
1113: jsMath.Box.Layout = jsMath.Box.LayoutAbsolute;
1114: } else {
1115: jsMath.Box.DelimExtend = jsMath.Box.DelimExtendRelative;
1116: jsMath.Box.Layout = jsMath.Box.LayoutRelative;
1117: }
1118:
1119: if (this.separateSkips) {
1120: jsMath.HTML.Place = jsMath.HTML.PlaceSeparateSkips;
1121: jsMath.Typeset.prototype.Place = jsMath.Typeset.prototype.PlaceSeparateSkips;
1122: }
1123: },
1124:
1125: //
1126: // Handle bug-filled Internet Explorer
1127: //
1128: MSIE: function () {
1129: if (this.spanHeightVaries && !this.spanHeightTooBig) {
1130: jsMath.browser = 'MSIE';
1131: if (navigator.platform == 'Win32') {
1132: this.allowAbsoluteDelim = 1; this.separateSkips = 1;
1133: this.buttonCheck = 1; this.msieBlankBug = 1;
1134: this.msieDivWidthBug = 1; this.msiePositionFixedBug = 1;
1135: this.msieIntegralBug = 1; this.waitForImages = 1;
1136: this.msieAlphaBug = 1; this.alphaPrintBug = 1;
1137: this.msieCenterBugFix = 'position:relative; ';
1138: this.msieInlineBlockFix = ' display:inline-block;';
1.2 ! albertel 1139: this.msieSpaceFix = '<span style="display:inline-block"></span>';
1.1 albertel 1140: jsMath.Macro('joinrel','\\mathrel{\\kern-5mu}'),
1141: jsMath.styles['.typeset .arial'] = "font-family: 'Arial unicode MS'";
1142: // MSIE doesn't implement fixed positioning, so use absolute
1143: jsMath.styles['#jsMath_message'] =
1144: jsMath.styles['#jsMath_message'].replace(/position:fixed/,"position:absolute").replace(/width:auto/,"");
1145: jsMath.styles['#jsMath_panel'] =
1146: jsMath.styles['#jsMath_panel'].replace(/position:fixed/,"position:absolute").replace(/width:auto/,"");
1147: jsMath.styles['#jsMath_button'] = 'width:1px; '
1148: + jsMath.styles['#jsMath_button'].replace(/position:fixed/,"position:absolute").replace(/width:auto/,"");
1149: jsMath.window.onscroll = jsMath.Controls.MoveButton;
1150: // MSIE needs this NOT to be inline-block
1151: jsMath.styles['.typeset .spacer'] =
1152: jsMath.styles['.typeset .spacer'].replace(/display:inline-block/,'');
1153: // MSIE will rescale images if the DPIs differ
1154: if (screen.deviceXDPI && screen.logicalXDPI
1155: && screen.deviceXDPI != screen.logicalXDPI) {
1156: this.imgScale *= screen.logicalXDPI/screen.deviceXDPI;
1157: jsMath.Controls.cookie.alpha = 0;
1158: }
1159: // Handle bug with getting width of italic text
1160: this.italicString = '<i>x</i>';
1161: jsMath.EmBoxFor = jsMath.EmBoxForItalics;
1162: } else if (navigator.platform == 'MacPPC') {
1163: this.msieAbsoluteBug = 1; this.msieButtonBug = 1;
1164: this.msieDivWidthBug = 1; this.msieBlankBug = 1;
1165: jsMath.Setup.Script('jsMath-msie-mac.js');
1166: jsMath.Parser.prototype.macros.angle = ['Replace','ord','<font face="Symbol">‹</font>','normal'];
1.2 ! albertel 1167: jsMath.styles['#jsMath_panel'] = 'width:42em; ' + jsMath.styles['#jsMath_panel'].replace(/width:auto/,"");
! 1168: jsMath.Controls.cookie.printwarn = 0; // MSIE/Mac doesn't handle '@media screen'
1.1 albertel 1169: }
1170: jsMath.Macro('not','\\mathrel{\\rlap{\\kern3mu/}}');
1171: }
1172: },
1173:
1174: //
1175: // Handle Netscape/Mozilla (any flavor)
1176: //
1177: Mozilla: function () {
1178: if (jsMath.hidden.ATTRIBUTE_NODE) {
1179: jsMath.browser = 'Mozilla';
1180: if (navigator.platform == 'Win32') {this.alphaPrintBug = 1}
1.2 ! albertel 1181: this.allowAbsoluteDelim = 1;
! 1182: jsMath.styles['#jsMath_button'] = jsMath.styles['#jsMath_button'].replace(/cursor:hand/,'cursor:pointer');
! 1183: jsMath.styles['#jsMath_noFont .link'] = jsMath.styles['#jsMath_noFont .link'].replace(/cursor:hand/,'cursor:pointer');
1.1 albertel 1184: jsMath.Macro('not','\\mathrel{\\rlap{\\kern3mu/}}');
1185: if (navigator.vendor == 'Firefox') {
1.2 ! albertel 1186: this.version = navigator.vendorSub;
1.1 albertel 1187: } else if (navigator.userAgent.match(' Firefox/([0-9.]+)( |$)')) {
1.2 ! albertel 1188: this.version = RegExp.$1;
1.1 albertel 1189: }
1190: }
1191: },
1192:
1193: //
1194: // Handle OmniWeb
1195: //
1196: OmniWeb: function () {
1197: if (navigator.accentColorName) {
1198: jsMath.browser = 'OmniWeb';
1199: this.allowAbsolute = this.hasInlineBlock;
1200: this.allowAbsoluteDelim = this.allowAbsolute;
1.2 ! albertel 1201: this.valignBug = !this.allowAbsolute;
1.1 albertel 1202: this.buttonCheck = 1; this.textNodeBug = 1;
1.2 ! albertel 1203: jsMath.noChangeGlobal = 1; // OmniWeb craches on GoGlobal
1.1 albertel 1204: if (!this.hasInlineBlock) {jsMath.Setup.Script('jsMath-old-browsers.js')}
1205: }
1206: },
1207:
1208: //
1209: // Handle Opera
1210: //
1211: Opera: function () {
1212: if (this.spanHeightTooBig) {
1213: jsMath.browser = 'Opera';
1214: var isOld = navigator.userAgent.match("Opera 7");
1215: this.allowAbsolute = 0;
1216: this.delay = 10;
1217: this.operaHiddenFix = '[Processing]';
1218: if (isOld) {jsMath.Setup.Script('jsMath-old-browsers.js')}
1219: }
1220: },
1221:
1222: //
1223: // Handle Safari
1224: //
1225: Safari: function () {
1226: if (navigator.appVersion.match(/Safari\//)) {
1227: jsMath.browser = 'Safari';
1228: var version = navigator.userAgent.match("Safari/([0-9]+)");
1229: version = (version)? version[1] : 400;
1.2 ! albertel 1230: for (var i = 0; i < jsMath.TeX.fam.length; i++) {
! 1231: if (jsMath.TeX.fam[i] && jsMath.TeX[jsMath.TeX.fam[i]])
! 1232: {jsMath.TeX[jsMath.TeX.fam[i]].dh = .1}
! 1233: }
1.1 albertel 1234: jsMath.TeX.axis_height += .05;
1.2 ! albertel 1235: jsMath.TeX.default_rule_thickness += .025;
1.1 albertel 1236: this.allowAbsoluteDelim = version >= 125;
1237: this.safariIFRAMEbug = version >= 312 && version < 412;
1.2 ! albertel 1238: this.safariButtonBug = version < 412;
1.1 albertel 1239: this.safariImgBug = 1; this.textNodeBug = 1;
1240: this.buttonCheck = 1;
1241: this.styleChangeDelay = 1;
1242: }
1243: },
1244:
1245: //
1246: // Handle Konqueror
1247: //
1248: Konqueror: function () {
1249: if (navigator.product && navigator.product.match("Konqueror")) {
1250: jsMath.browser = 'Konqueror';
1251: this.allowAbsolute = 0;
1252: this.allowAbsoluteDelim = 0;
1253: if (navigator.userAgent.match(/Konqueror\/(\d+)\.(\d+)/)) {
1254: if (RegExp.$1 < 3 || (RegExp.$1 == 3 && RegExp.$2 < 3)) {
1255: this.separateSkips = 1;
1256: this.valignBug = 1;
1257: jsMath.Setup.Script('jsMath-old-browsers.js');
1258: }
1259: }
1260: }
1261: }
1262:
1263: };
1264:
1265: /***************************************************************************/
1266:
1267: /*
1268: * Implement font check and messages
1269: */
1270: jsMath.Font = {
1271:
1272: fallback: "symbol", // the default fallback method
1.2 ! albertel 1273: register: [], // list of fonts registered before jsMath.Init()
1.1 albertel 1274:
1275: // the HTML for the missing font message
1276: message:
1277: '<b>No jsMath TeX fonts found</b> -- using image fonts instead.<br/>\n'
1278: + 'These may be slow and might not print well.<br/>\n'
1279: + 'Use the jsMath control panel to get additional information.',
1280:
1281: extra_message:
1282: 'Extra TeX fonts not found: <b><span id="jsMath_ExtraFonts"></span></b><br/>'
1283: + 'Using image fonts instead. This may be slow and might not print well.<br/>\n'
1284: + 'Use the jsMath control panel to get additional information.',
1.2 ! albertel 1285:
! 1286: print_message:
! 1287: 'To print higher-resolution math symbols, click the<br/>\n'
! 1288: + '<b>Hi-res Fonts for Printing</b> button on the jsMath control panel.<br/>\n',
! 1289:
! 1290: alpha_message:
! 1291: 'If the math symbols print as black boxes, turn off <b>image alpha channels</b><br/>\n'
! 1292: + 'using the <B>Options</B> pane of the jsMath control panel.<br/>\n',
1.1 albertel 1293:
1294: /*
1295: * Look to see if a font is found.
1296: * Check the character in a given position, and see if it is
1297: * wider than the usual one in that position.
1298: */
1299: Test1: function (name,n,factor,prefix) {
1300: if (n == null) {n = 0x7C}; if (factor == null) {factor = 2}; if (prefix == null) {prefix = ''}
1301: var wh1 = jsMath.BBoxFor('<span style="font-family: '+prefix+name+', serif">'+jsMath.TeX[name][n].c+'</span>');
1302: var wh2 = jsMath.BBoxFor('<span style="font-family: serif">'+jsMath.TeX[name][n].c+'</span>');
1303: //alert([wh1.w,wh2.w,wh1.h,factor*wh2.w]);
1304: return (wh1.w > factor*wh2.w && wh1.h != 0);
1305: },
1306:
1307: Test2: function (name,n,factor,prefix) {
1308: if (n == null) {n = 0x7C}; if (factor == null) {factor = 2}; if (prefix == null) {prefix = ''}
1309: var wh1 = jsMath.BBoxFor('<span style="font-family: '+prefix+name+', serif">'+jsMath.TeX[name][n].c+'</span>');
1310: var wh2 = jsMath.BBoxFor('<span style="font-family: serif">'+jsMath.TeX[name][n].c+'</span>');
1311: //alert([wh2.w,wh1.w,wh1.h,factor*wh1.w]);
1312: return (wh2.w > factor*wh1.w && wh1.h != 0);
1313: },
1314:
1315: /*
1316: * Check for the new jsMath versions of the fonts (blacker with
1317: * different encoding) and if not found, look for old-style fonts.
1318: * If they are found, load the BaKoMa encoding information.
1319: */
1320: CheckTeX: function () {
1321: var wh = jsMath.BBoxFor('<span style="font-family: jsMath-cmex10, serif">'+jsMath.TeX.cmex10[1].c+'</span>');
1322: jsMath.nofonts = ((wh.w*3 > wh.h || wh.h == 0) && !this.Test1('cmr10',null,null,'jsMath-'));
1323: if (jsMath.nofonts && (navigator.platform != "MacPPC" ||
1324: jsMath.browser != 'Mozilla' || !jsMath.Browser.VersionAtLeast(1.5))) {
1325: wh = jsMath.BBoxFor('<span style="font-family: cmex10, serif">'+jsMath.TeX.cmex10[1].c+'</span>');
1326: jsMath.nofonts = ((wh.w*3 > wh.h || wh.h == 0) && !this.Test1('cmr10'));
1327: if (!jsMath.nofonts) {jsMath.Setup.Script("jsMath-BaKoMa-fonts.js")}
1328: }
1329: },
1330:
1331: /*
1332: * Check for the availability of TeX fonts. We do this by looking at
1333: * the width and height of a character in the cmex10 font. The cmex10
1334: * font has depth considerably greater than most characters' widths (the
1335: * whole font has the depth of the character with greatest depth). This
1336: * is not the case for most fonts, so if we can access cmex10, the
1337: * height of a character should be much bigger than the width.
1338: * Otherwise, if we don't have cmex10, we'll get a character in another
1339: * font with normal height and width. In this case, we insert a message
1340: * pointing the user to the jsMath site, and load one of the fallback
1341: * definitions.
1342: *
1343: */
1344: Check: function () {
1345: var cookie = jsMath.Controls.cookie;
1346: this.CheckTeX();
1347: if (jsMath.nofonts) {
1348: if (cookie.autofont || cookie.font == 'tex') {
1349: cookie.font = this.fallback;
1350: if (cookie.warn) {
1351: jsMath.nofontMessage = 1;
1352: cookie.warn = 0; jsMath.Controls.SetCookie(0);
1353: if (jsMath.window.NoFontMessage) {jsMath.window.NoFontMessage()}
1354: else {this.Message(this.message)}
1355: }
1356: }
1357: } else {
1358: if (cookie.autofont) {cookie.font = 'tex'}
1359: if (cookie.font == 'tex') return;
1360: }
1361: if (jsMath.noImgFonts) {cookie.font = 'unicode'}
1362: if (cookie.font == 'unicode') {
1363: var platform = ({Win32: 'pc', MacPPC: 'mac'})[navigator.platform] || 'unix';
1364: jsMath.Setup.Script('jsMath-fallback-'+platform+'.js');
1365: jsMath.Box.TeXnonfallback = jsMath.Box.TeX;
1366: jsMath.Box.TeX = jsMath.Box.TeXfallback;
1367: return;
1368: }
1.2 ! albertel 1369: if (!cookie.print && cookie.printwarn) {
! 1370: this.PrintMessage(
! 1371: (jsMath.Browser.alphaPrintBug && jsMath.Controls.cookie.alpha) ?
! 1372: this.print_message + this.alpha_message : this.print_message);
! 1373: }
1.1 albertel 1374: if (jsMath.Browser.waitForImages) {
1375: jsMath.Script.Push(jsMath.Script,"WaitForImage",jsMath.blank);
1376: }
1377: if (cookie.font == 'symbol') {
1378: jsMath.Setup.Script('jsMath-fallback-symbols.js');
1379: jsMath.Box.TeXnonfallback = jsMath.Box.TeX;
1380: jsMath.Box.TeX = jsMath.Box.TeXfallback;
1381: return;
1382: }
1383: jsMath.Img.SetFont({
1384: cmr10: ['all'], cmmi10: ['all'], cmsy10: ['all'],
1385: cmex10: ['all'], cmbx10: ['all'], cmti10: ['all']
1386: });
1387: jsMath.Img.LoadFont('cm-fonts');
1388: },
1389:
1390: /*
1391: * The message for when no TeX fonts. You can eliminate this message
1392: * by including
1393: *
1394: * <script>jsMath = {Font: {Message: function () {}}}</script>
1395: *
1396: * in your HTML file, before loading jsMath.js, if you want. But this
1397: * means the user may not know that he or she can get a better version
1398: * of your page.
1399: */
1400: Message: function (message) {
1.2 ! albertel 1401: if (jsMath.Element("Warning")) return;
1.1 albertel 1402: var div = jsMath.Setup.DIV("Warning",{});
1403: div.innerHTML =
1404: '<center><table><tr><td>'
1.2 ! albertel 1405: + '<div id="jsMath_noFont"><div class="message">' + message
1.1 albertel 1406: + '<div style="text-align:left"><span style="float:left; margin: 8px 0px 0px 20px">'
1407: + '<span onclick="jsMath.Controls.Panel()" title=" Open the jsMath Control Panel " class="link">jsMath Control Panel</span>'
1408: + '</span><span style="margin: 8px 20px 0px 0px; float:right">'
1409: + '<span onclick="jsMath.Font.HideMessage()" title=" Remove this font warning message " class="link">Hide this Message</span>'
1.2 ! albertel 1410: + '</span></div><div style="height:6px"></div><br clear="all"/></div></div>'
1.1 albertel 1411: + '<div style="width:22em; height:1px"></div>'
1412: + '</td></tr></table></center><hr/>';
1413: },
1414:
1415: HideMessage: function () {
1416: var message = jsMath.Element("Warning");
1417: if (message) {message.style.display = "none"}
1418: },
1419:
1.2 ! albertel 1420: PrintMessage: function (message) {
! 1421: if (jsMath.Element("PrintWarning")) return;
! 1422: var div = jsMath.Setup.DIV("PrintWarning",{});
! 1423: div.innerHTML =
! 1424: '<center><table><tr><td>'
! 1425: + '<div class="message">' + message + '</div>'
! 1426: + '<div style="width:22em; height:1px"></div>'
! 1427: + '</td></tr></table></center><hr/>';
! 1428: },
! 1429:
1.1 albertel 1430: /*
1431: * Register an extra font so jsMath knows about it
1432: */
1.2 ! albertel 1433: Register: function (data,force) {
1.1 albertel 1434: if (typeof(data) == 'string') {data = {name: data}}
1.2 ! albertel 1435: if (!jsMath.Setup.inited && !force) {
! 1436: this.register[this.register.length] = data;
! 1437: return;
! 1438: }
1.1 albertel 1439: var fontname = data.name; var name = fontname.replace(/10$/,'');
1440: var fontfam = jsMath.TeX.fam.length;
1441: if (data.prefix == null) {data.prefix = ""}
1442: if (!data.style) {data.style = "font-family: "+data.prefix+fontname+", serif"}
1443: if (!data.styles) {data.styles = {}}
1444: if (!data.macros) {data.macros = {}}
1445: /*
1446: * Register font family
1447: */
1448: jsMath.TeX.fam[fontfam] = fontname;
1449: jsMath.TeX.famName[fontname] = fontfam;
1450: data.macros[name] = ['HandleFont',fontfam];
1451: jsMath.Add(jsMath.Parser.prototype.macros,data.macros);
1452: /*
1453: * Set up styles
1454: */
1455: data.styles['.typeset .'+fontname] = data.style;
1456: jsMath.Setup.Styles(data.styles);
1.2 ! albertel 1457: if (jsMath.initialized) {jsMath.Script.Push(jsMath.Setup,'TeXfont',fontname)}
1.1 albertel 1458: /*
1459: * Check for font and give message if missing
1460: */
1461: var hasTeXfont = !jsMath.nofonts &&
1462: data.test(fontname,data.testChar,data.testFactor,data.prefix);
1463: if (hasTeXfont && jsMath.Controls.cookie.font == 'tex') {
1464: if (data.tex) {data.tex(fontname,fontfam,data)}
1465: return;
1466: }
1467: if (!hasTeXfont && jsMath.Controls.cookie.warn &&
1468: jsMath.Controls.cookie.font == 'tex' && !jsMath.nofonts) {
1469: if (!jsMath.Element("Warning")) this.Message(this.extra_message);
1470: var extra = jsMath.Element("ExtraFonts");
1471: if (extra) {
1472: if (extra.innerHTML != "") {extra.innerHTML += ','}
1473: extra.innerHTML += " " + data.prefix+fontname;
1474: }
1475: }
1476: if (jsMath.Controls.cookie.font == 'unicode') {
1477: if (data.fallback) {data.fallback(fontname,fontfam,data)}
1478: return;
1479: }
1480: // Image fonts
1481: var font = {}; font[fontname] = ['all'];
1482: jsMath.Img.SetFont(font);
1483: jsMath.Img.LoadFont(fontname);
1.2 ! albertel 1484: if (jsMath.initialized) {
! 1485: jsMath.Script.Push(jsMath.Img,'Scale');
! 1486: jsMath.Script.Push(jsMath.Img,'UpdateFonts');
! 1487: }
! 1488: },
! 1489: /*
! 1490: * If fonts are registered before jsMath.Init() is called, jsMath.em
! 1491: * will not be available, so they need to be delayed.
! 1492: */
! 1493: LoadRegistered: function () {
! 1494: var i = 0;
! 1495: while (i < this.register.length) {this.Register(this.register[i++],1)}
! 1496: this.register = [];
1.1 albertel 1497: },
1498:
1499: /*
1500: * Load a font
1501: */
1502: Load: function (name) {jsMath.Setup.Script(this.URL(name))},
1503: URL: function (name) {return jsMath.Img.root+name+'/def.js'}
1504:
1505: };
1506:
1507: /***************************************************************************/
1508:
1509: /*
1510: * Implements the jsMath control panel.
1511: * Much of the code is in jsMath-controls.html, which is
1512: * loaded into a hidden IFRAME on demand
1513: */
1514: jsMath.Controls = {
1515:
1516: // Data stored in the jsMath cookie
1517: cookie: {
1518: scale: 100,
1519: font: 'tex', autofont: 1, scaleImg: 0, alpha: 1,
1.2 ! albertel 1520: warn: 1, printwarn: 1, stayhires: 0,
! 1521: button: 1, progress: 1, asynch: 0, blank: 0,
! 1522: print: 0, keep: '0D', global: 'auto', hiddenGlobal: 1
1.1 albertel 1523: },
1524:
1525: cookiePath: '/', // can also set cookieDomain
1.2 ! albertel 1526: noCookiePattern: /^(file|mk):$/, // pattern for handling cookies locally
1.1 albertel 1527:
1528:
1529: /*
1530: * Create the HTML needed for control panel
1531: */
1532: Init: function () {
1533: this.panel = jsMath.Setup.DIV("panel",{display:'none'});
1534: if (!jsMath.Browser.msieButtonBug) {this.Button()}
1535: else {setTimeout("jsMath.Controls.Button()",500)}
1536: },
1537:
1538: /*
1539: * Load the control panel
1540: */
1541: Panel: function () {
1542: jsMath.Translate.Cancel();
1543: if (this.loaded) {this.Main()}
1544: else {jsMath.Script.delayedLoad(jsMath.root+"jsMath-controls.html")}
1545: },
1546:
1547: /*
1548: * Create the control panel button
1549: */
1550: Button: function () {
1551: var button = jsMath.Setup.DIV("button",{});
1552: button.title = ' Open jsMath Control Panel ';
1.2 ! albertel 1553: button.innerHTML =
! 1554: '<span onclick="jsMath.Controls.Panel()">jsMath</span>';
! 1555: if (!jsMath.Global.isLocal && !jsMath.noShowGlobal) {
! 1556: button.innerHTML +=
! 1557: '<span id="jsMath_global" title=" Open jsMath Global Panel " '
! 1558: + 'onclick="jsMath.Global.Show(1)">Global </span>';
! 1559: }
! 1560: if (button.offsetWidth < 30) {button.style.width = "auto"}
1.1 albertel 1561: if (!this.cookie.button) {button.style.display = "none"}
1562: },
1563:
1564: /*
1565: * MSIE doesn't implement position:fixed, so redraw the button on scrolls.
1566: */
1567: MoveButton: function () {
1568: if (!this.button) {this.button = jsMath.Element("button")}
1569: this.button.style.visibility = "hidden";
1570: this.button.style.visibility = "visible";
1571: },
1572:
1573: /*
1574: * Get the cookie data from the browser
1575: * (for file: references, use url '?' syntax)
1576: */
1577: GetCookie: function () {
1.2 ! albertel 1578: // save the current cookie settings as the defaults
! 1579: if (this.defaults == null) {this.defaults = {}}
! 1580: jsMath.Add(this.defaults,this.cookie); this.userSet = {};
! 1581: // get the browser's cookie data
1.1 albertel 1582: var cookies = jsMath.document.cookie;
1.2 ! albertel 1583: if (jsMath.window.location.protocol.match(this.noCookiePattern)) {
! 1584: cookies = this.localGetCookie();
! 1585: this.isLocalCookie = 1;
! 1586: }
! 1587: if (cookies.match(/jsMath=([^;]+)/)) {
1.1 albertel 1588: var data = RegExp.$1.split(/,/);
1589: for (var i = 0; i < data.length; i++) {
1590: var x = data[i].match(/(.*):(.*)/);
1591: if (x[2].match(/^\d+$/)) {x[2] = 1*x[2]} // convert from string
1592: this.cookie[x[1]] = x[2];
1.2 ! albertel 1593: this.userSet[x[1]] = 1;
1.1 albertel 1594: }
1595: }
1596: },
1.2 ! albertel 1597: localGetCookie: function () {
! 1598: return unescape(jsMath.window.location.search.substr(1));
! 1599: },
1.1 albertel 1600:
1601: /*
1602: * Save the cookie data in the browser
1603: * (for file: urls, append data like CGI reference)
1604: */
1605: SetCookie: function (warn) {
1606: var cookie = [];
1.2 ! albertel 1607: for (var id in this.cookie) {
! 1608: if (this.defaults[id] == null || this.cookie[id] != this.defaults[id])
! 1609: {cookie[cookie.length] = id + ':' + this.cookie[id]}
! 1610: }
1.1 albertel 1611: cookie = cookie.join(',');
1.2 ! albertel 1612: if (this.isLocalCookie) {
! 1613: if (warn == 2) {return 'jsMath='+escape(cookie)}
! 1614: this.localSetCookie(cookie,warn);
1.1 albertel 1615: } else {
1.2 ! albertel 1616: if (cookie == '') {warn = 0}
1.1 albertel 1617: if (this.cookiePath) {cookie += '; path='+this.cookiePath}
1618: if (this.cookieDomain) {cookie += '; domain='+this.cookieDomain}
1619: if (this.cookie.keep != '0D') {
1620: var ms = {
1621: D: 1000*60*60*24,
1622: W: 1000*60*60*24*7,
1623: M: 1000*60*60*24*30,
1624: Y: 1000*60*60*24*365
1625: };
1626: var exp = new Date;
1627: exp.setTime(exp.getTime() +
1628: this.cookie.keep.substr(0,1) * ms[this.cookie.keep.substr(1,1)]);
1629: cookie += '; expires=' + exp.toGMTString();
1630: }
1.2 ! albertel 1631: if (cookie != '') {
! 1632: jsMath.document.cookie = 'jsMath='+cookie;
! 1633: var cookies = jsMath.document.cookie;
! 1634: if (warn && !cookies.match(/jsMath=/))
! 1635: {alert("Cookies must be enabled in order to save jsMath options")}
! 1636: }
1.1 albertel 1637: }
1.2 ! albertel 1638: return null;
! 1639: },
! 1640: localSetCookie: function (cookie,warn) {
! 1641: if (!warn) return;
! 1642: var href = String(jsMath.window.location).replace(/\?.*/,"");
! 1643: if (cookie != '') {href += '?jsMath=' + escape(cookie)}
! 1644: if (href != jsMath.window.location.href) {this.Reload(href)}
! 1645: },
! 1646:
! 1647: /*
! 1648: * Reload the page (with the given URL)
! 1649: */
! 1650: Reload: function (url) {
! 1651: if (!this.loaded) return;
! 1652: this.loaded = 0;
! 1653: jsMath.Global.ClearCache();
! 1654: if (url) {jsMath.window.location.replace(url)}
! 1655: else {jsMath.window.location.reload()}
1.1 albertel 1656: }
1.2 ! albertel 1657:
1.1 albertel 1658: };
1659:
1660: /***************************************************************************/
1661:
1662: /*
1663: * Implements the actions for clicking and double-clicking
1664: * on math formulas
1665: */
1666: jsMath.Click = {
1667:
1668: /*
1669: * Handle clicking on math to get control panel
1670: */
1671: CheckClick: function (event) {
1672: if (!event) {event = jsMath.window.event}
1673: if (event.altKey) jsMath.Controls.Panel();
1674: },
1675:
1676: /*
1677: * Handle double-click for seeing TeX code
1678: */
1679:
1680: CheckDblClick: function (event) {
1681: if (!event) {event = jsMath.window.event}
1682: if (!jsMath.Click.DblClick) {
1683: jsMath.Extension.Require('double-click',1);
1684: // Firefox clears the event, so copy it
1685: var tmpEvent = event; event = {};
1686: for (var id in tmpEvent) {event[id] = tmpEvent[id]}
1687: }
1688: jsMath.Script.Push(jsMath.Click,'DblClick',[event,this.alt]);
1689: }
1690:
1691: };
1692:
1693: /***************************************************************************/
1694:
1695: /*
1696: * The TeX font information
1697: */
1698: jsMath.TeX = {
1699:
1700: //
1701: // The TeX font parameters
1702: //
1703: thinmuskip: 3/18,
1704: medmuskip: 4/18,
1705: thickmuskip: 5/18,
1706:
1707: x_height: .430554,
1708: quad: 1,
1709: num1: .676508,
1710: num2: .393732,
1711: num3: .44373,
1712: denom1: .685951,
1713: denom2: .344841,
1714: sup1: .412892,
1715: sup2: .362892,
1716: sup3: .288888,
1717: sub1: .15,
1718: sub2: .247217,
1719: sup_drop: .386108,
1720: sub_drop: .05,
1721: delim1: 2.39,
1722: delim2: 1.0,
1723: axis_height: .25,
1.2 ! albertel 1724: default_rule_thickness: .06,
1.1 albertel 1725: big_op_spacing1: .111111,
1726: big_op_spacing2: .166666,
1727: big_op_spacing3: .2,
1728: big_op_spacing4: .6,
1729: big_op_spacing5: .1,
1730:
1731: integer: 6553.6, // conversion of em's to TeX internal integer
1732: scriptspace: .05,
1733: nulldelimiterspace: .12,
1734: delimiterfactor: 901,
1735: delimitershortfall: .5,
1736: scale: 1, // scaling factor for font dimensions
1737:
1738: // The TeX math atom types (see Appendix G of the TeXbook)
1739: atom: ['ord', 'op', 'bin', 'rel', 'open', 'close', 'punct', 'ord'],
1740:
1741: // The TeX font families
1742: fam: ['cmr10','cmmi10','cmsy10','cmex10','cmti10','','cmbx10',''],
1743: famName: {cmr10:0, cmmi10:1, cmsy10:2, cmex10:3, cmti10:4, cmbx10:6},
1744:
1745: // Encoding used by jsMath fonts
1746: encoding: [
1747: 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç',
1748: 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï',
1749:
1750: '°', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', '·',
1751: 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'µ', '¶', 'ß',
1752:
1753: 'ï', '!', '"', '#', '$', '%', '&', ''',
1754: '(', ')', '*', '+', ',', '-', '.', '/',
1755:
1756: '0', '1', '2', '3', '4', '5', '6', '7',
1757: '8', '9', ':', ';', '<', '=', '>', '?',
1758:
1759: '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
1760: 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
1761:
1762: 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
1763: 'X', 'Y', 'Z', '[', '\', ']', '^', '_',
1764:
1765: '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
1766: 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
1767:
1768: 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
1769: 'x', 'y', 'z', '{', '|', '}', '~', 'ÿ'
1770: ],
1771:
1772: /*
1773: * The following are the TeX font mappings and metrics. The metric
1774: * information comes directly from the TeX .tfm files. Browser-specific
1775: * adjustments are made to these tables in the Browser.Init() routine
1776: */
1777: cmr10: [
1778: [0.625,0.683], [0.833,0.683], [0.778,0.683], [0.694,0.683],
1779: [0.667,0.683], [0.75,0.683], [0.722,0.683], [0.778,0.683],
1780: [0.722,0.683], [0.778,0.683], [0.722,0.683],
1781: [0.583,0.694,0,{ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 14, '108': 15}}],
1782: [0.556,0.694], [0.556,0.694], [0.833,0.694], [0.833,0.694],
1783:
1784: [0.278,0.431], [0.306,0.431,0.194], [0.5,0.694], [0.5,0.694],
1785: [0.5,0.628], [0.5,0.694], [0.5,0.568], [0.75,0.694],
1786: [0.444,0,0.17], [0.5,0.694], [0.722,0.431], [0.778,0.431],
1787: [0.5,0.528,0.0972], [0.903,0.683], [1.01,0.683], [0.778,0.732,0.0486],
1788:
1789: [0.278,0.431,0,{krn: {'108': -0.278, '76': -0.319}}],
1790: [0.278,0.694,0,{lig: {'96': 60}}],
1791: [0.5,0.694], [0.833,0.694,0.194], [0.5,0.75,0.0556],
1792: [0.833,0.75,0.0556], [0.778,0.694],
1793: [0.278,0.694,0,{krn: {'63': 0.111, '33': 0.111}, lig: {'39': 34}}],
1794: [0.389,0.75,0.25], [0.389,0.75,0.25], [0.5,0.75],
1795: [0.778,0.583,0.0833], [0.278,0.106,0.194],
1796: [0.333,0.431,0,{lig: {'45': 123}}],
1797: [0.278,0.106], [0.5,0.75,0.25],
1798:
1799: [0.5,0.644], [0.5,0.644], [0.5,0.644], [0.5,0.644],
1800: [0.5,0.644], [0.5,0.644], [0.5,0.644], [0.5,0.644],
1801: [0.5,0.644], [0.5,0.644], [0.278,0.431], [0.278,0.431,0.194],
1802: [0.278,0.5,0.194], [0.778,0.367,-0.133], [0.472,0.5,0.194],
1803: [0.472,0.694,0,{lig: {'96': 62}}],
1804:
1805: [0.778,0.694],
1806: [0.75,0.683,0,{krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}}],
1807: [0.708,0.683], [0.722,0.683],
1808: [0.764,0.683,0,{krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}}],
1809: [0.681,0.683],
1810: [0.653,0.683,0,{krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}}],
1811: [0.785,0.683], [0.75,0.683], [0.361,0.683,0,{krn: {'73': 0.0278}}],
1812: [0.514,0.683],
1813: [0.778,0.683,0,{krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}}],
1814: [0.625,0.683,0,{krn: {'84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}}],
1815: [0.917,0.683], [0.75,0.683],
1816: [0.778,0.683,0,{krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}}],
1817:
1818: [0.681,0.683,0,{krn: {'65': -0.0833, '111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}}],
1819: [0.778,0.683,0.194],
1820: [0.736,0.683,0,{krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}}],
1821: [0.556,0.683],
1822: [0.722,0.683,0,{krn: {'121': -0.0278, '101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}}],
1823: [0.75,0.683],
1824: [0.75,0.683,0,{ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}}],
1825: [1.03,0.683,0,{ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}}],
1826: [0.75,0.683,0,{krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}}],
1827: [0.75,0.683,0,{ic: 0.025, krn: {'101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}}],
1828: [0.611,0.683], [0.278,0.75,0.25], [0.5,0.694],
1829: [0.278,0.75,0.25], [0.5,0.694], [0.278,0.668],
1830:
1831: [0.278,0.694,0,{lig: {'96': 92}}],
1832: [0.5,0.431,0,{krn: {'118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}}],
1833: [0.556,0.694,0,{krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}}],
1834: [0.444,0.431,0,{krn: {'104': -0.0278, '107': -0.0278}}],
1835: [0.556,0.694], [0.444,0.431],
1836: [0.306,0.694,0,{ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 12, '102': 11, '108': 13}}],
1837: [0.5,0.431,0.194,{ic: 0.0139, krn: {'106': 0.0278}}],
1838: [0.556,0.694,0,{krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}}],
1839: [0.278,0.668], [0.306,0.668,0.194],
1840: [0.528,0.694,0,{krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}}],
1841: [0.278,0.694],
1842: [0.833,0.431,0,{krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}}],
1843: [0.556,0.431,0,{krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}}],
1844: [0.5,0.431,0,{krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}}],
1845:
1846: [0.556,0.431,0.194,{krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}}],
1847: [0.528,0.431,0.194], [0.392,0.431], [0.394,0.431],
1848: [0.389,0.615,0,{krn: {'121': -0.0278, '119': -0.0278}}],
1849: [0.556,0.431,0,{krn: {'119': -0.0278}}],
1850: [0.528,0.431,0,{ic: 0.0139, krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}}],
1851: [0.722,0.431,0,{ic: 0.0139, krn: {'101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}}],
1852: [0.528,0.431],
1853: [0.528,0.431,0.194,{ic: 0.0139, krn: {'111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}}],
1854: [0.444,0.431], [0.5,0.431,0,{ic: 0.0278, lig: {'45': 124}}],
1855: [1,0.431,0,{ic: 0.0278}], [0.5,0.694], [0.5,0.668], [0.5,0.668]
1856: ],
1857:
1858: cmmi10: [
1859: [0.615,0.683,0,{ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}}],
1860: [0.833,0.683,0,{krn: {'127': 0.167}}],
1861: [0.763,0.683,0,{ic: 0.0278, krn: {'127': 0.0833}}],
1862: [0.694,0.683,0,{krn: {'127': 0.167}}],
1863: [0.742,0.683,0,{ic: 0.0757, krn: {'127': 0.0833}}],
1864: [0.831,0.683,0,{ic: 0.0812, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}}],
1865: [0.78,0.683,0,{ic: 0.0576, krn: {'127': 0.0833}}],
1866: [0.583,0.683,0,{ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0556}}],
1867: [0.667,0.683,0,{krn: {'127': 0.0833}}],
1868: [0.612,0.683,0,{ic: 0.11, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}}],
1869: [0.772,0.683,0,{ic: 0.0502, krn: {'127': 0.0833}}],
1870: [0.64,0.431,0,{ic: 0.0037, krn: {'127': 0.0278}}],
1871: [0.566,0.694,0.194,{ic: 0.0528, krn: {'127': 0.0833}}],
1872: [0.518,0.431,0.194,{ic: 0.0556}],
1873: [0.444,0.694,0,{ic: 0.0378, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0556}}],
1874: [0.406,0.431,0,{krn: {'127': 0.0556}}],
1875:
1876: [0.438,0.694,0.194,{ic: 0.0738, krn: {'127': 0.0833}}],
1877: [0.497,0.431,0.194,{ic: 0.0359, krn: {'127': 0.0556}}],
1878: [0.469,0.694,0,{ic: 0.0278, krn: {'127': 0.0833}}],
1879: [0.354,0.431,0,{krn: {'127': 0.0556}}],
1880: [0.576,0.431], [0.583,0.694],
1881: [0.603,0.431,0.194,{krn: {'127': 0.0278}}],
1882: [0.494,0.431,0,{ic: 0.0637, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0278}}],
1883: [0.438,0.694,0.194,{ic: 0.046, krn: {'127': 0.111}}],
1884: [0.57,0.431,0,{ic: 0.0359}],
1885: [0.517,0.431,0.194,{krn: {'127': 0.0833}}],
1886: [0.571,0.431,0,{ic: 0.0359, krn: {'59': -0.0556, '58': -0.0556}}],
1887: [0.437,0.431,0,{ic: 0.113, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0278}}],
1888: [0.54,0.431,0,{ic: 0.0359, krn: {'127': 0.0278}}],
1889: [0.596,0.694,0.194,{krn: {'127': 0.0833}}],
1890: [0.626,0.431,0.194,{krn: {'127': 0.0556}}],
1891:
1892: [0.651,0.694,0.194,{ic: 0.0359, krn: {'127': 0.111}}],
1893: [0.622,0.431,0,{ic: 0.0359}],
1894: [0.466,0.431,0,{krn: {'127': 0.0833}}],
1895: [0.591,0.694,0,{krn: {'127': 0.0833}}],
1896: [0.828,0.431,0,{ic: 0.0278}],
1897: [0.517,0.431,0.194,{krn: {'127': 0.0833}}],
1898: [0.363,0.431,0.0972,{ic: 0.0799, krn: {'127': 0.0833}}],
1899: [0.654,0.431,0.194,{krn: {'127': 0.0833}}],
1900: [1,0.367,-0.133], [1,0.367,-0.133], [1,0.367,-0.133], [1,0.367,-0.133],
1901: [0.278,0.464,-0.0363], [0.278,0.464,-0.0363], [0.5,0.465,-0.0347], [0.5,0.465,-0.0347],
1902:
1903: [0.5,0.431], [0.5,0.431], [0.5,0.431], [0.5,0.431,0.194],
1904: [0.5,0.431,0.194], [0.5,0.431,0.194], [0.5,0.644], [0.5,0.431,0.194],
1905: [0.5,0.644], [0.5,0.431,0.194], [0.278,0.106], [0.278,0.106,0.194],
1906: [0.778,0.539,0.0391],
1907: [0.5,0.75,0.25,{krn: {'1': -0.0556, '65': -0.0556, '77': -0.0556, '78': -0.0556, '89': 0.0556, '90': -0.0556}}],
1908: [0.778,0.539,0.0391], [0.5,0.465,-0.0347],
1909:
1910: [0.531,0.694,0,{ic: 0.0556, krn: {'127': 0.0833}}],
1911: [0.75,0.683,0,{krn: {'127': 0.139}}],
1912: [0.759,0.683,0,{ic: 0.0502, krn: {'127': 0.0833}}],
1913: [0.715,0.683,0,{ic: 0.0715, krn: {'61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}}],
1914: [0.828,0.683,0,{ic: 0.0278, krn: {'127': 0.0556}}],
1915: [0.738,0.683,0,{ic: 0.0576, krn: {'127': 0.0833}}],
1916: [0.643,0.683,0,{ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}}],
1917: [0.786,0.683,0,{krn: {'127': 0.0833}}],
1918: [0.831,0.683,0,{ic: 0.0812, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}}],
1919: [0.44,0.683,0,{ic: 0.0785, krn: {'127': 0.111}}],
1920: [0.555,0.683,0,{ic: 0.0962, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.167}}],
1921: [0.849,0.683,0,{ic: 0.0715, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}}],
1922: [0.681,0.683,0,{krn: {'127': 0.0278}}],
1923: [0.97,0.683,0,{ic: 0.109, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}}],
1924: [0.803,0.683,0,{ic: 0.109, krn: {'61': -0.0833, '61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}}],
1925: [0.763,0.683,0,{ic: 0.0278, krn: {'127': 0.0833}}],
1926:
1927: [0.642,0.683,0,{ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}}],
1928: [0.791,0.683,0.194,{krn: {'127': 0.0833}}],
1929: [0.759,0.683,0,{ic: 0.00773, krn: {'127': 0.0833}}],
1930: [0.613,0.683,0,{ic: 0.0576, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}}],
1931: [0.584,0.683,0,{ic: 0.139, krn: {'61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}}],
1932: [0.683,0.683,0,{ic: 0.109, krn: {'59': -0.111, '58': -0.111, '61': -0.0556, '127': 0.0278}}],
1933: [0.583,0.683,0,{ic: 0.222, krn: {'59': -0.167, '58': -0.167, '61': -0.111}}],
1934: [0.944,0.683,0,{ic: 0.139, krn: {'59': -0.167, '58': -0.167, '61': -0.111}}],
1935: [0.828,0.683,0,{ic: 0.0785, krn: {'61': -0.0833, '61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}}],
1936: [0.581,0.683,0,{ic: 0.222, krn: {'59': -0.167, '58': -0.167, '61': -0.111}}],
1937: [0.683,0.683,0,{ic: 0.0715, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}}],
1938: [0.389,0.75], [0.389,0.694,0.194], [0.389,0.694,0.194],
1939: [1,0.358,-0.142], [1,0.358,-0.142],
1940:
1941: [0.417,0.694,0,{krn: {'127': 0.111}}],
1942: [0.529,0.431], [0.429,0.694], [0.433,0.431,0,{krn: {'127': 0.0556}}],
1943: [0.52,0.694,0,{krn: {'89': 0.0556, '90': -0.0556, '106': -0.111, '102': -0.167, '127': 0.167}}],
1944: [0.466,0.431,0,{krn: {'127': 0.0556}}],
1945: [0.49,0.694,0.194,{ic: 0.108, krn: {'59': -0.0556, '58': -0.0556, '127': 0.167}}],
1946: [0.477,0.431,0.194,{ic: 0.0359, krn: {'127': 0.0278}}],
1947: [0.576,0.694,0,{krn: {'127': -0.0278}}], [0.345,0.66],
1948: [0.412,0.66,0.194,{ic: 0.0572, krn: {'59': -0.0556, '58': -0.0556}}],
1949: [0.521,0.694,0,{ic: 0.0315}], [0.298,0.694,0,{ic: 0.0197, krn: {'127': 0.0833}}],
1950: [0.878,0.431], [0.6,0.431], [0.485,0.431,0,{krn: {'127': 0.0556}}],
1951:
1952: [0.503,0.431,0.194,{krn: {'127': 0.0833}}],
1953: [0.446,0.431,0.194,{ic: 0.0359, krn: {'127': 0.0833}}],
1954: [0.451,0.431,0,{ic: 0.0278, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0556}}],
1955: [0.469,0.431,0,{krn: {'127': 0.0556}}], [0.361,0.615,0,{krn: {'127': 0.0833}}],
1956: [0.572,0.431,0,{krn: {'127': 0.0278}}],
1957: [0.485,0.431,0,{ic: 0.0359, krn: {'127': 0.0278}}],
1958: [0.716,0.431,0,{ic: 0.0269, krn: {'127': 0.0833}}],
1959: [0.572,0.431,0,{krn: {'127': 0.0278}}],
1960: [0.49,0.431,0.194,{ic: 0.0359, krn: {'127': 0.0556}}],
1961: [0.465,0.431,0,{ic: 0.044, krn: {'127': 0.0556}}],
1962: [0.322,0.431,0,{krn: {'127': 0.0278}}],
1963: [0.384,0.431,0.194,{krn: {'127': 0.0833}}],
1964: [0.636,0.431,0.194,{krn: {'127': 0.111}}],
1965: [0.5,0.714,0,{ic: 0.154}], [0.278,0.694,0,{ic: 0.399}]
1966: ],
1967:
1968: cmsy10: [
1969: [0.778,0.583,0.0833], [0.278,0.444,-0.0556], [0.778,0.583,0.0833],
1970: [0.5,0.465,-0.0347], [0.778,0.583,0.0833], [0.5,0.444,-0.0556],
1971: [0.778,0.583,0.0833], [0.778,0.583,0.0833], [0.778,0.583,0.0833],
1972: [0.778,0.583,0.0833], [0.778,0.583,0.0833], [0.778,0.583,0.0833],
1973: [0.778,0.583,0.0833], [1,0.694,0.194], [0.5,0.444,-0.0556], [0.5,0.444,-0.0556],
1974:
1975: [0.778,0.464,-0.0363], [0.778,0.464,-0.0363], [0.778,0.636,0.136],
1976: [0.778,0.636,0.136], [0.778,0.636,0.136], [0.778,0.636,0.136],
1977: [0.778,0.636,0.136], [0.778,0.636,0.136], [0.778,0.367,-0.133],
1978: [0.778,0.483,-0.0169], [0.778,0.539,0.0391], [0.778,0.539,0.0391],
1979: [1,0.539,0.0391], [1,0.539,0.0391], [0.778,0.539,0.0391], [0.778,0.539,0.0391],
1980:
1981: [1,0.367,-0.133], [1,0.367,-0.133], [0.5,0.694,0.194], [0.5,0.694,0.194],
1982: [1,0.367,-0.133], [1,0.694,0.194], [1,0.694,0.194], [0.778,0.464,-0.0363],
1983: [1,0.367,-0.133], [1,0.367,-0.133], [0.611,0.694,0.194], [0.611,0.694,0.194],
1984: [1,0.367,-0.133], [1,0.694,0.194], [1,0.694,0.194], [0.778,0.431],
1985:
1986: [0.275,0.556], [1,0.431], [0.667,0.539,0.0391], [0.667,0.539,0.0391],
1987: [0.889,0.694,0.194], [0.889,0.694,0.194], [0,0.694,0.194], [0,0.367,-0.133],
1988: [0.556,0.694], [0.556,0.694], [0.667,0.431], [0.5,0.75,0.0556],
1989: [0.722,0.694], [0.722,0.694], [0.778,0.694], [0.778,0.694],
1990:
1991: [0.611,0.694], [0.798,0.683,0,{krn: {'48': 0.194}}],
1992: [0.657,0.683,0,{ic: 0.0304, krn: {'48': 0.139}}],
1993: [0.527,0.683,0,{ic: 0.0583, krn: {'48': 0.139}}],
1994: [0.771,0.683,0,{ic: 0.0278, krn: {'48': 0.0833}}],
1995: [0.528,0.683,0,{ic: 0.0894, krn: {'48': 0.111}}],
1996: [0.719,0.683,0,{ic: 0.0993, krn: {'48': 0.111}}],
1997: [0.595,0.683,0.0972,{ic: 0.0593, krn: {'48': 0.111}}],
1998: [0.845,0.683,0,{ic: 0.00965, krn: {'48': 0.111}}],
1999: [0.545,0.683,0,{ic: 0.0738, krn: {'48': 0.0278}}],
2000: [0.678,0.683,0.0972,{ic: 0.185, krn: {'48': 0.167}}],
2001: [0.762,0.683,0,{ic: 0.0144, krn: {'48': 0.0556}}],
2002: [0.69,0.683,0,{krn: {'48': 0.139}}], [1.2,0.683,0,{krn: {'48': 0.139}}],
2003: [0.82,0.683,0,{ic: 0.147, krn: {'48': 0.0833}}],
2004: [0.796,0.683,0,{ic: 0.0278, krn: {'48': 0.111}}],
2005:
2006: [0.696,0.683,0,{ic: 0.0822, krn: {'48': 0.0833}}],
2007: [0.817,0.683,0.0972,{krn: {'48': 0.111}}],
2008: [0.848,0.683,0,{krn: {'48': 0.0833}}],
2009: [0.606,0.683,0,{ic: 0.075, krn: {'48': 0.139}}],
2010: [0.545,0.683,0,{ic: 0.254, krn: {'48': 0.0278}}],
2011: [0.626,0.683,0,{ic: 0.0993, krn: {'48': 0.0833}}],
2012: [0.613,0.683,0,{ic: 0.0822, krn: {'48': 0.0278}}],
2013: [0.988,0.683,0,{ic: 0.0822, krn: {'48': 0.0833}}],
2014: [0.713,0.683,0,{ic: 0.146, krn: {'48': 0.139}}],
2015: [0.668,0.683,0.0972,{ic: 0.0822, krn: {'48': 0.0833}}],
2016: [0.725,0.683,0,{ic: 0.0794, krn: {'48': 0.139}}],
2017: [0.667,0.556], [0.667,0.556], [0.667,0.556], [0.667,0.556], [0.667,0.556],
2018:
2019: [0.611,0.694], [0.611,0.694], [0.444,0.75,0.25], [0.444,0.75,0.25],
2020: [0.444,0.75,0.25], [0.444,0.75,0.25], [0.5,0.75,0.25], [0.5,0.75,0.25],
2021: [0.389,0.75,0.25], [0.389,0.75,0.25], [0.278,0.75,0.25], [0.5,0.75,0.25],
2022: [0.5,0.75,0.25], [0.611,0.75,0.25], [0.5,0.75,0.25], [0.278,0.694,0.194],
2023:
2024: [0.833,0.04,0.96], [0.75,0.683], [0.833,0.683], [0.417,0.694,0.194,{ic: 0.111}],
2025: [0.667,0.556], [0.667,0.556], [0.778,0.636,0.136], [0.778,0.636,0.136],
2026: [0.444,0.694,0.194], [0.444,0.694,0.194], [0.444,0.694,0.194],
2027: [0.611,0.694,0.194], [0.778,0.694,0.13], [0.778,0.694,0.13],
2028: [0.778,0.694,0.13], [0.778,0.694,0.13]
2029: ],
2030:
2031: cmex10: [
2032: [0.458,0.04,1.16,{n: 16}], [0.458,0.04,1.16,{n: 17}],
2033: [0.417,0.04,1.16,{n: 104}], [0.417,0.04,1.16,{n: 105}],
2034: [0.472,0.04,1.16,{n: 106}], [0.472,0.04,1.16,{n: 107}],
2035: [0.472,0.04,1.16,{n: 108}], [0.472,0.04,1.16,{n: 109}],
2036: [0.583,0.04,1.16,{n: 110}], [0.583,0.04,1.16,{n: 111}],
2037: [0.472,0.04,1.16,{n: 68}], [0.472,0.04,1.16,{n: 69}],
2038: [0.333,0,0.6,{delim: {rep: 12}}], [0.556,0,0.6,{delim: {rep: 13}}],
2039: [0.578,0.04,1.16,{n: 46}], [0.578,0.04,1.16,{n: 47}],
2040:
2041: [0.597,0.04,1.76,{n: 18}], [0.597,0.04,1.76,{n: 19}],
2042: [0.736,0.04,2.36,{n: 32}], [0.736,0.04,2.36,{n: 33}],
2043: [0.528,0.04,2.36,{n: 34}], [0.528,0.04,2.36,{n: 35}],
2044: [0.583,0.04,2.36,{n: 36}], [0.583,0.04,2.36,{n: 37}],
2045: [0.583,0.04,2.36,{n: 38}], [0.583,0.04,2.36,{n: 39}],
2046: [0.75,0.04,2.36,{n: 40}], [0.75,0.04,2.36,{n: 41}],
2047: [0.75,0.04,2.36,{n: 42}], [0.75,0.04,2.36,{n: 43}],
2048: [1.04,0.04,2.36,{n: 44}], [1.04,0.04,2.36,{n: 45}],
2049:
2050: [0.792,0.04,2.96,{n: 48}], [0.792,0.04,2.96,{n: 49}],
2051: [0.583,0.04,2.96,{n: 50}], [0.583,0.04,2.96,{n: 51}],
2052: [0.639,0.04,2.96,{n: 52}], [0.639,0.04,2.96,{n: 53}],
2053: [0.639,0.04,2.96,{n: 54}], [0.639,0.04,2.96,{n: 55}],
2054: [0.806,0.04,2.96,{n: 56}], [0.806,0.04,2.96,{n: 57}],
2055: [0.806,0.04,2.96], [0.806,0.04,2.96],
2056: [1.28,0.04,2.96], [1.28,0.04,2.96],
2057: [0.811,0.04,1.76,{n: 30}], [0.811,0.04,1.76,{n: 31}],
2058:
2059: [0.875,0.04,1.76,{delim: {top: 48, bot: 64, rep: 66}}],
2060: [0.875,0.04,1.76,{delim: {top: 49, bot: 65, rep: 67}}],
2061: [0.667,0.04,1.76,{delim: {top: 50, bot: 52, rep: 54}}],
2062: [0.667,0.04,1.76,{delim: {top: 51, bot: 53, rep: 55}}],
2063: [0.667,0.04,1.76,{delim: {bot: 52, rep: 54}}],
2064: [0.667,0.04,1.76,{delim: {bot: 53, rep: 55}}],
2065: [0.667,0,0.6,{delim: {top: 50, rep: 54}}],
2066: [0.667,0,0.6,{delim: {top: 51, rep: 55}}],
2067: [0.889,0,0.9,{delim: {top: 56, mid: 60, bot: 58, rep: 62}}],
2068: [0.889,0,0.9,{delim: {top: 57, mid: 61, bot: 59, rep: 62}}],
2069: [0.889,0,0.9,{delim: {top: 56, bot: 58, rep: 62}}],
2070: [0.889,0,0.9,{delim: {top: 57, bot: 59, rep: 62}}],
2071: [0.889,0,1.8,{delim: {rep: 63}}],
2072: [0.889,0,1.8,{delim: {rep: 119}}],
2073: [0.889,0,0.3,{delim: {rep: 62}}],
2074: [0.667,0,0.6,{delim: {top: 120, bot: 121, rep: 63}}],
2075:
2076: [0.875,0.04,1.76,{delim: {top: 56, bot: 59, rep: 62}}],
2077: [0.875,0.04,1.76,{delim: {top: 57, bot: 58, rep: 62}}],
2078: [0.875,0,0.6,{delim: {rep: 66}}], [0.875,0,0.6,{delim: {rep: 67}}],
2079: [0.611,0.04,1.76,{n: 28}], [0.611,0.04,1.76,{n: 29}],
2080: [0.833,0,1,{n: 71}], [1.11,0.1,1.5], [0.472,0,1.11,{ic: 0.194, n: 73}],
2081: [0.556,0,2.22,{ic: 0.444}], [1.11,0,1,{n: 75}], [1.51,0.1,1.5],
2082: [1.11,0,1,{n: 77}], [1.51,0.1,1.5], [1.11,0,1,{n: 79}], [1.51,0.1,1.5],
2083:
2084: [1.06,0,1,{n: 88}], [0.944,0,1,{n: 89}], [0.472,0,1.11,{ic: 0.194, n: 90}],
2085: [0.833,0,1,{n: 91}], [0.833,0,1,{n: 92}], [0.833,0,1,{n: 93}],
2086: [0.833,0,1,{n: 94}], [0.833,0,1,{n: 95}], [1.44,0.1,1.5],
2087: [1.28,0.1,1.5], [0.556,0,2.22,{ic: 0.444}], [1.11,0.1,1.5],
2088: [1.11,0.1,1.5], [1.11,0.1,1.5], [1.11,0.1,1.5], [1.11,0.1,1.5],
2089:
2090: [0.944,0,1,{n: 97}], [1.28,0.1,1.5], [0.556,0.722,0,{n: 99}],
2091: [1,0.75,0,{n: 100}], [1.44,0.75], [0.556,0.722,0,{n: 102}],
2092: [1,0.75,0,{n: 103}], [1.44,0.75], [0.472,0.04,1.76,{n: 20}],
2093: [0.472,0.04,1.76,{n: 21}], [0.528,0.04,1.76,{n: 22}],
2094: [0.528,0.04,1.76,{n: 23}], [0.528,0.04,1.76,{n: 24}],
2095: [0.528,0.04,1.76,{n: 25}], [0.667,0.04,1.76,{n: 26}],
2096: [0.667,0.04,1.76,{n: 27}],
2097:
2098: [1,0.04,1.16,{n: 113}], [1,0.04,1.76,{n: 114}], [1,0.04,2.36,{n: 115}],
2099: [1,0.04,2.96,{n: 116}], [1.06,0,1.8,{delim: {top: 118, bot: 116, rep: 117}}],
2100: [1.06,0,0.6], [1.06,0.04,0.56],
2101: [0.778,0,0.6,{delim: {top: 126, bot: 127, rep: 119}}],
2102: [0.667,0,0.6,{delim: {top: 120, rep: 63}}],
2103: [0.667,0,0.6,{delim: {bot: 121, rep: 63}}],
2104: [0.45,0.12], [0.45,0.12], [0.45,0.12], [0.45,0.12],
2105: [0.778,0,0.6,{delim: {top: 126, rep: 119}}],
2106: [0.778,0,0.6,{delim: {bot: 127, rep: 119}}]
2107: ],
2108:
2109: cmti10: [
2110: [0.627,0.683,0,{ic: 0.133}], [0.818,0.683], [0.767,0.683,0,{ic: 0.094}],
2111: [0.692,0.683], [0.664,0.683,0,{ic: 0.153}], [0.743,0.683,0,{ic: 0.164}],
2112: [0.716,0.683,0,{ic: 0.12}], [0.767,0.683,0,{ic: 0.111}],
2113: [0.716,0.683,0,{ic: 0.0599}], [0.767,0.683,0,{ic: 0.111}],
2114: [0.716,0.683,0,{ic: 0.103}],
2115: [0.613,0.694,0.194,{ic: 0.212, krn: {'39': 0.104, '63': 0.104, '33': 0.104, '41': 0.104, '93': 0.104}, lig: {'105': 14, '108': 15}}],
2116: [0.562,0.694,0.194,{ic: 0.103}], [0.588,0.694,0.194,{ic: 0.103}],
2117: [0.882,0.694,0.194,{ic: 0.103}], [0.894,0.694,0.194,{ic: 0.103}],
2118:
2119: [0.307,0.431,0,{ic: 0.0767}], [0.332,0.431,0.194,{ic: 0.0374}],
2120: [0.511,0.694], [0.511,0.694,0,{ic: 0.0969}], [0.511,0.628,0,{ic: 0.083}],
2121: [0.511,0.694,0,{ic: 0.108}], [0.511,0.562,0,{ic: 0.103}], [0.831,0.694],
2122: [0.46,0,0.17], [0.537,0.694,0.194,{ic: 0.105}], [0.716,0.431,0,{ic: 0.0751}],
2123: [0.716,0.431,0,{ic: 0.0751}], [0.511,0.528,0.0972,{ic: 0.0919}],
2124: [0.883,0.683,0,{ic: 0.12}], [0.985,0.683,0,{ic: 0.12}],
2125: [0.767,0.732,0.0486,{ic: 0.094}],
2126:
2127: [0.256,0.431,0,{krn: {'108': -0.256, '76': -0.321}}],
2128: [0.307,0.694,0,{ic: 0.124, lig: {'96': 60}}],
2129: [0.514,0.694,0,{ic: 0.0696}], [0.818,0.694,0.194,{ic: 0.0662}],
2130: [0.769,0.694], [0.818,0.75,0.0556,{ic: 0.136}],
2131: [0.767,0.694,0,{ic: 0.0969}],
2132: [0.307,0.694,0,{ic: 0.124, krn: {'63': 0.102, '33': 0.102}, lig: {'39': 34}}],
2133: [0.409,0.75,0.25,{ic: 0.162}], [0.409,0.75,0.25,{ic: 0.0369}],
2134: [0.511,0.75,0,{ic: 0.149}], [0.767,0.562,0.0567,{ic: 0.0369}],
2135: [0.307,0.106,0.194], [0.358,0.431,0,{ic: 0.0283, lig: {'45': 123}}],
2136: [0.307,0.106], [0.511,0.75,0.25,{ic: 0.162}],
2137:
2138: [0.511,0.644,0,{ic: 0.136}], [0.511,0.644,0,{ic: 0.136}],
2139: [0.511,0.644,0,{ic: 0.136}], [0.511,0.644,0,{ic: 0.136}],
2140: [0.511,0.644,0.194,{ic: 0.136}], [0.511,0.644,0,{ic: 0.136}],
2141: [0.511,0.644,0,{ic: 0.136}], [0.511,0.644,0.194,{ic: 0.136}],
2142: [0.511,0.644,0,{ic: 0.136}], [0.511,0.644,0,{ic: 0.136}],
2143: [0.307,0.431,0,{ic: 0.0582}], [0.307,0.431,0.194,{ic: 0.0582}],
2144: [0.307,0.5,0.194,{ic: 0.0756}], [0.767,0.367,-0.133,{ic: 0.0662}],
2145: [0.511,0.5,0.194], [0.511,0.694,0,{ic: 0.122, lig: {'96': 62}}],
2146:
2147: [0.767,0.694,0,{ic: 0.096}],
2148: [0.743,0.683,0,{krn: {'110': -0.0256, '108': -0.0256, '114': -0.0256, '117': -0.0256, '109': -0.0256, '116': -0.0256, '105': -0.0256, '67': -0.0256, '79': -0.0256, '71': -0.0256, '104': -0.0256, '98': -0.0256, '85': -0.0256, '107': -0.0256, '118': -0.0256, '119': -0.0256, '81': -0.0256, '84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}}],
2149: [0.704,0.683,0,{ic: 0.103}], [0.716,0.683,0,{ic: 0.145}],
2150: [0.755,0.683,0,{ic: 0.094, krn: {'88': -0.0256, '87': -0.0256, '65': -0.0256, '86': -0.0256, '89': -0.0256}}],
2151: [0.678,0.683,0,{ic: 0.12}],
2152: [0.653,0.683,0,{ic: 0.133, krn: {'111': -0.0767, '101': -0.0767, '117': -0.0767, '114': -0.0767, '97': -0.0767, '65': -0.102, '79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}}],
2153: [0.774,0.683,0,{ic: 0.0872}], [0.743,0.683,0,{ic: 0.164}],
2154: [0.386,0.683,0,{ic: 0.158}], [0.525,0.683,0,{ic: 0.14}],
2155: [0.769,0.683,0,{ic: 0.145, krn: {'79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}}],
2156: [0.627,0.683,0,{krn: {'84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}}],
2157: [0.897,0.683,0,{ic: 0.164}], [0.743,0.683,0,{ic: 0.164}],
2158: [0.767,0.683,0,{ic: 0.094, krn: {'88': -0.0256, '87': -0.0256, '65': -0.0256, '86': -0.0256, '89': -0.0256}}],
2159:
2160: [0.678,0.683,0,{ic: 0.103, krn: {'65': -0.0767}}],
2161: [0.767,0.683,0.194,{ic: 0.094}],
2162: [0.729,0.683,0,{ic: 0.0387, krn: {'110': -0.0256, '108': -0.0256, '114': -0.0256, '117': -0.0256, '109': -0.0256, '116': -0.0256, '105': -0.0256, '67': -0.0256, '79': -0.0256, '71': -0.0256, '104': -0.0256, '98': -0.0256, '85': -0.0256, '107': -0.0256, '118': -0.0256, '119': -0.0256, '81': -0.0256, '84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}}],
2163: [0.562,0.683,0,{ic: 0.12}],
2164: [0.716,0.683,0,{ic: 0.133, krn: {'121': -0.0767, '101': -0.0767, '111': -0.0767, '114': -0.0767, '97': -0.0767, '117': -0.0767, '65': -0.0767}}],
2165: [0.743,0.683,0,{ic: 0.164}],
2166: [0.743,0.683,0,{ic: 0.184, krn: {'111': -0.0767, '101': -0.0767, '117': -0.0767, '114': -0.0767, '97': -0.0767, '65': -0.102, '79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}}],
2167: [0.999,0.683,0,{ic: 0.184, krn: {'65': -0.0767}}],
2168: [0.743,0.683,0,{ic: 0.158, krn: {'79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}}],
2169: [0.743,0.683,0,{ic: 0.194, krn: {'101': -0.0767, '111': -0.0767, '114': -0.0767, '97': -0.0767, '117': -0.0767, '65': -0.0767}}],
2170: [0.613,0.683,0,{ic: 0.145}], [0.307,0.75,0.25,{ic: 0.188}],
2171: [0.514,0.694,0,{ic: 0.169}], [0.307,0.75,0.25,{ic: 0.105}],
2172: [0.511,0.694,0,{ic: 0.0665}], [0.307,0.668,0,{ic: 0.118}],
2173:
2174: [0.307,0.694,0,{ic: 0.124, lig: {'96': 92}}], [0.511,0.431,0,{ic: 0.0767}],
2175: [0.46,0.694,0,{ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}}],
2176: [0.46,0.431,0,{ic: 0.0565, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}}],
2177: [0.511,0.694,0,{ic: 0.103, krn: {'108': 0.0511}}],
2178: [0.46,0.431,0,{ic: 0.0751, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}}],
2179: [0.307,0.694,0.194,{ic: 0.212, krn: {'39': 0.104, '63': 0.104, '33': 0.104, '41': 0.104, '93': 0.104}, lig: {'105': 12, '102': 11, '108': 13}}],
2180: [0.46,0.431,0.194,{ic: 0.0885}], [0.511,0.694,0,{ic: 0.0767}],
2181: [0.307,0.655,0,{ic: 0.102}], [0.307,0.655,0.194,{ic: 0.145}],
2182: [0.46,0.694,0,{ic: 0.108}], [0.256,0.694,0,{ic: 0.103, krn: {'108': 0.0511}}],
2183: [0.818,0.431,0,{ic: 0.0767}], [0.562,0.431,0,{ic: 0.0767, krn: {'39': -0.102}}],
2184: [0.511,0.431,0,{ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}}],
2185:
2186: [0.511,0.431,0.194,{ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}}],
2187: [0.46,0.431,0.194,{ic: 0.0885}],
2188: [0.422,0.431,0,{ic: 0.108, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}}],
2189: [0.409,0.431,0,{ic: 0.0821}], [0.332,0.615,0,{ic: 0.0949}],
2190: [0.537,0.431,0,{ic: 0.0767}], [0.46,0.431,0,{ic: 0.108}],
2191: [0.664,0.431,0,{ic: 0.108, krn: {'108': 0.0511}}],
2192: [0.464,0.431,0,{ic: 0.12}], [0.486,0.431,0.194,{ic: 0.0885}],
2193: [0.409,0.431,0,{ic: 0.123}], [0.511,0.431,0,{ic: 0.0921, lig: {'45': 124}}],
2194: [1.02,0.431,0,{ic: 0.0921}], [0.511,0.694,0,{ic: 0.122}],
2195: [0.511,0.668,0,{ic: 0.116}], [0.511,0.668,0,{ic: 0.105}]
2196: ],
2197:
2198: cmbx10: [
2199: [0.692,0.686], [0.958,0.686], [0.894,0.686], [0.806,0.686],
2200: [0.767,0.686], [0.9,0.686], [0.831,0.686], [0.894,0.686],
2201: [0.831,0.686], [0.894,0.686], [0.831,0.686],
2202: [0.671,0.694,0,{ic: 0.109, krn: {'39': 0.109, '63': 0.109, '33': 0.109, '41': 0.109, '93': 0.109}, lig: {'105': 14, '108': 15}}],
2203: [0.639,0.694], [0.639,0.694], [0.958,0.694], [0.958,0.694],
2204:
2205: [0.319,0.444], [0.351,0.444,0.194], [0.575,0.694], [0.575,0.694],
2206: [0.575,0.632], [0.575,0.694], [0.575,0.596], [0.869,0.694],
2207: [0.511,0,0.17], [0.597,0.694], [0.831,0.444], [0.894,0.444],
2208: [0.575,0.542,0.0972], [1.04,0.686], [1.17,0.686], [0.894,0.735,0.0486],
2209:
2210: [0.319,0.444,0,{krn: {'108': -0.319, '76': -0.378}}],
2211: [0.35,0.694,0,{lig: {'96': 60}}], [0.603,0.694], [0.958,0.694,0.194],
2212: [0.575,0.75,0.0556], [0.958,0.75,0.0556], [0.894,0.694],
2213: [0.319,0.694,0,{krn: {'63': 0.128, '33': 0.128}, lig: {'39': 34}}],
2214: [0.447,0.75,0.25], [0.447,0.75,0.25], [0.575,0.75], [0.894,0.633,0.133],
2215: [0.319,0.156,0.194], [0.383,0.444,0,{lig: {'45': 123}}],
2216: [0.319,0.156], [0.575,0.75,0.25],
2217:
2218: [0.575,0.644], [0.575,0.644], [0.575,0.644], [0.575,0.644],
2219: [0.575,0.644], [0.575,0.644], [0.575,0.644], [0.575,0.644],
2220: [0.575,0.644], [0.575,0.644], [0.319,0.444], [0.319,0.444,0.194],
2221: [0.35,0.5,0.194], [0.894,0.391,-0.109], [0.543,0.5,0.194],
2222: [0.543,0.694,0,{lig: {'96': 62}}],
2223:
2224: [0.894,0.694],
2225: [0.869,0.686,0,{krn: {'116': -0.0319, '67': -0.0319, '79': -0.0319, '71': -0.0319, '85': -0.0319, '81': -0.0319, '84': -0.0958, '89': -0.0958, '86': -0.128, '87': -0.128}}],
2226: [0.818,0.686], [0.831,0.686],
2227: [0.882,0.686,0,{krn: {'88': -0.0319, '87': -0.0319, '65': -0.0319, '86': -0.0319, '89': -0.0319}}],
2228: [0.756,0.686],
2229: [0.724,0.686,0,{krn: {'111': -0.0958, '101': -0.0958, '117': -0.0958, '114': -0.0958, '97': -0.0958, '65': -0.128, '79': -0.0319, '67': -0.0319, '71': -0.0319, '81': -0.0319}}],
2230: [0.904,0.686], [0.9,0.686], [0.436,0.686,0,{krn: {'73': 0.0319}}],
2231: [0.594,0.686],
2232: [0.901,0.686,0,{krn: {'79': -0.0319, '67': -0.0319, '71': -0.0319, '81': -0.0319}}],
2233: [0.692,0.686,0,{krn: {'84': -0.0958, '89': -0.0958, '86': -0.128, '87': -0.128}}],
2234: [1.09,0.686], [0.9,0.686],
2235: [0.864,0.686,0,{krn: {'88': -0.0319, '87': -0.0319, '65': -0.0319, '86': -0.0319, '89': -0.0319}}],
2236:
2237: [0.786,0.686,0,{krn: {'65': -0.0958, '111': -0.0319, '101': -0.0319, '97': -0.0319, '46': -0.0958, '44': -0.0958}}],
2238: [0.864,0.686,0.194],
2239: [0.862,0.686,0,{krn: {'116': -0.0319, '67': -0.0319, '79': -0.0319, '71': -0.0319, '85': -0.0319, '81': -0.0319, '84': -0.0958, '89': -0.0958, '86': -0.128, '87': -0.128}}],
2240: [0.639,0.686],
2241: [0.8,0.686,0,{krn: {'121': -0.0319, '101': -0.0958, '111': -0.0958, '114': -0.0958, '97': -0.0958, '65': -0.0958, '117': -0.0958}}],
2242: [0.885,0.686],
2243: [0.869,0.686,0,{ic: 0.016, krn: {'111': -0.0958, '101': -0.0958, '117': -0.0958, '114': -0.0958, '97': -0.0958, '65': -0.128, '79': -0.0319, '67': -0.0319, '71': -0.0319, '81': -0.0319}}],
2244: [1.19,0.686,0,{ic: 0.016, krn: {'111': -0.0958, '101': -0.0958, '117': -0.0958, '114': -0.0958, '97': -0.0958, '65': -0.128, '79': -0.0319, '67': -0.0319, '71': -0.0319, '81': -0.0319}}],
2245: [0.869,0.686,0,{krn: {'79': -0.0319, '67': -0.0319, '71': -0.0319, '81': -0.0319}}],
2246: [0.869,0.686,0,{ic: 0.0287, krn: {'101': -0.0958, '111': -0.0958, '114': -0.0958, '97': -0.0958, '65': -0.0958, '117': -0.0958}}],
2247: [0.703,0.686], [0.319,0.75,0.25], [0.603,0.694], [0.319,0.75,0.25],
2248: [0.575,0.694], [0.319,0.694],
2249:
2250: [0.319,0.694,0,{lig: {'96': 92}}],
2251: [0.559,0.444,0,{krn: {'118': -0.0319, '106': 0.0639, '121': -0.0319, '119': -0.0319}}],
2252: [0.639,0.694,0,{krn: {'101': 0.0319, '111': 0.0319, '120': -0.0319, '100': 0.0319, '99': 0.0319, '113': 0.0319, '118': -0.0319, '106': 0.0639, '121': -0.0319, '119': -0.0319}}],
2253: [0.511,0.444,0,{krn: {'104': -0.0319, '107': -0.0319}}],
2254: [0.639,0.694], [0.527,0.444],
2255: [0.351,0.694,0,{ic: 0.109, krn: {'39': 0.109, '63': 0.109, '33': 0.109, '41': 0.109, '93': 0.109}, lig: {'105': 12, '102': 11, '108': 13}}],
2256: [0.575,0.444,0.194,{ic: 0.016, krn: {'106': 0.0319}}],
2257: [0.639,0.694,0,{krn: {'116': -0.0319, '117': -0.0319, '98': -0.0319, '121': -0.0319, '118': -0.0319, '119': -0.0319}}],
2258: [0.319,0.694], [0.351,0.694,0.194],
2259: [0.607,0.694,0,{krn: {'97': -0.0639, '101': -0.0319, '97': -0.0319, '111': -0.0319, '99': -0.0319}}],
2260: [0.319,0.694],
2261: [0.958,0.444,0,{krn: {'116': -0.0319, '117': -0.0319, '98': -0.0319, '121': -0.0319, '118': -0.0319, '119': -0.0319}}],
2262: [0.639,0.444,0,{krn: {'116': -0.0319, '117': -0.0319, '98': -0.0319, '121': -0.0319, '118': -0.0319, '119': -0.0319}}],
2263: [0.575,0.444,0,{krn: {'101': 0.0319, '111': 0.0319, '120': -0.0319, '100': 0.0319, '99': 0.0319, '113': 0.0319, '118': -0.0319, '106': 0.0639, '121': -0.0319, '119': -0.0319}}],
2264:
2265: [0.639,0.444,0.194,{krn: {'101': 0.0319, '111': 0.0319, '120': -0.0319, '100': 0.0319, '99': 0.0319, '113': 0.0319, '118': -0.0319, '106': 0.0639, '121': -0.0319, '119': -0.0319}}],
2266: [0.607,0.444,0.194], [0.474,0.444], [0.454,0.444],
2267: [0.447,0.635,0,{krn: {'121': -0.0319, '119': -0.0319}}],
2268: [0.639,0.444,0,{krn: {'119': -0.0319}}],
2269: [0.607,0.444,0,{ic: 0.016, krn: {'97': -0.0639, '101': -0.0319, '97': -0.0319, '111': -0.0319, '99': -0.0319}}],
2270: [0.831,0.444,0,{ic: 0.016, krn: {'101': -0.0319, '97': -0.0319, '111': -0.0319, '99': -0.0319}}],
2271: [0.607,0.444],
2272: [0.607,0.444,0.194,{ic: 0.016, krn: {'111': -0.0319, '101': -0.0319, '97': -0.0319, '46': -0.0958, '44': -0.0958}}],
2273: [0.511,0.444], [0.575,0.444,0,{ic: 0.0319, lig: {'45': 124}}],
2274: [1.15,0.444,0,{ic: 0.0319}], [0.575,0.694], [0.575,0.694], [0.575,0.694]
2275: ]
2276: };
2277:
2278: /***************************************************************************/
2279:
2280: /*
2281: * Implement image-based fonts for fallback method
2282: */
2283: jsMath.Img = {
2284:
2285: // font sizes available
2286: fonts: [50, 60, 70, 85, 100, 120, 144, 173, 207, 249, 298, 358, 430],
2287:
2288: // em widths for the various font size directories
2289: w: {'50': 6.9, '60': 8.3, '70': 9.7, '85': 11.8, '100': 13.9,
2290: '120': 16.7, '144': 20.0, '173': 24.0, '207': 28.8, '249': 34.6,
2291: '298': 41.4, '358': 49.8, '430': 59.8},
2292:
2293: best: 4, // index of best font size in the fonts list
2294: update: {}, // fonts to update (see UpdateFonts below)
2295: factor: 1, // factor by which to shrink images (for better printing)
2296: loaded: 0, // image fonts are loaded
2297:
2298: // add characters to be drawn using images
2299: SetFont: function (change) {
2300: for (var font in change) {
2301: if (!this.update[font]) {this.update[font] = []}
2302: this.update[font] = this.update[font].concat(change[font]);
2303: }
2304: },
2305:
2306: /*
2307: * Called by the exta-font definition files to add an image font
2308: * into the mix
2309: */
2310: AddFont: function (size,def) {
2311: if (!jsMath.Img[size]) {jsMath.Img[size] = {}};
2312: jsMath.Add(jsMath.Img[size],def);
2313: },
2314:
2315: /*
2316: * Update font(s) to use image data rather than native fonts
2317: * It looks in the jsMath.Img.update array to find the names
2318: * of the fonts to udpate, and the arrays of character codes
2319: * to set (or 'all' to change every character);
2320: */
2321: UpdateFonts: function () {
2322: var change = this.update; if (!this.loaded) return;
2323: var best = this[jsMath.Img.fonts[this.best]];
2324: for (var font in change) {
2325: for (var i = 0; i < change[font].length; i++) {
2326: var c = change[font][i];
2327: if (c == 'all') {for (c in jsMath.TeX[font]) {jsMath.TeX[font][c].img = {}}}
2328: else {jsMath.TeX[font][c].img = {}}
2329: }
2330: }
2331: this.update = {};
2332: },
2333:
2334: /*
2335: * Find the font size that best fits our current font
2336: * (this is the directory name for the img files used
2337: * in some fallback modes).
2338: */
2339: BestSize: function () {
2340: var w = jsMath.em * this.factor;
2341: var m = this.w[this.fonts[0]];
2342: for (var i = 1; i < this.fonts.length; i++) {
2343: if (w < (this.w[this.fonts[i]] + 2*m) / 3) {return i-1}
2344: m = this.w[this.fonts[i]];
2345: }
2346: return i-1;
2347: },
2348:
2349: /*
2350: * Get the scaling factor for the image fonts
2351: */
2352: Scale: function () {
2353: if (!this.loaded) return;
2354: this.best = this.BestSize();
2355: this.em = jsMath.Img.w[this.fonts[this.best]];
2356: this.scale = (jsMath.em/this.em);
2357: if (Math.abs(this.scale - 1) < .12) {this.scale = 1}
2358: },
2359:
2360: /*
2361: * Get URL to directory for given font and size, based on the
2362: * user's alpha/plain setting
2363: */
2364: URL: function (name,size,C) {
2365: var type = (jsMath.Controls.cookie.alpha) ? '/alpha/': '/plain/';
2366: if (C == null) {C = "def.js"} else {C = 'char'+C+'.png'}
2367: if (size != "") {size += '/'}
2368: return this.root+name+type+size+C;
2369: },
2370:
2371: /*
2372: * Laod the data for an image font
2373: */
2374: LoadFont: function (name) {
2375: if (!this.loaded) this.Init();
2376: jsMath.Setup.Script(this.URL(name,""));
2377: },
2378:
2379: /*
2380: * Setup for print mode, and create the hex code table
2381: */
2382: Init: function () {
1.2 ! albertel 2383: if (jsMath.Controls.cookie.print || jsMath.Controls.cookie.stayhires) {
! 2384: jsMath.Controls.cookie.print = jsMath.Controls.cookie.stayhires;
1.1 albertel 2385: this.factor *= 3;
1.2 ! albertel 2386: if (!jsMath.Controls.isLocalCookie || !jsMath.Global.isLocal) {jsMath.Controls.SetCookie(0)}
1.1 albertel 2387: if (jsMath.Browser.alphaPrintBug) {jsMath.Controls.cookie.alpha = 0}
2388: }
2389: var codes = '0123456789ABCDEF';
2390: this.HexCode = [];
2391: for (var i = 0; i < 128; i++) {
2392: var h = Math.floor(i/16); var l = i - 16*h;
2393: this.HexCode[i] = codes.charAt(h)+codes.charAt(l);
2394: }
2395: this.loaded = 1;
2396: }
2397:
2398: };
2399:
2400: /***************************************************************************/
2401:
2402: /*
2403: * jsMath.HTML handles creation of most of the HTML needed for
2404: * presenting mathematics in HTML pages.
2405: */
2406:
2407: jsMath.HTML = {
2408:
2409: /*
2410: * Produce a string version of a measurement in ems,
2411: * showing only a limited number of digits, and
2412: * using 0 when the value is near zero.
2413: */
2414: Em: function (m) {
2415: var n = 5; if (m < 0) {n++}
2416: if (Math.abs(m) < .000001) {m = 0}
2417: var s = String(m); s = s.replace(/(\.\d\d\d).+/,'$1');
2418: return s+'em'
2419: },
2420:
2421: /*
2422: * Create a horizontal space of width w
2423: */
2424: Spacer: function (w) {
2425: if (w == 0) {return ''};
1.2 ! albertel 2426: return jsMath.Browser.msieSpaceFix+'<span class="spacer" style="margin-left:'+this.Em(w)+'"></span>';
1.1 albertel 2427: },
2428:
2429: /*
2430: * Create a blank rectangle of the given size
2431: * If the height is small, it is converted to pixels so that it
2432: * will not disappear at small font sizes.
2433: */
2434:
2435: Blank: function (w,h,d,isRule) {
2436: var backspace = ''; var style = ''
2437: if (isRule) {
2438: style += 'border-left:'+this.Em(w)+' solid;';
2439: if (jsMath.Browser.widthAddsBorder) {w = 0};
2440: }
2441: if (w == 0) {
2442: if (jsMath.Browser.blankWidthBug) {
2443: style += 'width:1px;';
2444: backspace = '<span class="spacer" style="margin-right:-1px"></span>'
2445: }
2446: } else {style += 'width:'+this.Em(w)+';'}
2447: if (d == null) {d = 0}
2448: if (h) {
2449: var H = this.Em(h+d);
1.2 ! albertel 2450: if (isRule && h*jsMath.em < 1.5) {H = "1px"; h = 1/jsMath.em}
1.1 albertel 2451: style += 'height:'+H+';';
2452: }
2453: if (jsMath.Browser.mozInlineBlockBug) {d = -h}
2454: if (jsMath.Browser.msieBorderBug && !isRule) {d -= jsMath.d}
2455: if (d) {style += 'vertical-align:'+this.Em(-d)}
2456: return backspace+'<span class="blank" style="'+style+'"></span>';
2457: },
2458:
2459: /*
2460: * Create a rule line for fractions, etc.
2461: */
2462: Rule: function (w,h) {
2463: if (h == null) {h = jsMath.TeX.default_rule_thickness}
2464: return this.Blank(w,h,0,1);
2465: },
2466:
2467: /*
2468: * Add a <SPAN> tag to activate a specific CSS class
2469: */
2470: Class: function (tclass,html) {
2471: return '<span class="'+tclass+'">'+html+'</span>';
2472: },
2473:
2474: /*
2475: * Use a <SPAN> to place some HTML at a specific position.
2476: * (This can be replaced by the ones below to overcome
2477: * some browser-specific bugs.)
2478: */
2479: Place: function (html,x,y) {
2480: if (Math.abs(x) < .0001) {x = 0}
2481: if (Math.abs(y) < .0001) {y = 0}
2482: if (x || y) {
2483: var span = '<span style="position: relative;';
2484: if (x) {span += ' margin-left:'+this.Em(x)+';'}
2485: if (y) {span += ' top:'+this.Em(-y)+';'}
2486: html = span + '">' + html + '</span>';
2487: }
2488: return html;
2489: },
2490:
2491: /*
2492: * For MSIE on Windows, backspacing must be done in a separate
2493: * <SPAN>, otherwise the contents will be clipped. Netscape
2494: * also doesn't combine vertical and horizontal spacing well.
2495: * Here the x and y positioning are done in separate <SPAN> tags
2496: */
2497: PlaceSeparateSkips: function (html,x,y) {
2498: if (Math.abs(x) < .0001) {x = 0}
2499: if (Math.abs(y) < .0001) {y = 0}
2500: if (y) {html = '<span style="position: relative; top:'+this.Em(-y)+';'
2501: + '">' + html + '</span>'}
2502: if (x) {html = this.Spacer(x) + html}
2503: return html;
2504: },
2505:
2506: /*
2507: * Place a SPAN with absolute coordinates
2508: */
2509: PlaceAbsolute: function (html,x,y) {
2510: if (Math.abs(x) < .0001) {x = 0}
2511: if (Math.abs(y) < .0001) {y = 0}
2512: html = '<span style="position:absolute; left:'+this.Em(x)+'; '
2513: + 'top:'+this.Em(y)+';">' + html + ' </span>';
2514: // space normalizes line height in script styles
2515: return html;
2516: },
2517:
2518: Absolute: function(html,w,h,d,y,H) {
2519: if (y != "none") {
2520: if (Math.abs(y) < .0001) {y = 0}
2521: html = '<span style="position:absolute; '
2522: + 'top:'+jsMath.HTML.Em(y)+'; left:0em;">'
2523: + html + ' ' // space normalizes line height in script styles
2524: + '</span>';
2525: }
2526: if (d == "none") {d = 0}
2527: html += this.Blank(w,h-d,d);
2528: if (jsMath.Browser.msieAbsoluteBug) { // for MSIE (Mac)
2529: html = '<span style="position:relative;">' + html + '</span>';
2530: }
2531: html = '<span style="position:relative;'
2532: + ' width: '+jsMath.HTML.Em(w)+';' // for MSIE
2533: + ' height: '+jsMath.HTML.Em(H)+';' // for MSIE
2534: + jsMath.Browser.msieInlineBlockFix // for MSIE
2535: + '">'
2536: + html
2537: + '</span>';
2538: return html;
2539: }
2540:
2541: };
2542:
2543:
2544: /***************************************************************************/
2545:
2546: /*
2547: * jsMath.Box handles TeX's math boxes and jsMath's equivalent of hboxes.
2548: */
2549:
2550: jsMath.Box = function (format,text,w,h,d) {
2551: if (d == null) {d = jsMath.d}
2552: this.type = 'typeset';
2553: this.w = w; this.h = h; this.d = d; this.bh = h; this.bd = d;
2554: this.x = 0; this.y = 0;
2555: this.html = text; this.format = format;
2556: };
2557:
2558:
2559: jsMath.Add(jsMath.Box,{
2560:
2561: defaultH: 0, // default height for characters with none specified
2562:
2563: /*
2564: * An empty box
2565: */
2566: Null: new jsMath.Box('null','',0,0,0),
2567:
2568: /*
2569: * A box containing only text whose class and style haven't been added
2570: * yet (so that we can combine ones with the same styles). It gets
2571: * the text dimensions, if needed. (In general, this has been
2572: * replaced by TeX() below, but is still used in fallback mode.)
2573: */
2574: Text: function (text,tclass,style,size,a,d) {
2575: var html = jsMath.Typeset.AddClass(tclass,text);
2576: html = jsMath.Typeset.AddStyle(style,size,html);
2577: var BB = jsMath.EmBoxFor(html); var TeX = jsMath.Typeset.TeX(style,size);
2578: var bd = ((tclass == 'cmsy10' || tclass == 'cmex10')? BB.h-TeX.h: TeX.d*BB.h/TeX.hd);
2579: var box = new jsMath.Box('text',text,BB.w,BB.h-bd,bd);
2580: box.style = style; box.size = size; box.tclass = tclass;
2581: if (d != null) {box.d = d*TeX.scale} else {box.d = 0}
2582: if (a == null || a == 1) {box.h = .9*TeX.M_height}
2583: else {box.h = 1.1*TeX.x_height + TeX.scale*a}
2584: return box;
2585: },
2586:
2587: /*
2588: * Produce a box containing a given TeX character from a given font.
2589: * The box is a text box (like the ones above), so that characters from
2590: * the same font can be combined.
2591: */
2592: TeX: function (C,font,style,size) {
2593: var c = jsMath.TeX[font][C];
2594: if (c.d == null) {c.d = 0}; if (c.h == null) {c.h = 0}
2595: if (c.img != null && c.c != '') this.TeXIMG(font,C,jsMath.Typeset.StyleSize(style,size));
2596: var scale = jsMath.Typeset.TeX(style,size).scale;
2597: var h = c.h + jsMath.TeX[font].dh
2598: var box = new jsMath.Box('text',c.c,c.w*scale,h*scale,c.d*scale);
2599: box.style = style; box.size = size;
2600: if (c.tclass) {
2601: box.tclass = c.tclass;
2602: if (c.img) {box.bh = c.img.bh; box.bd = c.img.bd}
2603: else {box.bh = scale*jsMath.h; box.bd = scale*jsMath.d}
2604: } else {
2605: box.tclass = font;
2606: box.bh = scale*jsMath.TeX[font].h;
2607: box.bd = scale*jsMath.TeX[font].d;
2608: if (jsMath.Browser.msieFontBug && box.html.match(/&#/)) {
2609: // hack to avoid font changing back to the default
2610: // font when a unicode reference is not followed
2611: // by a letter or number
1.2 ! albertel 2612: box.html += '<span style="display:none">x</span>';
1.1 albertel 2613: }
2614: }
2615: return box;
2616: },
2617:
2618: /*
2619: * In fallback modes, handle the fact that we don't have the
2620: * sizes of the characters precomputed
2621: */
2622: TeXfallback: function (C,font,style,size) {
1.2 ! albertel 2623: var c = jsMath.TeX[font][C]; if (!c.tclass) {c.tclass = font}
1.1 albertel 2624: if (c.img != null) {return this.TeXnonfallback(C,font,style,size)}
2625: if (c.h != null && c.a == null) {c.a = c.h-1.1*jsMath.TeX.x_height}
1.2 ! albertel 2626: var box = this.Text(c.c,c.tclass,style,size,c.a || 0,c.d || 0);
1.1 albertel 2627: var scale = jsMath.Typeset.TeX(style,size).scale;
2628: if (c.bh != null) {
2629: box.bh = c.bh*scale;
2630: box.bd = c.bd*scale;
2631: } else {
2632: var h = box.bd+box.bh;
2633: var html = jsMath.Typeset.AddClass(box.tclass,box.html);
2634: html = jsMath.Typeset.AddStyle(style,size,html);
2635: box.bd = jsMath.EmBoxFor(html+jsMath.HTML.Blank(1,h)).h - h;
2636: box.bh = h - box.bd;
2637: if (scale == 1) {c.bh = box.bh; c.bd = box.bd}
2638: }
2639: if (jsMath.msieFontBug && box.html.match(/&#/))
2640: {box.html += '<span style="display:none">x</span>'}
2641: return box;
2642: },
2643:
2644: /*
2645: * Set the character's string to the appropriate image file
2646: */
2647: TeXIMG: function (font,C,size) {
2648: var c = jsMath.TeX[font][C];
2649: if (c.img.size != null && c.img.size == size &&
2650: c.img.best != null && c.img.best == jsMath.Img.best) return;
2651: var mustScale = (jsMath.Img.scale != 1);
2652: var id = jsMath.Img.best + size - 4;
2653: if (id < 0) {id = 0; mustScale = 1} else
2654: if (id >= jsMath.Img.fonts.length) {id = jsMath.Img.fonts.length-1; mustScale = 1}
2655: var imgFont = jsMath.Img[jsMath.Img.fonts[id]];
2656: var img = imgFont[font][C];
2657: var scale = 1/jsMath.Img.w[jsMath.Img.fonts[id]];
2658: if (id != jsMath.Img.best + size - 4) {
2659: if (c.w != null) {scale = c.w/img[0]} else {
2660: scale *= jsMath.Img.fonts[size]/jsMath.Img.fonts[4]
2661: * jsMath.Img.fonts[jsMath.Img.best]/jsMath.Img.fonts[id];
2662: }
2663: }
2664: var w = img[0]*scale; var h = img[1]*scale; var d = -img[2]*scale; var v;
2665: var wadjust = (c.w == null || Math.abs(c.w-w) < .01)? "" : " margin-right:"+jsMath.HTML.Em(c.w-w)+';';
2666: var resize = ""; C = jsMath.Img.HexCode[C];
2667: if (!mustScale && !jsMath.Controls.cookie.scaleImg) {
2668: if (2*w < h || (jsMath.Browser.msieAlphaBug && jsMath.Controls.cookie.alpha))
2669: {resize = "height:"+(img[1]*jsMath.Browser.imgScale)+'px;'}
2670: resize += " width:"+(img[0]*jsMath.Browser.imgScale)+'px;'
2671: v = -img[2]+'px';
2672: } else {
2673: if (2*w < h || (jsMath.Browser.msieAlphaBug && jsMath.Controls.cookie.alpha))
2674: {resize = "height:"+jsMath.HTML.Em(h*jsMath.Browser.imgScale)+';'}
2675: resize += " width:"+jsMath.HTML.Em(w*jsMath.Browser.imgScale)+';'
2676: v = jsMath.HTML.Em(d);
2677: }
2678: var vadjust = (Math.abs(d) < .01 && !jsMath.Browser.valignBug)?
2679: "": " vertical-align:"+v+';';
2680: var URL = jsMath.Img.URL(font,jsMath.Img.fonts[id],C);
2681: if (jsMath.Browser.msieAlphaBug && jsMath.Controls.cookie.alpha) {
2682: c.c = '<img src="'+jsMath.blank+'" '
2683: + 'style="'+jsMath.Browser.msieCenterBugFix
2684: + resize + vadjust + wadjust
2685: + ' filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + "'"
2686: + URL + "', sizingMethod='scale'" + ');" />';
2687: } else {
2688: c.c = '<img src="'+URL+'" style="'+jsMath.Browser.msieCenterBugFix
2689: + resize + vadjust + wadjust + '" />';
2690: }
2691: c.tclass = "normal";
2692: c.img.bh = h+d; c.img.bd = -d;
2693: c.img.size = size; c.img.best = jsMath.Img.best;
2694: },
2695:
2696: /*
2697: * A box containing a spacer of a specific width
2698: */
2699: Space: function (w) {
2700: return new jsMath.Box('html',jsMath.HTML.Spacer(w),w,0,0);
2701: },
2702:
2703: /*
2704: * A box containing a horizontal rule
2705: */
2706: Rule: function (w,h) {
2707: if (h == null) {h = jsMath.TeX.default_rule_thickness}
2708: var html = jsMath.HTML.Rule(w,h);
2709: return new jsMath.Box('html',html,w,h,0);
2710: },
2711:
2712: /*
2713: * Get a character from a TeX font, and make sure that it has
2714: * its metrics specified.
2715: */
2716: GetChar: function (code,font) {
2717: var c = jsMath.TeX[font][code];
2718: if (c.img != null) {this.TeXIMG(font,code,4)}
2719: if (c.tclass == null) {c.tclass = font}
2720: if (!c.computedW) {
2721: c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w;
2722: if (c.h == null) {c.h = jsMath.Box.defaultH}; if (c.d == null) {c.d = 0}
2723: c.computedW = 1;
2724: }
2725: return c;
2726: },
2727:
2728: /*
2729: * Locate the TeX delimiter character that matches a given height.
2730: * Return the character, font, style and actual height used.
2731: */
2732: DelimBestFit: function (H,c,font,style) {
2733: if (c == 0 && font == 0) return null;
2734: var C; var h; font = jsMath.TeX.fam[font];
2735: var isSS = (style.charAt(1) == 'S');
2736: var isS = (style.charAt(0) == 'S');
2737: while (c != null) {
2738: C = jsMath.TeX[font][c];
2739: if (C.h == null) {C.h = jsMath.Box.defaultH}; if (C.d == null) {C.d = 0}
2740: h = C.h+C.d;
2741: if (C.delim) {return [c,font,'',H]}
2742: if (isSS && .5*h >= H) {return [c,font,'SS',.5*h]}
2743: if (isS && .7*h >= H) {return [c,font,'S',.7*h]}
2744: if (h >= H || C.n == null) {return [c,font,'T',h]}
2745: c = C.n;
2746: }
2747: return null;
2748: },
2749:
2750: /*
2751: * Create the HTML needed for a stretchable delimiter of a given height,
2752: * either centered or not. This version uses relative placement (i.e.,
2753: * backspaces, not line-breaks). This works with more browsers, but
2754: * if the font size changes, the backspacing may not be right, so the
2755: * delimiters may become jagged.
2756: */
2757: DelimExtendRelative: function (H,c,font,a,nocenter) {
2758: var C = jsMath.TeX[font][c];
2759: var top = this.GetChar(C.delim.top? C.delim.top: C.delim.rep,font);
2760: var rep = this.GetChar(C.delim.rep,font);
2761: var bot = this.GetChar(C.delim.bot? C.delim.bot: C.delim.rep,font);
2762: var ext = jsMath.Typeset.AddClass(rep.tclass,rep.c);
2763: var w = rep.w; var h = rep.h+rep.d
2764: var y; var dx;
2765: if (C.delim.mid) {// braces
2766: var mid = this.GetChar(C.delim.mid,font);
2767: var n = Math.ceil((H-(top.h+top.d)-(mid.h+mid.d)-(bot.h+bot.d))/(2*(rep.h+rep.d)));
2768: H = 2*n*(rep.h+rep.d) + (top.h+top.d) + (mid.h+mid.d) + (bot.h+bot.d);
2769: if (nocenter) {y = 0} else {y = H/2+a}; var Y = y;
2770: var html = jsMath.HTML.Place(jsMath.Typeset.AddClass(top.tclass,top.c),0,y-top.h)
2771: + jsMath.HTML.Place(jsMath.Typeset.AddClass(bot.tclass,bot.c),-(top.w+bot.w)/2,y-(H-bot.d))
2772: + jsMath.HTML.Place(jsMath.Typeset.AddClass(mid.tclass,mid.c),-(bot.w+mid.w)/2,y-(H+mid.h-mid.d)/2);
2773: dx = (w-mid.w)/2; if (Math.abs(dx) < .0001) {dx = 0}
2774: if (dx) {html += jsMath.HTML.Spacer(dx)}
2775: y -= top.h+top.d + rep.h;
2776: for (var i = 0; i < n; i++) {html += jsMath.HTML.Place(ext,-w,y-i*h)}
2777: y -= H/2 - rep.h/2;
2778: for (var i = 0; i < n; i++) {html += jsMath.HTML.Place(ext,-w,y-i*h)}
2779: } else {// everything else
2780: var n = Math.ceil((H - (top.h+top.d) - (bot.h+bot.d))/(rep.h+rep.d));
2781: // make sure two-headed arrows have an extender
2782: if (top.h+top.d < .9*(rep.h+rep.d)) {n = Math.max(1,n)}
2783: H = n*(rep.h+rep.d) + (top.h+top.d) + (bot.h+bot.d);
2784: if (nocenter) {y = 0} else {y = H/2+a}; var Y = y;
2785: var html = jsMath.HTML.Place(jsMath.Typeset.AddClass(top.tclass,top.c),0,y-top.h)
2786: dx = (w-top.w)/2; if (Math.abs(dx) < .0001) {dx = 0}
2787: if (dx) {html += jsMath.HTML.Spacer(dx)}
2788: y -= top.h+top.d + rep.h;
2789: for (var i = 0; i < n; i++) {html += jsMath.HTML.Place(ext,-w,y-i*h)}
2790: html += jsMath.HTML.Place(jsMath.Typeset.AddClass(bot.tclass,bot.c),-(w+bot.w)/2,Y-(H-bot.d));
2791: }
2792: if (nocenter) {h = top.h} else {h = H/2+a}
2793: var box = new jsMath.Box('html',html,rep.w,h,H-h);
2794: box.bh = jsMath.TeX[font].h; box.bd = jsMath.TeX[font].d;
2795: return box;
2796: },
2797:
2798: /*
2799: * Create the HTML needed for a stretchable delimiter of a given height,
2800: * either centered or not. This version uses absolute placement (i.e.,
2801: * line-breaks, not backspacing). This gives more reliable results,
2802: * but doesn't work with all browsers.
2803: */
2804: DelimExtendAbsolute: function (H,c,font,a,nocenter) {
2805: var Font = jsMath.TeX[font];
1.2 ! albertel 2806: var C = Font[c]; var html;
1.1 albertel 2807: var top = this.GetChar(C.delim.top? C.delim.top: C.delim.rep,font);
2808: var rep = this.GetChar(C.delim.rep,font);
2809: var bot = this.GetChar(C.delim.bot? C.delim.bot: C.delim.rep,font);
2810:
2811: if (C.delim.mid) {// braces
2812: var mid = this.GetChar(C.delim.mid,font);
2813: var n = Math.ceil((H-(top.h+top.d)-(mid.h+mid.d-.05)-(bot.h+bot.d-.05))/(2*(rep.h+rep.d-.05)));
2814: H = 2*n*(rep.h+rep.d-.05) + (top.h+top.d) + (mid.h+mid.d-.05) + (bot.h+bot.d-.05);
2815:
2816: html = jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(top.tclass,top.c),0,0);
2817: var h = rep.h+rep.d - .05; var y = top.d-.05 + rep.h;
2818: var ext = jsMath.Typeset.AddClass(font,rep.c)
2819: for (var i = 0; i < n; i++) {html += jsMath.HTML.PlaceAbsolute(ext,0,y+i*h)}
2820: html += jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(mid.tclass,mid.c),0,y+n*h-rep.h+mid.h);
2821: y += n*h + mid.h+mid.d - .05;
2822: for (var i = 0; i < n; i++) {html += jsMath.HTML.PlaceAbsolute(ext,0,y+i*h)}
2823: html += jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(bot.tclass,bot.c),0,y+n*h-rep.h+bot.h);
2824: } else {// all others
2825: var n = Math.ceil((H - (top.h+top.d) - (bot.h+bot.d-.05))/(rep.h+rep.d-.05));
2826: H = n*(rep.h+rep.d-.05) + (top.h+top.d) + (bot.h+bot.d-.05);
2827:
2828: html = jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(top.tclass,top.c),0,0);
2829: var h = rep.h+rep.d-.05; var y = top.d-.05 + rep.h;
2830: var ext = jsMath.Typeset.AddClass(rep.tclass,rep.c);
2831: for (var i = 0; i < n; i++) {html += jsMath.HTML.PlaceAbsolute(ext,0,y+i*h)}
2832: html += jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(bot.tclass,bot.c),0,y+n*h-rep.h+bot.h);
2833: }
2834:
2835: var w = top.w;
2836: if (nocenter) {h = top.h; y = 0} else {h = H/2 + a; y = h - top.h}
2837: html = jsMath.HTML.Absolute(html,w,Font.h,"none",-y,top.h);
2838: var box = new jsMath.Box('html',html,rep.w,h,H-h);
2839: box.bh = jsMath.TeX[font].h; box.bd = jsMath.TeX[font].d;
2840: return box;
2841: },
2842:
2843: /*
2844: * Get the HTML for a given delimiter of a given height.
2845: * It will return either a single character, if one exists, or the
2846: * more complex HTML needed for a stretchable delimiter.
2847: */
2848: Delimiter: function (H,delim,style,nocenter) {
2849: var size = 4; //### pass this?
2850: var TeX = jsMath.Typeset.TeX(style,size);
2851: if (!delim) {return this.Space(TeX.nulldelimiterspace)}
2852: var CFSH = this.DelimBestFit(H,delim[2],delim[1],style);
2853: if (CFSH == null || CFSH[3] < H)
2854: {CFSH = this.DelimBestFit(H,delim[4],delim[3],style)}
2855: if (CFSH == null) {return this.Space(TeX.nulldelimiterspace)}
2856: if (CFSH[2] == '')
2857: {return this.DelimExtend(H,CFSH[0],CFSH[1],TeX.axis_height,nocenter)}
1.2 ! albertel 2858: var box = jsMath.Box.TeX(CFSH[0],CFSH[1],CFSH[2],size).Styled();
1.1 albertel 2859: if (nocenter) {box.y = -jsMath.TeX[CFSH[1]].dh*TeX.scale}
2860: else {box.y = -((box.h+box.d)/2 - box.d - TeX.axis_height)}
2861: if (Math.abs(box.y) < .0001) {box.y = 0}
2862: if (box.y) {box = jsMath.Box.SetList([box],CFSH[2],size)}
2863: return box;
2864: },
2865:
2866: /*
2867: * Get a character by its TeX charcode, and make sure its width
2868: * is specified.
2869: */
2870: GetCharCode: function (code) {
2871: var font = jsMath.TeX.fam[code[0]];
2872: var Font = jsMath.TeX[font];
2873: var c = Font[code[1]];
2874: if (c.img != null) {this.TeXIMG(font,code[1],4)}
2875: if (c.w == null) {c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w}
2876: if (c.font == null) {c.font = font}
2877: return c;
2878: },
2879:
2880: /*
2881: * Add the class to the html, and use the font if there isn't one
2882: * specified already
2883: */
2884:
2885: AddClass: function (tclass,html,font) {
2886: if (tclass == null) {tclass = font}
2887: return jsMath.Typeset.AddClass(tclass,html);
2888: },
2889:
2890: /*
2891: * Create the HTML for an alignment (e.g., array or matrix)
2892: * Since the widths are not really accurate (they are based on pixel
2893: * widths not the sub-pixel widths of the actual characters), there
2894: * is some drift involved. We lay out the table column by column
2895: * to help reduce the problem.
2896: *
2897: * ### still need to allow users to specify row and column attributes,
2898: * and do things like \span and \multispan ###
2899: */
1.2 ! albertel 2900: LayoutRelative: function (size,table,align,cspacing,rspacing,vspace) {
1.1 albertel 2901: if (align == null) {align = []}
2902: if (cspacing == null) {cspacing = []}
1.2 ! albertel 2903: if (rspacing == null) {rspacing = []}
1.1 albertel 2904:
2905: // get row and column maximum dimensions
2906: var scale = jsMath.sizes[size]/100;
2907: var W = []; var H = []; var D = [];
2908: var unset = -1000; var bh = unset; var bd = unset;
2909: var i; var j; var row;
2910: for (i = 0; i < table.length; i++) {
1.2 ! albertel 2911: if (rspacing[i] == null) {rspacing[i] = 0}
1.1 albertel 2912: row = table[i]; H[i] = jsMath.h*scale; D[i] = jsMath.d*scale;
2913: for (j = 0; j < row.length; j++) {
2914: row[j] = row[j].Remeasured();
2915: if (row[j].h > H[i]) {H[i] = row[j].h}
2916: if (row[j].d > D[i]) {D[i] = row[j].d}
2917: if (j >= W.length) {W[j] = row[j].w}
2918: else if (row[j].w > W[j]) {W[j] = row[j].w}
2919: if (row[j].bh > bh) {bh = row[j].bh}
2920: if (row[j].bd > bd) {bd = row[j].bd}
2921: }
2922: }
1.2 ! albertel 2923: if (rspacing[table.length] == null) {rspacing[table.length] = 0}
1.1 albertel 2924: if (bh == unset) {bh = 0}; if (bd == unset) {bd = 0}
2925:
2926: // lay out the columns
2927: var HD = (jsMath.hd-.01)*scale;
1.2 ! albertel 2928: var dy = (vspace || 1) * scale/6;
1.1 albertel 2929: var html = ''; var pW = 0; var cW = 0;
2930: var w; var h; var y;
2931: var box; var mlist; var entry;
2932: for (j = 0; j < W.length; j++) {
1.2 ! albertel 2933: mlist = []; y = -H[0]-rspacing[0]; pW = 0;
1.1 albertel 2934: for (i = 0; i < table.length; i++) {
2935: entry = table[i][j];
2936: if (entry && entry.format != 'null') {
2937: if (align[j] == 'l') {w = 0} else
2938: if (align[j] == 'r') {w = W[j] - entry.w} else
2939: {w = (W[j] - entry.w)/2}
2940: entry.x = w - pW; pW = entry.w + w; entry.y = y;
2941: mlist[mlist.length] = entry;
2942: }
1.2 ! albertel 2943: if (i+1 < table.length) {y -= Math.max(HD,D[i]+H[i+1]) + dy + rspacing[i+1]}
1.1 albertel 2944: }
2945: if (cspacing[j] == null) cspacing[j] = scale;
2946: if (mlist.length > 0) {
2947: box = jsMath.Box.SetList(mlist,'T',size);
2948: html += jsMath.HTML.Place(box.html,cW,0);
2949: cW = W[j] - box.w + cspacing[j];
2950: } else {cW += cspacing[j]}
2951: }
2952:
2953: // get the full width and height
1.2 ! albertel 2954: w = -cspacing[W.length-1]; y = (H.length-1)*dy + rspacing[0];
1.1 albertel 2955: for (i = 0; i < W.length; i++) {w += W[i] + cspacing[i]}
1.2 ! albertel 2956: for (i = 0; i < H.length; i++) {y += Math.max(HD,H[i]+D[i]) + rspacing[i+1]}
1.1 albertel 2957: h = y/2 + jsMath.TeX.axis_height; var d = y-h;
2958:
2959: // adjust the final row width, and vcenter the table
2960: // (add 1/6em at each side for the \,)
2961: html += jsMath.HTML.Spacer(cW-cspacing[W.length-1] + scale/6);
2962: html = jsMath.HTML.Place(html,scale/6,h);
2963: box = new jsMath.Box('html',html,w+scale/3,h,d);
2964: box.bh = bh; box.bd = bd;
2965: return box;
2966: },
2967:
2968: /*
2969: * Create the HTML for an alignment (e.g., array or matrix)
2970: * Use absolute position for elements in the array.
2971: *
2972: * ### still need to allow users to specify row and column attributes,
2973: * and do things like \span and \multispan ###
2974: */
1.2 ! albertel 2975: LayoutAbsolute: function (size,table,align,cspacing,rspacing,vspace) {
1.1 albertel 2976: if (align == null) {align = []}
2977: if (cspacing == null) {cspacing = []}
1.2 ! albertel 2978: if (rspacing == null) {rspacing = []}
1.1 albertel 2979:
2980: // get row and column maximum dimensions
2981: var scale = jsMath.sizes[size]/100;
2982: var HD = (jsMath.hd-.01)*scale;
1.2 ! albertel 2983: var dy = (vspace || 1) * scale/6;
1.1 albertel 2984: var W = []; var H = []; var D = [];
2985: var w = 0; var h; var x; var y;
2986: var i; var j; var row;
2987: for (i = 0; i < table.length; i++) {
1.2 ! albertel 2988: if (rspacing[i] == null) {rspacing[i] = 0}
1.1 albertel 2989: row = table[i];
2990: H[i] = jsMath.h*scale; D[i] = jsMath.d*scale;
2991: for (j = 0; j < row.length; j++) {
2992: row[j] = row[j].Remeasured();
2993: if (row[j].h > H[i]) {H[i] = row[j].h}
2994: if (row[j].d > D[i]) {D[i] = row[j].d}
2995: if (j >= W.length) {W[j] = row[j].w}
2996: else if (row[j].w > W[j]) {W[j] = row[j].w}
2997: }
2998: }
1.2 ! albertel 2999: if (rspacing[table.length] == null) {rspacing[table.length] = 0}
1.1 albertel 3000:
3001: // get the height and depth of the centered table
1.2 ! albertel 3002: y = (H.length-1)*dy + rspacing[0];
! 3003: for (i = 0; i < H.length; i++) {y += Math.max(HD,H[i]+D[i]) + rspacing[i+1]}
1.1 albertel 3004: h = y/2 + jsMath.TeX.axis_height; var d = y - h;
3005:
3006: // lay out the columns
3007: var html = ''; var entry; w = scale/6;
3008: for (j = 0; j < W.length; j++) {
1.2 ! albertel 3009: y = H[0]-h + rspacing[0];
1.1 albertel 3010: for (i = 0; i < table.length; i++) {
3011: entry = table[i][j];
3012: if (entry && entry.format != 'null') {
1.2 ! albertel 3013: if (align[j] && align[j] == 'l') {x = 0} else
! 3014: if (align[j] && align[j] == 'r') {x = W[j] - entry.w} else
1.1 albertel 3015: {x = (W[j] - entry.w)/2}
3016: html += jsMath.HTML.PlaceAbsolute(entry.html,w+x,
3017: y-Math.max(0,entry.bh-jsMath.h*scale));
3018: }
1.2 ! albertel 3019: if (i+1 < table.length) {y += Math.max(HD,D[i]+H[i+1]) + dy + rspacing[i+1]}
1.1 albertel 3020: }
3021: if (cspacing[j] == null) cspacing[j] = scale;
3022: w += W[j] + cspacing[j];
3023: }
3024:
3025: // get the full width
3026: w = -cspacing[W.length-1]+scale/3;
3027: for (i = 0; i < W.length; i++) {w += W[i] + cspacing[i]}
3028:
3029: html = jsMath.HTML.Spacer(scale/6)+html+jsMath.HTML.Spacer(scale/6);
3030: if (jsMath.Browser.spanHeightVaries) {y = h-jsMath.h} else {y = 0}
3031: html = jsMath.HTML.Absolute(html,w,h+d,d,y,H[0]);
3032: var box = new jsMath.Box('html',html,w+scale/3,h,d);
3033: return box;
3034: },
3035:
3036: /*
3037: * Look for math within \hbox and other non-math text
3038: */
3039: InternalMath: function (text,size) {
3040: if (!text.match(/\$|\\\(/)) {return this.Text(text,'normal','T',size).Styled()}
3041:
3042: var i = 0; var k = 0; var c; var match = '';
3043: var mlist = []; var parse; var html; var box;
3044: while (i < text.length) {
3045: c = text.charAt(i++);
3046: if (c == '$') {
3047: if (match == '$') {
3048: parse = jsMath.Parse(text.slice(k,i-1),null,size);
3049: if (parse.error) {
3050: mlist[mlist.length] = this.Text(parse.error,'error','T',size,1,.2);
3051: } else {
3052: parse.Atomize();
3053: mlist[mlist.length] = parse.mlist.Typeset('T',size).Styled();
3054: }
3055: match = ''; k = i;
3056: } else {
3057: mlist[mlist.length] = this.Text(text.slice(k,i-1),'normal','T',size,1,.2);
3058: match = '$'; k = i;
3059: }
3060: } else if (c == '\\') {
3061: c = text.charAt(i++);
3062: if (c == '(' && match == '') {
3063: mlist[mlist.length] = this.Text(text.slice(k,i-2),'normal','T',size,1,.2);
3064: match = ')'; k = i;
3065: } else if (c == ')' && match == ')') {
3066: parse = jsMath.Parse(text.slice(k,i-2),null,size);
3067: if (parse.error) {
3068: mlist[mlist.length] = this.Text(parse.error,'error','T',size,1,.2);
3069: } else {
3070: parse.Atomize();
3071: mlist[mlist.length] = parse.mlist.Typeset('T',size).Styled();
3072: }
3073: match = ''; k = i;
3074: }
3075: }
3076: }
3077: mlist[mlist.length] = this.Text(text.slice(k),'normal','T',size,1,.2);
3078: return this.SetList(mlist,'T',size);
3079: },
3080:
3081: /*
3082: * Convert an abitrary box to a typeset box. I.e., make an
3083: * HTML version of the contents of the box, at its desired (x,y)
3084: * position.
3085: */
3086: Set: function (box,style,size,addstyle) {
3087: if (box && box.type) {
3088: if (box.type == 'typeset') {return box}
3089: if (box.type == 'mlist') {
3090: box.mlist.Atomize(style,size);
3091: return box.mlist.Typeset(style,size);
3092: }
3093: if (box.type == 'text') {
1.2 ! albertel 3094: box = this.Text(box.text,box.tclass,style,size,box.ascend||null,box.descend||null);
1.1 albertel 3095: if (addstyle != 0) {box.Styled()}
3096: return box;
3097: }
3098: box = this.TeX(box.c,box.font,style,size);
3099: if (addstyle != 0) {box.Styled()}
3100: return box;
3101: }
3102: return jsMath.Box.Null;
3103: },
3104:
3105: /*
3106: * Convert a list of boxes to a single typeset box. I.e., finalize
3107: * the HTML for the list of boxes, properly spaced and positioned.
3108: */
3109: SetList: function (boxes,style,size) {
3110: var mlist = []; var box;
3111: for (var i = 0; i < boxes.length; i++) {
3112: box = boxes[i];
3113: if (box.type == 'typeset') {box = jsMath.mItem.Typeset(box)}
3114: mlist[mlist.length] = box;
3115: }
3116: var typeset = new jsMath.Typeset(mlist);
3117: return typeset.Typeset(style,size);
3118: }
3119:
3120: });
3121:
3122:
3123: jsMath.Package(jsMath.Box,{
3124:
3125: /*
3126: * Add the class and style to a text box (i.e., finalize the
3127: * unpositioned HTML for the box).
3128: */
3129: Styled: function () {
3130: if (this.format == 'text') {
3131: this.html = jsMath.Typeset.AddClass(this.tclass,this.html);
3132: this.html = jsMath.Typeset.AddStyle(this.style,this.size,this.html);
3133: delete this.tclass; delete this.style;
3134: this.format = 'html';
3135: }
3136: return this;
3137: },
3138:
3139: /*
3140: * Recompute the box width to make it more accurate.
3141: */
3142: Remeasured: function () {
1.2 ! albertel 3143: if (this.w > 0) {this.w = jsMath.EmBoxFor(this.html).w}
1.1 albertel 3144: return this;
3145: }
3146:
3147: });
3148:
3149:
3150: /***************************************************************************/
3151:
3152: /*
3153: * mItems are the building blocks of mLists (math lists) used to
3154: * store the information about a mathematical expression. These are
3155: * basically the items listed in the TeXbook in Appendix G (plus some
3156: * minor extensions).
3157: */
3158: jsMath.mItem = function (type,def) {
3159: this.type = type;
3160: jsMath.Add(this,def);
3161: }
3162:
3163: jsMath.Add(jsMath.mItem,{
3164:
3165: /*
3166: * A general atom (given a nucleus for the atom)
3167: */
3168: Atom: function (type,nucleus) {
3169: return new jsMath.mItem(type,{atom: 1, nuc: nucleus});
3170: },
3171:
3172: /*
3173: * An atom whose nucleus is a piece of text, in a given
3174: * class, with a given additional height and depth
3175: */
3176: TextAtom: function (type,text,tclass,a,d) {
3177: var atom = new jsMath.mItem(type,{
3178: atom: 1,
3179: nuc: {
3180: type: 'text',
3181: text: text,
3182: tclass: tclass
3183: }
3184: });
3185: if (a != null) {atom.nuc.ascend = a}
3186: if (d != null) {atom.nuc.descend = d}
3187: return atom;
3188: },
3189:
3190: /*
3191: * An atom whose nucleus is a TeX character in a specific font
3192: */
3193: TeXAtom: function (type,c,font) {
3194: return new jsMath.mItem(type,{
3195: atom: 1,
3196: nuc: {
3197: type: 'TeX',
3198: c: c,
3199: font: font
3200: }
3201: });
3202: },
3203:
3204: /*
3205: * A generalized fraction atom, with given delimiters, rule
3206: * thickness, and a numerator and denominator.
3207: */
3208: Fraction: function (name,num,den,thickness,left,right) {
3209: return new jsMath.mItem('fraction',{
3210: from: name, num: num, den: den,
3211: thickness: thickness, left: left, right: right
3212: });
3213: },
3214:
3215: /*
3216: * An atom that inserts some glue
3217: */
3218: Space: function (w) {return new jsMath.mItem('space',{w: w})},
3219:
3220: /*
3221: * An atom that contains a typeset box (like an hbox or vbox)
3222: */
3223: Typeset: function (box) {return new jsMath.mItem('ord',{atom:1, nuc: box})},
3224:
3225: /*
3226: * An atom that contains some finished HTML (acts like a typeset box)
3227: */
3228: HTML: function (html) {return new jsMath.mItem('html',{html: html})}
3229:
3230: });
3231:
3232: /***************************************************************************/
3233:
3234: /*
3235: * mLists are lists of mItems, and encode the contents of
3236: * mathematical expressions and sub-expressions. They act as
3237: * the expression "stack" as the mathematics is parsed, and
3238: * contain some state information, like the position of the
3239: * most recent open paren and \over command, and the current font.
3240: */
3241: jsMath.mList = function (list,font,size,style) {
3242: if (list) {this.mlist = list} else {this.mlist = []}
3243: if (style == null) {style = 'T'}; if (size == null) {size = 4}
3244: this.data = {openI: null, overI: null, overF: null,
3245: font: font, size: size, style: style};
3246: this.init = {size: size, style: style};
3247: }
3248:
3249: jsMath.Package(jsMath.mList,{
3250:
3251: /*
3252: * Add an mItem to the list
3253: */
3254: Add: function (box) {return (this.mlist[this.mlist.length] = box)},
3255:
3256: /*
3257: * Get the i-th mItem from the list
3258: */
3259: Get: function (i) {return this.mlist[i]},
3260:
3261: /*
3262: * Get the length of the list
3263: */
3264: Length: function() {return this.mlist.length},
3265:
3266: /*
3267: * Get the tail mItem of the list
3268: */
3269: Last: function () {
3270: if (this.mlist.length == 0) {return null}
3271: return this.mlist[this.mlist.length-1]
3272: },
3273:
3274: /*
3275: * Get a sublist of an mList
3276: */
3277: Range: function (i,j) {
3278: if (j == null) {j = this.mlist.length}
3279: return new jsMath.mList(this.mlist.slice(i,j+1));
3280: },
3281:
3282: /*
3283: * Remove a range of mItems from the list.
3284: */
3285: Delete: function (i,j) {
3286: if (j == null) {j = i}
3287: if (this.mlist.splice) {this.mlist.splice(i,j-i+1)} else {
3288: var mlist = [];
3289: for (var k = 0; k < this.mlist.length; k++)
3290: {if (k < i || k > j) {mlist[mlist.length] = this.mlist[k]}}
3291: this.mlist = mlist;
3292: }
3293: },
3294:
3295: /*
3296: * Add an open brace and maintain the stack information
3297: * about the previous open brace so we can recover it
3298: * when this one os closed.
3299: */
3300: Open: function (left) {
3301: var box = this.Add(new jsMath.mItem('boundary',{data: this.data}));
3302: var olddata = this.data;
3303: this.data = {}; for (var i in olddata) {this.data[i] = olddata[i]}
3304: delete this.data.overI; delete this.data.overF;
3305: this.data.openI = this.mlist.length-1;
3306: if (left != null) {box.left = left}
3307: return box;
3308: },
3309:
3310: /*
3311: * Attempt to close a brace. Recover the stack information
3312: * about previous open braces and \over commands. If there was an
3313: * \over (or \above, etc) in this set of braces, create a fraction
3314: * atom from the two halves, otherwise create an inner or ord
3315: * from the contents of the braces.
3316: * Remove the braced material from the list and add the newly
3317: * created atom (the fraction, inner or ord).
3318: */
3319: Close: function (right) {
3320: if (right != null) {right = new jsMath.mItem('boundary',{right: right})}
3321: var atom; var open = this.data.openI;
3322: var over = this.data.overI; var from = this.data.overF;
3323: this.data = this.mlist[open].data;
3324: if (over) {
3325: atom = jsMath.mItem.Fraction(from.name,
3326: {type: 'mlist', mlist: this.Range(open+1,over-1)},
3327: {type: 'mlist', mlist: this.Range(over)},
3328: from.thickness,from.left,from.right);
3329: if (right) {
3330: var mlist = new jsMath.mList([this.mlist[open],atom,right]);
3331: atom = jsMath.mItem.Atom('inner',{type: 'mlist', mlist: mlist});
3332: }
3333: } else {
3334: var openI = open+1; if (right) {this.Add(right); openI--}
3335: atom = jsMath.mItem.Atom((right)?'inner':'ord',
3336: {type: 'mlist', mlist: this.Range(openI)});
3337: }
3338: this.Delete(open,this.Length());
3339: return this.Add(atom);
3340: },
3341:
3342: /*
3343: * Create a generalized fraction from an mlist that
3344: * contains an \over (or \above, etc).
3345: */
3346: Over: function () {
3347: var over = this.data.overI; var from = this.data.overF;
3348: var atom = jsMath.mItem.Fraction(from.name,
3349: {type: 'mlist', mlist: this.Range(open+1,over-1)},
3350: {type: 'mlist', mlist: this.Range(over)},
3351: from.thickness,from.left,from.right);
3352: this.mlist = [atom];
3353: },
3354:
3355: /*
3356: * Take a raw mList (that has been produced by parsing some TeX
3357: * expression), and perform the modifications outlined in
3358: * Appendix G of the TeXbook.
3359: */
3360: Atomize: function (style,size) {
3361: var mitem; var prev = '';
3362: this.style = style; this.size = size;
3363: for (var i = 0; i < this.mlist.length; i++) {
3364: mitem = this.mlist[i]; mitem.delta = 0;
3365: if (mitem.type == 'choice')
3366: {this.mlist = this.Atomize.choice(this.style,mitem,i,this.mlist); i--}
3367: else if (this.Atomize[mitem.type]) {
3368: var f = this.Atomize[mitem.type]; // Opera needs separate name
3369: f(this.style,this.size,mitem,prev,this,i);
3370: }
3371: prev = mitem;
3372: }
3373: if (mitem && mitem.type == 'bin') {mitem.type = 'ord'}
3374: if (this.mlist.length >= 2 && mitem.type == 'boundary' &&
3375: this.mlist[0].type == 'boundary') {this.AddDelimiters(style,size)}
3376: },
3377:
3378: /*
3379: * For a list that has boundary delimiters as its first and last
3380: * entries, we replace the boundary atoms by open and close
3381: * atoms whose nuclii are the specified delimiters properly sized
3382: * for the contents of the list. (Rule 19)
3383: */
3384: AddDelimiters: function(style,size) {
3385: var unset = -10000; var h = unset; var d = unset;
3386: for (var i = 0; i < this.mlist.length; i++) {
1.2 ! albertel 3387: var mitem = this.mlist[i];
1.1 albertel 3388: if (mitem.atom || mitem.type == 'box') {
3389: h = Math.max(h,mitem.nuc.h+mitem.nuc.y);
3390: d = Math.max(d,mitem.nuc.d-mitem.nuc.y);
3391: }
3392: }
3393: var TeX = jsMath.TeX; var a = jsMath.Typeset.TeX(style,size).axis_height;
3394: var delta = Math.max(h-a,d+a);
3395: var H = Math.max(Math.floor(TeX.integer*delta/500)*TeX.delimiterfactor,
3396: TeX.integer*(2*delta-TeX.delimitershortfall))/TeX.integer;
3397: var left = this.mlist[0]; var right = this.mlist[this.mlist.length-1];
3398: left.nuc = jsMath.Box.Delimiter(H,left.left,style);
3399: right.nuc = jsMath.Box.Delimiter(H,right.right,style);
3400: left.type = 'open'; left.atom = 1; delete left.left;
3401: right.type = 'close'; right.atom = 1; delete right.right;
3402: },
3403:
3404: /*
3405: * Typeset a math list to produce final HTML for the list.
3406: */
3407: Typeset: function (style,size) {
3408: var typeset = new jsMath.Typeset(this.mlist);
3409: return typeset.Typeset(style,size);
3410: }
3411:
3412: });
3413:
3414:
3415: /*
3416: * These routines implement the main rules given in Appendix G of the
3417: * TeXbook
3418: */
3419:
3420: jsMath.Add(jsMath.mList.prototype.Atomize,{
3421:
3422: /*
3423: * Handle \displaystyle, \textstyle, etc.
3424: */
3425: style: function (style,size,mitem,prev,mlist) {
3426: mlist.style = mitem.style;
3427: },
3428:
3429: /*
3430: * Handle \tiny, \small, etc.
3431: */
3432: size: function (style,size,mitem,prev,mlist) {
3433: mlist.size = mitem.size;
3434: },
3435:
3436: /*
3437: * Create empty boxes of the proper sizes for the various
3438: * phantom-type commands
3439: */
3440: phantom: function (style,size,mitem) {
3441: var box = mitem.nuc = jsMath.Box.Set(mitem.phantom,style,size);
3442: if (mitem.h) {box.Remeasured(); box.html = jsMath.HTML.Spacer(box.w)}
3443: else {box.html = '', box.w = 0}
3444: if (!mitem.v) {box.h = box.d = 0}
3445: box.bd = box.bh = 0;
3446: delete mitem.phantom;
3447: mitem.type = 'box';
3448: },
3449:
3450: /*
3451: * Create a box of zero height and depth containing the
3452: * contents of the atom
3453: */
3454: smash: function (style,size,mitem) {
3455: var box = mitem.nuc = jsMath.Box.Set(mitem.smash,style,size).Remeasured();
3456: box.h = box.d = box.bd = box.bh = 0;
3457: delete mitem.smash;
3458: mitem.type = 'box';
3459: },
3460:
3461: /*
3462: * Move a box up or down vertically
3463: */
3464: raise: function (style,size,mitem) {
3465: mitem.nuc = jsMath.Box.Set(mitem.nuc,style,size);
3466: var y = mitem.raise;
3467: mitem.nuc.html = jsMath.HTML.Place(mitem.nuc.html,0,y);
3468: mitem.nuc.h += y; mitem.nuc.d -= y;
3469: mitem.type = 'ord'; mitem.atom = 1;
3470: },
3471:
3472: /*
3473: * Hide the size of a box so that it laps to the left or right, or
3474: * up or down.
3475: */
3476: lap: function (style,size,mitem) {
3477: var box = jsMath.Box.Set(mitem.nuc,style,size).Remeasured();
3478: var mlist = [box];
3479: if (mitem.lap == 'llap') {box.x = -box.w} else
3480: if (mitem.lap == 'rlap') {mlist[1] = jsMath.mItem.Space(-box.w)} else
3481: if (mitem.lap == 'ulap') {box.y = box.d; box.h = box.d = 0} else
3482: if (mitem.lap == 'dlap') {box.y = -box.h; box.h = box.d = 0}
3483: mitem.nuc = jsMath.Box.SetList(mlist,style,size);
3484: if (mitem.lap == 'ulap' || mitem.lap == 'dlap') {mitem.nuc.h = mitem.nuc.d = 0}
3485: mitem.type = 'box'; delete mitem.atom;
3486: },
3487:
3488: /*
3489: * Handle a Bin atom. (Rule 5)
3490: */
3491: bin: function (style,size,mitem,prev) {
1.2 ! albertel 3492: if (prev && prev.type) {
1.1 albertel 3493: var type = prev.type;
3494: if (type == 'bin' || type == 'op' || type == 'rel' ||
3495: type == 'open' || type == 'punct' || type == '' ||
3496: (type == 'boundary' && prev.left != '')) {mitem.type = 'ord'}
3497: } else {mitem.type = 'ord'}
3498: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3499: },
3500:
3501: /*
3502: * Handle a Rel atom. (Rule 6)
3503: */
3504: rel: function (style,size,mitem,prev) {
1.2 ! albertel 3505: if (prev.type && prev.type == 'bin') {prev.type = 'ord'}
1.1 albertel 3506: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3507: },
3508:
3509: /*
3510: * Handle a Close atom. (Rule 6)
3511: */
3512: close: function (style,size,mitem,prev) {
1.2 ! albertel 3513: if (prev.type && prev.type == 'bin') {prev.type = 'ord'}
1.1 albertel 3514: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3515: },
3516:
3517: /*
3518: * Handle a Punct atom. (Rule 6)
3519: */
3520: punct: function (style,size,mitem,prev) {
1.2 ! albertel 3521: if (prev.type && prev.type == 'bin') {prev.type = 'ord'}
1.1 albertel 3522: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3523: },
3524:
3525: /*
3526: * Handle an Open atom. (Rule 7)
3527: */
3528: open: function (style,size,mitem) {
3529: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3530: },
3531:
3532: /*
3533: * Handle an Inner atom. (Rule 7)
3534: */
3535: inner: function (style,size,mitem) {
3536: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3537: },
3538:
3539: /*
3540: * Handle a Vcent atom. (Rule 8)
3541: */
3542: vcenter: function (style,size,mitem) {
3543: var box = jsMath.Box.Set(mitem.nuc,style,size);
3544: var TeX = jsMath.Typeset.TeX(style,size);
3545: box.y = TeX.axis_height - (box.h-box.d)/2;
3546: mitem.nuc = box; mitem.type = 'ord';
3547: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3548: },
3549:
3550: /*
3551: * Handle an Over atom. (Rule 9)
3552: */
3553: overline: function (style,size,mitem) {
3554: var TeX = jsMath.Typeset.TeX(style,size);
3555: var box = jsMath.Box.Set(mitem.nuc,jsMath.Typeset.PrimeStyle(style),size).Remeasured();
3556: var t = TeX.default_rule_thickness;
3557: var rule = jsMath.Box.Rule(box.w,t);
3558: rule.x = -rule.w; rule.y = box.h + 3*t;
3559: mitem.nuc = jsMath.Box.SetList([box,rule],style,size);
3560: mitem.nuc.h += t;
3561: mitem.type = 'ord';
3562: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3563: },
3564:
3565: /*
3566: * Handle an Under atom. (Rule 10)
3567: */
3568: underline: function (style,size,mitem) {
3569: var TeX = jsMath.Typeset.TeX(style,size);
3570: var box = jsMath.Box.Set(mitem.nuc,jsMath.Typeset.PrimeStyle(style),size).Remeasured();
3571: var t = TeX.default_rule_thickness;
3572: var rule = jsMath.Box.Rule(box.w,t);
3573: rule.x = -rule.w; rule.y = -box.d - 3*t - t;
3574: mitem.nuc = jsMath.Box.SetList([box,rule],style,size);
3575: mitem.nuc.d += t;
3576: mitem.type = 'ord';
3577: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3578: },
3579:
3580: /*
3581: * Handle a Rad atom. (Rule 11 plus stuff for \root..\of)
3582: */
3583: radical: function (style,size,mitem) {
3584: var TeX = jsMath.Typeset.TeX(style,size);
3585: var Cp = jsMath.Typeset.PrimeStyle(style);
3586: var box = jsMath.Box.Set(mitem.nuc,Cp,size).Remeasured();
3587: var t = TeX.default_rule_thickness;
3588: var p = t; if (style == 'D' || style == "D'") {p = TeX.x_height}
3589: var r = t + p/4;
3590: var surd = jsMath.Box.Delimiter(box.h+box.d+r+t,[0,2,0x70,3,0x70],style,1);
1.2 ! albertel 3591: // if (surd.h > 0) {t = surd.h} // thickness of rule is height of surd character
1.1 albertel 3592: if (surd.d > box.h+box.d+r) {r = (r+surd.d-box.h-box.d)/2}
3593: surd.y = box.h+r;
3594: var rule = jsMath.Box.Rule(box.w,t);
3595: rule.y = surd.y-t/2; rule.h += 3*t/2; box.x = -box.w;
3596: var Cr = jsMath.Typeset.UpStyle(jsMath.Typeset.UpStyle(style));
1.2 ! albertel 3597: var root = jsMath.Box.Set(mitem.root || null,Cr,size).Remeasured();
1.1 albertel 3598: if (mitem.root) {
3599: root.y = .55*(box.h+box.d+3*t+r)-box.d;
3600: surd.x = Math.max(root.w-(11/18)*surd.w,0);
3601: rule.x = (7/18)*surd.w;
3602: root.x = -(root.w+rule.x);
3603: }
3604: mitem.nuc = jsMath.Box.SetList([surd,root,rule,box],style,size);
3605: mitem.type = 'ord';
3606: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3607: },
3608:
3609: /*
3610: * Handle an Acc atom. (Rule 12)
3611: */
3612: accent: function (style,size,mitem) {
3613: var TeX = jsMath.Typeset.TeX(style,size);
3614: var Cp = jsMath.Typeset.PrimeStyle(style);
3615: var box = jsMath.Box.Set(mitem.nuc,Cp,size);
3616: var u = box.w; var s; var Font;
3617: if (mitem.nuc.type == 'TeX') {
3618: Font = jsMath.TeX[mitem.nuc.font];
3619: if (Font[mitem.nuc.c].krn && Font.skewchar)
3620: {s = Font[mitem.nuc.c].krn[Font.skewchar]}
3621: }
3622: if (s == null) {s = 0}
3623:
3624: var c = mitem.accent[2];
3625: var font = jsMath.TeX.fam[mitem.accent[1]]; Font = jsMath.TeX[font];
3626: while (Font[c].n && Font[Font[c].n].w <= u) {c = Font[c].n}
3627:
3628: var delta = Math.min(box.h,TeX.x_height);
3629: if (mitem.nuc.type == 'TeX') {
3630: var nitem = jsMath.mItem.Atom('ord',mitem.nuc);
3631: nitem.sup = mitem.sup; nitem.sub = mitem.sub; nitem.delta = 0;
3632: jsMath.mList.prototype.Atomize.SupSub(style,size,nitem);
3633: delta += (nitem.nuc.h - box.h);
3634: box = mitem.nuc = nitem.nuc;
3635: delete mitem.sup; delete mitem.sub;
3636: }
3637: var acc = jsMath.Box.TeX(c,font,style,size);
3638: acc.y = box.h - delta; acc.x = -box.w + s + (u-acc.w)/2;
3639: if (Font[c].ic) {acc.x -= Font[c].ic * TeX.scale}
3640:
3641: mitem.nuc = jsMath.Box.SetList([box,acc],style,size);
3642: if (mitem.nuc.w != box.w) {
3643: var space = jsMath.mItem.Space(box.w-mitem.nuc.w);
3644: mitem.nuc = jsMath.Box.SetList([mitem.nuc,space],style,size);
3645: }
3646: mitem.type = 'ord';
3647: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3648: },
3649:
3650: /*
3651: * Handle an Op atom. (Rules 13 and 13a)
3652: */
3653: op: function (style,size,mitem) {
3654: var TeX = jsMath.Typeset.TeX(style,size); var box;
3655: mitem.delta = 0; var isD = (style.charAt(0) == 'D');
3656: if (mitem.limits == null && isD) {mitem.limits = 1}
3657:
3658: if (mitem.nuc.type == 'TeX') {
3659: var C = jsMath.TeX[mitem.nuc.font][mitem.nuc.c];
3660: if (isD && C.n) {mitem.nuc.c = C.n; C = jsMath.TeX[mitem.nuc.font][C.n]}
3661: box = jsMath.Box.Set(mitem.nuc,style,size);
3662: if (C.ic) {
3663: mitem.delta = C.ic * TeX.scale;
3664: if (mitem.limits || !mitem.sub || jsMath.Browser.msieIntegralBug)
3665: {box = jsMath.Box.SetList([box,jsMath.mItem.Space(mitem.delta)],style,size)}
3666: }
3667: box.y = -((box.h+box.d)/2 - box.d - TeX.axis_height);
3668: if (Math.abs(box.y) < .0001) {box.y = 0}
3669: }
3670:
3671: if (!box) {box = jsMath.Box.Set(mitem.nuc,style,size).Remeasured()}
3672: if (mitem.limits) {
3673: var W = box.w; var x = box.w;
3674: var mlist = [box]; var dh = 0; var dd = 0;
3675: if (mitem.sup) {
3676: var sup = jsMath.Box.Set(mitem.sup,jsMath.Typeset.UpStyle(style),size).Remeasured();
3677: sup.x = ((box.w-sup.w)/2 + mitem.delta/2) - x; dh = TeX.big_op_spacing5;
3678: W = Math.max(W,sup.w); x += sup.x + sup.w;
3679: sup.y = box.h+sup.d + box.y +
3680: Math.max(TeX.big_op_spacing1,TeX.big_op_spacing3-sup.d);
3681: mlist[mlist.length] = sup; delete mitem.sup;
3682: }
3683: if (mitem.sub) {
3684: var sub = jsMath.Box.Set(mitem.sub,jsMath.Typeset.DownStyle(style),size).Remeasured();
3685: sub.x = ((box.w-sub.w)/2 - mitem.delta/2) - x; dd = TeX.big_op_spacing5;
3686: W = Math.max(W,sub.w); x += sub.x + sub.w;
3687: sub.y = -box.d-sub.h + box.y -
3688: Math.max(TeX.big_op_spacing2,TeX.big_op_spacing4-sub.h);
3689: mlist[mlist.length] = sub; delete mitem.sub;
3690: }
3691: if (W > box.w) {box.x = (W-box.w)/2; x += box.x}
3692: if (x < W) {mlist[mlist.length] = jsMath.mItem.Space(W-x)}
3693: mitem.nuc = jsMath.Box.SetList(mlist,style,size);
3694: mitem.nuc.h += dh; mitem.nuc.d += dd;
3695: } else {
3696: if (jsMath.Browser.msieIntegralBug && mitem.sub && C && C.ic)
3697: {mitem.nuc = jsMath.Box.SetList([box,jsMath.Box.Space(-C.ic*TeX.scale)],style,size)}
3698: else if (box.y) {mitem.nuc = jsMath.Box.SetList([box],style,size)}
3699: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3700: }
3701: },
3702:
3703: /*
3704: * Handle an Ord atom. (Rule 14)
3705: */
3706: ord: function (style,size,mitem,prev,mList,i) {
3707: if (mitem.nuc.type == 'TeX' && !mitem.sup && !mitem.sub) {
3708: var nitem = mList.mlist[i+1];
3709: if (nitem && nitem.atom && nitem.type &&
3710: (nitem.type == 'ord' || nitem.type == 'op' || nitem.type == 'bin' ||
3711: nitem.type == 'rel' || nitem.type == 'open' ||
3712: nitem.type == 'close' || nitem.type == 'punct')) {
3713: if (nitem.nuc.type == 'TeX' && nitem.nuc.font == mitem.nuc.font) {
3714: mitem.textsymbol = 1;
3715: var krn = jsMath.TeX[mitem.nuc.font][mitem.nuc.c].krn;
3716: krn *= jsMath.Typeset.TeX(style,size).scale;
3717: if (krn && krn[nitem.nuc.c]) {
3718: for (var k = mList.mlist.length-1; k > i; k--)
3719: {mList.mlist[k+1] = mList.mlist[k]}
3720: mList.mlist[i+1] = jsMath.mItem.Space(krn[nitem.nuc.c]);
3721: }
3722: }
3723: }
3724: }
3725: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3726: },
3727:
3728: /*
3729: * Handle a generalized fraction. (Rules 15 to 15e)
3730: */
3731: fraction: function (style,size,mitem) {
3732: var TeX = jsMath.Typeset.TeX(style,size); var t = 0;
3733: if (mitem.thickness != null) {t = mitem.thickness}
3734: else if (mitem.from.match(/over/)) {t = TeX.default_rule_thickness}
3735: var isD = (style.charAt(0) == 'D');
3736: var Cn = (style == 'D')? 'T': (style == "D'")? "T'": jsMath.Typeset.UpStyle(style);
3737: var Cd = (isD)? "T'": jsMath.Typeset.DownStyle(style);
3738: var num = jsMath.Box.Set(mitem.num,Cn,size).Remeasured();
3739: var den = jsMath.Box.Set(mitem.den,Cd,size).Remeasured();
3740:
3741: var u; var v; var w;
3742: var H = (isD)? TeX.delim1 : TeX.delim2;
3743: var mlist = [jsMath.Box.Delimiter(H,mitem.left,style)]
3744: var right = jsMath.Box.Delimiter(H,mitem.right,style);
3745:
3746: if (num.w < den.w) {
3747: num.x = (den.w-num.w)/2;
3748: den.x = -(num.w + num.x);
3749: w = den.w; mlist[1] = num; mlist[2] = den;
3750: } else {
3751: den.x = (num.w-den.w)/2;
3752: num.x = -(den.w + den.x);
3753: w = num.w; mlist[1] = den; mlist[2] = num;
3754: }
3755: if (isD) {u = TeX.num1; v = TeX.denom1} else {
3756: u = (t != 0)? TeX.num2: TeX.num3;
3757: v = TeX.denom2;
3758: }
3759: if (t == 0) {// atop
3760: var p = (isD)? 7*TeX.default_rule_thickness: 3*TeX.default_rule_thickness;
3761: var r = (u - num.d) - (den.h - v);
3762: if (r < p) {u += (p-r)/2; v += (p-r)/2}
3763: } else {// over
3764: var p = (isD)? 3*t: t; var a = TeX.axis_height;
3765: var r = (u-num.d)-(a+t/2); if (r < p) {u += p-r}
3766: r = (a-t/2)-(den.h-v); if (r < p) {v += p-r}
3767: var rule = jsMath.Box.Rule(w,t); rule.x = -w; rule.y = a - t/2;
3768: mlist[mlist.length] = rule;
3769: }
3770: num.y = u; den.y = -v;
3771:
3772: mlist[mlist.length] = right;
3773: mitem.nuc = jsMath.Box.SetList(mlist,style,size);
3774: mitem.type = 'ord'; mitem.atom = 1;
3775: delete mitem.num; delete mitem.den;
3776: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
3777: },
3778:
3779: /*
3780: * Add subscripts and superscripts. (Rules 17-18f)
3781: */
3782: SupSub: function (style,size,mitem) {
3783: var TeX = jsMath.Typeset.TeX(style,size);
3784: var nuc = mitem.nuc;
3785: var box = mitem.nuc = jsMath.Box.Set(mitem.nuc,style,size,0);
3786: if (box.format == 'null')
3787: {box = mitem.nuc = jsMath.Box.Text('','normal',style,size)}
3788:
3789: if (nuc.type == 'TeX') {
3790: if (!mitem.textsymbol) {
3791: var C = jsMath.TeX[nuc.font][nuc.c];
3792: if (C.ic) {
3793: mitem.delta = C.ic * TeX.scale;
3794: if (!mitem.sub) {
3795: box = mitem.nuc = jsMath.Box.SetList([box,jsMath.Box.Space(mitem.delta)],style,size);
3796: mitem.delta = 0;
3797: }
3798: }
3799: } else {mitem.delta = 0}
3800: }
3801:
3802: if (!mitem.sup && !mitem.sub) return;
3803: mitem.nuc.Styled();
3804:
3805: var Cd = jsMath.Typeset.DownStyle(style);
3806: var Cu = jsMath.Typeset.UpStyle(style);
3807: var q = jsMath.Typeset.TeX(Cu,size).sup_drop;
3808: var r = jsMath.Typeset.TeX(Cd,size).sub_drop;
3809: var u = 0; var v = 0; var p;
3810: if (nuc.type && nuc.type != 'text' && nuc.type != 'TeX' && nuc.type != 'null')
3811: {u = box.h - q; v = box.d + r}
3812:
3813: if (mitem.sub) {
3814: var sub = jsMath.Box.Set(mitem.sub,Cd,size);
3815: sub = jsMath.Box.SetList([sub,jsMath.mItem.Space(TeX.scriptspace)],style,size);
3816: }
3817:
3818: if (!mitem.sup) {
3819: sub.y = -Math.max(v,TeX.sub1,sub.h-(4/5)*jsMath.Typeset.TeX(Cd,size).x_height);
3820: mitem.nuc = jsMath.Box.SetList([box,sub],style,size).Styled(); delete mitem.sub;
3821: return;
3822: }
3823:
3824: var sup = jsMath.Box.Set(mitem.sup,Cu,size);
3825: sup = jsMath.Box.SetList([sup,jsMath.mItem.Space(TeX.scriptspace)],style,size);
3826: if (style == 'D') {p = TeX.sup1}
3827: else if (style.charAt(style.length-1) == "'") {p = TeX.sup3}
3828: else {p = TeX.sup2}
3829: u = Math.max(u,p,sup.d+jsMath.Typeset.TeX(Cu,size).x_height/4);
3830:
3831: if (!mitem.sub) {
3832: sup.y = u;
3833: mitem.nuc = jsMath.Box.SetList([box,sup],style,size); delete mitem.sup;
3834: return;
3835: }
3836:
3837: v = Math.max(v,jsMath.Typeset.TeX(Cd,size).sub2);
3838: var t = TeX.default_rule_thickness;
3839: if ((u-sup.d) - (sub.h -v) < 4*t) {
3840: v = 4*t + sub.h - (u-sup.d);
3841: p = (4/5)*TeX.x_height - (u-sup.d);
3842: if (p > 0) {u += p; v -= p}
3843: }
3844: sup.Remeasured(); sub.Remeasured();
3845: sup.y = u; sub.y = -v; sup.x = mitem.delta;
3846: if (sup.w+sup.x > sub.w)
3847: {sup.x -= sub.w; mitem.nuc = jsMath.Box.SetList([box,sub,sup],style,size)} else
3848: {sub.x -= (sup.w+sup.x); mitem.nuc = jsMath.Box.SetList([box,sup,sub],style,size)}
3849:
3850: delete mitem.sup; delete mitem.sub;
3851: }
3852:
3853: });
3854:
3855:
3856: /***************************************************************************/
3857:
3858: /*
3859: * The Typeset object handles most of the TeX-specific processing
3860: */
3861:
3862: jsMath.Typeset = function (mlist) {
3863: this.type = 'typeset';
3864: this.mlist = mlist;
3865: }
3866:
3867: jsMath.Add(jsMath.Typeset,{
3868:
3869: /*
3870: * The "C-uparrow" style table (TeXbook, p. 441)
3871: */
3872: upStyle: {
3873: D: "S", T: "S", "D'": "S'", "T'": "S'",
3874: S: "SS", SS: "SS", "S'": "SS'", "SS'": "SS'"
3875: },
3876:
3877: /*
3878: * The "C-downarrow" style table (TeXbook, p. 441)
3879: */
3880: downStyle: {
3881: D: "S'", T: "S'", "D'": "S'", "T'": "S'",
3882: S: "SS'", SS: "SS'", "S'": "SS'", "SS'": "SS'"
3883: },
3884:
3885: /*
3886: * Get the various styles given the current style
3887: * (see TeXbook, p. 441)
3888: */
3889: UpStyle: function (style) {return this.upStyle[style]},
3890: DownStyle: function (style) {return this.downStyle[style]},
3891: PrimeStyle: function (style) {
3892: if (style.charAt(style.length-1) == "'") {return style}
3893: return style + "'"
3894: },
3895:
3896: /*
3897: * A value scaled to the appropriate size for scripts
3898: */
3899: StyleValue: function (style,v) {
3900: if (style == "S" || style == "S'") {return .7*v}
3901: if (style == "SS" || style == "SS'") {return .5*v}
3902: return v;
3903: },
3904:
3905: /*
3906: * Return the size associated with a given style and size
3907: */
3908: StyleSize: function (style,size) {
3909: if (style == "S" || style == "S'") {size = Math.max(0,size-2)}
3910: else if (style == "SS" || style == "SS'") {size = Math.max(0,size-4)}
3911: return size;
3912: },
3913:
3914: /*
3915: * Return the font parameter table for the given style
3916: */
3917: TeX: function (style,size) {
3918: if (style == "S" || style == "S'") {size = Math.max(0,size-2)}
3919: else if (style == "SS" || style == "SS'") {size = Math.max(0,size-4)}
3920: return jsMath.TeXparams[size];
3921: },
3922:
3923:
3924: /*
3925: * Add the CSS class for the given TeX style
3926: */
3927: AddStyle: function (style,size,html) {
3928: if (style == "S" || style == "S'") {size = Math.max(0,size-2)}
3929: else if (style == "SS" || style == "SS'") {size = Math.max(0,size-4)}
3930: if (size != 4) {html = '<span class="size'+size+'">' + html + '</span>'}
3931: return html;
3932: },
3933:
3934: /*
3935: * Add the font class, if needed
3936: */
3937: AddClass: function (tclass,html) {
3938: if (tclass != '' && tclass != 'normal') {html = jsMath.HTML.Class(tclass,html)}
3939: return html;
3940: }
3941:
3942: });
3943:
3944:
3945: jsMath.Package(jsMath.Typeset,{
3946:
3947: /*
3948: * The spacing tables for inter-atom spacing
3949: * (See rule 20, and Chapter 18, p 170)
3950: */
3951: DTsep: {
3952: ord: {op: 1, bin: 2, rel: 3, inner: 1},
3953: op: {ord: 1, op: 1, rel: 3, inner: 1},
3954: bin: {ord: 2, op: 2, open: 2, inner: 2},
3955: rel: {ord: 3, op: 3, open: 3, inner: 3},
3956: open: {},
3957: close: {op: 1, bin:2, rel: 3, inner: 1},
3958: punct: {ord: 1, op: 1, rel: 1, open: 1, close: 1, punct: 1, inner: 1},
3959: inner: {ord: 1, op: 1, bin: 2, rel: 3, open: 1, punct: 1, inner: 1}
3960: },
3961:
3962: SSsep: {
3963: ord: {op: 1},
3964: op: {ord: 1, op: 1},
3965: bin: {},
3966: rel: {},
3967: open: {},
3968: close: {op: 1},
3969: punct: {},
3970: inner: {op: 1}
3971: },
3972:
3973: /*
3974: * The sizes used in the tables above
3975: */
3976: sepW: ['','thinmuskip','medmuskip','thickmuskip'],
3977:
3978:
3979: /*
3980: * Find the amount of separation to use between two adjacent
3981: * atoms in the given style
3982: */
3983: GetSeparation: function (l,r,style) {
3984: if (l && l.atom && r.atom) {
3985: var table = this.DTsep; if (style.charAt(0) == "S") {table = this.SSsep}
3986: var row = table[l.type];
3987: if (row && row[r.type] != null) {return jsMath.TeX[this.sepW[row[r.type]]]}
3988: }
3989: return 0;
3990: },
3991:
3992: /*
3993: * Typeset an mlist (i.e., turn it into HTML).
3994: * Here, text items of the same class and style are combined
3995: * to reduce the number of <SPAN> tags used (though it is still
3996: * huge). Spaces are combined, when possible.
3997: * ### More needs to be done with that. ###
3998: * The width of the final box is recomputed at the end, since
3999: * the final width is not necessarily the sum of the widths of
4000: * the individual parts (widths are in pixels, but the browsers
4001: * puts pieces together using sub-pixel accuracy).
4002: */
4003: Typeset: function (style,size) {
4004: this.style = style; this.size = size; var unset = -10000
4005: this.w = 0; this.h = unset; this.d = unset;
4006: this.bh = this.h; this.bd = this.d;
4007: this.tbuf = ''; this.tx = 0; this.tclass = '';
4008: this.cbuf = ''; this.hbuf = ''; this.hx = 0;
4009: var mitem = null; var prev; this.x = 0; this.dx = 0;
4010:
4011: for (var i = 0; i < this.mlist.length; i++) {
4012: prev = mitem; mitem = this.mlist[i];
4013: switch (mitem.type) {
4014:
4015: case 'size':
4016: this.FlushClassed();
4017: this.size = mitem.size;
4018: mitem = prev; // hide this from TeX
4019: break;
4020:
4021: case 'style':
4022: this.FlushClassed();
4023: if (this.style.charAt(this.style.length-1) == "'")
4024: {this.style = mitem.style + "'"} else {this.style = mitem.style}
4025: mitem = prev; // hide this from TeX
4026: break;
4027:
4028: case 'space':
4029: if (typeof(mitem.w) == 'object') {
4030: if (this.style.charAt(1) == 'S') {mitem.w = .5*mitem.w[0]/18}
4031: else if (this.style.charAt(0) == 'S') {mitem.w = .7*mitem.w[0]/18}
4032: else {mitem.w = mitem.w[0]/18}
4033: }
4034: this.dx += mitem.w-0; // mitem.w is sometimes a string?
4035: mitem = prev; // hide this from TeX
4036: break;
4037:
4038: case 'html':
4039: this.FlushClassed();
4040: if (this.hbuf == '') {this.hx = this.x}
4041: this.hbuf += mitem.html;
4042: mitem = prev; // hide this from TeX
4043: break;
4044:
4045: default: // atom
4046: if (!mitem.atom && mitem.type != 'box') break;
4047: mitem.nuc.x += this.dx + this.GetSeparation(prev,mitem,this.style);
4048: if (mitem.nuc.y || mitem.nuc.x) mitem.nuc.Styled();
4049: this.dx = 0; this.x = this.x + this.w;
4050: this.w += mitem.nuc.w + mitem.nuc.x;
4051: if (mitem.nuc.format == 'text') {
4052: if (this.tclass != mitem.nuc.tclass && this.tclass != '') this.FlushText();
4053: if (this.tbuf == '' && this.cbuf == '') {this.tx = this.x}
4054: this.tbuf += mitem.nuc.html; this.tclass = mitem.nuc.tclass;
4055: } else {
4056: this.FlushClassed();
4057: if (mitem.nuc.x || mitem.nuc.y) this.Place(mitem.nuc);
4058: if (this.hbuf == '') {this.hx = this.x}
4059: this.hbuf += mitem.nuc.html;
4060: }
4061: this.h = Math.max(this.h,mitem.nuc.h+mitem.nuc.y); this.bh = Math.max(this.bh,mitem.nuc.bh);
4062: this.d = Math.max(this.d,mitem.nuc.d-mitem.nuc.y); this.bd = Math.max(this.bd,mitem.nuc.bd);
4063: break;
4064: }
4065: }
4066:
4067: this.FlushClassed(); // make sure scaling is included
4068: if (this.dx) {this.hbuf += jsMath.HTML.Spacer(this.dx); this.w += this.dx}
4069: if (this.hbuf == '') {return jsMath.Box.Null}
4070: if (this.h == unset) {this.h = 0}
4071: if (this.d == unset) {this.d = 0}
4072: var box = new jsMath.Box('html',this.hbuf,this.w,this.h,this.d);
4073: box.bh = this.bh; box.bd = this.bd;
4074: return box;
4075: },
4076:
4077: /*
4078: * Add the font to the buffered text and move it to the
4079: * classed-text buffer.
4080: */
4081: FlushText: function () {
4082: if (this.tbuf == '') return;
4083: this.cbuf += jsMath.Typeset.AddClass(this.tclass,this.tbuf);
4084: this.tbuf = ''; this.tclass = '';
4085: },
4086:
4087: /*
4088: * Add the script or scriptscript style to the text and
4089: * move it to the HTML buffer
4090: */
4091: FlushClassed: function () {
4092: this.FlushText();
4093: if (this.cbuf == '') return;
4094: if (this.hbuf == '') {this.hx = this.tx}
4095: this.hbuf += jsMath.Typeset.AddStyle(this.style,this.size,this.cbuf);
4096: this.cbuf = '';
4097: },
4098:
4099: /*
4100: * Add a <SPAN> to position an item's HTML, and
4101: * adjust the item's height and depth.
4102: * (This may be replaced buy one of the following browser-specific
4103: * versions by Browser.Init().)
4104: */
4105: Place: function (item) {
4106: var html = '<span style="position: relative;';
4107: if (item.x) {html += ' margin-left:'+jsMath.HTML.Em(item.x)+';'}
4108: if (item.y) {html += ' top:'+jsMath.HTML.Em(-item.y)+';'}
4109: item.html = html + '">' + item.html + '</span>';
4110: item.h += item.y; item.d -= item.y;
4111: item.x = 0; item.y = 0;
4112: },
4113:
4114: /*
4115: * For MSIE on Windows, backspacing must be done in a separate
4116: * <SPAN>, otherwise the contents will be clipped. Netscape
4117: * also doesn't combine vertical and horizontal spacing well.
4118: * Here, the horizontal and vertical spacing are done separately.
4119: */
4120: PlaceSeparateSkips: function (item) {
4121: if (item.y) {
4122: item.html = '<span style="position: relative; '
4123: + 'top:'+jsMath.HTML.Em(-item.y)+';'
4124: + '">' + item.html + '</span>'
4125: }
4126: if (item.x) {item.html = jsMath.HTML.Spacer(item.x) + item.html}
4127: item.h += item.y; item.d -= item.y;
4128: item.x = 0; item.y = 0;
4129: }
4130:
4131: });
4132:
4133:
4134:
4135: /***************************************************************************/
4136:
4137: /*
4138: * The Parse object handles the parsing of the TeX input string, and creates
4139: * the mList to be typeset by the Typeset object above.
4140: */
4141:
4142: jsMath.Parse = function (s,font,size,style) {
4143: var parse = new jsMath.Parser(s,font,size,style);
4144: parse.Parse();
4145: return parse;
4146: }
4147:
4148: jsMath.Parser = function (s,font,size,style) {
4149: this.string = s; this.i = 0;
4150: this.mlist = new jsMath.mList(null,font,size,style);
4151: }
4152:
4153: jsMath.Package(jsMath.Parser,{
4154:
4155: // special characters
4156: cmd: '\\',
4157: open: '{',
4158: close: '}',
4159:
4160: // patterns for letters and numbers
4161: letter: /[a-z]/i,
4162: number: /[0-9]/,
4163: // pattern for macros to ^ and _ that should be read with arguments
1.2 ! albertel 4164: scriptargs: /^((math|text)..|mathcal|[hm]box)$/,
1.1 albertel 4165:
4166: // the \mathchar definitions (see Appendix B of the TeXbook).
4167: mathchar: {
4168: '!': [5,0,0x21],
4169: '(': [4,0,0x28],
4170: ')': [5,0,0x29],
4171: '*': [2,2,0x03], // \ast
4172: '+': [2,0,0x2B],
4173: ',': [6,1,0x3B],
4174: '-': [2,2,0x00],
4175: '.': [0,1,0x3A],
4176: '/': [0,1,0x3D],
4177: ':': [3,0,0x3A],
4178: ';': [6,0,0x3B],
4179: '<': [3,1,0x3C],
4180: '=': [3,0,0x3D],
4181: '>': [3,1,0x3E],
4182: '?': [5,0,0x3F],
4183: '[': [4,0,0x5B],
4184: ']': [5,0,0x5D],
4185: // '{': [4,2,0x66],
4186: // '}': [5,2,0x67],
4187: '|': [0,2,0x6A]
4188: },
4189:
4190: // handle special \catcode characters
4191: special: {
4192: '~': 'Tilde',
4193: '^': 'HandleSuperscript',
4194: '_': 'HandleSubscript',
4195: ' ': 'Space',
4196: '\01': 'Space',
4197: "\t": 'Space',
4198: "\r": 'Space',
4199: "\n": 'Space',
4200: "'": 'Prime',
4201: '%': 'HandleComment',
4202: '&': 'HandleEntry'
4203: },
4204:
4205: // the \mathchardef table (see Appendix B of the TeXbook).
4206: mathchardef: {
4207: // brace parts
4208: braceld: [0,3,0x7A],
4209: bracerd: [0,3,0x7B],
4210: bracelu: [0,3,0x7C],
4211: braceru: [0,3,0x7D],
4212:
4213: // Greek letters
4214: alpha: [0,1,0x0B],
4215: beta: [0,1,0x0C],
4216: gamma: [0,1,0x0D],
4217: delta: [0,1,0x0E],
4218: epsilon: [0,1,0x0F],
4219: zeta: [0,1,0x10],
4220: eta: [0,1,0x11],
4221: theta: [0,1,0x12],
4222: iota: [0,1,0x13],
4223: kappa: [0,1,0x14],
4224: lambda: [0,1,0x15],
4225: mu: [0,1,0x16],
4226: nu: [0,1,0x17],
4227: xi: [0,1,0x18],
4228: pi: [0,1,0x19],
4229: rho: [0,1,0x1A],
4230: sigma: [0,1,0x1B],
4231: tau: [0,1,0x1C],
4232: upsilon: [0,1,0x1D],
4233: phi: [0,1,0x1E],
4234: chi: [0,1,0x1F],
4235: psi: [0,1,0x20],
4236: omega: [0,1,0x21],
4237: varepsilon: [0,1,0x22],
4238: vartheta: [0,1,0x23],
4239: varpi: [0,1,0x24],
4240: varrho: [0,1,0x25],
4241: varsigma: [0,1,0x26],
4242: varphi: [0,1,0x27],
4243:
4244: Gamma: [7,0,0x00],
4245: Delta: [7,0,0x01],
4246: Theta: [7,0,0x02],
4247: Lambda: [7,0,0x03],
4248: Xi: [7,0,0x04],
4249: Pi: [7,0,0x05],
4250: Sigma: [7,0,0x06],
4251: Upsilon: [7,0,0x07],
4252: Phi: [7,0,0x08],
4253: Psi: [7,0,0x09],
4254: Omega: [7,0,0x0A],
4255:
4256: // Ord symbols
4257: aleph: [0,2,0x40],
4258: imath: [0,1,0x7B],
4259: jmath: [0,1,0x7C],
4260: ell: [0,1,0x60],
4261: wp: [0,1,0x7D],
4262: Re: [0,2,0x3C],
4263: Im: [0,2,0x3D],
4264: partial: [0,1,0x40],
4265: infty: [0,2,0x31],
4266: prime: [0,2,0x30],
4267: emptyset: [0,2,0x3B],
4268: nabla: [0,2,0x72],
4269: surd: [1,2,0x70],
4270: top: [0,2,0x3E],
4271: bot: [0,2,0x3F],
4272: triangle: [0,2,0x34],
4273: forall: [0,2,0x38],
4274: exists: [0,2,0x39],
4275: neg: [0,2,0x3A],
4276: lnot: [0,2,0x3A],
4277: flat: [0,1,0x5B],
4278: natural: [0,1,0x5C],
4279: sharp: [0,1,0x5D],
4280: clubsuit: [0,2,0x7C],
4281: diamondsuit: [0,2,0x7D],
4282: heartsuit: [0,2,0x7E],
4283: spadesuit: [0,2,0x7F],
4284:
4285: // big ops
4286: coprod: [1,3,0x60],
4287: bigvee: [1,3,0x57],
4288: bigwedge: [1,3,0x56],
4289: biguplus: [1,3,0x55],
4290: bigcap: [1,3,0x54],
4291: bigcup: [1,3,0x53],
4292: intop: [1,3,0x52],
4293: prod: [1,3,0x51],
4294: sum: [1,3,0x50],
4295: bigotimes: [1,3,0x4E],
4296: bigoplus: [1,3,0x4C],
4297: bigodot: [1,3,0x4A],
4298: ointop: [1,3,0x48],
4299: bigsqcup: [1,3,0x46],
4300: smallint: [1,2,0x73],
4301:
4302: // binary operations
4303: triangleleft: [2,1,0x2F],
4304: triangleright: [2,1,0x2E],
4305: bigtriangleup: [2,2,0x34],
4306: bigtriangledown: [2,2,0x35],
4307: wedge: [2,2,0x5E],
4308: land: [2,2,0x5E],
4309: vee: [2,2,0x5F],
4310: lor: [2,2,0x5F],
4311: cap: [2,2,0x5C],
4312: cup: [2,2,0x5B],
4313: ddagger: [2,2,0x7A],
4314: dagger: [2,2,0x79],
4315: sqcap: [2,2,0x75],
4316: sqcup: [2,2,0x74],
4317: uplus: [2,2,0x5D],
4318: amalg: [2,2,0x71],
4319: diamond: [2,2,0x05],
4320: bullet: [2,2,0x0F],
4321: wr: [2,2,0x6F],
4322: div: [2,2,0x04],
4323: odot: [2,2,0x0C],
4324: oslash: [2,2,0x0B],
4325: otimes: [2,2,0x0A],
4326: ominus: [2,2,0x09],
4327: oplus: [2,2,0x08],
4328: mp: [2,2,0x07],
4329: pm: [2,2,0x06],
4330: circ: [2,2,0x0E],
4331: bigcirc: [2,2,0x0D],
4332: setminus: [2,2,0x6E], // for set difference A\setminus B
4333: cdot: [2,2,0x01],
4334: ast: [2,2,0x03],
4335: times: [2,2,0x02],
4336: star: [2,1,0x3F],
4337:
4338: // Relations
4339: propto: [3,2,0x2F],
4340: sqsubseteq: [3,2,0x76],
4341: sqsupseteq: [3,2,0x77],
4342: parallel: [3,2,0x6B],
4343: mid: [3,2,0x6A],
4344: dashv: [3,2,0x61],
4345: vdash: [3,2,0x60],
4346: leq: [3,2,0x14],
4347: le: [3,2,0x14],
4348: geq: [3,2,0x15],
4349: ge: [3,2,0x15],
4350: succ: [3,2,0x1F],
4351: prec: [3,2,0x1E],
4352: approx: [3,2,0x19],
4353: succeq: [3,2,0x17],
4354: preceq: [3,2,0x16],
4355: supset: [3,2,0x1B],
4356: subset: [3,2,0x1A],
4357: supseteq: [3,2,0x13],
4358: subseteq: [3,2,0x12],
4359: 'in': [3,2,0x32],
4360: ni: [3,2,0x33],
4361: owns: [3,2,0x33],
4362: gg: [3,2,0x1D],
4363: ll: [3,2,0x1C],
4364: not: [3,2,0x36],
4365: sim: [3,2,0x18],
4366: simeq: [3,2,0x27],
4367: perp: [3,2,0x3F],
4368: equiv: [3,2,0x11],
4369: asymp: [3,2,0x10],
4370: smile: [3,1,0x5E],
4371: frown: [3,1,0x5F],
4372:
4373: // Arrows
4374: Leftrightarrow: [3,2,0x2C],
4375: Leftarrow: [3,2,0x28],
4376: Rightarrow: [3,2,0x29],
4377: leftrightarrow: [3,2,0x24],
4378: leftarrow: [3,2,0x20],
4379: gets: [3,2,0x20],
4380: rightarrow: [3,2,0x21],
4381: to: [3,2,0x21],
4382: mapstochar: [3,2,0x37],
4383: leftharpoonup: [3,1,0x28],
4384: leftharpoondown: [3,1,0x29],
4385: rightharpoonup: [3,1,0x2A],
4386: rightharpoondown: [3,1,0x2B],
4387: nearrow: [3,2,0x25],
4388: searrow: [3,2,0x26],
4389: nwarrow: [3,2,0x2D],
4390: swarrow: [3,2,0x2E],
4391:
4392: hbarchar: [0,0,0x16], // for \hbar
4393: lhook: [3,1,0x2C],
4394: rhook: [3,1,0x2D],
4395:
4396: ldotp: [6,1,0x3A], // ldot as a punctuation mark
4397: cdotp: [6,2,0x01], // cdot as a punctuation mark
4398: colon: [6,0,0x3A], // colon as a punctuation mark
4399:
4400: '#': [7,0,0x23],
4401: '$': [7,0,0x24],
4402: '%': [7,0,0x25],
4403: '&': [7,0,0x26]
4404: },
4405:
4406: // The delimiter table (see Appendix B of the TeXbook)
4407: delimiter: {
4408: '(': [0,0,0x28,3,0x00],
4409: ')': [0,0,0x29,3,0x01],
4410: '[': [0,0,0x5B,3,0x02],
4411: ']': [0,0,0x5D,3,0x03],
4412: '<': [0,2,0x68,3,0x0A],
4413: '>': [0,2,0x69,3,0x0B],
4414: '/': [0,0,0x2F,3,0x0E],
4415: '|': [0,2,0x6A,3,0x0C],
4416: '.': [0,0,0x00,0,0x00],
4417: '\\': [0,2,0x6E,3,0x0F],
4418: '\\lmoustache': [4,3,0x7A,3,0x40], // top from (, bottom from )
4419: '\\rmoustache': [5,3,0x7B,3,0x41], // top from ), bottom from (
4420: '\\lgroup': [4,6,0x28,3,0x3A], // extensible ( with sharper tips
4421: '\\rgroup': [5,6,0x29,3,0x3B], // extensible ) with sharper tips
4422: '\\arrowvert': [0,2,0x6A,3,0x3C], // arrow without arrowheads
4423: '\\Arrowvert': [0,2,0x6B,3,0x3D], // double arrow without arrowheads
4424: // '\\bracevert': [0,7,0x7C,3,0x3E], // the vertical bar that extends braces
4425: '\\bracevert': [0,2,0x6A,3,0x3E], // we don't load tt, so use | instead
4426: '\\Vert': [0,2,0x6B,3,0x0D],
4427: '\\|': [0,2,0x6B,3,0x0D],
4428: '\\vert': [0,2,0x6A,3,0x0C],
4429: '\\uparrow': [3,2,0x22,3,0x78],
4430: '\\downarrow': [3,2,0x23,3,0x79],
4431: '\\updownarrow': [3,2,0x6C,3,0x3F],
4432: '\\Uparrow': [3,2,0x2A,3,0x7E],
4433: '\\Downarrow': [3,2,0x2B,3,0x7F],
4434: '\\Updownarrow': [3,2,0x6D,3,0x77],
4435: '\\backslash': [0,2,0x6E,3,0x0F], // for double coset G\backslash H
4436: '\\rangle': [5,2,0x69,3,0x0B],
4437: '\\langle': [4,2,0x68,3,0x0A],
4438: '\\rbrace': [5,2,0x67,3,0x09],
4439: '\\lbrace': [4,2,0x66,3,0x08],
4440: '\\}': [5,2,0x67,3,0x09],
4441: '\\{': [4,2,0x66,3,0x08],
4442: '\\rceil': [5,2,0x65,3,0x07],
4443: '\\lceil': [4,2,0x64,3,0x06],
4444: '\\rfloor': [5,2,0x63,3,0x05],
4445: '\\lfloor': [4,2,0x62,3,0x04],
4446: '\\lbrack': [0,0,0x5B,3,0x02],
4447: '\\rbrack': [0,0,0x5D,3,0x03]
4448: },
4449:
4450: /*
4451: * The basic macros for plain TeX.
4452: *
4453: * When the control sequence on the left is called, the JavaScript
4454: * funtion on the right is called, with the name of the control sequence
4455: * as its first parameter (this way, the same function can be called by
4456: * several different control sequences to do similar actions, and the
4457: * function can still tell which TeX command was issued). If the right
4458: * is an array, the first entry is the routine to call, and the
4459: * remaining entries in the array are parameters to pass to the function
4460: * as the second parameter (they are in an array reference).
4461: *
4462: * Note: TeX macros as defined by the user are discussed below.
4463: */
4464: macros: {
4465: displaystyle: ['HandleStyle','D'],
4466: textstyle: ['HandleStyle','T'],
4467: scriptstyle: ['HandleStyle','S'],
4468: scriptscriptstyle: ['HandleStyle','SS'],
4469:
4470: rm: ['HandleFont',0],
4471: mit: ['HandleFont',1],
4472: oldstyle: ['HandleFont',1],
4473: cal: ['HandleFont',2],
4474: it: ['HandleFont',4],
4475: bf: ['HandleFont',6],
4476:
1.2 ! albertel 4477: font: ['Extension','font'],
! 4478:
1.1 albertel 4479: left: 'HandleLeft',
4480: right: 'HandleRight',
4481:
4482: arcsin: ['NamedOp',0],
4483: arccos: ['NamedOp',0],
4484: arctan: ['NamedOp',0],
4485: arg: ['NamedOp',0],
4486: cos: ['NamedOp',0],
4487: cosh: ['NamedOp',0],
4488: cot: ['NamedOp',0],
4489: coth: ['NamedOp',0],
4490: csc: ['NamedOp',0],
4491: deg: ['NamedOp',0],
4492: det: 'NamedOp',
4493: dim: ['NamedOp',0],
4494: exp: ['NamedOp',0],
4495: gcd: 'NamedOp',
4496: hom: ['NamedOp',0],
4497: inf: 'NamedOp',
4498: ker: ['NamedOp',0],
4499: lg: ['NamedOp',0],
4500: lim: 'NamedOp',
4501: liminf: ['NamedOp',null,'lim<span style="margin-left: '+1/6+'em"></span>inf'],
4502: limsup: ['NamedOp',null,'lim<span style="margin-left: '+1/6+'em"></span>sup'],
4503: ln: ['NamedOp',0],
4504: log: ['NamedOp',0],
4505: max: 'NamedOp',
4506: min: 'NamedOp',
4507: Pr: 'NamedOp',
4508: sec: ['NamedOp',0],
4509: sin: ['NamedOp',0],
4510: sinh: ['NamedOp',0],
4511: sup: 'NamedOp',
4512: tan: ['NamedOp',0],
4513: tanh: ['NamedOp',0],
4514:
4515: vcenter: ['HandleAtom','vcenter'],
4516: overline: ['HandleAtom','overline'],
4517: underline: ['HandleAtom','underline'],
4518: over: 'HandleOver',
4519: overwithdelims: 'HandleOver',
4520: atop: 'HandleOver',
4521: atopwithdelims: 'HandleOver',
4522: above: 'HandleOver',
4523: abovewithdelims: 'HandleOver',
4524: brace: ['HandleOver','\\{','\\}'],
4525: brack: ['HandleOver','[',']'],
4526: choose: ['HandleOver','(',')'],
4527:
4528: overbrace: ['Extension','leaders'],
4529: underbrace: ['Extension','leaders'],
4530: overrightarrow: ['Extension','leaders'],
4531: overleftarrow: ['Extension','leaders'],
4532: overset: ['Extension','underset-overset'],
4533: underset: ['Extension','underset-overset'],
4534:
4535: llap: 'HandleLap',
4536: rlap: 'HandleLap',
4537: ulap: 'HandleLap',
4538: dlap: 'HandleLap',
4539: raise: 'RaiseLower',
4540: lower: 'RaiseLower',
4541: moveleft: 'MoveLeftRight',
4542: moveright: 'MoveLeftRight',
4543:
4544: frac: 'Frac',
4545: root: 'Root',
4546: sqrt: 'Sqrt',
4547:
4548: // TeX substitution macros
4549: hbar: ['Macro','\\hbarchar\\kern-.5em h'],
4550: ne: ['Macro','\\not='],
4551: neq: ['Macro','\\not='],
4552: notin: ['Macro','\\mathrel{\\rlap{\\kern2mu/}}\\in'],
4553: cong: ['Macro','\\mathrel{\\lower2mu{\\mathrel{{\\rlap{=}\\raise6mu\\sim}}}}'],
4554: bmod: ['Macro','\\mathbin{\\rm mod}'],
4555: pmod: ['Macro','\\kern 18mu ({\\rm mod}\\,\\,#1)',1],
4556: 'int': ['Macro','\\intop\\nolimits'],
4557: oint: ['Macro','\\ointop\\nolimits'],
4558: doteq: ['Macro','\\buildrel\\textstyle.\\over='],
4559: ldots: ['Macro','\\mathinner{\\ldotp\\ldotp\\ldotp}'],
4560: cdots: ['Macro','\\mathinner{\\cdotp\\cdotp\\cdotp}'],
4561: vdots: ['Macro','\\mathinner{\\rlap{\\raise8pt{.\\rule 0pt 6pt 0pt}}\\rlap{\\raise4pt{.}}.}'],
4562: ddots: ['Macro','\\mathinner{\\kern1mu\\raise7pt{\\rule 0pt 7pt 0pt .}\\kern2mu\\raise4pt{.}\\kern2mu\\raise1pt{.}\\kern1mu}'],
4563: joinrel: ['Macro','\\mathrel{\\kern-4mu}'],
4564: relbar: ['Macro','\\mathrel{\\smash-}'], // \smash, because - has the same height as +
4565: Relbar: ['Macro','\\mathrel='],
4566: bowtie: ['Macro','\\mathrel\\triangleright\\joinrel\\mathrel\\triangleleft'],
4567: models: ['Macro','\\mathrel|\\joinrel='],
4568: mapsto: ['Macro','\\mapstochar\\rightarrow'],
4569: rightleftharpoons: ['Macro','\\vcenter{\\mathrel{\\rlap{\\raise3mu{\\rightharpoonup}}}\\leftharpoondown}'],
4570: hookrightarrow: ['Macro','\\lhook\\joinrel\\rightarrow'],
4571: hookleftarrow: ['Macro','\\leftarrow\\joinrel\\rhook'],
4572: Longrightarrow: ['Macro','\\Relbar\\joinrel\\Rightarrow'],
4573: longrightarrow: ['Macro','\\relbar\\joinrel\\rightarrow'],
4574: longleftarrow: ['Macro','\\leftarrow\\joinrel\\relbar'],
4575: Longleftarrow: ['Macro','\\Leftarrow\\joinrel\\Relbar'],
4576: longmapsto: ['Macro','\\mapstochar\\char{cmsy10}{0}\\joinrel\\rightarrow'],
4577: longleftrightarrow: ['Macro','\\leftarrow\\joinrel\\rightarrow'],
4578: Longleftrightarrow: ['Macro','\\Leftarrow\\joinrel\\Rightarrow'],
4579: iff: ['Macro','\\;\\Longleftrightarrow\\;'],
4580: mathcal: ['Macro','{\\cal #1}',1],
4581: mathrm: ['Macro','{\\rm #1}',1],
4582: mathbf: ['Macro','{\\bf #1}',1],
4583: mathbb: ['Macro','{\\bf #1}',1],
4584: mathit: ['Macro','{\\it #1}',1],
4585: textrm: ['Macro','\\mathord{\\hbox{#1}}',1],
4586: textit: ['Macro','\\mathord{\\class{textit}{\\hbox{#1}}}',1],
4587: textbf: ['Macro','\\mathord{\\class{textbf}{\\hbox{#1}}}',1],
4588:
4589: TeX: ['Macro','T\\kern-.1667em\\lower.5ex{E}\\kern-.125em X'],
4590:
4591: limits: ['Limits',1],
4592: nolimits: ['Limits',0],
4593:
4594: ',': ['Spacer',1/6],
4595: ':': ['Spacer',1/6], // for LaTeX
4596: '>': ['Spacer',2/9],
4597: ';': ['Spacer',5/18],
4598: '!': ['Spacer',-1/6],
4599: enspace: ['Spacer',1/2],
4600: quad: ['Spacer',1],
4601: qquad: ['Spacer',2],
4602: thinspace: ['Spacer',1/6],
4603: negthinspace: ['Spacer',-1/6],
4604:
4605: hskip: 'Hskip',
4606: kern: 'Hskip',
4607: rule: ['Rule','colored'],
4608: space: ['Rule','blank'],
4609:
4610: big: ['MakeBig','ord',0.85],
4611: Big: ['MakeBig','ord',1.15],
4612: bigg: ['MakeBig','ord',1.45],
4613: Bigg: ['MakeBig','ord',1.75],
4614: bigl: ['MakeBig','open',0.85],
4615: Bigl: ['MakeBig','open',1.15],
4616: biggl: ['MakeBig','open',1.45],
4617: Biggl: ['MakeBig','open',1.75],
4618: bigr: ['MakeBig','close',0.85],
4619: Bigr: ['MakeBig','close',1.15],
4620: biggr: ['MakeBig','close',1.45],
4621: Biggr: ['MakeBig','close',1.75],
4622: bigm: ['MakeBig','rel',0.85],
4623: Bigm: ['MakeBig','rel',1.15],
4624: biggm: ['MakeBig','rel',1.45],
4625: Biggm: ['MakeBig','rel',1.75],
4626:
4627: mathord: ['HandleAtom','ord'],
4628: mathop: ['HandleAtom','op'],
4629: mathopen: ['HandleAtom','open'],
4630: mathclose: ['HandleAtom','close'],
4631: mathbin: ['HandleAtom','bin'],
4632: mathrel: ['HandleAtom','rel'],
4633: mathpunct: ['HandleAtom','punct'],
4634: mathinner: ['HandleAtom','inner'],
4635:
4636: mathchoice: ['Extension','mathchoice'],
4637: buildrel: 'BuildRel',
4638:
4639: hbox: 'HBox',
4640: text: 'HBox',
4641: mbox: 'HBox',
4642: fbox: ['Extension','fbox'],
4643:
4644: strut: 'Strut',
4645: mathstrut: ['Macro','\\vphantom{(}'],
4646: phantom: ['Phantom',1,1],
4647: vphantom: ['Phantom',1,0],
4648: hphantom: ['Phantom',0,1],
4649: smash: 'Smash',
4650:
4651: acute: ['MathAccent', [7,0,0x13]],
4652: grave: ['MathAccent', [7,0,0x12]],
4653: ddot: ['MathAccent', [7,0,0x7F]],
4654: tilde: ['MathAccent', [7,0,0x7E]],
4655: bar: ['MathAccent', [7,0,0x16]],
4656: breve: ['MathAccent', [7,0,0x15]],
4657: check: ['MathAccent', [7,0,0x14]],
4658: hat: ['MathAccent', [7,0,0x5E]],
4659: vec: ['MathAccent', [0,1,0x7E]],
4660: dot: ['MathAccent', [7,0,0x5F]],
4661: widetilde: ['MathAccent', [0,3,0x65]],
4662: widehat: ['MathAccent', [0,3,0x62]],
4663:
4664: '_': ['Replace','ord','_','normal',-.4,.1],
4665: ' ': ['Replace','ord',' ','normal'],
4666: angle: ['Replace','ord','∠','normal'],
4667:
4668: matrix: 'Matrix',
4669: array: 'Matrix', // ### still need to do alignment options ###
4670: pmatrix: ['Matrix','(',')','c'],
1.2 ! albertel 4671: cases: ['Matrix','\\{','.',['l','l'],null,2],
! 4672: eqalign: ['Matrix',null,null,['r','l'],[5/18],3,'D'],
! 4673: displaylines: ['Matrix',null,null,['c'],null,3,'D'],
1.1 albertel 4674: cr: 'HandleRow',
4675: '\\': 'HandleRow',
1.2 ! albertel 4676: noalign: 'HandleNoAlign',
! 4677: eqalignno: ['Matrix',null,null,['r','l','r'],[5/8,3],3,'D'],
! 4678: leqalignno: ['Matrix',null,null,['r','l','r'],[5/8,3],3,'D'],
1.1 albertel 4679:
4680: // LaTeX
4681: begin: 'Begin',
4682: end: 'End',
4683: tiny: ['HandleSize',0],
4684: Tiny: ['HandleSize',1], // non-standard
4685: scriptsize: ['HandleSize',2],
4686: small: ['HandleSize',3],
4687: normalsize: ['HandleSize',4],
4688: large: ['HandleSize',5],
4689: Large: ['HandleSize',6],
4690: LARGE: ['HandleSize',7],
4691: huge: ['HandleSize',8],
4692: Huge: ['HandleSize',9],
4693: dots: ['Macro','\\ldots'],
4694:
4695: newcommand: ['Extension','newcommand'],
4696: def: ['Extension','newcommand'],
4697:
4698: // Extensions to TeX
4699: color: ['Extension','HTML'],
4700: href: ['Extension','HTML'],
4701: 'class': ['Extension','HTML'],
4702: style: ['Extension','HTML'],
4703: cssId: ['Extension','HTML'],
4704: unicode: ['Extension','HTML'],
1.2 ! albertel 4705: bbox: ['Extension','bbox'],
1.1 albertel 4706:
4707: require: 'Require',
4708:
4709: // debugging and test routines
4710: 'char': 'Char'
4711: },
4712:
4713: /*
4714: * LaTeX environments
4715: */
4716: environments: {
4717: array: 'Array',
4718: matrix: ['Array',null,null,'c'],
4719: pmatrix: ['Array','(',')','c'],
4720: bmatrix: ['Array','[',']','c'],
4721: Bmatrix: ['Array','\\{','\\}','c'],
4722: vmatrix: ['Array','\\vert','\\vert','c'],
4723: Vmatrix: ['Array','\\Vert','\\Vert','c'],
1.2 ! albertel 4724: cases: ['Array','\\{','.','ll',null,2],
! 4725: eqnarray: ['Array',null,null,'rcl',[5/18,5/18],3,'D']
1.1 albertel 4726: },
4727:
4728:
4729: /***************************************************************************/
4730:
4731: /*
4732: * Add special characters to list above. (This makes it possible
4733: * to define them in a variable that the user can change.)
4734: */
4735: AddSpecial: function (obj) {
4736: for (var id in obj) {
4737: jsMath.Parser.prototype.special[jsMath.Parser.prototype[id]] = obj[id];
4738: }
4739: },
4740:
4741: /*
4742: * Throw an error
4743: */
4744: Error: function (s) {
4745: this.i = this.string.length;
4746: if (s.error) {this.error = s.error} else {
4747: if (!this.error) {this.error = s}
4748: }
4749: },
4750:
4751: /***************************************************************************/
4752:
4753: /*
4754: * Check if the next character is a space
4755: */
4756: nextIsSpace: function () {
4757: return this.string.charAt(this.i) == ' ';
4758: },
4759:
4760: /*
4761: * Trim spaces from a string
4762: */
4763: trimSpaces: function (text) {
4764: if (typeof(text) != 'string') {return text}
4765: return text.replace(/^\s+|\s+/g,'');
4766: },
4767:
4768: /*
4769: * Parse a substring to get its mList, and return it.
4770: * Check that no errors occured
4771: */
4772: Process: function (arg) {
4773: var data = this.mlist.data;
4774: arg = jsMath.Parse(arg,data.font,data.size,data.style);
4775: if (arg.error) {this.Error(arg); return null}
4776: if (arg.mlist.Length() == 0) {return null}
4777: if (arg.mlist.Length() == 1) {
4778: var atom = arg.mlist.Last();
4779: if (atom.atom && atom.type == 'ord' && atom.nuc &&
4780: !atom.sub && !atom.sup && (atom.nuc.type == 'text' || atom.nuc.type == 'TeX'))
4781: {return atom.nuc}
4782: }
4783: return {type: 'mlist', mlist: arg.mlist};
4784: },
4785:
4786: /*
4787: * Get and return a control-sequence name from the TeX string
4788: */
4789: GetCommand: function () {
4790: var letter = /^([a-z]+|.) ?/i;
4791: var cmd = letter.exec(this.string.slice(this.i));
4792: if (cmd) {this.i += cmd[1].length; return cmd[1]}
1.2 ! albertel 4793: this.i++; return " ";
1.1 albertel 4794: },
4795:
4796: /*
4797: * Get and return a TeX argument (either a single character or control sequence,
4798: * or the contents of the next set of braces).
4799: */
4800: GetArgument: function (name,noneOK) {
4801: while (this.nextIsSpace()) {this.i++}
4802: if (this.i >= this.string.length) {if (!noneOK) this.Error("Missing argument for "+name); return null}
4803: if (this.string.charAt(this.i) == this.close) {if (!noneOK) this.Error("Extra close brace"); return null}
4804: if (this.string.charAt(this.i) == this.cmd) {this.i++; return this.cmd+this.GetCommand()}
4805: if (this.string.charAt(this.i) != this.open) {return this.string.charAt(this.i++)}
4806: var j = ++this.i; var pcount = 1; var c = '';
4807: while (this.i < this.string.length) {
4808: c = this.string.charAt(this.i++);
4809: if (c == this.cmd) {this.i++}
4810: else if (c == this.open) {pcount++}
4811: else if (c == this.close) {
4812: if (pcount == 0) {this.Error("Extra close brace"); return null}
4813: if (--pcount == 0) {return this.string.slice(j,this.i-1)}
4814: }
4815: }
4816: this.Error("Missing close brace");
4817: return null;
4818: },
4819:
4820: /*
4821: * Get an argument and process it into an mList
4822: */
4823: ProcessArg: function (name) {
4824: var arg = this.GetArgument(name); if (this.error) {return null}
4825: return this.Process(arg);
4826: },
4827:
4828: /*
4829: * Get and process an argument for a super- or subscript.
4830: * (read extra args for \frac, \sqrt, \mathrm, etc.)
4831: * This handles these macros as special cases, so is really
4832: * rather a hack. A more general method for indicating
4833: * how to handle macros in scripts needs to be developed.
4834: */
4835: ProcessScriptArg: function (name) {
4836: var arg = this.GetArgument(name); if (this.error) {return null}
4837: if (arg.charAt(0) == this.cmd) {
1.2 ! albertel 4838: var csname = arg.substr(1);
1.1 albertel 4839: if (csname == "frac") {
4840: arg += '{'+this.GetArgument(csname)+'}'; if (this.error) {return null}
4841: arg += '{'+this.GetArgument(csname)+'}'; if (this.error) {return null}
4842: } else if (csname == "sqrt") {
4843: arg += '['+this.GetBrackets(csname)+']'; if (this.error) {return null}
4844: arg += '{'+this.GetArgument(csname)+'}'; if (this.error) {return null}
4845: } else if (csname.match(this.scriptargs)) {
4846: arg += '{'+this.GetArgument(csname)+'}'; if (this.error) {return null}
4847: }
4848: }
4849: return this.Process(arg);
4850: },
4851:
4852: /*
4853: * Get the name of a delimiter (check it in the delimiter list).
4854: */
4855: GetDelimiter: function (name) {
4856: while (this.nextIsSpace()) {this.i++}
4857: var c = this.string.charAt(this.i);
4858: if (this.i < this.string.length) {
4859: this.i++;
4860: if (c == this.cmd) {c = '\\'+this.GetCommand(name); if (this.error) return null}
4861: if (this.delimiter[c] != null) {return this.delimiter[c]}
4862: }
4863: this.Error("Missing or unrecognized delimiter for "+name);
4864: return null;
4865: },
4866:
4867: /*
4868: * Get a dimension (including its units).
4869: * Convert the dimen to em's, except for mu's, which must be
4870: * converted when typeset.
4871: */
4872: GetDimen: function (name,nomu) {
4873: var rest; var advance = 0;
4874: if (this.nextIsSpace()) {this.i++}
4875: if (this.string.charAt(this.i) == '{') {
4876: rest = this.GetArgument(name);
4877: } else {
4878: rest = this.string.slice(this.i);
4879: advance = 1;
4880: }
1.2 ! albertel 4881: return this.ParseDimen(rest,name,advance,nomu);
! 4882: },
! 4883:
! 4884: ParseDimen: function (dimen,name,advance,nomu) {
! 4885: var match = dimen.match(/^\s*([-+]?(\.\d+|\d+(\.\d*)?))(pt|em|ex|mu|px)/);
1.1 albertel 4886: if (!match) {this.Error("Missing dimension or its units for "+name); return null}
4887: if (advance) {
4888: this.i += match[0].length;
4889: if (this.nextIsSpace()) {this.i++}
4890: }
4891: var d = match[1]-0;
4892: if (match[4] == 'px') {d /= jsMath.em}
4893: else if (match[4] == 'pt') {d /= 10}
4894: else if (match[4] == 'ex') {d *= jsMath.TeX.x_height}
4895: else if (match[4] == 'mu') {if (nomu) {d = d/18} else {d = [d,'mu']}}
4896: return d;
4897: },
4898:
4899: /*
4900: * Get the next non-space character
4901: */
4902: GetNext: function () {
4903: while (this.nextIsSpace()) {this.i++}
4904: return this.string.charAt(this.i);
4905: },
4906:
4907: /*
4908: * Get an optional LaTeX argument in brackets
4909: */
4910: GetBrackets: function (name) {
4911: var c = this.GetNext(); if (c != '[') return '';
4912: var start = ++this.i; var pcount = 0;
4913: while (this.i < this.string.length) {
4914: var c = this.string.charAt(this.i++);
4915: if (c == '{') {pcount++}
4916: else if (c == '}') {
4917: if (pcount == 0)
4918: {this.Error("Extra close brace while looking for ']'"); return null}
4919: pcount --;
4920: } else if (c == this.cmd) {
4921: this.i++;
4922: } else if (c == ']') {
4923: if (pcount == 0) {return this.string.slice(start,this.i-1)}
4924: }
4925: }
4926: this.Error("Couldn't find closing ']' for argument to "+this.cmd+name);
4927: return null;
4928: },
4929:
4930: /*
4931: * Get everything up to the given control sequence name (token)
4932: */
4933: GetUpto: function (name,token) {
4934: while (this.nextIsSpace()) {this.i++}
4935: var start = this.i; var pcount = 0;
4936: while (this.i < this.string.length) {
4937: var c = this.string.charAt(this.i++);
4938: if (c == '{') {pcount++}
4939: else if (c == '}') {
4940: if (pcount == 0)
4941: {this.Error("Extra close brace while looking for "+this.cmd+token); return null}
4942: pcount --;
4943: } else if (c == this.cmd) {
4944: // really need separate counter for begin/end
4945: // and it should really be a stack (new pcount for each begin)
4946: if (this.string.slice(this.i,this.i+5) == "begin") {pcount++; this.i+=4}
4947: else if (this.string.slice(this.i,this.i+3) == "end") {
4948: if (pcount > 0) {pcount--; this.i += 2}
4949: }
4950: if (pcount == 0) {
4951: if (this.string.slice(this.i,this.i+token.length) == token) {
4952: c = this.string.charAt(this.i+token.length);
4953: if (c.match(/[^a-z]/i) || !token.match(/[a-z]/i)) {
4954: var arg = this.string.slice(start,this.i-1);
4955: this.i += token.length;
4956: return arg;
4957: }
4958: }
4959: }
4960: this.i++;
4961: }
4962: }
4963: this.Error("Couldn't find "+this.cmd+token+" for "+name);
4964: return null;
4965: },
4966:
4967: /*
4968: * Get a parameter delimited by a control sequence, and
4969: * process it to get its mlist
4970: */
4971: ProcessUpto: function (name,token) {
4972: var arg = this.GetUpto(name,token); if (this.error) return null;
4973: return this.Process(arg);
4974: },
4975:
4976: /*
4977: * Get everything up to \end{env}
4978: */
4979: GetEnd: function (env) {
4980: var body = ''; var name = '';
4981: while (name != env) {
4982: body += this.GetUpto('begin{'+env+'}','end'); if (this.error) return null;
4983: name = this.GetArgument(this.cmd+'end'); if (this.error) return null;
4984: }
4985: return body;
4986: },
4987:
4988:
4989: /***************************************************************************/
4990:
4991:
4992: /*
4993: * Ignore spaces
4994: */
4995: Space: function () {},
4996:
4997: /*
4998: * Collect together any primes and convert them to a superscript
4999: */
5000: Prime: function (c) {
5001: var base = this.mlist.Last();
5002: if (base == null || (!base.atom && base.type != 'box' && base.type != 'frac'))
5003: {base = this.mlist.Add(jsMath.mItem.Atom('ord',{type:null}))}
5004: if (base.sup) {this.Error("Prime causes double exponent: use braces to clarify"); return}
5005: var sup = '';
5006: while (c == "'") {sup += this.cmd+'prime'; c = this.GetNext(); if (c == "'") {this.i++}}
5007: base.sup = this.Process(sup);
5008: base.sup.isPrime = 1;
5009: },
5010:
5011: /*
5012: * Raise or lower its parameter by a given amount
5013: * @@@ Note that this is different from TeX, which requires an \hbox @@@
5014: * ### make this work with mu's ###
5015: */
5016: RaiseLower: function (name) {
5017: var h = this.GetDimen(this.cmd+name,1); if (this.error) return;
1.2 ! albertel 5018: var box = this.ProcessScriptArg(this.cmd+name); if (this.error) return;
1.1 albertel 5019: if (name == 'lower') {h = -h}
5020: this.mlist.Add(new jsMath.mItem('raise',{nuc: box, raise: h}));
5021: },
5022:
5023: /*
5024: * Shift an expression to the right or left
5025: * @@@ Note that this is different from TeX, which requires a \vbox @@@
5026: * ### make this work with mu's ###
5027: */
5028: MoveLeftRight: function (name) {
5029: var x = this.GetDimen(this.cmd+name,1); if (this.error) return;
5030: var box = this.ProcessArg(this.cmd+name); if (this.error) return;
5031: if (name == 'moveleft') {x = -x}
5032: this.mlist.Add(jsMath.mItem.Space(x));
5033: this.mlist.Add(jsMath.mItem.Atom('ord',box));
5034: this.mlist.Add(jsMath.mItem.Space(-x));
5035: },
5036:
5037: /*
5038: * Load an extension if it has not already been loaded
5039: */
5040: Require: function (name) {
5041: var file = this.GetArgument(this.cmd+name); if (this.error) return;
5042: file = jsMath.Extension.URL(file);
5043: if (jsMath.Setup.loaded[file]) return;
5044: this.Extension(null,[file]);
5045: },
5046:
5047: /*
5048: * Load an extension file and restart processing the math
5049: */
5050: Extension: function (name,data) {
5051: jsMath.Translate.restart = 1;
5052: if (name != null) {delete jsMath.Parser.prototype[data[1]||'macros'][name]}
5053: jsMath.Extension.Require(data[0],jsMath.Translate.asynchronous);
5054: throw "restart";
5055: },
5056:
5057: /*
5058: * Implements \frac{num}{den}
5059: */
5060: Frac: function (name) {
5061: var num = this.ProcessArg(this.cmd+name); if (this.error) return;
5062: var den = this.ProcessArg(this.cmd+name); if (this.error) return;
5063: this.mlist.Add(jsMath.mItem.Fraction('over',num,den));
5064: },
5065:
5066: /*
5067: * Implements \sqrt[n]{...}
5068: */
5069: Sqrt: function (name) {
5070: var n = this.GetBrackets(this.cmd+name); if (this.error) return;
5071: var arg = this.ProcessArg(this.cmd+name); if (this.error) return;
1.2 ! albertel 5072: var box = jsMath.mItem.Atom('radical',arg);
! 5073: if (n != '') {box.root = this.Process(n); if (this.error) return}
1.1 albertel 5074: this.mlist.Add(box);
5075: },
5076:
5077: /*
5078: * Implements \root...\of{...}
5079: */
5080: Root: function (name) {
5081: var n = this.ProcessUpto(this.cmd+name,'of'); if (this.error) return;
5082: var arg = this.ProcessArg(this.cmd+name); if (this.error) return;
1.2 ! albertel 5083: var box = jsMath.mItem.Atom('radical',arg);
1.1 albertel 5084: box.root = n; this.mlist.Add(box);
5085: },
5086:
5087:
5088: /*
5089: * Implements \buildrel...\over{...}
5090: */
5091: BuildRel: function (name) {
5092: var top = this.ProcessUpto(this.cmd+name,'over'); if (this.error) return;
5093: var bot = this.ProcessArg(this.cmd+name); if (this.error) return;
5094: var op = jsMath.mItem.Atom('op',bot);
5095: op.limits = 1; op.sup = top;
5096: this.mlist.Add(op);
5097: },
5098:
5099: /*
5100: * Create a delimiter of the type and size specified in the parameters
5101: */
5102: MakeBig: function (name,data) {
5103: var type = data[0]; var h = data[1] * jsMath.p_height;
5104: var delim = this.GetDelimiter(this.cmd+name); if (this.error) return;
5105: this.mlist.Add(jsMath.mItem.Atom(type,jsMath.Box.Delimiter(h,delim,'T')));
5106: },
5107:
5108: /*
5109: * Insert the specified character in the given font.
5110: * (Try to load the font if it is not already available.)
5111: */
5112: Char: function (name) {
5113: var font = this.GetArgument(this.cmd+name); if (this.error) return;
5114: var n = this.GetArgument(this.cmd+name); if (this.error) return;
5115: if (!jsMath.TeX[font]) {
5116: jsMath.TeX[font] = [];
5117: this.Extension(null,[jsMath.Font.URL(font)]);
5118: } else {
5119: this.mlist.Add(jsMath.mItem.Typeset(jsMath.Box.TeX(n-0,font,'T',this.mlist.data.size)));
5120: }
5121: },
5122:
5123: /*
5124: * Create an array or matrix.
5125: */
5126: Matrix: function (name,delim) {
5127: var data = this.mlist.data;
5128: var arg = this.GetArgument(this.cmd+name); if (this.error) return;
1.2 ! albertel 5129: var parse = new jsMath.Parser(arg+this.cmd+'\\',null,data.size,delim[5] || 'T');
! 5130: parse.matrix = name; parse.row = []; parse.table = []; parse.rspacing = [];
1.1 albertel 5131: parse.Parse(); if (parse.error) {this.Error(parse); return}
5132: parse.HandleRow(name,1); // be sure the last row is recorded
1.2 ! albertel 5133: var box = jsMath.Box.Layout(data.size,parse.table,delim[2]||null,delim[3]||null,parse.rspacing,delim[4]||null);
1.1 albertel 5134: // Add parentheses, if needed
5135: if (delim[0] && delim[1]) {
1.2 ! albertel 5136: var left = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[0]],'T');
! 5137: var right = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[1]],'T');
1.1 albertel 5138: box = jsMath.Box.SetList([left,box,right],data.style,data.size);
5139: }
5140: this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box));
5141: },
5142:
5143: /*
5144: * When we see an '&', try to add a matrix entry to the row data.
5145: * (Use all the data in the current mList, and then clear it)
5146: */
5147: HandleEntry: function (name) {
5148: if (!this.matrix)
5149: {this.Error(name+" can only appear in a matrix or array"); return}
5150: if (this.mlist.data.openI != null) {
5151: var open = this.mlist.Get(this.mlist.data.openI);
5152: if (open.left) {this.Error("Missing "+this.cmd+"right")}
5153: else {this.Error("Missing close brace")}
5154: }
5155: if (this.mlist.data.overI != null) {this.mlist.Over()}
5156: var data = this.mlist.data;
5157: this.mlist.Atomize(data.style,data.size);
5158: var box = this.mlist.Typeset(data.style,data.size);
5159: this.row[this.row.length] = box;
5160: this.mlist = new jsMath.mList(null,null,data.size,data.style);
5161: },
5162:
5163: /*
5164: * When we see a \cr or \\, try to add a row to the table
5165: */
5166: HandleRow: function (name,last) {
1.2 ! albertel 5167: var dimen;
! 5168: if (!this.matrix) {this.Error(this.cmd+name+" can only appear in a matrix or array"); return}
! 5169: if (name == "\\") {
! 5170: dimen = this.GetBrackets(this.cmd+name); if (this.error) return;
! 5171: if (dimen) {dimen = this.ParseDimen(dimen,this.cmd+name,0,1)}
! 5172: }
1.1 albertel 5173: this.HandleEntry(name);
5174: if (!last || this.row.length > 1 || this.row[0].format != 'null')
5175: {this.table[this.table.length] = this.row}
1.2 ! albertel 5176: if (dimen) {this.rspacing[this.table.length] = dimen}
1.1 albertel 5177: this.row = [];
5178: },
5179:
5180: /*
1.2 ! albertel 5181: * Look for \vskip or \vspace in \noalign parameters
! 5182: */
! 5183: HandleNoAlign: function (name) {
! 5184: var arg = this.GetArgument(this.cmd+name); if (this.error) return;
! 5185: var skip = arg.replace(/^.*(vskip|vspace)([^a-z])/i,'$2');
! 5186: if (skip.length == arg.length) return;
! 5187: var d = this.ParseDimen(skip,this.cmd+RegExp.$1,0,1); if (this.error) return;
! 5188: this.rspacing[this.table.length] = (this.rspacing[this.table.length] || 0) + d;
! 5189: },
! 5190:
! 5191: /*
1.1 albertel 5192: * LaTeX array environment
5193: */
5194: Array: function (name,delim) {
5195: var columns = delim[2]; var cspacing = delim[3];
5196: if (!columns) {
5197: columns = this.GetArgument(this.cmd+'begin{'+name+'}');
5198: if (this.error) return;
5199: }
5200: columns = columns.replace(/[^clr]/g,'');
5201: columns = columns.split('');
1.2 ! albertel 5202: var data = this.mlist.data; var style = delim[5] || 'T';
1.1 albertel 5203: var arg = this.GetEnd(name); if (this.error) return;
5204: var parse = new jsMath.Parser(arg+this.cmd+'\\',null,data.size,style);
1.2 ! albertel 5205: parse.matrix = name; parse.row = []; parse.table = []; parse.rspacing = [];
1.1 albertel 5206: parse.Parse(); if (parse.error) {this.Error(parse); return}
5207: parse.HandleRow(name,1); // be sure the last row is recorded
1.2 ! albertel 5208: var box = jsMath.Box.Layout(data.size,parse.table,columns,cspacing,parse.rspacing,delim[4]);
1.1 albertel 5209: // Add parentheses, if needed
5210: if (delim[0] && delim[1]) {
1.2 ! albertel 5211: var left = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[0]],'T');
! 5212: var right = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[1]],'T');
1.1 albertel 5213: box = jsMath.Box.SetList([left,box,right],data.style,data.size);
5214: }
5215: this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box));
5216: },
5217:
5218: /*
5219: * LaTeX \begin{env}
5220: */
5221: Begin: function (name) {
5222: var env = this.GetArgument(this.cmd+name); if (this.error) return;
5223: if (env.match(/[^a-z*]/i)) {this.Error('Invalid environment name "'+env+'"'); return}
5224: if (!this.environments[env]) {this.Error('Unknown environment "'+env+'"'); return}
5225: var cmd = this.environments[env];
5226: if (typeof(cmd) == "string") {cmd = [cmd]}
5227: this[cmd[0]](env,cmd.slice(1));
5228: },
5229:
5230: /*
5231: * LaTeX \end{env}
5232: */
5233: End: function (name) {
5234: var env = this.GetArgument(this.cmd+name); if (this.error) return;
5235: this.Error(this.cmd+name+'{'+env+'} without matching '+this.cmd+'begin');
5236: },
5237:
5238: /*
5239: * Add a fixed amount of horizontal space
5240: */
5241: Spacer: function (name,w) {
5242: this.mlist.Add(jsMath.mItem.Space(w-0));
5243: },
5244:
5245: /*
5246: * Add horizontal space given by the argument
5247: */
5248: Hskip: function (name) {
5249: var w = this.GetDimen(this.cmd+name); if (this.error) return;
5250: this.mlist.Add(jsMath.mItem.Space(w));
5251: },
5252:
5253: /*
5254: * Typeset the argument as plain text rather than math.
5255: */
5256: HBox: function (name) {
5257: var text = this.GetArgument(this.cmd+name); if (this.error) return;
5258: var box = jsMath.Box.InternalMath(text,this.mlist.data.size);
5259: this.mlist.Add(jsMath.mItem.Typeset(box));
5260: },
5261:
5262: /*
5263: * Insert a rule of a particular width, height and depth
5264: * This replaces \hrule and \vrule
5265: * @@@ not a standard TeX command, and all three parameters must be given @@@
5266: */
5267: Rule: function (name,style) {
5268: var w = this.GetDimen(this.cmd+name,1); if (this.error) return;
5269: var h = this.GetDimen(this.cmd+name,1); if (this.error) return;
5270: var d = this.GetDimen(this.cmd+name,1); if (this.error) return;
5271: h += d; var html;
5272: if (h != 0) {h = Math.max(1.05/jsMath.em,h)}
5273: if (h == 0 || w == 0 || style == "blank")
5274: {html = jsMath.HTML.Blank(w,h)} else {html = jsMath.HTML.Rule(w,h)}
5275: if (d) {
5276: html = '<span style="vertical-align:'+jsMath.HTML.Em(-d)+'">'
5277: + html + '</span>';
5278: }
5279: this.mlist.Add(jsMath.mItem.Typeset(new jsMath.Box('html',html,w,h-d,d)));
5280: },
5281:
5282: /*
5283: * Inserts an empty box of a specific height and depth
5284: */
5285: Strut: function () {
5286: var size = this.mlist.data.size;
5287: var box = jsMath.Box.Text('','normal','T',size).Styled();
5288: box.bh = box.bd = 0; box.h = .8; box.d = .3; box.w = 0;
5289: this.mlist.Add(jsMath.mItem.Typeset(box));
5290: },
5291:
5292: /*
5293: * Handles \phantom, \vphantom and \hphantom
5294: */
5295: Phantom: function (name,data) {
5296: var arg = this.ProcessArg(this.cmd+name); if (this.error) return;
5297: this.mlist.Add(new jsMath.mItem('phantom',{phantom: arg, v: data[0], h: data[1]}));
5298: },
5299:
5300: /*
5301: * Implements \smash
5302: */
5303: Smash: function (name,data) {
5304: var arg = this.ProcessArg(this.cmd+name); if (this.error) return;
5305: this.mlist.Add(new jsMath.mItem('smash',{smash: arg}));
5306: },
5307:
5308: /*
5309: * Puts an accent on the following argument
5310: */
5311: MathAccent: function (name,accent) {
5312: var c = this.ProcessArg(this.cmd+name); if (this.error) return;
5313: var atom = jsMath.mItem.Atom('accent',c); atom.accent = accent[0];
5314: this.mlist.Add(atom);
5315: },
5316:
5317: /*
5318: * Handles functions and operators like sin, cos, sum, etc.
5319: */
5320: NamedOp: function (name,data) {
5321: var a = (name.match(/[^acegm-su-z]/)) ? 1: 0;
5322: var d = (name.match(/[gjpqy]/)) ? .2: 0;
5323: if (data[1]) {name = data[1]}
5324: var box = jsMath.mItem.TextAtom('op',name,'cmr10',a,d);
5325: if (data[0] != null) {box.limits = data[0]}
5326: this.mlist.Add(box);
5327: },
5328:
5329: /*
5330: * Implements \limits
5331: */
5332: Limits: function (name,data) {
5333: var atom = this.mlist.Last();
5334: if (!atom || atom.type != 'op')
5335: {this.Error(this.cmd+name+" is allowed only on operators"); return}
5336: atom.limits = data[0];
5337: },
5338:
5339: /*
5340: * Implements macros like those created by \def. The named control
5341: * sequence is replaced by the string given as the first data value.
5342: * If there is a second data value, this specifies how many arguments
5343: * the macro uses, and in this case, those arguments are substituted
5344: * for #1, #2, etc. within the replacement string.
5345: *
5346: * See the jsMath.Macro() command below for more details.
5347: * The "newcommand" extension implements \newcommand and \def
5348: * and are loaded automatically if needed.
5349: */
5350: Macro: function (name,data) {
5351: var text = data[0];
5352: if (data[1]) {
5353: var args = [];
5354: for (var i = 0; i < data[1]; i++)
5355: {args[args.length] = this.GetArgument(this.cmd+name); if (this.error) return}
5356: text = this.SubstituteArgs(args,text);
5357: }
5358: this.string = this.AddArgs(text,this.string.slice(this.i));
5359: this.i = 0;
5360: },
5361:
5362: /*
5363: * Replace macro paramters with their values
5364: */
5365: SubstituteArgs: function (args,string) {
5366: var text = ''; var newstring = ''; var c; var i = 0;
5367: while (i < string.length) {
5368: c = string.charAt(i++);
5369: if (c == this.cmd) {text += c + string.charAt(i++)}
5370: else if (c == '#') {
5371: c = string.charAt(i++);
5372: if (c == "#") {text += c} else {
5373: if (!c.match(/[1-9]/) || c > args.length)
1.2 ! albertel 5374: {this.Error("Illegal macro parameter reference"); return null}
1.1 albertel 5375: newstring = this.AddArgs(this.AddArgs(newstring,text),args[c-1]);
5376: text = '';
5377: }
5378: } else {text += c}
5379: }
5380: return this.AddArgs(newstring,text);
5381: },
5382:
5383: /*
5384: * Make sure that macros are followed by a space if their names
5385: * could accidentally be continued into the following text.
5386: */
5387: AddArgs: function (s1,s2) {
5388: if (s2.match(/^[a-z]/i) && s1.match(/(^|[^\\])(\\\\)*\\[a-z]+$/i)) {s1 += ' '}
5389: return s1+s2;
5390: },
5391:
5392: /*
5393: * Replace the control sequence with the given text
5394: */
5395: Replace: function (name,data) {
5396: this.mlist.Add(jsMath.mItem.TextAtom(data[0],data[1],data[2],data[3]));
5397: },
5398:
5399: /*
5400: * Insert space for ~
5401: */
5402: Tilde: function (name) {
5403: this.mlist.Add(jsMath.mItem.TextAtom('ord',' ','normal'));
5404: },
5405:
5406: /*
5407: * Implements \llap, \rlap, etc.
5408: */
5409: HandleLap: function (name) {
5410: var box = this.ProcessArg(); if (this.error) return;
5411: box = this.mlist.Add(new jsMath.mItem('lap',{nuc: box, lap: name}));
5412: },
5413:
5414: /*
5415: * Adds the argument as a specific type of atom (for commands like
5416: * \overline, etc.)
5417: */
5418: HandleAtom: function (name,data) {
5419: var arg = this.ProcessArg(this.cmd+name); if (this.error) return;
5420: this.mlist.Add(jsMath.mItem.Atom(data,arg));
5421: },
5422:
5423:
5424: /*
5425: * Process the character associated with a specific \mathcharcode
5426: */
5427: HandleMathCode: function (name,code) {
5428: this.HandleTeXchar(code[0],code[1],code[2]);
5429: },
5430:
5431: /*
5432: * Add a specific character from a TeX font (use the current
5433: * font if the type is 7 (variable) or the font is not specified)
5434: * Load the font if it is not already loaded.
5435: */
5436: HandleTeXchar: function (type,font,code) {
5437: if (type == 7 && this.mlist.data.font != null) {font = this.mlist.data.font}
5438: font = jsMath.TeX.fam[font];
5439: if (!jsMath.TeX[font]) {
5440: jsMath.TeX[font] = [];
5441: this.Extension(null,[jsMath.Font.URL(font)]);
5442: } else {
5443: this.mlist.Add(jsMath.mItem.TeXAtom(jsMath.TeX.atom[type],code,font));
5444: }
5445: },
5446:
5447: /*
5448: * Add a TeX variable character or number
5449: */
5450: HandleVariable: function (c) {this.HandleTeXchar(7,1,c.charCodeAt(0))},
5451: HandleNumber: function (c) {this.HandleTeXchar(7,0,c.charCodeAt(0))},
5452:
5453: /*
5454: * For unmapped characters, just add them in as normal
5455: * (non-TeX) characters
5456: */
5457: HandleOther: function (c) {
5458: this.mlist.Add(jsMath.mItem.TextAtom('ord',c,'normal'));
5459: },
5460:
5461: /*
5462: * Ignore comments in TeX data
5463: * ### Some browsers remove the newlines, so this might cause
5464: * extra stuff to be ignored; look into this ###
5465: */
5466: HandleComment: function () {
5467: var c;
5468: while (this.i < this.string.length) {
5469: c = this.string.charAt(this.i++);
5470: if (c == "\r" || c == "\n") return;
5471: }
5472: },
5473:
5474: /*
5475: * Add a style change (e.g., \displaystyle, etc)
5476: */
5477: HandleStyle: function (name,style) {
5478: this.mlist.data.style = style[0];
5479: this.mlist.Add(new jsMath.mItem('style',{style: style[0]}));
5480: },
5481:
5482: /*
5483: * Implements \small, \large, etc.
5484: */
5485: HandleSize: function (name,size) {
5486: this.mlist.data.size = size[0];
5487: this.mlist.Add(new jsMath.mItem('size',{size: size[0]}));
5488: },
5489:
5490: /*
5491: * Set the current font (e.g., \rm, etc)
5492: */
5493: HandleFont: function (name,font) {
5494: this.mlist.data.font = font[0];
5495: },
5496:
5497: /*
5498: * Look for and process a control sequence
5499: */
5500: HandleCS: function () {
5501: var cmd = this.GetCommand(); if (this.error) return;
5502: if (this.macros[cmd]) {
5503: var macro = this.macros[cmd];
5504: if (typeof(macro) == "string") {macro = [macro]}
5505: this[macro[0]](cmd,macro.slice(1)); return;
5506: }
5507: if (this.mathchardef[cmd]) {
5508: this.HandleMathCode(cmd,this.mathchardef[cmd]);
5509: return;
5510: }
5511: if (this.delimiter[this.cmd+cmd]) {
5512: this.HandleMathCode(cmd,this.delimiter[this.cmd+cmd].slice(0,3))
5513: return;
5514: }
5515: this.Error("Unknown control sequence '"+this.cmd+cmd+"'");
5516: },
5517:
5518: /*
5519: * Process open and close braces
5520: */
5521: HandleOpen: function () {this.mlist.Open()},
5522: HandleClose: function () {
5523: if (this.mlist.data.openI == null) {this.Error("Extra close brace"); return}
5524: var open = this.mlist.Get(this.mlist.data.openI);
5525: if (!open || open.left == null) {this.mlist.Close()}
5526: else {this.Error("Extra close brace or missing "+this.cmd+"right"); return}
5527: },
5528:
5529: /*
5530: * Implements \left
5531: */
5532: HandleLeft: function (name) {
5533: var left = this.GetDelimiter(this.cmd+name); if (this.error) return;
5534: this.mlist.Open(left);
5535: },
5536:
5537: /*
5538: * Implements \right
5539: */
5540: HandleRight: function (name) {
5541: var right = this.GetDelimiter(this.cmd+name); if (this.error) return;
5542: var open = this.mlist.Get(this.mlist.data.openI);
5543: if (open && open.left != null) {this.mlist.Close(right)}
5544: else {this.Error("Extra open brace or missing "+this.cmd+"left");}
5545: },
5546:
5547: /*
5548: * Implements generalized fractions (\over, \above, etc.)
5549: */
5550: HandleOver: function (name,data) {
5551: if (this.mlist.data.overI != null)
5552: {this.Error('Ambiguous use of '+this.cmd+name); return}
5553: this.mlist.data.overI = this.mlist.Length();
5554: this.mlist.data.overF = {name: name};
5555: if (data.length > 0) {
5556: this.mlist.data.overF.left = this.delimiter[data[0]];
5557: this.mlist.data.overF.right = this.delimiter[data[1]];
5558: } else if (name.match(/withdelims$/)) {
5559: this.mlist.data.overF.left = this.GetDelimiter(this.cmd+name); if (this.error) return;
5560: this.mlist.data.overF.right = this.GetDelimiter(this.cmd+name); if (this.error) return;
5561: } else {
5562: this.mlist.data.overF.left = null;
5563: this.mlist.data.overF.right = null;
5564: }
5565: if (name.match(/^above/)) {
1.2 ! albertel 5566: this.mlist.data.overF.thickness = this.GetDimen(this.cmd+name,1);
1.1 albertel 5567: if (this.error) return;
5568: } else {
5569: this.mlist.data.overF.thickness = null;
5570: }
5571: },
5572:
5573: /*
5574: * Add a superscript to the preceeding atom
5575: */
5576: HandleSuperscript: function () {
5577: var base = this.mlist.Last();
5578: if (base == null || (!base.atom && base.type != 'box' && base.type != 'frac'))
5579: {base = this.mlist.Add(jsMath.mItem.Atom('ord',{type:null}))}
5580: if (base.sup) {
5581: if (base.sup.isPrime) {base = this.mlist.Add(jsMath.mItem.Atom('ord',{type:null}))}
5582: else {this.Error("Double exponent: use braces to clarify"); return}
5583: }
5584: base.sup = this.ProcessScriptArg('superscript'); if (this.error) return;
5585: },
5586:
5587: /*
5588: * Add a subscript to the preceeding atom
5589: */
5590: HandleSubscript: function () {
5591: var base = this.mlist.Last();
5592: if (base == null || (!base.atom && base.type != 'box' && base.type != 'frac'))
5593: {base = this.mlist.Add(jsMath.mItem.Atom('ord',{type:null}))}
5594: if (base.sub) {this.Error("Double subscripts: use braces to clarify"); return}
5595: base.sub = this.ProcessScriptArg('subscript'); if (this.error) return;
5596: },
5597:
5598: /*
5599: * Parse a TeX math string, handling macros, etc.
5600: */
5601: Parse: function () {
5602: var c;
5603: while (this.i < this.string.length) {
5604: c = this.string.charAt(this.i++);
5605: if (this.mathchar[c]) {this.HandleMathCode(c,this.mathchar[c])}
5606: else if (this.special[c]) {this[this.special[c]](c)}
5607: else if (this.letter.test(c)) {this.HandleVariable(c)}
5608: else if (this.number.test(c)) {this.HandleNumber(c)}
5609: else {this.HandleOther(c)}
5610: }
5611: if (this.mlist.data.openI != null) {
5612: var open = this.mlist.Get(this.mlist.data.openI);
5613: if (open.left) {this.Error("Missing "+this.cmd+"right")}
5614: else {this.Error("Missing close brace")}
5615: }
5616: if (this.mlist.data.overI != null) {this.mlist.Over()}
5617: },
5618:
5619: /*
5620: * Perform the processing of Appendix G
5621: */
5622: Atomize: function () {
5623: var data = this.mlist.init;
5624: if (!this.error) this.mlist.Atomize(data.style,data.size)
5625: },
5626:
5627: /*
5628: * Produce the final HTML.
5629: *
5630: * We have to wrap the HTML it appropriate <SPAN> tags to hide its
5631: * actual dimensions when these don't match the TeX dimensions of the
5632: * results. We also include an image to force the results to take up
5633: * the right amount of space. The results may need to be vertically
5634: * adjusted to make the baseline appear in the correct place.
5635: */
5636: Typeset: function () {
5637: var data = this.mlist.init;
5638: var box = this.typeset = this.mlist.Typeset(data.style,data.size);
5639: if (this.error) {return '<span class="error">'+this.error+'</span>'}
5640: if (box.format == 'null') {return ''};
5641:
5642: box.Styled().Remeasured(); var isSmall = 0; var isBig = 0;
5643: if (box.bh > box.h && box.bh > jsMath.h+.001) {isSmall = 1}
5644: if (box.bd > box.d && box.bd > jsMath.d+.001) {isSmall = 1}
5645: if (box.h > jsMath.h || box.d > jsMath.d) {isBig = 1}
5646:
5647: var html = box.html;
5648: if (isSmall) {// hide the extra size
5649: if (jsMath.Browser.allowAbsolute) {
5650: var y = 0;
5651: if (box.bh > jsMath.h+.001) {y = jsMath.h - box.bh}
5652: html = jsMath.HTML.Absolute(html,box.w,jsMath.h,0,y,jsMath.h);
1.2 ! albertel 5653: } else if (jsMath.Browser.valignBug) {
! 5654: // remove line height
! 5655: html = '<span style="line-height:'+jsMath.HTML.Em(jsMath.d)+';">'
! 5656: + html + '</span>';
! 5657: } else {
1.1 albertel 5658: // remove line height and try to hide the depth
5659: var dy = jsMath.HTML.Em(Math.max(0,box.bd-jsMath.hd)/3);
1.2 ! albertel 5660: html = '<span style="line-height:'+jsMath.HTML.Em(jsMath.d)+';'
1.1 albertel 5661: + ' position:relative; top:'+dy+'; vertical-align:'+dy
5662: + '">' + html + '</span>';
5663: }
5664: isBig = 1;
5665: }
5666: if (isBig) {
5667: // add height and depth to the line
5668: // (force a little extra to separate lines if needed)
5669: html += jsMath.HTML.Blank(0,box.h+.05,box.d+.05);
5670: }
5671: return '<nobr><span class="scale">'+html+'</span></nobr>';
5672: }
5673:
5674: });
5675:
5676: /*
5677: * Make these characters special (and call the given routines)
5678: */
5679: jsMath.Parser.prototype.AddSpecial({
5680: cmd: 'HandleCS',
5681: open: 'HandleOpen',
5682: close: 'HandleClose'
5683: });
5684:
5685:
5686: /*
5687: * The web-page author can call jsMath.Macro to create additional
5688: * TeX macros for use within his or her mathematics. See the
5689: * author's documentation for more details.
5690: */
5691:
5692: jsMath.Add(jsMath,{
5693: Macro: function (name) {
5694: var macro = jsMath.Parser.prototype.macros;
5695: macro[name] = ['Macro'];
5696: for (var i = 1; i < arguments.length; i++)
5697: {macro[name][macro[name].length] = arguments[i]}
5698: }
5699: });
5700:
5701: /*
5702: * Use these commands to create macros that load
5703: * JavaScript files and reprocess the mathematics when
5704: * the file is loaded. This lets you to have macros or
5705: * LaTeX environments that autoload their own definitions
5706: * only when they are needed, saving initial download time
5707: * on pages where they are not used. See the author's
5708: * documentation for more details.
5709: *
5710: */
5711:
5712: jsMath.Extension = {
5713:
5714: safeRequire: 1, // disables access to files outside of jsMath/extensions
5715:
5716: Macro: function (name,file) {
5717: var macro = jsMath.Parser.prototype.macros;
5718: if (file == null) {file = name}
5719: macro[name] = ['Extension',file];
5720: },
5721:
5722: LaTeX: function (env,file) {
5723: var latex = jsMath.Parser.prototype.environments;
5724: latex[env] = ['Extension',file,'environments'];
5725: },
5726:
5727: Font: function (name,font) {
5728: if (font == null) {font = name + "10"}
5729: var macro = jsMath.Parser.prototype.macros;
5730: macro[name] = ['Extension',jsMath.Font.URL(font)];
5731: },
5732:
5733: MathChar: function (font,defs) {
5734: var fam = jsMath.TeX.famName[font];
5735: if (fam == null) {
5736: fam = jsMath.TeX.fam.length;
5737: jsMath.TeX.fam[fam] = font;
5738: jsMath.TeX.famName[font] = fam;
5739: }
5740: var mathchardef = jsMath.Parser.prototype.mathchardef;
5741: for (var c in defs) {mathchardef[c] = [defs[c][0],fam,defs[c][1]]}
5742: },
5743:
5744: Require: function (file,show) {
5745: if (this.safeRequire && (file.match(/\.\.\/|[^-a-z0-9.\/:_+=%~]/i) ||
5746: (file.match(/:/) && file.substr(0,jsMath.root.length) != jsMath.root))) {
5747: jsMath.Setup.loaded[file] = 1;
5748: return;
5749: }
5750: jsMath.Setup.Script(this.URL(file),show);
5751: },
5752:
5753: URL: function (file) {
5754: file = file.replace(/^\s+|\s+$/g,'');
5755: if (!file.match(/^([a-z]+:|\/|fonts|extensions\/)/i)) {file = 'extensions/'+file}
5756: if (!file.match(/\.js$/)) {file += '.js'}
5757: return file;
5758: }
5759: }
5760:
5761:
5762: /***************************************************************************/
5763:
5764: /*
5765: * These routines look through the web page for math elements to process.
5766: * There are two main entry points you can call:
5767: *
5768: * <script> jsMath.Process() </script>
5769: * or
5770: * <script> jsMath.ProcessBeforeShowing() </script>
5771: *
5772: * The first will process the page asynchronously (so the user can start
5773: * reading the top of the file while jsMath is still processing the bottom)
5774: * while the second does not update until all the mathematics is typeset.
5775: */
5776:
5777: jsMath.Add(jsMath,{
5778: /*
5779: * Call this at the bottom of your HTML page to have the
5780: * mathematics typeset asynchronously. This lets the user
5781: * start reading the mathematics while the rest of the page
5782: * is being processed.
5783: */
5784: Process: function (obj) {
5785: jsMath.Setup.Body();
5786: jsMath.Script.Push(jsMath.Translate,'Asynchronous',obj);
5787: },
5788:
5789: /*
5790: * Call this at the bottom of your HTML page to have the
5791: * mathematics typeset before the page is displayed.
5792: * This can take a long time, so the user could cancel the
5793: * page before it is complete; use it with caution, and only
5794: * when there is a relatively small amount of math on the page.
5795: */
5796: ProcessBeforeShowing: function (obj) {
5797: jsMath.Setup.Body();
5798: var method = (jsMath.Controls.cookie.asynch ? "Asynchronous": "Synchronous");
5799: jsMath.Script.Push(jsMath.Translate,method,obj);
5800: }
5801:
5802: });
5803:
5804: jsMath.Translate = {
5805:
5806: element: [], // the list of math elements on the page
5807: cancel: 0, // set to 1 to cancel asynchronous processing
1.2 ! albertel 5808:
1.1 albertel 5809: /*
1.2 ! albertel 5810: * Parse a TeX string in Text or Display mode and return
! 5811: * the HTML for it (taking it from the cache, if available)
1.1 albertel 5812: */
1.2 ! albertel 5813: Parse: function (style,s,noCache) {
! 5814: var cache = jsMath.Global.cache[style];
! 5815: if (!cache[jsMath.em]) {cache[jsMath.em] = {}}
! 5816: var HTML = cache[jsMath.em][s];
! 5817: if (!HTML || noCache) {
! 5818: var parse = jsMath.Parse(s,null,null,style);
! 5819: parse.Atomize(); HTML = parse.Typeset();
! 5820: if (!noCache) {cache[jsMath.em][s] = HTML}
! 5821: }
! 5822: return HTML;
1.1 albertel 5823: },
5824:
1.2 ! albertel 5825: TextMode: function (s,noCache) {this.Parse('T',s,noCache)},
! 5826: DisplayMode: function (s,noCache) {this.Parse('D',s,noCache)},
1.1 albertel 5827:
5828: /*
5829: * Return the text of a given DOM element
5830: */
5831: GetElementText: function (element) {
5832: var text = this.recursiveElementText(element);
5833: element.alt = text;
5834: if (text.search('&') >= 0) {
5835: text = text.replace(/</g,'<');
5836: text = text.replace(/>/g,'>');
5837: text = text.replace(/"/g,'"');
5838: text = text.replace(/&/g,'&');
5839: }
5840: return text;
5841: },
5842: recursiveElementText: function (element) {
5843: if (element.nodeValue != null) {return element.nodeValue}
5844: if (element.childNodes.length == 0) {return " "}
5845: var text = '';
5846: for (var i = 0; i < element.childNodes.length; i++)
5847: {text += this.recursiveElementText(element.childNodes[i])}
5848: return text;
5849: },
5850:
5851: /*
5852: * Move hidden to the location of the math element to be
5853: * processed and reinitialize sizes for that location.
5854: */
5855: ResetHidden: function (element) {
5856: element.innerHTML =
5857: '<span style="visibility: hidden; position:absolute; top:0px;left:0px;"></span>'
5858: + jsMath.Browser.operaHiddenFix; // needed by Opera in tables
1.2 ! albertel 5859: element.className = '';
1.1 albertel 5860: jsMath.hidden = element.firstChild;
5861: if (!jsMath.BBoxFor("x").w) {jsMath.hidden = jsMath.hiddenTop}
5862: jsMath.ReInit();
5863: },
5864:
5865:
5866: /*
5867: * Typeset the contents of an element in \textstyle
5868: */
1.2 ! albertel 5869: ConvertText: function (element,noCache) {
1.1 albertel 5870: var text = this.GetElementText(element);
5871: this.ResetHidden(element);
1.2 ! albertel 5872: if (text.match(/^\s*\\nocache([^a-zA-Z])/))
! 5873: {noCache = true; text = text.replace(/\s*\\nocache/,'')}
! 5874: text = this.Parse('T',text,noCache);
1.1 albertel 5875: element.className = 'typeset';
5876: element.innerHTML = text;
5877: },
5878:
5879: /*
5880: * Typeset the contents of an element in \displaystyle
5881: */
1.2 ! albertel 5882: ConvertDisplay: function (element,noCache) {
1.1 albertel 5883: var text = this.GetElementText(element);
5884: this.ResetHidden(element);
1.2 ! albertel 5885: if (text.match(/^\s*\\nocache([^a-zA-Z])/))
! 5886: {noCache = true; text = text.replace(/\s*\\nocache/,'')}
! 5887: text = this.Parse('D',text,noCache);
1.1 albertel 5888: element.className = 'typeset';
5889: element.innerHTML = text;
5890: },
5891:
5892: /*
5893: * Process a math element
5894: */
5895: ProcessElement: function (element) {
5896: this.restart = 0;
1.2 ! albertel 5897: var noCache = (element.className.toLowerCase().match(/(^| )nocache( |$)/) != null);
1.1 albertel 5898: try {
5899: if (element.tagName.toLowerCase() == 'div') {
1.2 ! albertel 5900: this.ConvertDisplay(element,noCache);
1.1 albertel 5901: element.onclick = jsMath.Click.CheckClick;
5902: element.ondblclick = jsMath.Click.CheckDblClick;
5903: } else if (element.tagName.toLowerCase() == 'span') {
1.2 ! albertel 5904: this.ConvertText(element,noCache);
1.1 albertel 5905: element.onclick = jsMath.Click.CheckClick;
5906: element.ondblclick = jsMath.Click.CheckDblClick;
5907: }
5908: } catch (err) {
5909: if (element.alt) {
5910: var tex = element.alt;
5911: tex = tex.replace(/&/g,'&');
5912: tex = tex.replace(/</g,'<');
5913: tex = tex.replace(/>/g,'>');
5914: element.innerHTML = tex;
1.2 ! albertel 5915: element.className = 'math';
! 5916: if (noCache) {element.className += ' nocache'}
1.1 albertel 5917: }
5918: jsMath.hidden = jsMath.hiddenTop;
5919: }
5920: },
5921:
5922: /*
5923: * Asynchronously process all the math elements starting with
5924: * the k-th one
5925: */
5926: ProcessElements: function (k) {
5927: jsMath.Script.blocking = 1;
5928: if (k >= this.element.length || this.cancel) {
5929: this.ProcessComplete();
5930: if (this.cancel) {
5931: jsMath.Message.Set("Process Math: Canceled");
5932: jsMath.Message.Clear()
5933: }
5934: jsMath.Script.blocking = 0;
5935: jsMath.Script.Process();
5936: } else {
5937: this.ProcessElement(this.element[k]);
5938: if (this.restart) {
5939: jsMath.Script.Push(this,'ProcessElements',k);
5940: jsMath.Script.blocking = 0;
5941: setTimeout('jsMath.Script.Process()',jsMath.Browser.delay);
5942: } else {
5943: k++; var p = Math.floor(100 * k / this.element.length);
5944: jsMath.Message.Set('Processing Math: '+p+'%');
5945: setTimeout('jsMath.Translate.ProcessElements('+k+')',jsMath.Browser.delay);
5946: }
5947: }
5948: },
5949:
5950: /*
5951: * Start the asynchronous processing of mathematics
5952: */
5953: Asynchronous: function (obj) {
5954: if (!jsMath.initialized) {jsMath.Init()}
5955: this.element = this.GetMathElements(obj);
5956: this.cancel = 0; this.asynchronous = 1;
5957: jsMath.Script.blocking = 1;
5958: jsMath.Message.Set('Processing Math: 0%',1);
5959: setTimeout('jsMath.Translate.ProcessElements(0)',jsMath.Browser.delay);
5960: },
5961:
5962: /*
5963: * Do synchronous processing of mathematics
5964: */
5965: Synchronous: function (obj,i) {
5966: if (i == null) {
5967: if (!jsMath.initialized) {jsMath.Init()}
5968: this.element = this.GetMathElements(obj);
5969: i = 0;
5970: }
5971: this.asynchronous = 0;
5972: while (i < this.element.length) {
5973: this.ProcessElement(this.element[i]);
5974: if (this.restart) {
5975: jsMath.Synchronize('jsMath.Translate.Synchronous(null,'+i+')');
5976: jsMath.Script.Process();
5977: return;
5978: }
5979: i++;
5980: }
5981: this.ProcessComplete(1);
5982: },
5983:
5984: /*
5985: * Look up all the math elements on the page and
5986: * put them in a list sorted from top to bottom of the page
5987: */
5988: GetMathElements: function (obj) {
5989: var element = [];
5990: if (!obj) {obj = jsMath.document}
5991: if (typeof(obj) == 'string') {obj = jsMath.document.getElementById(obj)}
5992: if (!obj.getElementsByTagName) return null;
5993: var math = obj.getElementsByTagName('div');
5994: for (var k = 0; k < math.length; k++) {
1.2 ! albertel 5995: if (math[k].className.match(/(^| )math( |$)/)) {
1.1 albertel 5996: if (jsMath.Browser.renameOK && obj.getElementsByName)
5997: {math[k].setAttribute('name','_jsMath_')}
5998: else {element[element.length] = math[k]}
5999: }
6000: }
6001: math = obj.getElementsByTagName('span');
6002: for (var k = 0; k < math.length; k++) {
1.2 ! albertel 6003: if (math[k].className.match(/(^| )math( |$)/)) {
1.1 albertel 6004: if (jsMath.Browser.renameOK && obj.getElementsByName)
6005: {math[k].setAttribute('name','_jsMath_')}
6006: else {element[element.length] = math[k]}
6007: }
6008: }
6009: // this gets the SPAN and DIV elements interleaved in order
6010: if (jsMath.Browser.renameOK && obj.getElementsByName) {
6011: element = obj.getElementsByName('_jsMath_');
6012: } else if (jsMath.hidden.sourceIndex) {
6013: element.sort(function (a,b) {return a.sourceIndex - b.sourceIndex});
6014: }
6015: return element;
6016: },
6017:
6018: /*
6019: * Remove the window message about processing math
6020: * and clean up any marked <SPAN> or <DIV> tags
6021: */
6022: ProcessComplete: function (noMessage) {
6023: if (jsMath.Browser.renameOK) {
6024: var element = jsMath.document.getElementsByName('_jsMath_');
6025: for (var i = element.length-1; i >= 0; i--) {
6026: element[i].removeAttribute('name');
6027: }
6028: }
6029: jsMath.hidden = jsMath.hiddenTop;
6030: this.element = [];
6031: if (!noMessage) {
6032: jsMath.Message.Set('Processing Math: Done');
6033: jsMath.Message.Clear();
6034: }
6035: jsMath.Message.UnBlank();
6036: if (jsMath.Browser.safariImgBug &&
6037: (jsMath.Controls.cookie.font == 'symbol' ||
6038: jsMath.Controls.cookie.font == 'image')) {
6039: //
6040: // For Safari, the images don't always finish
6041: // updating, so nudge the window to cause a
6042: // redraw. (Hack!)
6043: //
6044: if (this.timeout) {clearTimeout(this.timeout)}
6045: this.timeout = setTimeout("jsMath.window.resizeBy(-1,0); "
6046: + "jsMath.window.resizeBy(1,0); "
6047: + "jsMath.Translate.timeout = null",2000);
6048: }
6049: },
6050:
6051: /*
6052: * Cancel procesing elements
6053: */
6054: Cancel: function () {
6055: jsMath.Translate.cancel = 1;
6056: if (jsMath.Script.cancelTimer) {jsMath.Script.cancelLoad()}
6057: }
6058:
6059: };
6060:
6061: jsMath.Add(jsMath,{
6062: //
6063: // Synchronize these with the loading of the tex2math plugin.
6064: //
6065: ConvertTeX: function (element) {jsMath.Script.Push(jsMath.tex2math,'ConvertTeX',element)},
6066: ConvertTeX2: function (element) {jsMath.Script.Push(jsMath.tex2math,'ConvertTeX2',element)},
6067: ConvertLaTeX: function (element) {jsMath.Script.Push(jsMath.tex2math,'ConvertLaTeX',element)},
6068: ConvertCustom: function (element) {jsMath.Script.Push(jsMath.tex2math,'ConvertCustom',element)},
6069: CustomSearch: function (om,cm,od,cd) {jsMath.Script.Push(null,function () {jsMath.tex2math.CustomSearch(om,cm,od,cd)})},
6070: tex2math: {
6071: ConvertTeX: function () {},
6072: ConvertTeX2: function () {},
6073: ConvertLaTeX: function () {},
6074: ConvertCustom: function () {},
6075: CustomSearch: function () {}
6076: }
6077: });
6078: jsMath.Synchronize = jsMath.Script.Synchronize;
6079:
6080: /***************************************************************************/
6081:
1.2 ! albertel 6082:
1.1 albertel 6083: /*
6084: * Initialize things
6085: */
1.2 ! albertel 6086: try {
! 6087: if (window.parent != window && window.jsMathAutoload) {
! 6088: window.parent.jsMath = jsMath;
! 6089: jsMath.document = window.parent.document;
! 6090: jsMath.window = window.parent;
! 6091: }
! 6092: } catch (err) {}
! 6093:
! 6094: jsMath.Global.Register();
1.1 albertel 6095: jsMath.Loaded();
6096: jsMath.Controls.GetCookie();
6097: jsMath.Setup.Source();
1.2 ! albertel 6098: jsMath.Global.Init();
1.1 albertel 6099: jsMath.Script.Init();
6100: jsMath.Setup.Fonts();
6101: if (jsMath.document.body) {jsMath.Setup.Body()}
6102:
6103: }}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>