Annotation of loncom/html/adm/jsMath/jsMath.js, revision 1.1
1.1 ! albertel 1: /*****************************************************************************
! 2: *
! 3: * jsMath: Mathematics on the Web
! 4: *
! 5: * Version: 1.7e
! 6: *
! 7: * This jsMath package makes it possible to display mathematics in HTML pages
! 8: * that are viewable by a wide range of browsers on both the Mac and the IBM PC,
! 9: * including browsers that don't process MathML. See
! 10: *
! 11: * http://www.math.union.edu/locate/jsMath
! 12: *
! 13: * for the latest version, and for documentation on how to use jsMath.
! 14: *
! 15: * Copyright (c) 2004-2005 by Davide P. Cervone.
! 16: *
! 17: * This program is free software; you can redistribute it and/or
! 18: * modify it under the terms of the GNU General Public License
! 19: * as published by the Free Software Foundation; either version 2
! 20: * of the License.
! 21: *
! 22: * This program is distributed in the hope that it will be useful,
! 23: * but WITHOUT ANY WARRANTY; without even the implied warranty of
! 24: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 25: * GNU General Public License for more details.
! 26: *
! 27: * You should have received a copy of the GNU General Public License
! 28: * along with this program; if not, write to the Free Software
! 29: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
! 30: *
! 31: *****************************************************************************/
! 32:
! 33: /*
! 34: * Prevent running everything again if this file is loaded twice
! 35: */
! 36: if (!window.jsMath) {
! 37:
! 38: //
! 39: // debugging routine
! 40: //
! 41: function ShowObject (obj,spaces) {
! 42: var s = ''; if (!spaces) {spaces = ""}
! 43: for (var i in obj) {
! 44: if (obj[i] != null) {
! 45: if (typeof(obj[i]) == "object") {
! 46: s += spaces + i + ": {\n"
! 47: + ShowObject(obj[i],spaces + ' ')
! 48: + spaces + "}\n";
! 49: } else if (typeof(obj[i]) != "function") {
! 50: s += spaces + i + ': ' + obj[i] + "\n";
! 51: }
! 52: }
! 53: }
! 54: return s;
! 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:
! 68: var jsMath = {
! 69:
! 70: //
! 71: // Name of image files
! 72: //
! 73: blank: "blank.gif",
! 74: black: "black.gif",
! 75:
! 76: //
! 77: // The TeX font parameters
! 78: //
! 79: TeX: {
! 80: thinmuskip: 3/18,
! 81: medmuskip: 4/18,
! 82: thickmuskip: 5/18,
! 83:
! 84: x_height: .430554,
! 85: quad: 1,
! 86: num1: .676508,
! 87: num2: .393732,
! 88: num3: .44373,
! 89: denom1: .685951,
! 90: denom2: .344841,
! 91: sup1: .412892,
! 92: sup2: .362892,
! 93: sup3: .288888,
! 94: sub1: .15,
! 95: sub2: .247217,
! 96: sup_drop: .386108,
! 97: sub_drop: .05,
! 98: delim1: 2.39,
! 99: delim2: 1.0,
! 100: axis_height: .25,
! 101: default_rule_thickness: .04,
! 102: big_op_spacing1: .111111,
! 103: big_op_spacing2: .166666,
! 104: big_op_spacing3: .2,
! 105: big_op_spacing4: .6,
! 106: big_op_spacing5: .1,
! 107:
! 108: integer: 6553.6, // conversion of em's to TeX internal integer
! 109: scriptspace: .05,
! 110: nulldelimiterspace: .12,
! 111: delimiterfactor: 901,
! 112: delimitershortfall: .5,
! 113: scale: 1 // scaling factor for font dimensions
! 114: },
! 115:
! 116: // Font sizes for \tiny, \small, etc. (must match styles below)
! 117: sizes: [50, 60, 70, 85, 100, 120, 144, 173, 207, 249],
! 118:
! 119: allowAbsolute: 1, // tells if browser can nest absolutely positioned
! 120: // SPANs inside relative SPANs
! 121: absoluteOffsetY: 0, // vertical adjustment when absolute position is used
! 122: allowAbsoluteDelim: 0, // OK to use absolute placement for building delims?
! 123: renameOK: 1, // tells if brower will find a tag whose name
! 124: // has been set via setAttributes
! 125: separateNetgativeSkips: 0, // MSIE doesn't do negative left margins
! 126: separateSkips: 0, // Netscape doesn't combine skips well
! 127: noEmptySpans: 0, // empty spans are/aren't allowed
! 128: msieSpaceFix: '', // for MSIE spacing bug fix
! 129:
! 130: delay: 1, // delay for asynchronous math processing
! 131:
! 132: defaultH: 0, // default height for characters with no height specified
! 133:
! 134: //
! 135: // Debugging flags
! 136: //
! 137: show: {
! 138: BBox: false,
! 139: Baseline: false,
! 140: Top: false
! 141: },
! 142:
! 143: //
! 144: // The styles needed for the TeX fonts
! 145: //
! 146: styles: {
! 147: '.size0': 'font-size: 50%', // tiny (\scriptscriptsize)
! 148: '.size1': 'font-size: 60%', // (50% of \large for consistency)
! 149: '.size2': 'font-size: 70%', // scriptsize
! 150: '.size3': 'font-size: 85%', // small (70% of \large for consistency)
! 151: '.size4': 'font-size: 100%', // normalsize
! 152: '.size5': 'font-size: 120%', // large
! 153: '.size6': 'font-size: 144%', // Large
! 154: '.size7': 'font-size: 173%', // LARGE
! 155: '.size8': 'font-size: 207%', // huge
! 156: '.size9': 'font-size: 249%', // Huge
! 157:
! 158: '.cmr10': 'font-family: cmr10',
! 159: '.cmbx10': 'font-family: cmbx10, cmr10',
! 160: '.cmti10': 'font-family: cmti10, cmr10',
! 161: '.cmmi10': 'font-family: cmmi10',
! 162: '.cmsy10': 'font-family: cmsy10',
! 163: '.cmex10': 'font-family: cmex10',
! 164: '.arial': 'font-family: Arial unicode MS', // for MSIE
! 165:
! 166: '.normal': 'font-family: serif; font-style: normal',
! 167: '.math': 'font-family: serif; font-style: normal',
! 168: '.typeset': 'font-family: serif; font-style: normal',
! 169: 'span.typeset': 'font-family: serif; font-style: normal',
! 170: 'div.typeset': 'font-family: serif; font-style: normal; text-align: center; margin-top: 1em; margin-bottom: 1em',
! 171: '.mathlink': 'text-decoration: none',
! 172: '.mathHD': 'border-width: 0; width: 1px; margin-right: -1px',
! 173:
! 174: '.error': 'font-size: 10pt; font-style: italic; '
! 175: + 'background-color: #FFFFCC; padding: 1; '
! 176: + 'border-width: 1; border-style: solid; border-color: #CC0000'
! 177: },
! 178:
! 179:
! 180: /***************************************************************************/
! 181:
! 182: /*
! 183: * Get the width and height (in pixels) of an HTML string
! 184: */
! 185: BBoxFor: function (s) {
! 186: this.hidden.innerHTML = s;
! 187: var bbox = {w: this.hidden.offsetWidth, h: this.hidden.offsetHeight};
! 188: this.hidden.innerHTML = ''; // avoid MSIE bug on the Mac
! 189: return bbox;
! 190: },
! 191:
! 192: /*
! 193: * Get the width and height (in ems) of an HTML string
! 194: */
! 195: EmBoxFor: function (s) {
! 196: var bbox = this.BBoxFor(s);
! 197: return {w: bbox.w/this.em, h: bbox.h/this.em};
! 198: },
! 199:
! 200: /*
! 201: * Determine if the "top" of a <SPAN> is always at the same height
! 202: * or varies with the height of the rest of the line (MSIE).
! 203: */
! 204: TestSpanHeight: function () {
! 205: this.hidden.innerHTML = '<SPAN><IMG SRC="'+jsMath.blank+'" STYLE="height: 2em"></SPAN>';
! 206: var span = this.hidden.getElementsByTagName('SPAN')[0];
! 207: var img = this.hidden.getElementsByTagName('IMG')[0];
! 208: this.spanHeightVaries = (span.offsetHeight == img.offsetHeight);
! 209: this.hidden.innerHTML = '';
! 210: },
! 211:
! 212: /*
! 213: * Determine if the NAME attribute of a tag can be changed
! 214: * using the setAttribute function, and then be properly
! 215: * returned by getElementByName.
! 216: */
! 217: TestRenameOK: function () {
! 218: this.hidden.innerHTML = '<SPAN ID="jsMath.test"></SPAN>';
! 219: var test = document.getElementById('jsMath.test');
! 220: test.setAttribute('NAME','jsMath_test');
! 221: this.renameOK = (document.getElementsByName('jsMath_test').length > 0);
! 222: this.hidden.innerHTML = '';
! 223: },
! 224:
! 225: /*
! 226: * Look to see if a font is found. HACK!
! 227: * Check the character in the '|' position, and see if it is
! 228: * wider than the usual '|'.
! 229: */
! 230: TestFont: function (name,n,factor) {
! 231: if (n == null) {n = 124}; if (factor == null) {factor = 2}
! 232: var wh1 = this.BBoxFor('<SPAN STYLE="font-family: '+name+', serif">'+this.TeX[name][n].c+'</SPAN>');
! 233: var wh2 = this.BBoxFor('<SPAN STYLE="font-family: serif">'+this.TeX[name][n].c+'</SPAN>');
! 234: return (wh1.w > factor*wh2.w && wh1.h != 0);
! 235: },
! 236:
! 237: TestFont2: function (name,n,factor) {
! 238: if (n == null) {n = 124}; if (factor == null) {factor = 2}
! 239: var wh1 = this.BBoxFor('<SPAN STYLE="font-family: '+name+', serif">'+this.TeX[name][n].c+'</SPAN>');
! 240: var wh2 = this.BBoxFor('<SPAN STYLE="font-family: serif">'+this.TeX[name][n].c+'</SPAN>');
! 241: return (wh2.w > factor*wh1.w && wh1.h != 0);
! 242: },
! 243:
! 244: /*
! 245: * Check for the availability of TeX fonts. We do this by looking at
! 246: * the width and height of a character in the cmex10 font. The cmex10
! 247: * font has depth considerably greater than most characters' widths (the
! 248: * whole font has the depth of the character with greatest depth). This
! 249: * is not the case for most fonts, so if we can access cmex10, the
! 250: * height of a character should be much bigger than the width.
! 251: * Otherwise, if we don't have cmex10, we'll get a character in another
! 252: * font with normal height and width. In this case, we insert a message
! 253: * pointing the user to the jsMath site, and load one of the fallback
! 254: * definitions.
! 255: *
! 256: */
! 257: CheckFonts: function () {
! 258: jsMath.nofonts = 0;
! 259: var wh = this.BBoxFor('<SPAN STYLE="font-family: cmex10">'+this.TeX.cmex10[1].c+'</SPAN>');
! 260: if (wh.w*3 < wh.h && wh.h != 0) return;
! 261: if (this.TestFont('cmr10')) return;
! 262: if (window.NoFontMessage) {window.NoFontMessage()} else {this.NoFontMessage()}
! 263: if (navigator.platform == 'Win32') {
! 264: document.writeln('<SCRIPT SRC="'+this.root+'jsMath-fallback-pc.js"></SCRIPT>');
! 265: } else if (navigator.platform == 'MacPPC') {
! 266: document.writeln('<SCRIPT SRC="'+this.root+'jsMath-fallback-mac.js"></SCRIPT>');
! 267: } else {
! 268: // default to unix? Is there a better way to tell if unix?
! 269: document.writeln('<SCRIPT SRC="'+this.root+'jsMath-fallback-unix.js"></SCRIPT>');
! 270: }
! 271: jsMath.nofonts = 1;
! 272: },
! 273:
! 274: /*
! 275: * The message for when no TeX fonts. You can eliminate this message
! 276: * by including
! 277: *
! 278: * <SCRIPT>function NoFontMessage() {}</SCRIPT>
! 279: *
! 280: * in your HTML file, if you want. But this means the user may not know
! 281: * that he or she can get a better version of your page.
! 282: */
! 283: NoFontMessage: function () {
! 284: document.writeln
! 285: ('<CENTER><DIV STYLE="padding: 10; border-style: solid; border-width:3;'
! 286: +' border-color: #DD0000; background-color: #FFF8F8; width: 75%; text-align: left">'
! 287: +'<SMALL><FONT COLOR="#AA0000"><B>Warning:</B>\n'
! 288: +'It looks like you don\'t have the TeX math fonts installed.\n'
! 289: +'The mathematics on this page may not look right without them.\n'
! 290: +'The <A HREF="http://www.math.union.edu/locate/jsMath/" TARGET="_blank">'
! 291: +'jsMath Home Page</A> has information on how to download the\n'
! 292: +'needed fonts. In the meantime, we will do the best we can\n'
! 293: +'with the fonts you have, but it may not be pretty and some equations\n'
! 294: +'may not be rendered correctly.\n'
! 295: +'</FONT></SMALL></DIV></CENTER><p><HR><p>');
! 296: },
! 297:
! 298: /*
! 299: * Initialize jsMath. This determines the em size, and a variety
! 300: * of other parameters used throughout jsMath.
! 301: */
! 302: Init: function() {
! 303: this.em = this.BBoxFor('<DIV STYLE="width: 20em; height: 1em"></DIV>').w/20;
! 304: var h = this.BBoxFor('x').h; // Line height and depth to baseline
! 305: var d = this.BBoxFor('x<IMG SRC="'+jsMath.black+'" HEIGHT="'+h+'" WIDTH="1">').h - h;
! 306: this.h = (h-d)/this.em; this.d = d/this.em;
! 307: this.hd = this.h + this.d;
! 308: this.ph = h-d; this.pd = d;
! 309:
! 310: this.InitTeXfonts();
! 311:
! 312: var x_height = this.EmBoxFor('<SPAN CLASS="cmr10">M</SPAN>').w/2;
! 313: this.TeX.M_height = x_height*(26/14);
! 314: this.TeX.h = this.h; this.TeX.d = this.d; this.TeX.hd = this.hd;
! 315: // factor for \big and its brethren
! 316: this.p_height = (this.TeX.cmex10[0].h+this.TeX.cmex10[0].d) / .85;
! 317:
! 318: this.InitSizes();
! 319:
! 320: this.initialized = 1;
! 321: },
! 322:
! 323: /*
! 324: * Find the root URL for the jsMath files (so we can load
! 325: * the other .js and .gif files
! 326: */
! 327: InitSource: function () {
! 328: var script = document.getElementsByTagName('SCRIPT');
! 329: var src = script[script.length-1].getAttribute('SRC');
! 330: if (src.match('(^|/)jsMath.js$')) {
! 331: this.root = src.replace(/jsMath.js$/,'');
! 332: this.blank = this.root + this.blank;
! 333: this.black = this.root + this.black;
! 334: }
! 335: },
! 336:
! 337: /*
! 338: * Look up the default height and depth for a TeX font
! 339: * and set the skewchar
! 340: */
! 341: InitTeXfont: function (name) {
! 342: var font = this.TeX[name];
! 343: var WH = this.EmBoxFor('<SPAN CLASS="'+name+'">'+font[65].c+'</SPAN>');
! 344: font.hd = WH.h;
! 345: font.d = this.EmBoxFor('<SPAN CLASS="'+name+'">'+ font[65].c +
! 346: '<IMG SRC="'+jsMath.black+'" STYLE="height:'+font.hd+'em; width:1"></SPAN>').h
! 347: - font.hd;
! 348: font.h = font.hd - font.d;
! 349: font.dh = .05;
! 350: if (name == 'cmmi10') {font.skewchar = 0177}
! 351: else if (name == 'cmsy10') {font.skewchar = 060}
! 352: },
! 353:
! 354: /*
! 355: * Init all the TeX fonts
! 356: */
! 357: InitTeXfonts: function () {
! 358: for (var i = 0; i < this.TeX.fam.length; i++)
! 359: {if (this.TeX.fam[i]) {this.InitTeXfont(this.TeX.fam[i])}}
! 360: },
! 361:
! 362: /*
! 363: * Compute font parameters for various sizes
! 364: */
! 365: InitSizes: function () {
! 366: this.TeXparams = [];
! 367: for (var j=0; j < this.sizes.length; j++) {this.TeXparams[j] = {}}
! 368: for (var i in this.TeX) {
! 369: if (typeof(this.TeX[i]) != 'object') {
! 370: for (var j=0; j < this.sizes.length; j++) {
! 371: this.TeXparams[j][i] = this.sizes[j]*this.TeX[i]/100;
! 372: }
! 373: }
! 374: }
! 375: },
! 376:
! 377: /*
! 378: * Test for browser characteristics, and adjust the font table
! 379: * to overcome specific browser bugs
! 380: */
! 381: InitBrowser: function () {
! 382: jsMath.browser = 'unknown';
! 383: this.isSafari = navigator.userAgent.match(/Safari/);
! 384: this.TestSpanHeight();
! 385: this.TestRenameOK();
! 386:
! 387: //
! 388: // Check for bug-filled Internet Explorer
! 389: //
! 390: if (this.spanHeightVaries) {
! 391: jsMath.browser = 'MSIE';
! 392: if (navigator.platform == 'Win32') {
! 393: this.UpdateTeXfonts({
! 394: cmr10: {'10': {c: 'Ω', tclass: 'normal'}},
! 395: cmmi10: {
! 396: '10': {c: '<I>Ω</I>', tclass: 'normal'},
! 397: '126': {c: '~<SPAN STYLE="margin-left:.1em"></SPAN>'}
! 398: },
! 399: cmsy10: {'10': {c: '⊗', tclass: 'arial'}},
! 400: cmex10: {'10': {c: '<SPAN STYLE="font-size: 67%">D</SPAN>'}},
! 401: cmti10: {'10': {c: '<I>Ω</I>', tclass: 'normal'}},
! 402: cmbx10: {'10': {c: '<B>Ω</B>', tclass: 'normal'}}
! 403: });
! 404: this.allowAbsoluteDelim = 1;
! 405: this.separateSkips = 1;
! 406: this.msieFontBug = 1; this.msieIntegralBug = 1;
! 407: this.msieSpaceFix = '<IMG SRC="'+jsMath.blank+'" CLASS="mathHD">';
! 408: jsMath.Macro('joinrel','\\mathrel{\\kern-5mu}'),
! 409: jsMath.Macro('mapsto','\\mapstochar\\kern-.54em\\rightarrow');
! 410: jsMath.Macro('longmapsto','\\mapstochar\\kern-.54em\\char{cmsy10}{0}\\joinrel\\rightarrow');
! 411: } else if (navigator.platform == 'MacPPC') {
! 412: document.writeln('<SCRIPT SRC="'+this.root+'jsMath-msie-mac.js"></SCRIPT>');
! 413: jsMath.Parser.prototype.macros.angle = ['Replace','ord','<FONT FACE="Symbol">‹</FONT>','normal'];
! 414: jsMath.msieAbsoluteBug = 1;
! 415: }
! 416: jsMath.Macro('not','\\mathrel{\\rlap{\\kern3mu/}}');
! 417: }
! 418:
! 419: //
! 420: // Look for Netscape/Mozilla (any flavor)
! 421: //
! 422: if (this.hidden.ATTRIBUTE_NODE) {
! 423: jsMath.browser = 'Mozilla';
! 424: if (navigator.platform == 'MacPPC') {
! 425: this.UpdateTeXfonts({
! 426: cmr10: {'10': {c: 'Ω', tclass: 'normal'}},
! 427: cmmi10: {'10': {c: '<I>Ω</I>', tclass: 'normal'}},
! 428: cmsy10: {'10': {c: '⊗', tclass: 'normal'}},
! 429: cmex10: {'10': {c: '<SPAN STYLE="font-size: 67%">D</SPAN>'}},
! 430: cmti10: {'10': {c: '<I>Ω</I>', tclass: 'normal'}},
! 431: cmbx10: {'10': {c: '<B>Ω</B>', tclass: 'normal'}}
! 432: });
! 433: } else {
! 434: document.writeln('<SCRIPT SRC="'+this.root+'jsMath-mozilla.js"></SCRIPT>');
! 435: }
! 436: for (var i = 0; i < this.TeX.fam.length; i++) {
! 437: if (this.TeX.fam[i])
! 438: {this.styles['.'+this.TeX.fam[i]] += '; position: relative'}
! 439: }
! 440: this.allowAbsoluteDelim = 1;
! 441: this.separateSkips = 1;
! 442: jsMath.Macro('not','\\mathrel{\\rlap{\\kern3mu/}}');
! 443: }
! 444:
! 445: //
! 446: // Look for OmniWeb
! 447: //
! 448: if (navigator.accentColorName) {
! 449: jsMath.browser = 'OmniWeb';
! 450: this.allowAbsolute = 0;
! 451: }
! 452:
! 453: //
! 454: // Look for Opera
! 455: //
! 456: if (navigator.userAgent.search(" Opera ") >= 0) {
! 457: jsMath.browser = 'Opera';
! 458: this.isOpera = 1;
! 459: this.UpdateTeXfonts({
! 460: cmr10: {
! 461: '10': {c: 'Ω', tclass: 'normal'},
! 462: '20': {c: 'ˇ', tclass: 'normal'}
! 463: },
! 464: cmmi10: {
! 465: '10': {c: '<I>Ω</I>', tclass: 'normal'},
! 466: '20': {c: 'κ', tclass: 'normal'}
! 467: },
! 468: cmsy10: {
! 469: '10': {c: '⊗', tclass: 'normal'},
! 470: '20': {c: '≤', tclass: 'normal'}
! 471: },
! 472: cmex10: {
! 473: '10': {c: '<SPAN STYLE="font-size: 67%">D</SPAN>'},
! 474: '20': {c: '<SPAN STYLE="font-size: 82%">"</SPAN>'}
! 475: },
! 476: cmti10: {
! 477: '10': {c: '<I>Ω</I>', tclass: 'normal'},
! 478: '20': {c: '<I>ˇ</I>', tclass: 'normal'}
! 479: },
! 480: cmbx10: {
! 481: '10': {c: '<B>Ω</B>', tclass: 'normal'},
! 482: '20': {c: '<B>ˇ</B>', tclass: 'normal'}
! 483: }
! 484: });
! 485: this.allowAbsolute = 0;
! 486: jsMath.delay = 10;
! 487: }
! 488:
! 489: //
! 490: // Look for Safari
! 491: //
! 492: if (this.isSafari) {
! 493: jsMath.browser = 'Safari';
! 494: var version = navigator.userAgent.match("Safari/([0-9]+)")[1];
! 495: if (version < 125) {this.allowAbsolute = 0; this.oldSafari = 1}
! 496: for (var i = 0; i < this.TeX.fam.length; i++)
! 497: {if (this.TeX.fam[i] != '') {this.TeX[this.TeX.fam[i]].dh = .1}}
! 498: this.absoluteOffsetY = -.05;
! 499: this.TeX.axis_height += .05;
! 500: this.allowAbsoluteDelim = ! this.oldSafari;
! 501: }
! 502:
! 503: //
! 504: // Change some routines depending on the browser
! 505: //
! 506: if (this.allowAbsoluteDelim) {
! 507: jsMath.Box.DelimExtend = jsMath.Box.DelimExtendAbsolute;
! 508: jsMath.Box.Layout = jsMath.Box.LayoutAbsolute;
! 509: } else {
! 510: jsMath.Box.DelimExtend = jsMath.Box.DelimExtendRelative;
! 511: jsMath.Box.Layout = jsMath.Box.LayoutRelative;
! 512: }
! 513:
! 514: if (this.separateNegativeSkips) {
! 515: jsMath.HTML.Place = jsMath.HTML.PlaceSeparateNegative;
! 516: jsMath.Typeset.prototype.Place = jsMath.Typeset.prototype.PlaceSeparateNegative;
! 517: } else if (this.separateSkips) {
! 518: jsMath.HTML.Place = jsMath.HTML.PlaceSeparateSkips;
! 519: jsMath.Typeset.prototype.Place = jsMath.Typeset.prototype.PlaceSeparateSkips;
! 520: }
! 521:
! 522: if (this.noEmptySpans) {jsMath.HTML.Spacer = jsMath.HTML.SpacerImage}
! 523:
! 524: },
! 525:
! 526: /*
! 527: * Define some styles
! 528: */
! 529: WriteStyles: function (styles) {
! 530: document.writeln('<STYLE TYPE="text/css">');
! 531: for (var id in styles) {document.writeln(' '+id+' {'+styles[id]+'}')}
! 532: document.writeln('</STYLE>');
! 533: },
! 534:
! 535: /*
! 536: * Send the style definitions to the browser (these may be adjusted
! 537: * by the browser-specific code)
! 538: */
! 539: InitStyles: function () {this.WriteStyles(this.styles)},
! 540:
! 541: /*
! 542: * Update specific parameters for a limited number of font entries
! 543: */
! 544: UpdateTeXfonts: function (change) {
! 545: for (var font in change) {
! 546: for (var code in change[font]) {
! 547: for (var id in change[font][code]) {
! 548: this.TeX[font][code][id] = change[font][code][id];
! 549: }
! 550: }
! 551: }
! 552: },
! 553:
! 554: /*
! 555: * Update the character code for every character in a list
! 556: * of fonts
! 557: */
! 558: UpdateTeXfontCodes: function (change) {
! 559: for (var font in change) {
! 560: for (var i = 0; i < change[font].length; i++) {
! 561: this.TeX[font][i].c = change[font][i];
! 562: }
! 563: }
! 564: },
! 565:
! 566: /*
! 567: * Add a collection of styles to the style list
! 568: */
! 569: UpdateStyles: function (styles) {
! 570: for (var i in styles) {this.styles[i] = styles[i]}
! 571: },
! 572:
! 573: /*
! 574: * Manage JavaScript objects:
! 575: *
! 576: * Add: simply add items to an object
! 577: * Package: add items to an object prototype
! 578: */
! 579: Add: function (obj,def) {for (var id in def) {obj[id] = def[id]}},
! 580: Package: function (obj,def) {this.Add(obj.prototype,def)}
! 581:
! 582: }
! 583:
! 584:
! 585: /***************************************************************************/
! 586:
! 587: jsMath.Add(jsMath.TeX,{
! 588:
! 589: // The TeX math atom types (see Appendix G of the TeXbook)
! 590: atom: ['ord', 'op', 'bin', 'rel', 'open', 'close', 'punct', 'ord'],
! 591:
! 592: // The TeX font families
! 593: fam: ['cmr10','cmmi10','cmsy10','cmex10','cmti10','','cmbx10'],
! 594:
! 595: /*
! 596: * The following are the TeX font mappings and metrics. The metric
! 597: * information comes directly from the TeX .tfm files, and the
! 598: * character mappings are for the TrueType TeX fonts. Browser-specific
! 599: * adjustments are made to these tables in the InitBrowser() routine
! 600: */
! 601: cmr10: [
! 602: // 00 - 0F
! 603: {c: '¡', h: 0.683, w: 0.625},
! 604: {c: '¢', h: 0.683, w: 0.833},
! 605: {c: '£', h: 0.683, w: 0.778},
! 606: {c: '¤', h: 0.683, w: 0.694},
! 607: {c: '¥', h: 0.683, w: 0.667},
! 608: {c: '¦', h: 0.683, w: 0.75},
! 609: {c: '§', h: 0.683, w: 0.722},
! 610: {c: '¨', h: 0.683, w: 0.778},
! 611: {c: '©', h: 0.683, w: 0.722},
! 612: {c: 'ª', h: 0.683, w: 0.778},
! 613: {c: '­', h: 0.683, w: 0.722},
! 614: {c: '®', h: 0.694, w: 0.583, ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 14, '108': 15}},
! 615: {c: '¯', h: 0.694, w: 0.556},
! 616: {c: '°', h: 0.694, w: 0.556},
! 617: {c: '±', h: 0.694, w: 0.833},
! 618: {c: '²', h: 0.694, w: 0.833},
! 619: // 10 - 1F
! 620: {c: '³', h: 0.431, w: 0.278},
! 621: {c: '´', h: 0.431, d: 0.194, w: 0.306},
! 622: {c: 'µ', h: 0.694, w: 0.5},
! 623: {c: '¶', h: 0.694, w: 0.5},
! 624: {c: '∙', h: 0.628, w: 0.5},
! 625: {c: '¸', h: 0.694, w: 0.5},
! 626: {c: '¹', h: 0.568, w: 0.5},
! 627: {c: 'º', h: 0.694, w: 0.75},
! 628: {c: '»', d: 0.17, w: 0.444},
! 629: {c: '¼', h: 0.694, w: 0.5},
! 630: {c: '½', h: 0.431, w: 0.722},
! 631: {c: '¾', h: 0.431, w: 0.778},
! 632: {c: '¿', h: 0.528, d: 0.0972, w: 0.5},
! 633: {c: 'À', h: 0.683, w: 0.903},
! 634: {c: 'Á', h: 0.683, w: 1.01},
! 635: {c: 'Â', h: 0.732, d: 0.0486, w: 0.778},
! 636: // 20 - 2F
! 637: {c: 'Ã', h: 0.431, w: 0.278, krn: {'108': -0.278, '76': -0.319}},
! 638: {c: '!', h: 0.694, w: 0.278, lig: {'96': 60}},
! 639: {c: '"', h: 0.694, w: 0.5},
! 640: {c: '#', h: 0.694, d: 0.194, w: 0.833},
! 641: {c: '$', h: 0.75, d: 0.0556, w: 0.5},
! 642: {c: '%', h: 0.75, d: 0.0556, w: 0.833},
! 643: {c: '&', h: 0.694, w: 0.778},
! 644: {c: '\'', h: 0.694, w: 0.278, krn: {'63': 0.111, '33': 0.111}, lig: {'39': 34}},
! 645: {c: '(', h: 0.75, d: 0.25, w: 0.389},
! 646: {c: ')', h: 0.75, d: 0.25, w: 0.389},
! 647: {c: '*', h: 0.75, w: 0.5},
! 648: {c: '+', h: 0.583, d: 0.0833, w: 0.778},
! 649: {c: ',', h: 0.106, d: 0.194, w: 0.278},
! 650: {c: '-', h: 0.431, w: 0.333, lig: {'45': 123}},
! 651: {c: '.', h: 0.106, w: 0.278},
! 652: {c: '/', h: 0.75, d: 0.25, w: 0.5},
! 653: // 30 - 3F
! 654: {c: '0', h: 0.644, w: 0.5},
! 655: {c: '1', h: 0.644, w: 0.5},
! 656: {c: '2', h: 0.644, w: 0.5},
! 657: {c: '3', h: 0.644, w: 0.5},
! 658: {c: '4', h: 0.644, w: 0.5},
! 659: {c: '5', h: 0.644, w: 0.5},
! 660: {c: '6', h: 0.644, w: 0.5},
! 661: {c: '7', h: 0.644, w: 0.5},
! 662: {c: '8', h: 0.644, w: 0.5},
! 663: {c: '9', h: 0.644, w: 0.5},
! 664: {c: ':', h: 0.431, w: 0.278},
! 665: {c: ';', h: 0.431, d: 0.194, w: 0.278},
! 666: {c: '<', h: 0.5, d: 0.194, w: 0.278},
! 667: {c: '=', h: 0.367, d: -0.133, w: 0.778},
! 668: {c: '>', h: 0.5, d: 0.194, w: 0.472},
! 669: {c: '?', h: 0.694, w: 0.472, lig: {'96': 62}},
! 670: // 40 - 4F
! 671: {c: '@', h: 0.694, w: 0.778},
! 672: {c: 'A', h: 0.683, w: 0.75, 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}},
! 673: {c: 'B', h: 0.683, w: 0.708},
! 674: {c: 'C', h: 0.683, w: 0.722},
! 675: {c: 'D', h: 0.683, w: 0.764, krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}},
! 676: {c: 'E', h: 0.683, w: 0.681},
! 677: {c: 'F', h: 0.683, w: 0.653, 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}},
! 678: {c: 'G', h: 0.683, w: 0.785},
! 679: {c: 'H', h: 0.683, w: 0.75},
! 680: {c: 'I', h: 0.683, w: 0.361, krn: {'73': 0.0278}},
! 681: {c: 'J', h: 0.683, w: 0.514},
! 682: {c: 'K', h: 0.683, w: 0.778, krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
! 683: {c: 'L', h: 0.683, w: 0.625, krn: {'84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}},
! 684: {c: 'M', h: 0.683, w: 0.917},
! 685: {c: 'N', h: 0.683, w: 0.75},
! 686: {c: 'O', h: 0.683, w: 0.778, krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}},
! 687: // 50 - 5F
! 688: {c: 'P', h: 0.683, w: 0.681, krn: {'65': -0.0833, '111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}},
! 689: {c: 'Q', h: 0.683, d: 0.194, w: 0.778},
! 690: {c: 'R', h: 0.683, w: 0.736, 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}},
! 691: {c: 'S', h: 0.683, w: 0.556},
! 692: {c: 'T', h: 0.683, w: 0.722, krn: {'121': -0.0278, '101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}},
! 693: {c: 'U', h: 0.683, w: 0.75},
! 694: {c: 'V', h: 0.683, w: 0.75, 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}},
! 695: {c: 'W', h: 0.683, w: 1.03, 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}},
! 696: {c: 'X', h: 0.683, w: 0.75, krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
! 697: {c: 'Y', h: 0.683, w: 0.75, ic: 0.025, krn: {'101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}},
! 698: {c: 'Z', h: 0.683, w: 0.611},
! 699: {c: '[', h: 0.75, d: 0.25, w: 0.278},
! 700: {c: '\\', h: 0.694, w: 0.5},
! 701: {c: ']', h: 0.75, d: 0.25, w: 0.278},
! 702: {c: '^', h: 0.694, w: 0.5},
! 703: {c: '_', h: 0.668, w: 0.278},
! 704: // 60 - 6F
! 705: {c: '`', h: 0.694, w: 0.278, lig: {'96': 92}},
! 706: {c: 'a', h: 0.431, w: 0.5, krn: {'118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}},
! 707: {c: 'b', h: 0.694, w: 0.556, 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}},
! 708: {c: 'c', h: 0.431, w: 0.444, krn: {'104': -0.0278, '107': -0.0278}},
! 709: {c: 'd', h: 0.694, w: 0.556},
! 710: {c: 'e', h: 0.431, w: 0.444},
! 711: {c: 'f', h: 0.694, w: 0.306, 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}},
! 712: {c: 'g', h: 0.431, d: 0.194, w: 0.5, ic: 0.0139, krn: {'106': 0.0278}},
! 713: {c: 'h', h: 0.694, w: 0.556, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}},
! 714: {c: 'i', h: 0.668, w: 0.278},
! 715: {c: 'j', h: 0.668, d: 0.194, w: 0.306},
! 716: {c: 'k', h: 0.694, w: 0.528, krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}},
! 717: {c: 'l', h: 0.694, w: 0.278},
! 718: {c: 'm', h: 0.431, w: 0.833, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}},
! 719: {c: 'n', h: 0.431, w: 0.556, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}},
! 720: {c: 'o', h: 0.431, w: 0.5, 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}},
! 721: // 70 - 7F
! 722: {c: 'p', h: 0.431, d: 0.194, w: 0.556, 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}},
! 723: {c: 'q', h: 0.431, d: 0.194, w: 0.528},
! 724: {c: 'r', h: 0.431, w: 0.392},
! 725: {c: 's', h: 0.431, w: 0.394},
! 726: {c: 't', h: 0.615, w: 0.389, krn: {'121': -0.0278, '119': -0.0278}},
! 727: {c: 'u', h: 0.431, w: 0.556, krn: {'119': -0.0278}},
! 728: {c: 'v', h: 0.431, w: 0.528, ic: 0.0139, krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}},
! 729: {c: 'w', h: 0.431, w: 0.722, ic: 0.0139, krn: {'101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}},
! 730: {c: 'x', h: 0.431, w: 0.528},
! 731: {c: 'y', h: 0.431, d: 0.194, w: 0.528, ic: 0.0139, krn: {'111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}},
! 732: {c: 'z', h: 0.431, w: 0.444},
! 733: {c: '{', h: 0.431, w: 0.5, ic: 0.0278, lig: {'45': 124}},
! 734: {c: '|', h: 0.431, w: 1, ic: 0.0278},
! 735: {c: '}', h: 0.694, w: 0.5},
! 736: {c: '~', h: 0.668, w: 0.5},
! 737: {c: 'Ä', h: 0.668, w: 0.5}
! 738: ],
! 739:
! 740: cmmi10: [
! 741: // 00 - 0F
! 742: {c: '¡', h: 0.683, w: 0.615, ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}},
! 743: {c: '¢', h: 0.683, w: 0.833, krn: {'127': 0.167}},
! 744: {c: '£', h: 0.683, w: 0.763, ic: 0.0278, krn: {'127': 0.0833}},
! 745: {c: '¤', h: 0.683, w: 0.694, krn: {'127': 0.167}},
! 746: {c: '¥', h: 0.683, w: 0.742, ic: 0.0757, krn: {'127': 0.0833}},
! 747: {c: '¦', h: 0.683, w: 0.831, ic: 0.0812, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}},
! 748: {c: '§', h: 0.683, w: 0.78, ic: 0.0576, krn: {'127': 0.0833}},
! 749: {c: '¨', h: 0.683, w: 0.583, ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0556}},
! 750: {c: '©', h: 0.683, w: 0.667, krn: {'127': 0.0833}},
! 751: {c: 'ª', h: 0.683, w: 0.612, ic: 0.11, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}},
! 752: {c: '­', h: 0.683, w: 0.772, ic: 0.0502, krn: {'127': 0.0833}},
! 753: {c: '®', h: 0.431, w: 0.64, ic: 0.0037, krn: {'127': 0.0278}},
! 754: {c: '¯', h: 0.694, d: 0.194, w: 0.566, ic: 0.0528, krn: {'127': 0.0833}},
! 755: {c: '°', h: 0.431, d: 0.194, w: 0.518, ic: 0.0556},
! 756: {c: '±', h: 0.694, w: 0.444, ic: 0.0378, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0556}},
! 757: {c: '²', h: 0.431, w: 0.406, krn: {'127': 0.0556}},
! 758: // 10 - 1F
! 759: {c: '³', h: 0.694, d: 0.194, w: 0.438, ic: 0.0738, krn: {'127': 0.0833}},
! 760: {c: '´', h: 0.431, d: 0.194, w: 0.497, ic: 0.0359, krn: {'127': 0.0556}},
! 761: {c: 'µ', h: 0.694, w: 0.469, ic: 0.0278, krn: {'127': 0.0833}},
! 762: {c: '¶', h: 0.431, w: 0.354, krn: {'127': 0.0556}},
! 763: {c: '∙', h: 0.431, w: 0.576},
! 764: {c: '¸', h: 0.694, w: 0.583},
! 765: {c: '¹', h: 0.431, d: 0.194, w: 0.603, krn: {'127': 0.0278}},
! 766: {c: 'º', h: 0.431, w: 0.494, ic: 0.0637, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0278}},
! 767: {c: '»', h: 0.694, d: 0.194, w: 0.438, ic: 0.046, krn: {'127': 0.111}},
! 768: {c: '¼', h: 0.431, w: 0.57, ic: 0.0359},
! 769: {c: '½', h: 0.431, d: 0.194, w: 0.517, krn: {'127': 0.0833}},
! 770: {c: '¾', h: 0.431, w: 0.571, ic: 0.0359, krn: {'59': -0.0556, '58': -0.0556}},
! 771: {c: '¿', h: 0.431, w: 0.437, ic: 0.113, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0278}},
! 772: {c: 'À', h: 0.431, w: 0.54, ic: 0.0359, krn: {'127': 0.0278}},
! 773: {c: 'Á', h: 0.694, d: 0.194, w: 0.596, krn: {'127': 0.0833}},
! 774: {c: 'Â', h: 0.431, d: 0.194, w: 0.626, krn: {'127': 0.0556}},
! 775: // 20 - 2F
! 776: {c: 'Ã', h: 0.694, d: 0.194, w: 0.651, ic: 0.0359, krn: {'127': 0.111}},
! 777: {c: '!', h: 0.431, w: 0.622, ic: 0.0359},
! 778: {c: '"', h: 0.431, w: 0.466, krn: {'127': 0.0833}},
! 779: {c: '#', h: 0.694, w: 0.591, krn: {'127': 0.0833}},
! 780: {c: '$', h: 0.431, w: 0.828, ic: 0.0278},
! 781: {c: '%', h: 0.431, d: 0.194, w: 0.517, krn: {'127': 0.0833}},
! 782: {c: '&', h: 0.431, d: 0.0972, w: 0.363, ic: 0.0799, krn: {'127': 0.0833}},
! 783: {c: '\'', h: 0.431, d: 0.194, w: 0.654, krn: {'127': 0.0833}},
! 784: {c: '(', h: 0.367, d: -0.133, w: 1},
! 785: {c: ')', h: 0.367, d: -0.133, w: 1},
! 786: {c: '*', h: 0.367, d: -0.133, w: 1},
! 787: {c: '+', h: 0.367, d: -0.133, w: 1},
! 788: {c: ',', h: 0.464, d: -0.0363, w: 0.278},
! 789: {c: '-', h: 0.464, d: -0.0363, w: 0.278},
! 790: {c: '.', h: 0.465, d: -0.0347, w: 0.5},
! 791: {c: '/', h: 0.465, d: -0.0347, w: 0.5},
! 792: // 30 - 3F
! 793: {c: '0', h: 0.431, w: 0.5},
! 794: {c: '1', h: 0.431, w: 0.5},
! 795: {c: '2', h: 0.431, w: 0.5},
! 796: {c: '3', h: 0.431, d: 0.194, w: 0.5},
! 797: {c: '4', h: 0.431, d: 0.194, w: 0.5},
! 798: {c: '5', h: 0.431, d: 0.194, w: 0.5},
! 799: {c: '6', h: 0.644, w: 0.5},
! 800: {c: '7', h: 0.431, d: 0.194, w: 0.5},
! 801: {c: '8', h: 0.644, w: 0.5},
! 802: {c: '9', h: 0.431, d: 0.194, w: 0.5},
! 803: {c: ':', h: 0.106, w: 0.278},
! 804: {c: ';', h: 0.106, d: 0.194, w: 0.278},
! 805: {c: '<', h: 0.539, d: 0.0391, w: 0.778},
! 806: {c: '=', h: 0.75, d: 0.25, w: 0.5, krn: {'1': -0.0556, '65': -0.0556, '77': -0.0556, '78': -0.0556, '89': 0.0556, '90': -0.0556}},
! 807: {c: '>', h: 0.539, d: 0.0391, w: 0.778},
! 808: {c: '?', h: 0.465, d: -0.0347, w: 0.5},
! 809: // 40 - 4F
! 810: {c: '@', h: 0.694, w: 0.531, ic: 0.0556, krn: {'127': 0.0833}},
! 811: {c: 'A', h: 0.683, w: 0.75, krn: {'127': 0.139}},
! 812: {c: 'B', h: 0.683, w: 0.759, ic: 0.0502, krn: {'127': 0.0833}},
! 813: {c: 'C', h: 0.683, w: 0.715, ic: 0.0715, krn: {'61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
! 814: {c: 'D', h: 0.683, w: 0.828, ic: 0.0278, krn: {'127': 0.0556}},
! 815: {c: 'E', h: 0.683, w: 0.738, ic: 0.0576, krn: {'127': 0.0833}},
! 816: {c: 'F', h: 0.683, w: 0.643, ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}},
! 817: {c: 'G', h: 0.683, w: 0.786, krn: {'127': 0.0833}},
! 818: {c: 'H', h: 0.683, w: 0.831, ic: 0.0812, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}},
! 819: {c: 'I', h: 0.683, w: 0.44, ic: 0.0785, krn: {'127': 0.111}},
! 820: {c: 'J', h: 0.683, w: 0.555, ic: 0.0962, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.167}},
! 821: {c: 'K', h: 0.683, w: 0.849, ic: 0.0715, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}},
! 822: {c: 'L', h: 0.683, w: 0.681, krn: {'127': 0.0278}},
! 823: {c: 'M', h: 0.683, w: 0.97, ic: 0.109, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
! 824: {c: 'N', h: 0.683, w: 0.803, ic: 0.109, krn: {'61': -0.0833, '61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
! 825: {c: 'O', h: 0.683, w: 0.763, ic: 0.0278, krn: {'127': 0.0833}},
! 826: // 50 - 5F
! 827: {c: 'P', h: 0.683, w: 0.642, ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}},
! 828: {c: 'Q', h: 0.683, d: 0.194, w: 0.791, krn: {'127': 0.0833}},
! 829: {c: 'R', h: 0.683, w: 0.759, ic: 0.00773, krn: {'127': 0.0833}},
! 830: {c: 'S', h: 0.683, w: 0.613, ic: 0.0576, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
! 831: {c: 'T', h: 0.683, w: 0.584, ic: 0.139, krn: {'61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
! 832: {c: 'U', h: 0.683, w: 0.683, ic: 0.109, krn: {'59': -0.111, '58': -0.111, '61': -0.0556, '127': 0.0278}},
! 833: {c: 'V', h: 0.683, w: 0.583, ic: 0.222, krn: {'59': -0.167, '58': -0.167, '61': -0.111}},
! 834: {c: 'W', h: 0.683, w: 0.944, ic: 0.139, krn: {'59': -0.167, '58': -0.167, '61': -0.111}},
! 835: {c: 'X', h: 0.683, w: 0.828, ic: 0.0785, krn: {'61': -0.0833, '61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
! 836: {c: 'Y', h: 0.683, w: 0.581, ic: 0.222, krn: {'59': -0.167, '58': -0.167, '61': -0.111}},
! 837: {c: 'Z', h: 0.683, w: 0.683, ic: 0.0715, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
! 838: {c: '[', h: 0.75, w: 0.389},
! 839: {c: '\\', h: 0.694, d: 0.194, w: 0.389},
! 840: {c: ']', h: 0.694, d: 0.194, w: 0.389},
! 841: {c: '^', h: 0.358, d: -0.142, w: 1},
! 842: {c: '_', h: 0.358, d: -0.142, w: 1},
! 843: // 60 - 6F
! 844: {c: '`', h: 0.694, w: 0.417, krn: {'127': 0.111}},
! 845: {c: 'a', h: 0.431, w: 0.529},
! 846: {c: 'b', h: 0.694, w: 0.429},
! 847: {c: 'c', h: 0.431, w: 0.433, krn: {'127': 0.0556}},
! 848: {c: 'd', h: 0.694, w: 0.52, krn: {'89': 0.0556, '90': -0.0556, '106': -0.111, '102': -0.167, '127': 0.167}},
! 849: {c: 'e', h: 0.431, w: 0.466, krn: {'127': 0.0556}},
! 850: {c: 'f', h: 0.694, d: 0.194, w: 0.49, ic: 0.108, krn: {'59': -0.0556, '58': -0.0556, '127': 0.167}},
! 851: {c: 'g', h: 0.431, d: 0.194, w: 0.477, ic: 0.0359, krn: {'127': 0.0278}},
! 852: {c: 'h', h: 0.694, w: 0.576, krn: {'127': -0.0278}},
! 853: {c: 'i', h: 0.66, w: 0.345},
! 854: {c: 'j', h: 0.66, d: 0.194, w: 0.412, ic: 0.0572, krn: {'59': -0.0556, '58': -0.0556}},
! 855: {c: 'k', h: 0.694, w: 0.521, ic: 0.0315},
! 856: {c: 'l', h: 0.694, w: 0.298, ic: 0.0197, krn: {'127': 0.0833}},
! 857: {c: 'm', h: 0.431, w: 0.878},
! 858: {c: 'n', h: 0.431, w: 0.6},
! 859: {c: 'o', h: 0.431, w: 0.485, krn: {'127': 0.0556}},
! 860: // 70 - 7F
! 861: {c: 'p', h: 0.431, d: 0.194, w: 0.503, krn: {'127': 0.0833}},
! 862: {c: 'q', h: 0.431, d: 0.194, w: 0.446, ic: 0.0359, krn: {'127': 0.0833}},
! 863: {c: 'r', h: 0.431, w: 0.451, ic: 0.0278, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0556}},
! 864: {c: 's', h: 0.431, w: 0.469, krn: {'127': 0.0556}},
! 865: {c: 't', h: 0.615, w: 0.361, krn: {'127': 0.0833}},
! 866: {c: 'u', h: 0.431, w: 0.572, krn: {'127': 0.0278}},
! 867: {c: 'v', h: 0.431, w: 0.485, ic: 0.0359, krn: {'127': 0.0278}},
! 868: {c: 'w', h: 0.431, w: 0.716, ic: 0.0269, krn: {'127': 0.0833}},
! 869: {c: 'x', h: 0.431, w: 0.572, krn: {'127': 0.0278}},
! 870: {c: 'y', h: 0.431, d: 0.194, w: 0.49, ic: 0.0359, krn: {'127': 0.0556}},
! 871: {c: 'z', h: 0.431, w: 0.465, ic: 0.044, krn: {'127': 0.0556}},
! 872: {c: '{', h: 0.431, w: 0.322, krn: {'127': 0.0278}},
! 873: {c: '|', h: 0.431, d: 0.194, w: 0.384, krn: {'127': 0.0833}},
! 874: {c: '}', h: 0.431, d: 0.194, w: 0.636, krn: {'127': 0.111}},
! 875: {c: '~', h: 0.714, w: 0.5, ic: 0.154},
! 876: {c: 'Ä', h: 0.694, w: 0.278, ic: 0.399}
! 877: ],
! 878:
! 879: cmsy10: [
! 880: // 00 - 0F
! 881: {c: '¡', h: 0.583, d: 0.0833, w: 0.778},
! 882: {c: '¢', h: 0.444, d: -0.0556, w: 0.278},
! 883: {c: '£', h: 0.583, d: 0.0833, w: 0.778},
! 884: {c: '¤', h: 0.465, d: -0.0347, w: 0.5},
! 885: {c: '¥', h: 0.583, d: 0.0833, w: 0.778},
! 886: {c: '¦', h: 0.444, d: -0.0556, w: 0.5},
! 887: {c: '§', h: 0.583, d: 0.0833, w: 0.778},
! 888: {c: '¨', h: 0.583, d: 0.0833, w: 0.778},
! 889: {c: '©', h: 0.583, d: 0.0833, w: 0.778},
! 890: {c: 'ª', h: 0.583, d: 0.0833, w: 0.778},
! 891: {c: '­', h: 0.583, d: 0.0833, w: 0.778},
! 892: {c: '®', h: 0.583, d: 0.0833, w: 0.778},
! 893: {c: '¯', h: 0.583, d: 0.0833, w: 0.778},
! 894: {c: '°', h: 0.694, d: 0.194, w: 1},
! 895: {c: '±', h: 0.444, d: -0.0556, w: 0.5},
! 896: {c: '²', h: 0.444, d: -0.0556, w: 0.5},
! 897: // 10 - 1F
! 898: {c: '³', h: 0.464, d: -0.0363, w: 0.778},
! 899: {c: '´', h: 0.464, d: -0.0363, w: 0.778},
! 900: {c: 'µ', h: 0.636, d: 0.136, w: 0.778},
! 901: {c: '¶', h: 0.636, d: 0.136, w: 0.778},
! 902: {c: '∙', h: 0.636, d: 0.136, w: 0.778},
! 903: {c: '¸', h: 0.636, d: 0.136, w: 0.778},
! 904: {c: '¹', h: 0.636, d: 0.136, w: 0.778},
! 905: {c: 'º', h: 0.636, d: 0.136, w: 0.778},
! 906: {c: '»', h: 0.367, d: -0.133, w: 0.778},
! 907: {c: '¼', h: 0.483, d: -0.0169, w: 0.778},
! 908: {c: '½', h: 0.539, d: 0.0391, w: 0.778},
! 909: {c: '¾', h: 0.539, d: 0.0391, w: 0.778},
! 910: {c: '¿', h: 0.539, d: 0.0391, w: 1},
! 911: {c: 'À', h: 0.539, d: 0.0391, w: 1},
! 912: {c: 'Á', h: 0.539, d: 0.0391, w: 0.778},
! 913: {c: 'Â', h: 0.539, d: 0.0391, w: 0.778},
! 914: // 20 - 2F
! 915: {c: 'Ã', h: 0.367, d: -0.133, w: 1},
! 916: {c: '!', h: 0.367, d: -0.133, w: 1},
! 917: {c: '"', h: 0.694, d: 0.194, w: 0.5},
! 918: {c: '#', h: 0.694, d: 0.194, w: 0.5},
! 919: {c: '$', h: 0.367, d: -0.133, w: 1},
! 920: {c: '%', h: 0.694, d: 0.194, w: 1},
! 921: {c: '&', h: 0.694, d: 0.194, w: 1},
! 922: {c: '\'', h: 0.464, d: -0.0363, w: 0.778},
! 923: {c: '(', h: 0.367, d: -0.133, w: 1},
! 924: {c: ')', h: 0.367, d: -0.133, w: 1},
! 925: {c: '*', h: 0.694, d: 0.194, w: 0.611},
! 926: {c: '+', h: 0.694, d: 0.194, w: 0.611},
! 927: {c: ',', h: 0.367, d: -0.133, w: 1},
! 928: {c: '-', h: 0.694, d: 0.194, w: 1},
! 929: {c: '.', h: 0.694, d: 0.194, w: 1},
! 930: {c: '/', h: 0.431, w: 0.778},
! 931: // 30 - 3F
! 932: {c: '0', h: 0.556, w: 0.275},
! 933: {c: '1', h: 0.431, w: 1},
! 934: {c: '2', h: 0.539, d: 0.0391, w: 0.667},
! 935: {c: '3', h: 0.539, d: 0.0391, w: 0.667},
! 936: {c: '4', h: 0.694, d: 0.194, w: 0.889},
! 937: {c: '5', h: 0.694, d: 0.194, w: 0.889},
! 938: {c: '6', h: 0.694, d: 0.194, w: 0},
! 939: {c: '7', h: 0.367, d: -0.133, w: 0},
! 940: {c: '8', h: 0.694, w: 0.556},
! 941: {c: '9', h: 0.694, w: 0.556},
! 942: {c: ':', h: 0.431, w: 0.667},
! 943: {c: ';', h: 0.75, d: 0.0556, w: 0.5},
! 944: {c: '<', h: 0.694, w: 0.722},
! 945: {c: '=', h: 0.694, w: 0.722},
! 946: {c: '>', h: 0.694, w: 0.778},
! 947: {c: '?', h: 0.694, w: 0.778},
! 948: // 40 - 4F
! 949: {c: '@', h: 0.694, w: 0.611},
! 950: {c: 'A', h: 0.683, w: 0.798, krn: {'48': 0.194}},
! 951: {c: 'B', h: 0.683, w: 0.657, ic: 0.0304, krn: {'48': 0.139}},
! 952: {c: 'C', h: 0.683, w: 0.527, ic: 0.0583, krn: {'48': 0.139}},
! 953: {c: 'D', h: 0.683, w: 0.771, ic: 0.0278, krn: {'48': 0.0833}},
! 954: {c: 'E', h: 0.683, w: 0.528, ic: 0.0894, krn: {'48': 0.111}},
! 955: {c: 'F', h: 0.683, w: 0.719, ic: 0.0993, krn: {'48': 0.111}},
! 956: {c: 'G', h: 0.683, d: 0.0972, w: 0.595, ic: 0.0593, krn: {'48': 0.111}},
! 957: {c: 'H', h: 0.683, w: 0.845, ic: 0.00965, krn: {'48': 0.111}},
! 958: {c: 'I', h: 0.683, w: 0.545, ic: 0.0738, krn: {'48': 0.0278}},
! 959: {c: 'J', h: 0.683, d: 0.0972, w: 0.678, ic: 0.185, krn: {'48': 0.167}},
! 960: {c: 'K', h: 0.683, w: 0.762, ic: 0.0144, krn: {'48': 0.0556}},
! 961: {c: 'L', h: 0.683, w: 0.69, krn: {'48': 0.139}},
! 962: {c: 'M', h: 0.683, w: 1.2, krn: {'48': 0.139}},
! 963: {c: 'N', h: 0.683, w: 0.82, ic: 0.147, krn: {'48': 0.0833}},
! 964: {c: 'O', h: 0.683, w: 0.796, ic: 0.0278, krn: {'48': 0.111}},
! 965: // 50 - 5F
! 966: {c: 'P', h: 0.683, w: 0.696, ic: 0.0822, krn: {'48': 0.0833}},
! 967: {c: 'Q', h: 0.683, d: 0.0972, w: 0.817, krn: {'48': 0.111}},
! 968: {c: 'R', h: 0.683, w: 0.848, krn: {'48': 0.0833}},
! 969: {c: 'S', h: 0.683, w: 0.606, ic: 0.075, krn: {'48': 0.139}},
! 970: {c: 'T', h: 0.683, w: 0.545, ic: 0.254, krn: {'48': 0.0278}},
! 971: {c: 'U', h: 0.683, w: 0.626, ic: 0.0993, krn: {'48': 0.0833}},
! 972: {c: 'V', h: 0.683, w: 0.613, ic: 0.0822, krn: {'48': 0.0278}},
! 973: {c: 'W', h: 0.683, w: 0.988, ic: 0.0822, krn: {'48': 0.0833}},
! 974: {c: 'X', h: 0.683, w: 0.713, ic: 0.146, krn: {'48': 0.139}},
! 975: {c: 'Y', h: 0.683, d: 0.0972, w: 0.668, ic: 0.0822, krn: {'48': 0.0833}},
! 976: {c: 'Z', h: 0.683, w: 0.725, ic: 0.0794, krn: {'48': 0.139}},
! 977: {c: '[', h: 0.556, w: 0.667},
! 978: {c: '\\', h: 0.556, w: 0.667},
! 979: {c: ']', h: 0.556, w: 0.667},
! 980: {c: '^', h: 0.556, w: 0.667},
! 981: {c: '_', h: 0.556, w: 0.667},
! 982: // 60 - 6F
! 983: {c: '`', h: 0.694, w: 0.611},
! 984: {c: 'a', h: 0.694, w: 0.611},
! 985: {c: 'b', h: 0.75, d: 0.25, w: 0.444},
! 986: {c: 'c', h: 0.75, d: 0.25, w: 0.444},
! 987: {c: 'd', h: 0.75, d: 0.25, w: 0.444},
! 988: {c: 'e', h: 0.75, d: 0.25, w: 0.444},
! 989: {c: 'f', h: 0.75, d: 0.25, w: 0.5},
! 990: {c: 'g', h: 0.75, d: 0.25, w: 0.5},
! 991: {c: 'h', h: 0.75, d: 0.25, w: 0.389},
! 992: {c: 'i', h: 0.75, d: 0.25, w: 0.389},
! 993: {c: 'j', h: 0.75, d: 0.25, w: 0.278},
! 994: {c: 'k', h: 0.75, d: 0.25, w: 0.5},
! 995: {c: 'l', h: 0.75, d: 0.25, w: 0.5},
! 996: {c: 'm', h: 0.75, d: 0.25, w: 0.611},
! 997: {c: 'n', h: 0.75, d: 0.25, w: 0.5},
! 998: {c: 'o', h: 0.694, d: 0.194, w: 0.278},
! 999: // 70 - 7F
! 1000: {c: 'p', h: 0.04, d: 0.96, w: 0.833},
! 1001: {c: 'q', h: 0.683, w: 0.75},
! 1002: {c: 'r', h: 0.683, w: 0.833},
! 1003: {c: 's', h: 0.694, d: 0.194, w: 0.417, ic: 0.111},
! 1004: {c: 't', h: 0.556, w: 0.667},
! 1005: {c: 'u', h: 0.556, w: 0.667},
! 1006: {c: 'v', h: 0.636, d: 0.136, w: 0.778},
! 1007: {c: 'w', h: 0.636, d: 0.136, w: 0.778},
! 1008: {c: 'x', h: 0.694, d: 0.194, w: 0.444},
! 1009: {c: 'y', h: 0.694, d: 0.194, w: 0.444},
! 1010: {c: 'z', h: 0.694, d: 0.194, w: 0.444},
! 1011: {c: '{', h: 0.694, d: 0.194, w: 0.611},
! 1012: {c: '|', h: 0.694, d: 0.13, w: 0.778},
! 1013: {c: '}', h: 0.694, d: 0.13, w: 0.778},
! 1014: {c: '~', h: 0.694, d: 0.13, w: 0.778},
! 1015: {c: 'Ä', h: 0.694, d: 0.13, w: 0.778}
! 1016: ],
! 1017:
! 1018: cmex10: [
! 1019: // 00 - 0F
! 1020: {c: '¡', h: 0.04, d: 1.16, w: 0.458, n: 16},
! 1021: {c: '¢', h: 0.04, d: 1.16, w: 0.458, n: 17},
! 1022: {c: '£', h: 0.04, d: 1.16, w: 0.417, n: 104},
! 1023: {c: '¤', h: 0.04, d: 1.16, w: 0.417, n: 105},
! 1024: {c: '¥', h: 0.04, d: 1.16, w: 0.472, n: 106},
! 1025: {c: '¦', h: 0.04, d: 1.16, w: 0.472, n: 107},
! 1026: {c: '§', h: 0.04, d: 1.16, w: 0.472, n: 108},
! 1027: {c: '¨', h: 0.04, d: 1.16, w: 0.472, n: 109},
! 1028: {c: '©', h: 0.04, d: 1.16, w: 0.583, n: 110},
! 1029: {c: 'ª', h: 0.04, d: 1.16, w: 0.583, n: 111},
! 1030: {c: '­', h: 0.04, d: 1.16, w: 0.472, n: 68},
! 1031: {c: '®', h: 0.04, d: 1.16, w: 0.472, n: 69},
! 1032: {c: '¯', d: 0.6, w: 0.333, delim: {rep: 12}},
! 1033: {c: '°', d: 0.6, w: 0.556, delim: {rep: 13}},
! 1034: {c: '±', h: 0.04, d: 1.16, w: 0.578, n: 46},
! 1035: {c: '²', h: 0.04, d: 1.16, w: 0.578, n: 47},
! 1036: // 10 - 1F
! 1037: {c: '³', h: 0.04, d: 1.76, w: 0.597, n: 18},
! 1038: {c: '´', h: 0.04, d: 1.76, w: 0.597, n: 19},
! 1039: {c: 'µ', h: 0.04, d: 2.36, w: 0.736, n: 32},
! 1040: {c: '¶', h: 0.04, d: 2.36, w: 0.736, n: 33},
! 1041: {c: '∙', h: 0.04, d: 2.36, w: 0.528, n: 34},
! 1042: {c: '¸', h: 0.04, d: 2.36, w: 0.528, n: 35},
! 1043: {c: '¹', h: 0.04, d: 2.36, w: 0.583, n: 36},
! 1044: {c: 'º', h: 0.04, d: 2.36, w: 0.583, n: 37},
! 1045: {c: '»', h: 0.04, d: 2.36, w: 0.583, n: 38},
! 1046: {c: '¼', h: 0.04, d: 2.36, w: 0.583, n: 39},
! 1047: {c: '½', h: 0.04, d: 2.36, w: 0.75, n: 40},
! 1048: {c: '¾', h: 0.04, d: 2.36, w: 0.75, n: 41},
! 1049: {c: '¿', h: 0.04, d: 2.36, w: 0.75, n: 42},
! 1050: {c: 'À', h: 0.04, d: 2.36, w: 0.75, n: 43},
! 1051: {c: 'Á', h: 0.04, d: 2.36, w: 1.04, n: 44},
! 1052: {c: 'Â', h: 0.04, d: 2.36, w: 1.04, n: 45},
! 1053: // 20 - 2F
! 1054: {c: 'Ã', h: 0.04, d: 2.96, w: 0.792, n: 48},
! 1055: {c: '!', h: 0.04, d: 2.96, w: 0.792, n: 49},
! 1056: {c: '"', h: 0.04, d: 2.96, w: 0.583, n: 50},
! 1057: {c: '#', h: 0.04, d: 2.96, w: 0.583, n: 51},
! 1058: {c: '$', h: 0.04, d: 2.96, w: 0.639, n: 52},
! 1059: {c: '%', h: 0.04, d: 2.96, w: 0.639, n: 53},
! 1060: {c: '&', h: 0.04, d: 2.96, w: 0.639, n: 54},
! 1061: {c: '\'', h: 0.04, d: 2.96, w: 0.639, n: 55},
! 1062: {c: '(', h: 0.04, d: 2.96, w: 0.806, n: 56},
! 1063: {c: ')', h: 0.04, d: 2.96, w: 0.806, n: 57},
! 1064: {c: '*', h: 0.04, d: 2.96, w: 0.806},
! 1065: {c: '+', h: 0.04, d: 2.96, w: 0.806},
! 1066: {c: ',', h: 0.04, d: 2.96, w: 1.28},
! 1067: {c: '-', h: 0.04, d: 2.96, w: 1.28},
! 1068: {c: '.', h: 0.04, d: 1.76, w: 0.811, n: 30},
! 1069: {c: '/', h: 0.04, d: 1.76, w: 0.811, n: 31},
! 1070: // 30 - 3F
! 1071: {c: '0', h: 0.04, d: 1.76, w: 0.875, delim: {top: 48, bot: 64, rep: 66}},
! 1072: {c: '1', h: 0.04, d: 1.76, w: 0.875, delim: {top: 49, bot: 65, rep: 67}},
! 1073: {c: '2', h: 0.04, d: 1.76, w: 0.667, delim: {top: 50, bot: 52, rep: 54}},
! 1074: {c: '3', h: 0.04, d: 1.76, w: 0.667, delim: {top: 51, bot: 53, rep: 55}},
! 1075: {c: '4', h: 0.04, d: 1.76, w: 0.667, delim: {bot: 52, rep: 54}},
! 1076: {c: '5', h: 0.04, d: 1.76, w: 0.667, delim: {bot: 53, rep: 55}},
! 1077: {c: '6', d: 0.6, w: 0.667, delim: {top: 50, rep: 54}},
! 1078: {c: '7', d: 0.6, w: 0.667, delim: {top: 51, rep: 55}},
! 1079: {c: '8', d: 0.9, w: 0.889, delim: {top: 56, mid: 60, bot: 58, rep: 62}},
! 1080: {c: '9', d: 0.9, w: 0.889, delim: {top: 57, mid: 61, bot: 59, rep: 62}},
! 1081: {c: ':', d: 0.9, w: 0.889, delim: {top: 56, bot: 58, rep: 62}},
! 1082: {c: ';', d: 0.9, w: 0.889, delim: {top: 57, bot: 59, rep: 62}},
! 1083: {c: '<', d: 1.8, w: 0.889, delim: {rep: 63}},
! 1084: {c: '=', d: 1.8, w: 0.889, delim: {rep: 119}},
! 1085: {c: '>', d: 0.3, w: 0.889, delim: {rep: 62}},
! 1086: {c: '?', d: 0.6, w: 0.667, delim: {top: 120, bot: 121, rep: 63}},
! 1087: // 40 - 4F
! 1088: {c: '@', h: 0.04, d: 1.76, w: 0.875, delim: {top: 56, bot: 59, rep: 62}},
! 1089: {c: 'A', h: 0.04, d: 1.76, w: 0.875, delim: {top: 57, bot: 58, rep: 62}},
! 1090: {c: 'B', d: 0.6, w: 0.875, delim: {rep: 66}},
! 1091: {c: 'C', d: 0.6, w: 0.875, delim: {rep: 67}},
! 1092: {c: 'D', h: 0.04, d: 1.76, w: 0.611, n: 28},
! 1093: {c: 'E', h: 0.04, d: 1.76, w: 0.611, n: 29},
! 1094: {c: 'F', d: 1, w: 0.833, n: 71},
! 1095: {c: 'G', h: 0.1, d: 1.5, w: 1.11},
! 1096: {c: 'H', d: 1.11, w: 0.472, ic: 0.194, n: 73},
! 1097: {c: 'I', d: 2.22, w: 0.556, ic: 0.444},
! 1098: {c: 'J', d: 1, w: 1.11, n: 75},
! 1099: {c: 'K', h: 0.1, d: 1.5, w: 1.51},
! 1100: {c: 'L', d: 1, w: 1.11, n: 77},
! 1101: {c: 'M', h: 0.1, d: 1.5, w: 1.51},
! 1102: {c: 'N', d: 1, w: 1.11, n: 79},
! 1103: {c: 'O', h: 0.1, d: 1.5, w: 1.51},
! 1104: // 50 - 5F
! 1105: {c: 'P', d: 1, w: 1.06, n: 88},
! 1106: {c: 'Q', d: 1, w: 0.944, n: 89},
! 1107: {c: 'R', d: 1.11, w: 0.472, ic: 0.194, n: 90},
! 1108: {c: 'S', d: 1, w: 0.833, n: 91},
! 1109: {c: 'T', d: 1, w: 0.833, n: 92},
! 1110: {c: 'U', d: 1, w: 0.833, n: 93},
! 1111: {c: 'V', d: 1, w: 0.833, n: 94},
! 1112: {c: 'W', d: 1, w: 0.833, n: 95},
! 1113: {c: 'X', h: 0.1, d: 1.5, w: 1.44},
! 1114: {c: 'Y', h: 0.1, d: 1.5, w: 1.28},
! 1115: {c: 'Z', d: 2.22, w: 0.556, ic: 0.444},
! 1116: {c: '[', h: 0.1, d: 1.5, w: 1.11},
! 1117: {c: '\\', h: 0.1, d: 1.5, w: 1.11},
! 1118: {c: ']', h: 0.1, d: 1.5, w: 1.11},
! 1119: {c: '^', h: 0.1, d: 1.5, w: 1.11},
! 1120: {c: '_', h: 0.1, d: 1.5, w: 1.11},
! 1121: // 60 - 6F
! 1122: {c: '`', d: 1, w: 0.944, n: 97},
! 1123: {c: 'a', h: 0.1, d: 1.5, w: 1.28},
! 1124: {c: 'b', h: 0.722, w: 0.556, n: 99},
! 1125: {c: 'c', h: 0.75, w: 1, n: 100},
! 1126: {c: 'd', h: 0.75, w: 1.44},
! 1127: {c: 'e', h: 0.722, w: 0.556, n: 102},
! 1128: {c: 'f', h: 0.75, w: 1, n: 103},
! 1129: {c: 'g', h: 0.75, w: 1.44},
! 1130: {c: 'h', h: 0.04, d: 1.76, w: 0.472, n: 20},
! 1131: {c: 'i', h: 0.04, d: 1.76, w: 0.472, n: 21},
! 1132: {c: 'j', h: 0.04, d: 1.76, w: 0.528, n: 22},
! 1133: {c: 'k', h: 0.04, d: 1.76, w: 0.528, n: 23},
! 1134: {c: 'l', h: 0.04, d: 1.76, w: 0.528, n: 24},
! 1135: {c: 'm', h: 0.04, d: 1.76, w: 0.528, n: 25},
! 1136: {c: 'n', h: 0.04, d: 1.76, w: 0.667, n: 26},
! 1137: {c: 'o', h: 0.04, d: 1.76, w: 0.667, n: 27},
! 1138: // 70 - 7F
! 1139: {c: 'p', h: 0.04, d: 1.16, w: 1, n: 113},
! 1140: {c: 'q', h: 0.04, d: 1.76, w: 1, n: 114},
! 1141: {c: 'r', h: 0.04, d: 2.36, w: 1, n: 115},
! 1142: {c: 's', h: 0.04, d: 2.96, w: 1, n: 116},
! 1143: {c: 't', d: 1.8, w: 1.06, delim: {top: 118, bot: 116, rep: 117}},
! 1144: {c: 'u', d: 0.6, w: 1.06},
! 1145: {c: 'v', h: 0.04, d: 0.56, w: 1.06},
! 1146: {c: 'w', d: 0.6, w: 0.778, delim: {top: 126, bot: 127, rep: 119}},
! 1147: {c: 'x', d: 0.6, w: 0.667, delim: {top: 120, rep: 63}},
! 1148: {c: 'y', d: 0.6, w: 0.667, delim: {bot: 121, rep: 63}},
! 1149: {c: 'z', h: 0.12, w: 0.45},
! 1150: {c: '{', h: 0.12, w: 0.45},
! 1151: {c: '|', h: 0.12, w: 0.45},
! 1152: {c: '}', h: 0.12, w: 0.45},
! 1153: {c: '~', d: 0.6, w: 0.778, delim: {top: 126, rep: 119}},
! 1154: {c: 'Ä', d: 0.6, w: 0.778, delim: {bot: 127, rep: 119}}
! 1155: ],
! 1156:
! 1157: cmti10: [
! 1158: // 00 - 0F
! 1159: {c: '¡', h: 0.683, w: 0.627, ic: 0.133},
! 1160: {c: '¢', h: 0.683, w: 0.818},
! 1161: {c: '£', h: 0.683, w: 0.767, ic: 0.094},
! 1162: {c: '¤', h: 0.683, w: 0.692},
! 1163: {c: '¥', h: 0.683, w: 0.664, ic: 0.153},
! 1164: {c: '¦', h: 0.683, w: 0.743, ic: 0.164},
! 1165: {c: '§', h: 0.683, w: 0.716, ic: 0.12},
! 1166: {c: '¨', h: 0.683, w: 0.767, ic: 0.111},
! 1167: {c: '©', h: 0.683, w: 0.716, ic: 0.0599},
! 1168: {c: 'ª', h: 0.683, w: 0.767, ic: 0.111},
! 1169: {c: '­', h: 0.683, w: 0.716, ic: 0.103},
! 1170: {c: '®', h: 0.694, d: 0.194, w: 0.613, ic: 0.212, krn: {'39': 0.104, '63': 0.104, '33': 0.104, '41': 0.104, '93': 0.104}, lig: {'105': 14, '108': 15}},
! 1171: {c: '¯', h: 0.694, d: 0.194, w: 0.562, ic: 0.103},
! 1172: {c: '°', h: 0.694, d: 0.194, w: 0.588, ic: 0.103},
! 1173: {c: '±', h: 0.694, d: 0.194, w: 0.882, ic: 0.103},
! 1174: {c: '²', h: 0.694, d: 0.194, w: 0.894, ic: 0.103},
! 1175: // 10 - 1F
! 1176: {c: '³', h: 0.431, w: 0.307, ic: 0.0767},
! 1177: {c: '´', h: 0.431, d: 0.194, w: 0.332, ic: 0.0374},
! 1178: {c: 'µ', h: 0.694, w: 0.511},
! 1179: {c: '¶', h: 0.694, w: 0.511, ic: 0.0969},
! 1180: {c: '∙', h: 0.628, w: 0.511, ic: 0.083},
! 1181: {c: '¸', h: 0.694, w: 0.511, ic: 0.108},
! 1182: {c: '¹', h: 0.562, w: 0.511, ic: 0.103},
! 1183: {c: 'º', h: 0.694, w: 0.831},
! 1184: {c: '»', d: 0.17, w: 0.46},
! 1185: {c: '¼', h: 0.694, d: 0.194, w: 0.537, ic: 0.105},
! 1186: {c: '½', h: 0.431, w: 0.716, ic: 0.0751},
! 1187: {c: '¾', h: 0.431, w: 0.716, ic: 0.0751},
! 1188: {c: '¿', h: 0.528, d: 0.0972, w: 0.511, ic: 0.0919},
! 1189: {c: 'À', h: 0.683, w: 0.883, ic: 0.12},
! 1190: {c: 'Á', h: 0.683, w: 0.985, ic: 0.12},
! 1191: {c: 'Â', h: 0.732, d: 0.0486, w: 0.767, ic: 0.094},
! 1192: // 20 - 2F
! 1193: {c: 'Ã', h: 0.431, w: 0.256, krn: {'108': -0.256, '76': -0.321}},
! 1194: {c: '!', h: 0.694, w: 0.307, ic: 0.124, lig: {'96': 60}},
! 1195: {c: '"', h: 0.694, w: 0.514, ic: 0.0696},
! 1196: {c: '#', h: 0.694, d: 0.194, w: 0.818, ic: 0.0662},
! 1197: {c: '$', h: 0.694, w: 0.769},
! 1198: {c: '%', h: 0.75, d: 0.0556, w: 0.818, ic: 0.136},
! 1199: {c: '&', h: 0.694, w: 0.767, ic: 0.0969},
! 1200: {c: '\'', h: 0.694, w: 0.307, ic: 0.124, krn: {'63': 0.102, '33': 0.102}, lig: {'39': 34}},
! 1201: {c: '(', h: 0.75, d: 0.25, w: 0.409, ic: 0.162},
! 1202: {c: ')', h: 0.75, d: 0.25, w: 0.409, ic: 0.0369},
! 1203: {c: '*', h: 0.75, w: 0.511, ic: 0.149},
! 1204: {c: '+', h: 0.562, d: 0.0567, w: 0.767, ic: 0.0369},
! 1205: {c: ',', h: 0.106, d: 0.194, w: 0.307},
! 1206: {c: '-', h: 0.431, w: 0.358, ic: 0.0283, lig: {'45': 123}},
! 1207: {c: '.', h: 0.106, w: 0.307},
! 1208: {c: '/', h: 0.75, d: 0.25, w: 0.511, ic: 0.162},
! 1209: // 30 - 3F
! 1210: {c: '0', h: 0.644, w: 0.511, ic: 0.136},
! 1211: {c: '1', h: 0.644, w: 0.511, ic: 0.136},
! 1212: {c: '2', h: 0.644, w: 0.511, ic: 0.136},
! 1213: {c: '3', h: 0.644, w: 0.511, ic: 0.136},
! 1214: {c: '4', h: 0.644, d: 0.194, w: 0.511, ic: 0.136},
! 1215: {c: '5', h: 0.644, w: 0.511, ic: 0.136},
! 1216: {c: '6', h: 0.644, w: 0.511, ic: 0.136},
! 1217: {c: '7', h: 0.644, d: 0.194, w: 0.511, ic: 0.136},
! 1218: {c: '8', h: 0.644, w: 0.511, ic: 0.136},
! 1219: {c: '9', h: 0.644, w: 0.511, ic: 0.136},
! 1220: {c: ':', h: 0.431, w: 0.307, ic: 0.0582},
! 1221: {c: ';', h: 0.431, d: 0.194, w: 0.307, ic: 0.0582},
! 1222: {c: '<', h: 0.5, d: 0.194, w: 0.307, ic: 0.0756},
! 1223: {c: '=', h: 0.367, d: -0.133, w: 0.767, ic: 0.0662},
! 1224: {c: '>', h: 0.5, d: 0.194, w: 0.511},
! 1225: {c: '?', h: 0.694, w: 0.511, ic: 0.122, lig: {'96': 62}},
! 1226: // 40 - 4F
! 1227: {c: '@', h: 0.694, w: 0.767, ic: 0.096},
! 1228: {c: 'A', h: 0.683, w: 0.743, 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}},
! 1229: {c: 'B', h: 0.683, w: 0.704, ic: 0.103},
! 1230: {c: 'C', h: 0.683, w: 0.716, ic: 0.145},
! 1231: {c: 'D', h: 0.683, w: 0.755, ic: 0.094, krn: {'88': -0.0256, '87': -0.0256, '65': -0.0256, '86': -0.0256, '89': -0.0256}},
! 1232: {c: 'E', h: 0.683, w: 0.678, ic: 0.12},
! 1233: {c: 'F', h: 0.683, w: 0.653, 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}},
! 1234: {c: 'G', h: 0.683, w: 0.774, ic: 0.0872},
! 1235: {c: 'H', h: 0.683, w: 0.743, ic: 0.164},
! 1236: {c: 'I', h: 0.683, w: 0.386, ic: 0.158},
! 1237: {c: 'J', h: 0.683, w: 0.525, ic: 0.14},
! 1238: {c: 'K', h: 0.683, w: 0.769, ic: 0.145, krn: {'79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}},
! 1239: {c: 'L', h: 0.683, w: 0.627, 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}},
! 1240: {c: 'M', h: 0.683, w: 0.897, ic: 0.164},
! 1241: {c: 'N', h: 0.683, w: 0.743, ic: 0.164},
! 1242: {c: 'O', h: 0.683, w: 0.767, ic: 0.094, krn: {'88': -0.0256, '87': -0.0256, '65': -0.0256, '86': -0.0256, '89': -0.0256}},
! 1243: // 50 - 5F
! 1244: {c: 'P', h: 0.683, w: 0.678, ic: 0.103, krn: {'65': -0.0767}},
! 1245: {c: 'Q', h: 0.683, d: 0.194, w: 0.767, ic: 0.094},
! 1246: {c: 'R', h: 0.683, w: 0.729, 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}},
! 1247: {c: 'S', h: 0.683, w: 0.562, ic: 0.12},
! 1248: {c: 'T', h: 0.683, w: 0.716, 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}},
! 1249: {c: 'U', h: 0.683, w: 0.743, ic: 0.164},
! 1250: {c: 'V', h: 0.683, w: 0.743, 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}},
! 1251: {c: 'W', h: 0.683, w: 0.999, ic: 0.184, krn: {'65': -0.0767}},
! 1252: {c: 'X', h: 0.683, w: 0.743, ic: 0.158, krn: {'79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}},
! 1253: {c: 'Y', h: 0.683, w: 0.743, ic: 0.194, krn: {'101': -0.0767, '111': -0.0767, '114': -0.0767, '97': -0.0767, '117': -0.0767, '65': -0.0767}},
! 1254: {c: 'Z', h: 0.683, w: 0.613, ic: 0.145},
! 1255: {c: '[', h: 0.75, d: 0.25, w: 0.307, ic: 0.188},
! 1256: {c: '\\', h: 0.694, w: 0.514, ic: 0.169},
! 1257: {c: ']', h: 0.75, d: 0.25, w: 0.307, ic: 0.105},
! 1258: {c: '^', h: 0.694, w: 0.511, ic: 0.0665},
! 1259: {c: '_', h: 0.668, w: 0.307, ic: 0.118},
! 1260: // 60 - 6F
! 1261: {c: '`', h: 0.694, w: 0.307, ic: 0.124, lig: {'96': 92}},
! 1262: {c: 'a', h: 0.431, w: 0.511, ic: 0.0767},
! 1263: {c: 'b', h: 0.694, w: 0.46, 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}},
! 1264: {c: 'c', h: 0.431, w: 0.46, 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}},
! 1265: {c: 'd', h: 0.694, w: 0.511, ic: 0.103, krn: {'108': 0.0511}},
! 1266: {c: 'e', h: 0.431, w: 0.46, 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}},
! 1267: {c: 'f', h: 0.694, d: 0.194, w: 0.307, 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}},
! 1268: {c: 'g', h: 0.431, d: 0.194, w: 0.46, ic: 0.0885},
! 1269: {c: 'h', h: 0.694, w: 0.511, ic: 0.0767},
! 1270: {c: 'i', h: 0.655, w: 0.307, ic: 0.102},
! 1271: {c: 'j', h: 0.655, d: 0.194, w: 0.307, ic: 0.145},
! 1272: {c: 'k', h: 0.694, w: 0.46, ic: 0.108},
! 1273: {c: 'l', h: 0.694, w: 0.256, ic: 0.103, krn: {'108': 0.0511}},
! 1274: {c: 'm', h: 0.431, w: 0.818, ic: 0.0767},
! 1275: {c: 'n', h: 0.431, w: 0.562, ic: 0.0767, krn: {'39': -0.102}},
! 1276: {c: 'o', h: 0.431, w: 0.511, 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}},
! 1277: // 70 - 7F
! 1278: {c: 'p', h: 0.431, d: 0.194, w: 0.511, 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}},
! 1279: {c: 'q', h: 0.431, d: 0.194, w: 0.46, ic: 0.0885},
! 1280: {c: 'r', h: 0.431, w: 0.422, 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}},
! 1281: {c: 's', h: 0.431, w: 0.409, ic: 0.0821},
! 1282: {c: 't', h: 0.615, w: 0.332, ic: 0.0949},
! 1283: {c: 'u', h: 0.431, w: 0.537, ic: 0.0767},
! 1284: {c: 'v', h: 0.431, w: 0.46, ic: 0.108},
! 1285: {c: 'w', h: 0.431, w: 0.664, ic: 0.108, krn: {'108': 0.0511}},
! 1286: {c: 'x', h: 0.431, w: 0.464, ic: 0.12},
! 1287: {c: 'y', h: 0.431, d: 0.194, w: 0.486, ic: 0.0885},
! 1288: {c: 'z', h: 0.431, w: 0.409, ic: 0.123},
! 1289: {c: '{', h: 0.431, w: 0.511, ic: 0.0921, lig: {'45': 124}},
! 1290: {c: '|', h: 0.431, w: 1.02, ic: 0.0921},
! 1291: {c: '}', h: 0.694, w: 0.511, ic: 0.122},
! 1292: {c: '~', h: 0.668, w: 0.511, ic: 0.116},
! 1293: {c: 'Ä', h: 0.668, w: 0.511, ic: 0.105}
! 1294: ],
! 1295:
! 1296: cmbx10: [
! 1297: // 00 - 0F
! 1298: {c: '¡', h: 0.686, w: 0.692},
! 1299: {c: '¢', h: 0.686, w: 0.958},
! 1300: {c: '£', h: 0.686, w: 0.894},
! 1301: {c: '¤', h: 0.686, w: 0.806},
! 1302: {c: '¥', h: 0.686, w: 0.767},
! 1303: {c: '¦', h: 0.686, w: 0.9},
! 1304: {c: '§', h: 0.686, w: 0.831},
! 1305: {c: '¨', h: 0.686, w: 0.894},
! 1306: {c: '©', h: 0.686, w: 0.831},
! 1307: {c: 'ª', h: 0.686, w: 0.894},
! 1308: {c: '­', h: 0.686, w: 0.831},
! 1309: {c: '®', h: 0.694, w: 0.671, ic: 0.109, krn: {'39': 0.109, '63': 0.109, '33': 0.109, '41': 0.109, '93': 0.109}, lig: {'105': 14, '108': 15}},
! 1310: {c: '¯', h: 0.694, w: 0.639},
! 1311: {c: '°', h: 0.694, w: 0.639},
! 1312: {c: '±', h: 0.694, w: 0.958},
! 1313: {c: '²', h: 0.694, w: 0.958},
! 1314: // 10 - 1F
! 1315: {c: '³', h: 0.444, w: 0.319},
! 1316: {c: '´', h: 0.444, d: 0.194, w: 0.351},
! 1317: {c: 'µ', h: 0.694, w: 0.575},
! 1318: {c: '¶', h: 0.694, w: 0.575},
! 1319: {c: '∙', h: 0.632, w: 0.575},
! 1320: {c: '¸', h: 0.694, w: 0.575},
! 1321: {c: '¹', h: 0.596, w: 0.575},
! 1322: {c: 'º', h: 0.694, w: 0.869},
! 1323: {c: '»', d: 0.17, w: 0.511},
! 1324: {c: '¼', h: 0.694, w: 0.597},
! 1325: {c: '½', h: 0.444, w: 0.831},
! 1326: {c: '¾', h: 0.444, w: 0.894},
! 1327: {c: '¿', h: 0.542, d: 0.0972, w: 0.575},
! 1328: {c: 'À', h: 0.686, w: 1.04},
! 1329: {c: 'Á', h: 0.686, w: 1.17},
! 1330: {c: 'Â', h: 0.735, d: 0.0486, w: 0.894},
! 1331: // 20 - 2F
! 1332: {c: 'Ã', h: 0.444, w: 0.319, krn: {'108': -0.319, '76': -0.378}},
! 1333: {c: '!', h: 0.694, w: 0.35, lig: {'96': 60}},
! 1334: {c: '"', h: 0.694, w: 0.603},
! 1335: {c: '#', h: 0.694, d: 0.194, w: 0.958},
! 1336: {c: '$', h: 0.75, d: 0.0556, w: 0.575},
! 1337: {c: '%', h: 0.75, d: 0.0556, w: 0.958},
! 1338: {c: '&', h: 0.694, w: 0.894},
! 1339: {c: '\'', h: 0.694, w: 0.319, krn: {'63': 0.128, '33': 0.128}, lig: {'39': 34}},
! 1340: {c: '(', h: 0.75, d: 0.25, w: 0.447},
! 1341: {c: ')', h: 0.75, d: 0.25, w: 0.447},
! 1342: {c: '*', h: 0.75, w: 0.575},
! 1343: {c: '+', h: 0.633, d: 0.133, w: 0.894},
! 1344: {c: ',', h: 0.156, d: 0.194, w: 0.319},
! 1345: {c: '-', h: 0.444, w: 0.383, lig: {'45': 123}},
! 1346: {c: '.', h: 0.156, w: 0.319},
! 1347: {c: '/', h: 0.75, d: 0.25, w: 0.575},
! 1348: // 30 - 3F
! 1349: {c: '0', h: 0.644, w: 0.575},
! 1350: {c: '1', h: 0.644, w: 0.575},
! 1351: {c: '2', h: 0.644, w: 0.575},
! 1352: {c: '3', h: 0.644, w: 0.575},
! 1353: {c: '4', h: 0.644, w: 0.575},
! 1354: {c: '5', h: 0.644, w: 0.575},
! 1355: {c: '6', h: 0.644, w: 0.575},
! 1356: {c: '7', h: 0.644, w: 0.575},
! 1357: {c: '8', h: 0.644, w: 0.575},
! 1358: {c: '9', h: 0.644, w: 0.575},
! 1359: {c: ':', h: 0.444, w: 0.319},
! 1360: {c: ';', h: 0.444, d: 0.194, w: 0.319},
! 1361: {c: '<', h: 0.5, d: 0.194, w: 0.35},
! 1362: {c: '=', h: 0.391, d: -0.109, w: 0.894},
! 1363: {c: '>', h: 0.5, d: 0.194, w: 0.543},
! 1364: {c: '?', h: 0.694, w: 0.543, lig: {'96': 62}},
! 1365: // 40 - 4F
! 1366: {c: '@', h: 0.694, w: 0.894},
! 1367: {c: 'A', h: 0.686, w: 0.869, 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}},
! 1368: {c: 'B', h: 0.686, w: 0.818},
! 1369: {c: 'C', h: 0.686, w: 0.831},
! 1370: {c: 'D', h: 0.686, w: 0.882, krn: {'88': -0.0319, '87': -0.0319, '65': -0.0319, '86': -0.0319, '89': -0.0319}},
! 1371: {c: 'E', h: 0.686, w: 0.756},
! 1372: {c: 'F', h: 0.686, w: 0.724, 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}},
! 1373: {c: 'G', h: 0.686, w: 0.904},
! 1374: {c: 'H', h: 0.686, w: 0.9},
! 1375: {c: 'I', h: 0.686, w: 0.436, krn: {'73': 0.0319}},
! 1376: {c: 'J', h: 0.686, w: 0.594},
! 1377: {c: 'K', h: 0.686, w: 0.901, krn: {'79': -0.0319, '67': -0.0319, '71': -0.0319, '81': -0.0319}},
! 1378: {c: 'L', h: 0.686, w: 0.692, krn: {'84': -0.0958, '89': -0.0958, '86': -0.128, '87': -0.128}},
! 1379: {c: 'M', h: 0.686, w: 1.09},
! 1380: {c: 'N', h: 0.686, w: 0.9},
! 1381: {c: 'O', h: 0.686, w: 0.864, krn: {'88': -0.0319, '87': -0.0319, '65': -0.0319, '86': -0.0319, '89': -0.0319}},
! 1382: // 50 - 5F
! 1383: {c: 'P', h: 0.686, w: 0.786, krn: {'65': -0.0958, '111': -0.0319, '101': -0.0319, '97': -0.0319, '46': -0.0958, '44': -0.0958}},
! 1384: {c: 'Q', h: 0.686, d: 0.194, w: 0.864},
! 1385: {c: 'R', h: 0.686, w: 0.862, 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}},
! 1386: {c: 'S', h: 0.686, w: 0.639},
! 1387: {c: 'T', h: 0.686, w: 0.8, krn: {'121': -0.0319, '101': -0.0958, '111': -0.0958, '114': -0.0958, '97': -0.0958, '65': -0.0958, '117': -0.0958}},
! 1388: {c: 'U', h: 0.686, w: 0.885},
! 1389: {c: 'V', h: 0.686, w: 0.869, 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}},
! 1390: {c: 'W', h: 0.686, w: 1.19, 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}},
! 1391: {c: 'X', h: 0.686, w: 0.869, krn: {'79': -0.0319, '67': -0.0319, '71': -0.0319, '81': -0.0319}},
! 1392: {c: 'Y', h: 0.686, w: 0.869, ic: 0.0287, krn: {'101': -0.0958, '111': -0.0958, '114': -0.0958, '97': -0.0958, '65': -0.0958, '117': -0.0958}},
! 1393: {c: 'Z', h: 0.686, w: 0.703},
! 1394: {c: '[', h: 0.75, d: 0.25, w: 0.319},
! 1395: {c: '\\', h: 0.694, w: 0.603},
! 1396: {c: ']', h: 0.75, d: 0.25, w: 0.319},
! 1397: {c: '^', h: 0.694, w: 0.575},
! 1398: {c: '_', h: 0.694, w: 0.319},
! 1399: // 60 - 6F
! 1400: {c: '`', h: 0.694, w: 0.319, lig: {'96': 92}},
! 1401: {c: 'a', h: 0.444, w: 0.559, krn: {'118': -0.0319, '106': 0.0639, '121': -0.0319, '119': -0.0319}},
! 1402: {c: 'b', h: 0.694, w: 0.639, 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}},
! 1403: {c: 'c', h: 0.444, w: 0.511, krn: {'104': -0.0319, '107': -0.0319}},
! 1404: {c: 'd', h: 0.694, w: 0.639},
! 1405: {c: 'e', h: 0.444, w: 0.527},
! 1406: {c: 'f', h: 0.694, w: 0.351, 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}},
! 1407: {c: 'g', h: 0.444, d: 0.194, w: 0.575, ic: 0.016, krn: {'106': 0.0319}},
! 1408: {c: 'h', h: 0.694, w: 0.639, krn: {'116': -0.0319, '117': -0.0319, '98': -0.0319, '121': -0.0319, '118': -0.0319, '119': -0.0319}},
! 1409: {c: 'i', h: 0.694, w: 0.319},
! 1410: {c: 'j', h: 0.694, d: 0.194, w: 0.351},
! 1411: {c: 'k', h: 0.694, w: 0.607, krn: {'97': -0.0639, '101': -0.0319, '97': -0.0319, '111': -0.0319, '99': -0.0319}},
! 1412: {c: 'l', h: 0.694, w: 0.319},
! 1413: {c: 'm', h: 0.444, w: 0.958, krn: {'116': -0.0319, '117': -0.0319, '98': -0.0319, '121': -0.0319, '118': -0.0319, '119': -0.0319}},
! 1414: {c: 'n', h: 0.444, w: 0.639, krn: {'116': -0.0319, '117': -0.0319, '98': -0.0319, '121': -0.0319, '118': -0.0319, '119': -0.0319}},
! 1415: {c: 'o', h: 0.444, w: 0.575, 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}},
! 1416: // 70 - 7F
! 1417: {c: 'p', h: 0.444, d: 0.194, w: 0.639, 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}},
! 1418: {c: 'q', h: 0.444, d: 0.194, w: 0.607},
! 1419: {c: 'r', h: 0.444, w: 0.474},
! 1420: {c: 's', h: 0.444, w: 0.454},
! 1421: {c: 't', h: 0.635, w: 0.447, krn: {'121': -0.0319, '119': -0.0319}},
! 1422: {c: 'u', h: 0.444, w: 0.639, krn: {'119': -0.0319}},
! 1423: {c: 'v', h: 0.444, w: 0.607, ic: 0.016, krn: {'97': -0.0639, '101': -0.0319, '97': -0.0319, '111': -0.0319, '99': -0.0319}},
! 1424: {c: 'w', h: 0.444, w: 0.831, ic: 0.016, krn: {'101': -0.0319, '97': -0.0319, '111': -0.0319, '99': -0.0319}},
! 1425: {c: 'x', h: 0.444, w: 0.607},
! 1426: {c: 'y', h: 0.444, d: 0.194, w: 0.607, ic: 0.016, krn: {'111': -0.0319, '101': -0.0319, '97': -0.0319, '46': -0.0958, '44': -0.0958}},
! 1427: {c: 'z', h: 0.444, w: 0.511},
! 1428: {c: '{', h: 0.444, w: 0.575, ic: 0.0319, lig: {'45': 124}},
! 1429: {c: '|', h: 0.444, w: 1.15, ic: 0.0319},
! 1430: {c: '}', h: 0.694, w: 0.575},
! 1431: {c: '~', h: 0.694, w: 0.575},
! 1432: {c: 'Ä', h: 0.694, w: 0.575}
! 1433: ]
! 1434: });
! 1435:
! 1436: /***************************************************************************/
! 1437:
! 1438: /*
! 1439: * jsMath.HTML handles creation of most of the HTML needed for
! 1440: * presenting mathematics in HTML pages.
! 1441: */
! 1442:
! 1443: jsMath.HTML = {
! 1444:
! 1445: /*
! 1446: * produce a string version of a measurement in ems,
! 1447: * showing only a limited number of digits, and
! 1448: * using 0 when the value is near zero.
! 1449: */
! 1450: Em: function (m) {
! 1451: var n = 5; if (m < 0) {n++}
! 1452: if (Math.abs(m) < .000001) {m = 0}
! 1453: var s = String(m); s = s.replace(/(\.\d\d\d).+/,'$1');
! 1454: return s+'em'
! 1455: },
! 1456:
! 1457: /*
! 1458: * Create a horizontal space of width w
! 1459: */
! 1460: Spacer: function (w) {
! 1461: if (w == 0) {return ''};
! 1462: return jsMath.msieSpaceFix
! 1463: + '<SPAN STYLE="margin-left: '+this.Em(w)+'"></SPAN>';
! 1464: },
! 1465:
! 1466: /*
! 1467: * Use an image to create a horizontal space of width w
! 1468: */
! 1469: SpacerImage: function (w) {
! 1470: if (w == 0) {return ''};
! 1471: return '<IMG SRC="'+jsMath.blank+'" STYLE="'
! 1472: + ' width: 0; margin-left: '+this.Em(w)+'">';
! 1473: },
! 1474:
! 1475: /*
! 1476: * Create a colored frame (for debugging use)
! 1477: */
! 1478: Frame: function (x,y,w,h,c,pos) {
! 1479:
! 1480: h -= 2/jsMath.em; // use 2 pixels to compensate for border size
! 1481: w -= 2/jsMath.em;
! 1482: y -= 1/jsMath.em;
! 1483: if (!c) {c = 'black'};
! 1484: if (pos) {pos = 'absolute;'} else
! 1485: {pos = 'relative; margin-right: '+this.Em(-(w+2/jsMath.em))+'; '}
! 1486: return '<IMG SRC="'+jsMath.blank+'" STYLE="position:' + pos
! 1487: + 'vertical-align: '+this.Em(y)+'; left: '+this.Em(x)+'; '
! 1488: + 'width:'+this.Em(w)+'; height: '+this.Em(h)+'; '
! 1489: + 'border-color: '+c+'; border-style: solid; border-width: 1px;">';
! 1490: },
! 1491:
! 1492: /*
! 1493: * Create a 1-pixel-high horizontal line at a particular
! 1494: * position, width and color.
! 1495: */
! 1496: Line: function (x,y,w,c,pos) {
! 1497: if (!c) {c = 'black'};
! 1498: if (pos) {pos = 'absolute;'} else
! 1499: {pos = 'relative; margin-right: '+this.Em(-w)+'; '}
! 1500: return '<IMG SRC="'+jsMath.blank+'" STYLE="position:'+pos
! 1501: + 'top: '+this.Em(-y)+'; left:'+this.Em(x)+'; '
! 1502: + 'width:'+this.Em(w)+'; height:1px; background-color: '+c+';">';
! 1503: },
! 1504:
! 1505: /*
! 1506: * Create a black rule line for fractions, etc.
! 1507: * Height is converted to pixels (with a minimum of 1), so that
! 1508: * the line will not disappear at small font sizes. This means that
! 1509: * the thickness will not change if you change the font size, or
! 1510: * may not be correct within a header or other enlarged text.
! 1511: */
! 1512: Rule: function (w,h) {
! 1513: if (h == null) {h = jsMath.TeX.default_rule_thickness}
! 1514: if (w == 0 || h == 0) return; // should make an invisible box?
! 1515: h = Math.round(h*jsMath.em);
! 1516: if (h < 1) {h = 1}
! 1517: return '<IMG SRC="'+jsMath.black+'" HSPACE="0" VSPACE="0" '
! 1518: + 'STYLE="width:'+this.Em(w)+'; height: '+h+'px">';
! 1519: },
! 1520:
! 1521: /*
! 1522: * Create a colored block of a specific size (won't always print
! 1523: * correctly).
! 1524: */
! 1525: Block: function (w,h,c) {
! 1526: if (c == null) {c = 'black'}
! 1527: return '<IMG SRC="'+jsMath.blank+'" HSPACE="0" VSPACE="0" '
! 1528: + 'STYLE="width:'+this.Em(w)+'; height: '+this.Em(h)+'; '
! 1529: + 'background-color: '+c+'">';
! 1530: },
! 1531:
! 1532: /*
! 1533: * Add a <SPAN> tag to activate a specific CSS class
! 1534: */
! 1535: Class: function (tclass,html) {
! 1536: return '<SPAN CLASS="'+tclass+'">'+html+'</SPAN>';
! 1537: },
! 1538:
! 1539: /*
! 1540: * Use a <SPAN> to place some HTML at a specific position.
! 1541: * (This can be replaced by the ones below to overcome
! 1542: * some browser-specific bugs.)
! 1543: */
! 1544: Place: function (html,x,y) {
! 1545: if (Math.abs(x) < .0001) {x = 0}
! 1546: if (Math.abs(y) < .0001) {y = 0}
! 1547: if (x || y) {
! 1548: var span = '<SPAN STYLE="position: relative;';
! 1549: if (x) {span += ' margin-left:'+this.Em(x)+';'}
! 1550: if (y) {span += ' top:'+this.Em(-y)+';'}
! 1551: html = span + '">' + html + '</SPAN>';
! 1552: }
! 1553: return html;
! 1554: },
! 1555:
! 1556: /*
! 1557: * For MSIE on Windows, backspacing must be done in a separate
! 1558: * <SPAN>, otherwise the contents will be clipped.
! 1559: */
! 1560: PlaceSeparateNegative: function (html,x,y) {
! 1561: if (Math.abs(x) < .0001) {x = 0}
! 1562: if (Math.abs(y) < .0001) {y = 0}
! 1563: if (x > 0 || y) {
! 1564: var span = '<SPAN STYLE="position: relative;';
! 1565: if (x > 0) {span += ' margin-left:'+this.Em(x)+';'}
! 1566: if (y) {span += ' top:'+this.Em(-y)+';'}
! 1567: html = span + '">' + html + '</SPAN>';
! 1568: }
! 1569: if (x < 0) {
! 1570: html = jsMath.msieSpaceFix
! 1571: + '<SPAN STYLE="margin-left:'+this.Em(x)+';"></SPAN>' + html;
! 1572: }
! 1573: return html;
! 1574: },
! 1575:
! 1576: /*
! 1577: * Here the x and y positioning is done in separate <SPAN> tags
! 1578: */
! 1579: PlaceSeparateSkips: function (html,x,y) {
! 1580: if (Math.abs(x) < .0001) {x = 0}
! 1581: if (Math.abs(y) < .0001) {y = 0}
! 1582: if (y) {html = '<SPAN STYLE="position: relative; top:'+this.Em(-y)+';'
! 1583: + '">' + html + '</SPAN>'}
! 1584: if (x) {html = jsMath.msieSpaceFix
! 1585: + '<SPAN STYLE="margin-left:'+this.Em(x)+';"></SPAN>' + html}
! 1586: return html;
! 1587: },
! 1588:
! 1589: /*
! 1590: * Place a SPAN with absolute coordinates
! 1591: */
! 1592: PlaceAbsolute: function (html,x,y) {
! 1593: if (Math.abs(x) < .0001) {x = 0}
! 1594: if (Math.abs(y) < .0001) {y = 0}
! 1595: html = '<SPAN STYLE="position: absolute; left:'+this.Em(x)+'; '
! 1596: + 'top:'+this.Em(y)+';">' + html + ' </SPAN>';
! 1597: // space normalizes line height
! 1598: return html;
! 1599: },
! 1600:
! 1601: Absolute: function(html,w,h,d,y,H) {
! 1602: var align = "";
! 1603: if (d) {align = ' vertical-align: '+jsMath.HTML.Em(-d)+';'}
! 1604: if (y != "none") {
! 1605: if (Math.abs(y) < .0001) {y = 0}
! 1606: html = '<SPAN STYLE="position: absolute; '
! 1607: + 'top:'+jsMath.HTML.Em(y)+'; left: 0em;">'
! 1608: + html + ' ' // space normalizes line height in script styles
! 1609: + '</SPAN>';
! 1610: }
! 1611: html += '<IMG SRC="'+jsMath.blank+'" STYLE="width: '+jsMath.HTML.Em(w)+'; '
! 1612: + 'height: '+jsMath.HTML.Em(h)+';'+align+'">';
! 1613: if (jsMath.msieAbsoluteBug) {// for MSIE (Mac)
! 1614: html = '<SPAN STYLE="position: relative;">' + html + '</SPAN>';
! 1615: }
! 1616: html = '<SPAN STYLE="position: relative;'
! 1617: + ' width: '+jsMath.HTML.Em(w)+';' // for MSIE
! 1618: + ' height: '+jsMath.HTML.Em(H)+';' // for MSIE
! 1619: + '">'
! 1620: + html
! 1621: + '</SPAN>';
! 1622: return html;
! 1623: }
! 1624:
! 1625: };
! 1626:
! 1627:
! 1628: /***************************************************************************/
! 1629:
! 1630: /*
! 1631: * jsMath.Box handles TeX's math boxes and jsMath's equivalent of hboxes.
! 1632: */
! 1633:
! 1634: jsMath.Box = function (format,text,w,h,d) {
! 1635: if (d == null) {d = jsMath.d}
! 1636: this.type = 'typeset';
! 1637: this.w = w; this.h = h; this.d = d; this.bh = h; this.bd = d;
! 1638: this.x = 0; this.y = 0;
! 1639: this.html = text; this.format = format;
! 1640: };
! 1641:
! 1642:
! 1643: jsMath.Add(jsMath.Box,{
! 1644:
! 1645: /*
! 1646: * An empty box
! 1647: */
! 1648: Null: new jsMath.Box('null','',0,0,0),
! 1649:
! 1650: /*
! 1651: * A box containing only text whose class and style haven't been added
! 1652: * yet (so that we can combine ones with the same styles). It gets
! 1653: * the text dimensions, if needed. (In general, this has been
! 1654: * replaced by TeX() below, but is still used in fallback mode.)
! 1655: */
! 1656: Text: function (text,tclass,style,size,a,d) {
! 1657: var html = jsMath.Typeset.AddClass(tclass,text);
! 1658: html = jsMath.Typeset.AddStyle(style,size,html);
! 1659: var BB = jsMath.EmBoxFor(html); var TeX = jsMath.Typeset.TeX(style,size);
! 1660: var bd = ((tclass == 'cmsy10' || tclass == 'cmex10')? BB.h-TeX.h: TeX.d*BB.h/TeX.hd);
! 1661: var box = new jsMath.Box('text',text,BB.w,BB.h-bd,bd);
! 1662: box.style = style; box.size = size; box.tclass = tclass;
! 1663: if (d != null) {if (d != 1) {box.d = d}} else {box.d = 0}
! 1664: if (a == null || a == 1) {box.h = .9*TeX.M_height}
! 1665: else {box.h = 1.1*TeX.x_height + 1*a}; // sometimes a is a string?
! 1666: return box;
! 1667: },
! 1668:
! 1669: /*
! 1670: * Produce a box containing a given TeX character from a given font.
! 1671: * The box is a text box (like the ones above), so that characters from
! 1672: * the same font can be combined.
! 1673: */
! 1674: TeX: function (c,font,style,size) {
! 1675: c = jsMath.TeX[font][c];
! 1676: if (c.d == null) {c.d = 0}; if (c.h == null) {c.h = 0}
! 1677: var scale = jsMath.Typeset.TeX(style,size).scale;
! 1678: var h = c.h + jsMath.TeX[font].dh
! 1679: var box = new jsMath.Box('text',c.c,c.w*scale,h*scale,c.d*scale);
! 1680: box.style = style; box.size = size;
! 1681: if (c.tclass) {
! 1682: box.tclass = c.tclass;
! 1683: box.bh = scale*jsMath.h;
! 1684: box.bd = scale*jsMath.d;
! 1685: } else {
! 1686: box.tclass = font;
! 1687: box.bh = scale*jsMath.TeX[font].h;
! 1688: box.bd = scale*jsMath.TeX[font].d;
! 1689: if (jsMath.msieFontBug) {
! 1690: // hack to avoid Font changing back to the default
! 1691: // font when a unicode reference is not followed
! 1692: // by a letter or number
! 1693: box.html += '<SPAN STYLE="display: none">x</SPAN>'
! 1694: }
! 1695: }
! 1696: return box;
! 1697: },
! 1698:
! 1699: /*
! 1700: * A box containing a spacer of a specific width
! 1701: */
! 1702: Space: function (w) {
! 1703: return new jsMath.Box('html',jsMath.HTML.Spacer(w),w,0,0);
! 1704: },
! 1705:
! 1706: /*
! 1707: * A box containing a horizontal rule
! 1708: */
! 1709: Rule: function (w,h) {
! 1710: if (h == null) {h = jsMath.TeX.default_rule_thickness}
! 1711: html = jsMath.HTML.Rule(w,h);
! 1712: return new jsMath.Box('html',html,w,h,0);
! 1713: },
! 1714:
! 1715: /*
! 1716: * A box containing a colored block
! 1717: */
! 1718: Block: function (w,h,c) {
! 1719: return new jsMath.Box('html',jsMath.HTML.Block(w,h,c),w,h,0);
! 1720: },
! 1721:
! 1722: /*
! 1723: * Get a character from a TeX font, and make sure that it has
! 1724: * its metrics specified.
! 1725: */
! 1726: GetChar: function (code,font) {
! 1727: var c = jsMath.TeX[font][code];
! 1728: if (c.tclass == null) {c.tclass = font}
! 1729: if (!c.computedW) {
! 1730: c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w;
! 1731: if (c.h == null) {c.h = jsMath.defaultH}; if (c.d == null) {c.d = 0}
! 1732: c.computedW = 1;
! 1733: }
! 1734: return c;
! 1735: },
! 1736:
! 1737: /*
! 1738: * Locate the TeX delimiter character that matches a given height.
! 1739: * Return the character, font, style and actual height used.
! 1740: */
! 1741: DelimBestFit: function (H,c,font,style) {
! 1742: if (c == 0 && font == 0) return;
! 1743: var C; var h; font = jsMath.TeX.fam[font];
! 1744: var isSS = (style.charAt(1) == 'S');
! 1745: var isS = (style.charAt(0) == 'S');
! 1746: while (c != null) {
! 1747: C = jsMath.TeX[font][c];
! 1748: if (C.h == null) {C.h = jsMath.defaultH}; if (C.d == null) {C.d = 0}
! 1749: h = C.h+C.d;
! 1750: if (C.delim) {return [c,font,'',H]}
! 1751: if (isSS && .5*h >= H) {return [c,font,'SS',.5*h]}
! 1752: if (isS && .7*h >= H) {return [c,font,'S',.7*h]}
! 1753: if (h >= H || C.n == null) {return [c,font,'T',h]}
! 1754: c = C.n
! 1755: }
! 1756: },
! 1757:
! 1758: /*
! 1759: * Create the HTML needed for a stretchable delimiter of a given height,
! 1760: * either centered or not. This version uses relative placement (i.e.,
! 1761: * backspaces, not line-breaks). This works with more browsers, but
! 1762: * if the font size changes, the backspacing may not be right, so the
! 1763: * delimiters may become jagged.
! 1764: */
! 1765: DelimExtendRelative: function (H,c,font,a,nocenter) {
! 1766: var C = jsMath.TeX[font][c];
! 1767: var top = this.GetChar(C.delim.top? C.delim.top: C.delim.rep,font);
! 1768: var rep = this.GetChar(C.delim.rep,font);
! 1769: var bot = this.GetChar(C.delim.bot? C.delim.bot: C.delim.rep,font);
! 1770: var ext = jsMath.Typeset.AddClass(rep.tclass,rep.c);
! 1771: var w = rep.w; var h = rep.h+rep.d
! 1772: var y; var dx;
! 1773: if (C.delim.mid) {// braces
! 1774: var mid = this.GetChar(C.delim.mid,font);
! 1775: var n = Math.ceil((H-(top.h+top.d)-(mid.h+mid.d)-(bot.h+bot.d))/(2*(rep.h+rep.d)));
! 1776: H = 2*n*(rep.h+rep.d) + (top.h+top.d) + (mid.h+mid.d) + (bot.h+bot.d);
! 1777: if (nocenter) {y = 0} else {y = H/2+a}; var Y = y;
! 1778: var html = jsMath.HTML.Place(jsMath.Typeset.AddClass(top.tclass,top.c),0,y-top.h)
! 1779: + jsMath.HTML.Place(jsMath.Typeset.AddClass(bot.tclass,bot.c),-(top.w+bot.w)/2,y-(H-bot.d))
! 1780: + jsMath.HTML.Place(jsMath.Typeset.AddClass(mid.tclass,mid.c),-(bot.w+mid.w)/2,y-(H+mid.h-mid.d)/2);
! 1781: dx = (w-mid.w)/2; if (Math.abs(dx) < .0001) {dx = 0}
! 1782: if (dx) {html += jsMath.HTML.Spacer(dx)}
! 1783: y -= top.h+top.d + rep.h;
! 1784: for (var i = 0; i < n; i++) {html += jsMath.HTML.Place(ext,-w,y-i*h)}
! 1785: y -= H/2 - rep.h/2;
! 1786: for (var i = 0; i < n; i++) {html += jsMath.HTML.Place(ext,-w,y-i*h)}
! 1787: } else {// everything else
! 1788: var n = Math.ceil((H - (top.h+top.d) - (bot.h+bot.d))/(rep.h+rep.d));
! 1789: // make sure two-headed arrows have an extender
! 1790: if (top.h+top.d < .9*(rep.h+rep.d)) {n = Math.max(1,n)}
! 1791: H = n*(rep.h+rep.d) + (top.h+top.d) + (bot.h+bot.d);
! 1792: if (nocenter) {y = 0} else {y = H/2+a}; var Y = y;
! 1793: var html = jsMath.HTML.Place(jsMath.Typeset.AddClass(top.tclass,top.c),0,y-top.h)
! 1794: dx = (w-top.w)/2; if (Math.abs(dx) < .0001) {dx = 0}
! 1795: if (dx) {html += jsMath.HTML.Spacer(dx)}
! 1796: y -= top.h+top.d + rep.h;
! 1797: for (var i = 0; i < n; i++) {html += jsMath.HTML.Place(ext,-w,y-i*h)}
! 1798: html += jsMath.HTML.Place(jsMath.Typeset.AddClass(bot.tclass,bot.c),-(w+bot.w)/2,Y-(H-bot.d));
! 1799: }
! 1800: if (nocenter) {h = top.h} else {h = H/2+a}
! 1801: var box = new jsMath.Box('html',html,rep.w,h,H-h);
! 1802: box.bh = jsMath.TeX[font].h; box.bd = jsMath.TeX[font].d;
! 1803: return box;
! 1804: },
! 1805:
! 1806: /*
! 1807: * Create the HTML needed for a stretchable delimiter of a given height,
! 1808: * either centered or not. This version uses absolute placement (i.e.,
! 1809: * line-breaks, not backspacing). This gives more reliable results,
! 1810: * but doesn't work with all browsers.
! 1811: */
! 1812: DelimExtendAbsolute: function (H,c,font,a,nocenter) {
! 1813: var Font = jsMath.TeX[font];
! 1814: var C = Font[c];
! 1815: var top = this.GetChar(C.delim.top? C.delim.top: C.delim.rep,font);
! 1816: var rep = this.GetChar(C.delim.rep,font);
! 1817: var bot = this.GetChar(C.delim.bot? C.delim.bot: C.delim.rep,font);
! 1818:
! 1819: if (C.delim.mid) {// braces
! 1820: var mid = this.GetChar(C.delim.mid,font);
! 1821: 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)));
! 1822: H = 2*n*(rep.h+rep.d-.05) + (top.h+top.d) + (mid.h+mid.d-.05) + (bot.h+bot.d-.05);
! 1823:
! 1824: html = jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(top.tclass,top.c),0,0);
! 1825: var h = rep.h+rep.d - .05; var y = top.d-.05 + rep.h;
! 1826: var ext = jsMath.Typeset.AddClass(font,rep.c)
! 1827: for (var i = 0; i < n; i++) {html += jsMath.HTML.PlaceAbsolute(ext,0,y+i*h)}
! 1828: html += jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(mid.tclass,mid.c),0,y+n*h-rep.h+mid.h);
! 1829: y += n*h + mid.h+mid.d - .05;
! 1830: for (var i = 0; i < n; i++) {html += jsMath.HTML.PlaceAbsolute(ext,0,y+i*h)}
! 1831: html += jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(bot.tclass,bot.c),0,y+n*h-rep.h+bot.h);
! 1832: } else {// all others
! 1833: var n = Math.ceil((H - (top.h+top.d) - (bot.h+bot.d-.05))/(rep.h+rep.d-.05));
! 1834: H = n*(rep.h+rep.d-.05) + (top.h+top.d) + (bot.h+bot.d-.05);
! 1835:
! 1836: html = jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(top.tclass,top.c),0,0);
! 1837: var h = rep.h+rep.d-.05; var y = top.d-.05 + rep.h;
! 1838: var ext = jsMath.Typeset.AddClass(rep.tclass,rep.c);
! 1839: for (var i = 0; i < n; i++) {html += jsMath.HTML.PlaceAbsolute(ext,0,y+i*h)}
! 1840: html += jsMath.HTML.PlaceAbsolute(jsMath.Typeset.AddClass(bot.tclass,bot.c),0,y+n*h-rep.h+bot.h);
! 1841: }
! 1842:
! 1843: var w = top.w;
! 1844: if (nocenter) {h = top.h; y = 0} else {h = H/2 + a; y = h - top.h}
! 1845: html = jsMath.HTML.Absolute(html,w,Font.h,"none",-y,top.h);
! 1846: var box = new jsMath.Box('html',html,rep.w,h,H-h);
! 1847: box.bh = jsMath.TeX[font].h; box.bd = jsMath.TeX[font].d;
! 1848: return box;
! 1849: },
! 1850:
! 1851: /*
! 1852: * Get the HTML for a given delimiter of a given height.
! 1853: * It will return either a single character, if one exists, or the
! 1854: * more complex HTML needed for a stretchable delimiter.
! 1855: */
! 1856: Delimiter: function (H,delim,style,nocenter) {
! 1857: var size = 4; //### pass this?
! 1858: var TeX = jsMath.Typeset.TeX(style,size);
! 1859: var CFSH = this.DelimBestFit(H,(delim&0xFF000)>>12,(delim&0xF00000)>>20,style);
! 1860: if (CFSH == null || CFSH[3] < H)
! 1861: {CFSH = this.DelimBestFit(H,(delim&0xFF),(delim&0xF00)>>8,style)}
! 1862: if (CFSH == null) {return this.Space(TeX.nulldelimiterspace)}
! 1863: if (CFSH[2] == '')
! 1864: {return this.DelimExtend(H,CFSH[0],CFSH[1],TeX.axis_height,nocenter)}
! 1865: box = jsMath.Box.TeX(CFSH[0],CFSH[1],CFSH[2],size).Styled();
! 1866: if (nocenter) {box.y = -jsMath.TeX[CFSH[1]].dh*TeX.scale}
! 1867: else {box.y = -((box.h+box.d)/2 - box.d - TeX.axis_height)}
! 1868: if (Math.abs(box.y) < .0001) {box.y = 0}
! 1869: if (box.y) {box = jsMath.Box.SetList([box],CFSH[2],size)}
! 1870: return box;
! 1871: },
! 1872:
! 1873: /*
! 1874: * Get a character by its TeX charcode, and make sure its width
! 1875: * is specified.
! 1876: */
! 1877: GetCharCode: function (code) {
! 1878: var font = jsMath.TeX.fam[(code&0xF00)>>8];
! 1879: var Font = jsMath.TeX[font];
! 1880: var c = Font[code & 0xFF];
! 1881: if (c.w == null) {c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w}
! 1882: if (c.font == null) {c.font = font}
! 1883: return c;
! 1884: },
! 1885:
! 1886: /*
! 1887: * Add the class to the html, and use the font if there isn't one
! 1888: * specified already
! 1889: */
! 1890:
! 1891: AddClass: function (tclass,html,font) {
! 1892: if (tclass == null) {tclass = font}
! 1893: return jsMath.Typeset.AddClass(tclass,html);
! 1894: },
! 1895:
! 1896: /*
! 1897: * Create a horizontally stretchable "delimiter" (like over- and
! 1898: * underbraces).
! 1899: */
! 1900: //### Add size?
! 1901: Leaders: function (W,leader) {
! 1902: var h; var d; var w; var html; var font;
! 1903: if (leader.lmid) {// braces
! 1904: font = jsMath.TeX.fam[(leader.left & 0xF00) >> 8];
! 1905: var left = this.GetCharCode(leader.left);
! 1906: var right = this.GetCharCode(leader.right);
! 1907: var lmid = this.GetCharCode(leader.lmid);
! 1908: var rmid = this.GetCharCode(leader.rmid);
! 1909: w = (W - left.w - right.w - lmid.w - rmid.w)/2 - .1; h = .4; d = .3;
! 1910: if (w < 0) {w = 0}
! 1911: html = this.AddClass(left.tclass,left.c,left.font)
! 1912: + jsMath.HTML.Rule(w,left.h)
! 1913: + this.AddClass(lmid.tclass,lmid.c+rmid.c,lmid.font)
! 1914: + jsMath.HTML.Rule(w,right.h)
! 1915: + this.AddClass(right.tclass,right.c,right.font);
! 1916: } else { //arrows
! 1917: font = jsMath.TeX.fam[(leader.rep &0xF00) >> 8];
! 1918: var left = this.GetCharCode(leader.left? leader.left: leader.rep);
! 1919: var rep = this.GetCharCode(leader.rep);
! 1920: var right = this.GetCharCode(leader.right? leader.right: leader.rep);
! 1921: var n = Math.ceil((W - left.w - right.w + .4)/(rep.w - .3));
! 1922: w = (W - left.w - right.w + .4 - n*(rep.w - .3));
! 1923: if (leader.left) {h = left.h; d = left.d} else {h = right.h; d = right.d}
! 1924: if (d == null) {d = 0}; if (h == null) {h = 0}
! 1925: var html = this.AddClass(left.tclass,left.c,left.font); var m = Math.floor(n/2);
! 1926: var ext = jsMath.HTML.Place(rep.c,-.3,0);
! 1927: var ehtml = ''; for (var i = 0; i < m; i++) {ehtml += ext};
! 1928: html += this.AddClass(rep.tclass,ehtml,rep.font) + jsMath.HTML.Spacer(w);
! 1929: ehtml = ''; for (var i = m; i < n; i++) {ehtml += ext};
! 1930: html += this.AddClass(rep.tclass,ehtml,rep.font);
! 1931: if (jsMath.msieFontBug) {html += '<SPAN STYLE="display: none">x</SPAN>'}
! 1932: html += jsMath.HTML.Place(this.AddClass(right.tclass,right.c,right.font),-.4,0);
! 1933: }
! 1934: w = jsMath.EmBoxFor(html).w;
! 1935: if (w != W) {
! 1936: w = jsMath.HTML.Spacer((W-w)/2);
! 1937: html = w + html + w;
! 1938: }
! 1939: var box = new jsMath.Box('html',html,W,h,d);
! 1940: box.bh = jsMath.TeX[font].h; box.bd = jsMath.TeX[font].d;
! 1941: return box;
! 1942: },
! 1943:
! 1944: /*
! 1945: * Create the HTML for an alignment (e.g., array or matrix)
! 1946: * Since the widths are not really accurate (they are based on pixel
! 1947: * widths not the sub-pixel widths of the actual characters), there
! 1948: * is some drift involved. We lay out the table column by column
! 1949: * to help reduce the problem.
! 1950: *
! 1951: * ### still need to allow users to specify row and column attributes,
! 1952: * and do things like \span and \multispan ###
! 1953: */
! 1954: LayoutRelative: function (size,table,align,cspacing) {
! 1955: if (align == null) {align = []}
! 1956: if (cspacing == null) {cspacing = []}
! 1957:
! 1958: // get row and column maximum dimensions
! 1959: var scale = jsMath.sizes[size]/100;
! 1960: var W = []; var H = []; var D = [];
! 1961: var unset = -1000; var bh = unset; var bd = unset;
! 1962: var i; var j; var row;
! 1963: for (i = 0; i < table.length; i++) {
! 1964: row = table[i]; H[i] = jsMath.h*scale; D[i] = jsMath.d*scale;
! 1965: for (j = 0; j < row.length; j++) {
! 1966: row[j] = row[j].Remeasured();
! 1967: if (row[j].h > H[i]) {H[i] = row[j].h}
! 1968: if (row[j].d > D[i]) {D[i] = row[j].d}
! 1969: if (j >= W.length) {W[j] = row[j].w}
! 1970: else if (row[j].w > W[j]) {W[j] = row[j].w}
! 1971: if (row[j].bh > bh) {bh = row[j].bh}
! 1972: if (row[j].bd > bd) {bd = row[j].bd}
! 1973: }
! 1974: }
! 1975: if (bh == unset) {bh = 0}; if (bd == unset) {bd = 0}
! 1976:
! 1977: // lay out the columns
! 1978: var HD = (jsMath.hd-.01)*scale;
! 1979: var html = ''; var pW = 0; var cW = 0;
! 1980: var w; var h; var y;
! 1981: var box; var mlist; var entry;
! 1982: for (j = 0; j < W.length; j++) {
! 1983: mlist = []; y = -H[0]; pW = 0;
! 1984: for (i = 0; i < table.length; i++) {
! 1985: entry = table[i][j];
! 1986: if (entry && entry.format != 'null') {
! 1987: if (align[j] == 'l') {w = 0} else
! 1988: if (align[j] == 'r') {w = W[j] - entry.w} else
! 1989: {w = (W[j] - entry.w)/2}
! 1990: entry.x = w - pW; pW = entry.w + w; entry.y = y;
! 1991: mlist[mlist.length] = entry;
! 1992: }
! 1993: if (i == table.length-1) {y -= D[i]}
! 1994: else {y -= Math.max(HD,D[i]+H[i+1]) + scale/10}
! 1995: }
! 1996: if (cspacing[j] == null) cspacing[j] = scale;
! 1997: if (mlist.length > 0) {
! 1998: box = jsMath.Box.SetList(mlist,'T',size);
! 1999: html += jsMath.HTML.Place(box.html,cW,0);
! 2000: cW = W[j] - box.w + cspacing[j];
! 2001: } else {cW += cspacing[j]}
! 2002: }
! 2003:
! 2004: // get the full width and height
! 2005: w = -cspacing[W.length-1]; y = (H.length-1)*scale/10;
! 2006: for (i = 0; i < W.length; i++) {w += W[i] + cspacing[i]}
! 2007: for (i = 0; i < H.length; i++) {y += Math.max(HD,H[i]+D[i])}
! 2008: h = y/2 + jsMath.TeX.axis_height; var d = y-h;
! 2009:
! 2010: // adjust the final row width, and vcenter the table
! 2011: // (add 1/6em at each side for the \,)
! 2012: html += jsMath.HTML.Spacer(cW-cspacing[W.length-1] + scale/6);
! 2013: html = jsMath.HTML.Place(html,scale/6,h);
! 2014: box = new jsMath.Box('html',html,w+scale/3,h,d);
! 2015: box.bh = bh; box.bd = bd;
! 2016: return box;
! 2017: },
! 2018:
! 2019: /*
! 2020: * Create the HTML for an alignment (e.g., array or matrix)
! 2021: * Use absolute position for elements in the array.
! 2022: *
! 2023: * ### still need to allow users to specify row and column attributes,
! 2024: * and do things like \span and \multispan ###
! 2025: */
! 2026: LayoutAbsolute: function (size,table,align,cspacing) {
! 2027: if (align == null) {align = []}
! 2028: if (cspacing == null) {cspacing = []}
! 2029:
! 2030: // get row and column maximum dimensions
! 2031: var scale = jsMath.sizes[size]/100;
! 2032: var HD = (jsMath.hd-.01)*scale;
! 2033: var W = []; var H = []; var D = [];
! 2034: var w = 0; var h; var x; var y;
! 2035: var i; var j; var row;
! 2036: for (i = 0; i < table.length; i++) {
! 2037: row = table[i];
! 2038: H[i] = jsMath.h*scale; D[i] = jsMath.d*scale;
! 2039: for (j = 0; j < row.length; j++) {
! 2040: row[j] = row[j].Remeasured();
! 2041: if (row[j].h > H[i]) {H[i] = row[j].h}
! 2042: if (row[j].d > D[i]) {D[i] = row[j].d}
! 2043: if (j >= W.length) {W[j] = row[j].w}
! 2044: else if (row[j].w > W[j]) {W[j] = row[j].w}
! 2045: }
! 2046: }
! 2047:
! 2048: // get the height and depth of the centered table
! 2049: y = (H.length-1)*scale/6;
! 2050: for (i = 0; i < H.length; i++) {y += Math.max(HD,H[i]+D[i])}
! 2051: h = y/2 + jsMath.TeX.axis_height; var d = y - h;
! 2052:
! 2053: // lay out the columns
! 2054: var html = ''; var entry; w = scale/6;
! 2055: for (j = 0; j < W.length; j++) {
! 2056: y = H[0]-h;
! 2057: for (i = 0; i < table.length; i++) {
! 2058: entry = table[i][j];
! 2059: if (entry && entry.format != 'null') {
! 2060: if (align[j] == 'l') {x = 0} else
! 2061: if (align[j] == 'r') {x = W[j] - entry.w} else
! 2062: {x = (W[j] - entry.w)/2}
! 2063: html += jsMath.HTML.PlaceAbsolute(entry.html,w+x,
! 2064: y-Math.max(0,entry.bh-jsMath.h*scale));
! 2065: }
! 2066: if (i == table.length-1) {y += D[i]}
! 2067: else {y += Math.max(HD,D[i]+H[i+1]) + scale/6}
! 2068: }
! 2069: if (cspacing[j] == null) cspacing[j] = scale;
! 2070: w += W[j] + cspacing[j];
! 2071: }
! 2072:
! 2073: // get the full width
! 2074: w = -cspacing[W.length-1]+scale/3;
! 2075: for (i = 0; i < W.length; i++) {w += W[i] + cspacing[i]}
! 2076:
! 2077: html = jsMath.HTML.Spacer(scale/6)+html+jsMath.HTML.Spacer(scale/6);
! 2078: if (jsMath.spanHeightVaries) {y = h-jsMath.h} else {y = 0}
! 2079: html = jsMath.HTML.Absolute(html,w,h+d,d,y,H[0]);
! 2080: var box = new jsMath.Box('html',html,w+scale/3,h,d);
! 2081: return box;
! 2082: },
! 2083:
! 2084: /*
! 2085: * Look for math within \hbox and other non-math text
! 2086: */
! 2087: InternalMath: function (text,size) {
! 2088: if (!text.match(/\$|\\\(/)) {return this.Text(text,'nonmath','T',size).Styled()}
! 2089:
! 2090: var i = 0; var k = 0; var c; var match = '';
! 2091: var mlist = []; var parse; var html; var box;
! 2092: while (i < text.length) {
! 2093: c = text.charAt(i++);
! 2094: if (c == '$') {
! 2095: if (match == '$') {
! 2096: parse = jsMath.Parse(text.slice(k,i-1),null,size);
! 2097: if (parse.error) {
! 2098: mlist[mlist.length] = this.Text(parse.error,'error','T',size,1,1);
! 2099: } else {
! 2100: parse.Atomize();
! 2101: mlist[mlist.length] = parse.mlist.Typeset('T',size).Styled();
! 2102: }
! 2103: match = ''; k = i;
! 2104: } else {
! 2105: mlist[mlist.length] = this.Text(text.slice(k,i-1),'nonmath','T',size,1,1);
! 2106: match = '$'; k = i;
! 2107: }
! 2108: } else if (c == '\\') {
! 2109: c = text.charAt(i++);
! 2110: if (c == '(' && match == '') {
! 2111: mlist[mlist.length] = this.Text(text.slice(k,i-2),'nonmath','T',size,1,1);
! 2112: match = ')'; k = i;
! 2113: } else if (c == ')' && match == ')') {
! 2114: parse = jsMath.Parse(text.slice(k,i-2),null,size);
! 2115: if (parse.error) {
! 2116: mlist[mlist.length] = this.Text(parse.error,'error','T',size,1,1);
! 2117: } else {
! 2118: parse.Atomize();
! 2119: mlist[mlist.length] = parse.mlist.Typeset('T',size).Styled();
! 2120: }
! 2121: match = ''; k = i;
! 2122: }
! 2123: }
! 2124: }
! 2125: mlist[mlist.length] = this.Text(text.slice(k),'nonmath','T',size,1,1);
! 2126: return this.SetList(mlist,'T',size);
! 2127: },
! 2128:
! 2129: /*
! 2130: * Convert an abitrary box to a typeset box. I.e., make an
! 2131: * HTML version of the contents of the box, at its desired (x,y)
! 2132: * position.
! 2133: */
! 2134: Set: function (box,style,size,addstyle) {
! 2135: if (box) {
! 2136: if (box.type == 'typeset') {return box}
! 2137: if (box.type == 'mlist') {
! 2138: box.mlist.Atomize(style,size);
! 2139: return box.mlist.Typeset(style,size);
! 2140: }
! 2141: if (box.type == 'text') {
! 2142: box = this.Text(box.text,box.tclass,style,size,box.ascend,box.descend);
! 2143: if (addstyle != 0) {box.Styled()}
! 2144: return box;
! 2145: }
! 2146: box = this.TeX(box.c,box.font,style,size);
! 2147: if (addstyle != 0) {box.Styled()}
! 2148: return box;
! 2149: }
! 2150: return jsMath.Box.Null;
! 2151: },
! 2152:
! 2153: /*
! 2154: * Convert a list of boxes to a single typeset box. I.e., finalize
! 2155: * the HTML for the list of boxes, properly spaced and positioned.
! 2156: */
! 2157: SetList: function (boxes,style,size) {
! 2158: var mlist = []; var box;
! 2159: for (var i = 0; i < boxes.length; i++) {
! 2160: box = boxes[i];
! 2161: if (box.type == 'typeset') {box = jsMath.mItem.Typeset(box)}
! 2162: mlist[mlist.length] = box;
! 2163: }
! 2164: var typeset = new jsMath.Typeset(mlist);
! 2165: return typeset.Typeset(style,size);
! 2166: }
! 2167:
! 2168: });
! 2169:
! 2170:
! 2171: jsMath.Package(jsMath.Box,{
! 2172:
! 2173: /*
! 2174: * Add the class and style to a text box (i.e., finalize the
! 2175: * unpositioned HTML for the box).
! 2176: */
! 2177: Styled: function () {
! 2178: if (this.format == 'text') {
! 2179: this.html = jsMath.Typeset.AddClass(this.tclass,this.html);
! 2180: this.html = jsMath.Typeset.AddStyle(this.style,this.size,this.html);
! 2181: delete this.tclass; delete this.style;
! 2182: this.format = 'html';
! 2183: }
! 2184: return this;
! 2185: },
! 2186:
! 2187: /*
! 2188: * Recompute the box width to make it more accurate.
! 2189: */
! 2190: Remeasured: function () {
! 2191: if (this.w > 0) {
! 2192: if (!jsMath.spanHeightVaries || !this.html.match(/position: ?absolute/))
! 2193: {this.w = jsMath.EmBoxFor(this.html).w}
! 2194: }
! 2195: return this;
! 2196: }
! 2197:
! 2198: });
! 2199:
! 2200:
! 2201: /***************************************************************************/
! 2202:
! 2203: /*
! 2204: * mItems are the buiulding blocks of mLists (math lists) used to
! 2205: * store the information about a mathematical expression. These are
! 2206: * basically the items listed in the TeXbook in Appendix G (plus some
! 2207: * minor extensions).
! 2208: */
! 2209: jsMath.mItem = function (type,def) {
! 2210: this.type = type;
! 2211: jsMath.Add(this,def);
! 2212: }
! 2213:
! 2214: jsMath.Add(jsMath.mItem,{
! 2215:
! 2216: /*
! 2217: * a general atom (given a nucleus for the atom)
! 2218: */
! 2219: Atom: function (type,nucleus) {
! 2220: return new jsMath.mItem(type,{atom: 1, nuc: nucleus});
! 2221: },
! 2222:
! 2223: /*
! 2224: * An atom whose nucleus is a piece of text, in a given
! 2225: * class, with a given additional height and depth
! 2226: */
! 2227: TextAtom: function (type,text,tclass,a,d) {
! 2228: var atom = new jsMath.mItem(type,{
! 2229: atom: 1,
! 2230: nuc: {
! 2231: type: 'text',
! 2232: text: text,
! 2233: tclass: tclass
! 2234: }
! 2235: });
! 2236: if (a != null) {atom.nuc.ascend = a}
! 2237: if (d != null) {atom.nuc.descend = d}
! 2238: return atom;
! 2239: },
! 2240:
! 2241: /*
! 2242: * An atom whose nucleus is a TeX character in a specific font
! 2243: */
! 2244: TeXAtom: function (type,c,font) {
! 2245: return new jsMath.mItem(type,{
! 2246: atom: 1,
! 2247: nuc: {
! 2248: type: 'TeX',
! 2249: c: c,
! 2250: font: font
! 2251: }
! 2252: });
! 2253: },
! 2254:
! 2255: /*
! 2256: * A generalized fraction atom, with given delimiters, rule
! 2257: * thickness, and a numerator and denominator.
! 2258: */
! 2259: Fraction: function (name,num,den,thickness,left,right) {
! 2260: return new jsMath.mItem('fraction',{
! 2261: from: name, num: num, den: den,
! 2262: thickness: thickness, left: left, right: right
! 2263: });
! 2264: },
! 2265:
! 2266: /*
! 2267: * An atom that inserts some glue
! 2268: */
! 2269: Space: function (w) {return new jsMath.mItem('space',{w: w})},
! 2270:
! 2271: /*
! 2272: * An atom that contains a typeset box (like an hbox or vbox)
! 2273: */
! 2274: Typeset: function (box) {return new jsMath.mItem('box',{nuc: box})},
! 2275:
! 2276: /*
! 2277: * An atom that contains some finished HTML (acts like a typeset box)
! 2278: */
! 2279: HTML: function (html) {return new jsMath.mItem('html',{html: html})}
! 2280:
! 2281: });
! 2282:
! 2283: /***************************************************************************/
! 2284:
! 2285: /*
! 2286: * mLists are lists of mItems, and encode the contents of
! 2287: * mathematical expressions and sub-expressions. They act as
! 2288: * the expression "stack" as the mathematics is parsed, and
! 2289: * contain some state information, like the position of the
! 2290: * most recent open paren and \over command, and the current font.
! 2291: */
! 2292: jsMath.mList = function (list,font,size,style) {
! 2293: if (list) {this.mlist = list} else {this.mlist = []}
! 2294: if (style == null) {style = 'T'}; if (size == null) {size = 4}
! 2295: this.data = {openI: null, overI: null, overF: null,
! 2296: font: font, size: size, style: style};
! 2297: this.init = {size: size, style: style};
! 2298: }
! 2299:
! 2300: jsMath.Package(jsMath.mList,{
! 2301:
! 2302: /*
! 2303: * Add an mItem to the list
! 2304: */
! 2305: Add: function (box) {return (this.mlist[this.mlist.length] = box)},
! 2306:
! 2307: /*
! 2308: * Get the i-th mItem from the list
! 2309: */
! 2310: Get: function (i) {return this.mlist[i]},
! 2311:
! 2312: /*
! 2313: * Get the length of the list
! 2314: */
! 2315: Length: function() {return this.mlist.length},
! 2316:
! 2317: /*
! 2318: * Get the tail mItem of the list
! 2319: */
! 2320: Last: function () {
! 2321: if (this.mlist.length == 0) {return null}
! 2322: return this.mlist[this.mlist.length-1]
! 2323: },
! 2324:
! 2325: /*
! 2326: * Get a sublist of an mList
! 2327: */
! 2328: Range: function (i,j) {
! 2329: if (j == null) {j = this.mlist.length}
! 2330: return new jsMath.mList(this.mlist.slice(i,j+1));
! 2331: },
! 2332:
! 2333: /*
! 2334: * Remove a range of mItems from the list.
! 2335: */
! 2336: Delete: function (i,j) {
! 2337: if (j == null) {j = i}
! 2338: if (this.mlist.splice) {this.mlist.splice(i,j-i+1)} else {
! 2339: var mlist = [];
! 2340: for (var k = 0; k < this.mlist.length; k++)
! 2341: {if (k < i || k > j) {mlist[mlist.length] = this.mlist[k]}}
! 2342: this.mlist = mlist;
! 2343: }
! 2344: },
! 2345:
! 2346: /*
! 2347: * Add an open brace and maintain the stack information
! 2348: * about the previous open brace so we can recover it
! 2349: * when this one os closed.
! 2350: */
! 2351: Open: function (left) {
! 2352: var box = this.Add(new jsMath.mItem('boundary',{data: this.data}));
! 2353: var olddata = this.data;
! 2354: this.data = {}; for (var i in olddata) {this.data[i] = olddata[i]}
! 2355: delete this.data.overI; delete this.data.overF;
! 2356: this.data.openI = this.mlist.length-1;
! 2357: if (left != null) {box.left = left}
! 2358: return box;
! 2359: },
! 2360:
! 2361: /*
! 2362: * Attempt to close a brace. Recover the stack information
! 2363: * about previous open braces and \over commands. If there was an
! 2364: * \over (or \above, etc) in this set of braces, create a fraction
! 2365: * atom from the two halves, otherwise create an inner or ord
! 2366: * from the contents of the braces.
! 2367: * Remove the braced material from the list and add the newly
! 2368: * created atom (the fraction, inner or ord).
! 2369: */
! 2370: Close: function (right) {
! 2371: if (right != null) {right = new jsMath.mItem('boundary',{right: right})}
! 2372: var atom; var open = this.data.openI;
! 2373: var over = this.data.overI; var from = this.data.overF;
! 2374: this.data = this.mlist[open].data;
! 2375: if (over) {
! 2376: atom = jsMath.mItem.Fraction(from.name,
! 2377: {type: 'mlist', mlist: this.Range(open+1,over-1)},
! 2378: {type: 'mlist', mlist: this.Range(over)},
! 2379: from.thickness,from.left,from.right);
! 2380: if (right) {
! 2381: var mlist = new jsMath.mList([this.mlist[open],atom,right]);
! 2382: atom = jsMath.mItem.Atom('inner',{type: 'mlist', mlist: mlist});
! 2383: }
! 2384: } else {
! 2385: var openI = open+1; if (right) {this.Add(right); openI--}
! 2386: atom = jsMath.mItem.Atom((right)?'inner':'ord',
! 2387: {type: 'mlist', mlist: this.Range(openI)});
! 2388: }
! 2389: this.Delete(open,this.Length());
! 2390: return this.Add(atom);
! 2391: },
! 2392:
! 2393: /*
! 2394: * Create a generalized fraction from an mlist that
! 2395: * contains an \over (or \above, etc).
! 2396: */
! 2397: Over: function () {
! 2398: var over = this.data.overI; var from = this.data.overF
! 2399: var atom = jsMath.mItem.Fraction(from.name,
! 2400: {type: 'mlist', mlist: this.Range(open+1,over-1)},
! 2401: {type: 'mlist', mlist: this.Range(over)},
! 2402: from.thickness,from.left,from.right);
! 2403: this.mlist = [atom];
! 2404: },
! 2405:
! 2406: /*
! 2407: * Take a raw mList (that has been produced by parsing some TeX
! 2408: * expression), and perform the modifications outlined in
! 2409: * Appendix G of the TeXbook.
! 2410: */
! 2411: Atomize: function (style,size) {
! 2412: var mitem; var prev = '';
! 2413: this.style = style; this.size = size;
! 2414: for (var i = 0; i < this.mlist.length; i++) {
! 2415: mitem = this.mlist[i]; mitem.delta = 0;
! 2416: if (mitem.type == 'choice')
! 2417: {this.mlist = this.Atomize.choice(this.style,mitem,i,this.mlist); i--}
! 2418: else if (this.Atomize[mitem.type]) {
! 2419: var f = this.Atomize[mitem.type]; // Opera needs separate name
! 2420: f(this.style,this.size,mitem,prev,this,i);
! 2421: }
! 2422: prev = mitem;
! 2423: }
! 2424: if (mitem && mitem.type == 'bin') {mitem.type = 'ord'}
! 2425: if (this.mlist.length >= 2 && mitem.type == 'boundary' &&
! 2426: this.mlist[0].type == 'boundary') {this.AddDelimiters(style,size)}
! 2427: },
! 2428:
! 2429: /*
! 2430: * For a list that has boundary delimiters as its first and last
! 2431: * entries, we replace the boundary atoms by open and close
! 2432: * atoms whose nuclei are the specified delimiters properly sized
! 2433: * for the contents of the list. (Rule 19)
! 2434: */
! 2435: AddDelimiters: function(style,size) {
! 2436: var unset = -10000; var h = unset; var d = unset;
! 2437: for (var i = 0; i < this.mlist.length; i++) {
! 2438: mitem = this.mlist[i];
! 2439: if (mitem.atom || mitem.type == 'box') {
! 2440: h = Math.max(h,mitem.nuc.h+mitem.nuc.y);
! 2441: d = Math.max(d,mitem.nuc.d-mitem.nuc.y);
! 2442: }
! 2443: }
! 2444: var TeX = jsMath.TeX; var a = jsMath.Typeset.TeX(style,size).axis_height;
! 2445: var delta = Math.max(h-a,d+a);
! 2446: var H = Math.max(Math.floor(TeX.integer*delta/500)*TeX.delimiterfactor,
! 2447: TeX.integer*(2*delta-TeX.delimitershortfall))/TeX.integer;
! 2448: var left = this.mlist[0]; var right = this.mlist[this.mlist.length-1];
! 2449: left.nuc = jsMath.Box.Delimiter(H,left.left,style);
! 2450: right.nuc = jsMath.Box.Delimiter(H,right.right,style);
! 2451: left.type = 'open'; left.atom = 1; delete left.left;
! 2452: right.type = 'close'; right.atom = 1; delete right.right;
! 2453: },
! 2454:
! 2455: /*
! 2456: * Typeset a math list to produce final HTML for the list.
! 2457: */
! 2458: Typeset: function (style,size) {
! 2459: var typeset = new jsMath.Typeset(this.mlist);
! 2460: return typeset.Typeset(style,size);
! 2461: }
! 2462:
! 2463: });
! 2464:
! 2465:
! 2466: /*
! 2467: * These routines implement the main rules given in Appendix G of the
! 2468: * TeXbook
! 2469: */
! 2470:
! 2471: jsMath.Add(jsMath.mList.prototype.Atomize,{
! 2472:
! 2473: /*
! 2474: * Handle a 4-way choice atom. (Rule 4)
! 2475: */
! 2476: choice: function (style,mitem,i,mlist) {
! 2477: if (style.charAt(style.length-1) == "'") {style = style.slice(0,style.length-1)}
! 2478: var nlist = []; var M = mitem[style]; if (!M) {M = {type: 'mlist', mlist: []}}
! 2479: if (M.type == 'mlist') {
! 2480: M = M.mlist.mlist;
! 2481: for (var k = 0; k < i; k++) {nlist[k] = mlist[k]}
! 2482: for (k = 0; k < M.length; k++) {nlist[i+k] = M[k]}
! 2483: for (k = i+1; k < mlist.length; k++) {nlist[nlist.length] = mlist[k]}
! 2484: return nlist;
! 2485: } else {
! 2486: mlist[i] = jsMath.mItem.Atom('ord',M);
! 2487: return mlist;
! 2488: }
! 2489: },
! 2490:
! 2491: /*
! 2492: * Handle \displaystyle, \textstyle, etc.
! 2493: */
! 2494: style: function (style,size,mitem,prev,mlist) {
! 2495: mlist.style = mitem.style;
! 2496: },
! 2497:
! 2498: /*
! 2499: * Handle \tiny, \small, etc.
! 2500: */
! 2501: size: function (style,size,mitem,prev,mlist) {
! 2502: mlist.size = mitem.size;
! 2503: },
! 2504:
! 2505: /*
! 2506: * Create empty boxes of the proper sizes for the various
! 2507: * phantom-type commands
! 2508: */
! 2509: phantom: function (style,size,mitem) {
! 2510: var box = mitem.nuc = jsMath.Box.Set(mitem.phantom,style,size);
! 2511: if (mitem.h) {box.Remeasured(); box.html = jsMath.HTML.Spacer(box.w)}
! 2512: else {box.html = '', box.w = 0}
! 2513: if (!mitem.v) {box.h = box.d = 0}
! 2514: box.bd = box.bh = 0;
! 2515: delete mitem.phantom;
! 2516: mitem.type = 'box';
! 2517: },
! 2518:
! 2519: /*
! 2520: * Create a box of zero height and depth containing the
! 2521: * contents of the atom
! 2522: */
! 2523: smash: function (style,size,mitem) {
! 2524: var box = mitem.nuc = jsMath.Box.Set(mitem.smash,style,size).Remeasured();
! 2525: box.h = box.d = box.bd = box.bh = 0;
! 2526: delete mitem.smash;
! 2527: mitem.type = 'box';
! 2528: },
! 2529:
! 2530: /*
! 2531: * Move a box up or down vertically
! 2532: */
! 2533: raise: function (style,size,mitem) {
! 2534: mitem.nuc = jsMath.Box.Set(mitem.nuc,style,size);
! 2535: var y = mitem.raise;
! 2536: mitem.nuc.html = jsMath.HTML.Place(mitem.nuc.html,0,y);
! 2537: mitem.nuc.h += y; mitem.nuc.d -= y;
! 2538: mitem.type = 'ord'; mitem.atom = 1;
! 2539: },
! 2540:
! 2541: /*
! 2542: * Hide the size of a box so that it laps to the left or right, or
! 2543: * up or down.
! 2544: */
! 2545: lap: function (style,size,mitem) {
! 2546: var box = jsMath.Box.Set(mitem.nuc,style,size).Remeasured();
! 2547: var mlist = [box];
! 2548: if (mitem.lap == 'llap') {box.x = -box.w} else
! 2549: if (mitem.lap == 'rlap') {mlist[1] = jsMath.mItem.Space(-box.w)} else
! 2550: if (mitem.lap == 'ulap') {box.y = box.d; box.h = box.d = 0} else
! 2551: if (mitem.lap == 'dlap') {box.y = -box.h; box.h = box.d = 0}
! 2552: mitem.nuc = jsMath.Box.SetList(mlist,style,size);
! 2553: if (mitem.lap == 'ulap' || mitem.lap == 'dlap') {mitem.nuc.h = mitem.nuc.d = 0}
! 2554: mitem.type = 'box'; delete mitem.atom;
! 2555: },
! 2556:
! 2557: /*
! 2558: * Handle a Bin atom. (Rule 5)
! 2559: */
! 2560: bin: function (style,size,mitem,prev) {
! 2561: if (prev) {
! 2562: var type = prev.type;
! 2563: if (type == 'bin' || type == 'op' || type == 'rel' ||
! 2564: type == 'open' || type == 'punct' || type == '' ||
! 2565: (type == 'boundary' && prev.left != '')) {mitem.type = 'ord'}
! 2566: } else {mitem.type = 'ord'}
! 2567: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2568: },
! 2569:
! 2570: /*
! 2571: * Handle a Rel atom. (Rule 6)
! 2572: */
! 2573: rel: function (style,size,mitem,prev) {
! 2574: if (prev.type == 'bin') {prev.type = 'ord'}
! 2575: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2576: },
! 2577:
! 2578: /*
! 2579: * Handle a Close atom. (Rule 6)
! 2580: */
! 2581: close: function (style,size,mitem,prev) {
! 2582: if (prev.type == 'bin') {prev.type = 'ord'}
! 2583: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2584: },
! 2585:
! 2586: /*
! 2587: * Handle a Punct atom. (Rule 6)
! 2588: */
! 2589: punct: function (style,size,mitem,prev) {
! 2590: if (prev.type == 'bin') {prev.type = 'ord'}
! 2591: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2592: },
! 2593:
! 2594: /*
! 2595: * Handle an Open atom. (Rule 7)
! 2596: */
! 2597: open: function (style,size,mitem) {
! 2598: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2599: },
! 2600:
! 2601: /*
! 2602: * Handle an Inner atom. (Rule 7)
! 2603: */
! 2604: inner: function (style,size,mitem) {
! 2605: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2606: },
! 2607:
! 2608: /*
! 2609: * Handle a Vcent atom. (Rule 8)
! 2610: */
! 2611: vcenter: function (style,size,mitem) {
! 2612: var box = jsMath.Box.Set(mitem.nuc,style,size);
! 2613: var TeX = jsMath.Typeset.TeX(style,size);
! 2614: box.y = TeX.axis_height - (box.h-box.d)/2;
! 2615: mitem.nuc = box; mitem.type = 'ord';
! 2616: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2617: },
! 2618:
! 2619: /*
! 2620: * Handle an Over atom. (Rule 9)
! 2621: */
! 2622: overline: function (style,size,mitem) {
! 2623: var TeX = jsMath.Typeset.TeX(style,size);
! 2624: var box = jsMath.Box.Set(mitem.nuc,jsMath.Typeset.PrimeStyle(style),size).Remeasured();
! 2625: var t = TeX.default_rule_thickness;
! 2626: var rule = jsMath.Box.Rule(box.w,t);
! 2627: rule.x = -rule.w; rule.y = box.h + 3*t;
! 2628: mitem.nuc = jsMath.Box.SetList([box,rule],style,size);
! 2629: mitem.nuc.h += t;
! 2630: mitem.type = 'ord';
! 2631: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2632: },
! 2633:
! 2634: /*
! 2635: * Handle an Under atom. (Rule 10)
! 2636: */
! 2637: underline: function (style,size,mitem) {
! 2638: var TeX = jsMath.Typeset.TeX(style,size);
! 2639: var box = jsMath.Box.Set(mitem.nuc,jsMath.Typeset.PrimeStyle(style),size).Remeasured();
! 2640: var t = TeX.default_rule_thickness;
! 2641: var rule = jsMath.Box.Rule(box.w,t);
! 2642: rule.x = -rule.w; rule.y = -box.d - 3*t - t;
! 2643: mitem.nuc = jsMath.Box.SetList([box,rule],style,size);
! 2644: mitem.nuc.d += t;
! 2645: mitem.type = 'ord';
! 2646: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2647: },
! 2648:
! 2649: /*
! 2650: * Handle a Rad atom. (Rule 11 plus stuff for \root..\of)
! 2651: */
! 2652: radical: function (style,size,mitem) {
! 2653: var TeX = jsMath.Typeset.TeX(style,size);
! 2654: var Cp = jsMath.Typeset.PrimeStyle(style);
! 2655: var box = jsMath.Box.Set(mitem.nuc,Cp,size).Remeasured();
! 2656: var t = TeX.default_rule_thickness;
! 2657: var p = t; if (style == 'D' || style == "D'") {p = TeX.x_height}
! 2658: var r = t + p/4;
! 2659: var surd = jsMath.Box.Delimiter(box.h+box.d+r+t,0x270370,style,1);
! 2660: t = surd.h; // thickness of rule is height of surd character
! 2661: if (surd.d > box.h+box.d+r) {r = (r+surd.d-box.h-box.d)/2}
! 2662: surd.y = box.h+r;
! 2663: var rule = jsMath.Box.Rule(box.w,t);
! 2664: rule.y = surd.y-t/2; rule.h += 3*t/2; box.x = -box.w;
! 2665: var Cr = jsMath.Typeset.UpStyle(jsMath.Typeset.UpStyle(style));
! 2666: var root = jsMath.Box.Set(mitem.root,Cr,size).Remeasured();
! 2667: if (mitem.root) {
! 2668: root.y = .55*(box.h+box.d+3*t+r)-box.d; surd.x = -(11/18)*surd.w;
! 2669: root.x = Math.max((11/18)*surd.w - root.w, 0);
! 2670: }
! 2671: mitem.nuc = jsMath.Box.SetList([root,surd,rule,box],style,size);
! 2672: mitem.type = 'ord';
! 2673: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2674: },
! 2675:
! 2676: /*
! 2677: * Handle an Acc atom. (Rule 12)
! 2678: */
! 2679: accent: function (style,size,mitem) {
! 2680: var TeX = jsMath.Typeset.TeX(style,size);
! 2681: var Cp = jsMath.Typeset.PrimeStyle(style);
! 2682: var box = jsMath.Box.Set(mitem.nuc,Cp,size);
! 2683: var u = box.w; var s; var Font;
! 2684: if (mitem.nuc.type == 'TeX') {
! 2685: Font = jsMath.TeX[mitem.nuc.font];
! 2686: if (Font[mitem.nuc.c].krn && Font.skewchar)
! 2687: {s = Font[mitem.nuc.c].krn[Font.skewchar]}
! 2688: }
! 2689: if (s == null) {s = 0}
! 2690:
! 2691: var c = mitem.accent & 0xFF;
! 2692: var font = jsMath.TeX.fam[(mitem.accent&0xF00)>>8]; Font = jsMath.TeX[font];
! 2693: while (Font[c].n && Font[Font[c].n].w <= u) {c = Font[c].n}
! 2694:
! 2695: var delta = Math.min(box.h,TeX.x_height);
! 2696: if (mitem.nuc.type == 'TeX') {
! 2697: var nitem = jsMath.mItem.Atom('ord',mitem.nuc);
! 2698: nitem.sup = mitem.sup; nitem.sub = mitem.sub; nitem.delta = 0;
! 2699: jsMath.mList.prototype.Atomize.SupSub(style,size,nitem);
! 2700: delta += (nitem.nuc.h - box.h);
! 2701: box = mitem.nuc = nitem.nuc;
! 2702: delete mitem.sup; delete mitem.sub;
! 2703: }
! 2704: var acc = jsMath.Box.TeX(c,font,style,size);
! 2705: acc.y = box.h - delta; acc.x = -box.w + s + (u-acc.w)/2;
! 2706: if (Font[c].ic) {acc.x -= Font[c].ic * TeX.scale}
! 2707:
! 2708: mitem.nuc = jsMath.Box.SetList([box,acc],style,size);
! 2709: if (mitem.nuc.w != box.w) {
! 2710: var space = jsMath.mItem.Space(box.w-mitem.nuc.w);
! 2711: mitem.nuc = jsMath.Box.SetList([mitem.nuc,space],style,size);
! 2712: }
! 2713: mitem.type = 'ord';
! 2714: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2715: },
! 2716:
! 2717: /*
! 2718: * Handle an Op atom. (Rules 13 and 13a)
! 2719: */
! 2720: op: function (style,size,mitem) {
! 2721: var TeX = jsMath.Typeset.TeX(style,size); var box;
! 2722: mitem.delta = 0; var isD = (style.charAt(0) == 'D');
! 2723: if (mitem.limits == null && isD) {mitem.limits = 1}
! 2724:
! 2725: if (mitem.nuc.type == 'TeX') {
! 2726: var C = jsMath.TeX[mitem.nuc.font][mitem.nuc.c];
! 2727: if (isD && C.n) {mitem.nuc.c = C.n; C = jsMath.TeX[mitem.nuc.font][C.n]}
! 2728: box = jsMath.Box.Set(mitem.nuc,style,size);
! 2729: if (C.ic) {
! 2730: mitem.delta = C.ic * TeX.scale;
! 2731: if (mitem.limits || !mitem.sub || jsMath.msieIntegralBug)
! 2732: {box = jsMath.Box.SetList([box,jsMath.mItem.Space(mitem.delta)],style,size)}
! 2733: }
! 2734: box.y = -((box.h+box.d)/2 - box.d - TeX.axis_height);
! 2735: if (Math.abs(box.y) < .0001) (box.y = 0)
! 2736: }
! 2737:
! 2738: if (!box) {box = jsMath.Box.Set(mitem.nuc,style,size).Remeasured()}
! 2739: if (mitem.limits) {
! 2740: var W = box.w; var x = box.w;
! 2741: var mlist = [box]; var dh = 0; var dd = 0;
! 2742: if (mitem.sup) {
! 2743: var sup = jsMath.Box.Set(mitem.sup,jsMath.Typeset.UpStyle(style),size).Remeasured();
! 2744: sup.x = ((box.w-sup.w)/2 + mitem.delta/2) - x; dh = TeX.big_op_spacing5;
! 2745: W = Math.max(W,sup.w); x += sup.x + sup.w;
! 2746: sup.y = box.h+sup.d + box.y +
! 2747: Math.max(TeX.big_op_spacing1,TeX.big_op_spacing3-sup.d);
! 2748: mlist[mlist.length] = sup; delete mitem.sup;
! 2749: }
! 2750: if (mitem.sub) {
! 2751: var sub = jsMath.Box.Set(mitem.sub,jsMath.Typeset.DownStyle(style),size).Remeasured();
! 2752: sub.x = ((box.w-sub.w)/2 - mitem.delta/2) - x; dd = TeX.big_op_spacing5;
! 2753: W = Math.max(W,sub.w); x += sub.x + sub.w;
! 2754: sub.y = -box.d-sub.h + box.y -
! 2755: Math.max(TeX.big_op_spacing2,TeX.big_op_spacing4-sub.h);
! 2756: mlist[mlist.length] = sub; delete mitem.sub;
! 2757: }
! 2758: if (W > box.w) {box.x = (W-box.w)/2; x += box.x}
! 2759: if (x < W) {mlist[mlist.length] = jsMath.mItem.Space(W-x)}
! 2760: mitem.nuc = jsMath.Box.SetList(mlist,style,size);
! 2761: mitem.nuc.h += dh; mitem.nuc.d += dd;
! 2762: } else {
! 2763: if (jsMath.msieIntegralBug && mitem.sub && C && C.ic)
! 2764: {mitem.nuc = jsMath.Box.SetList([box,jsMath.Box.Space(-C.ic*TeX.scale)],style,size)}
! 2765: else if (box.y) {mitem.nuc = jsMath.Box.SetList([box],style,size)}
! 2766: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2767: }
! 2768: },
! 2769:
! 2770: /*
! 2771: * Handle an Ord atom. (Rule 14)
! 2772: */
! 2773: ord: function (style,size,mitem,prev,mList,i) {
! 2774: if (mitem.nuc.type == 'TeX' && !mitem.sup && !mitem.sub) {
! 2775: var nitem = mList.mlist[i+1];
! 2776: if (nitem && nitem.atom && nitem.type &&
! 2777: (nitem.type == 'ord' || nitem.type == 'op' || nitem.type == 'bin' ||
! 2778: nitem.type == 'rel' || nitem.type == 'open' ||
! 2779: nitem.type == 'close' || nitem.type == 'punct')) {
! 2780: if (nitem.nuc.type == 'TeX' && nitem.nuc.font == mitem.nuc.font) {
! 2781: mitem.textsymbol = 1;
! 2782: var krn = jsMath.TeX[mitem.nuc.font][mitem.nuc.c].krn;
! 2783: krn *= jsMath.Typeset.TeX(style,size).scale;
! 2784: if (krn && krn[nitem.nuc.c]) {
! 2785: for (var k = mList.mlist.length-1; k > i; k--)
! 2786: {mList.mlist[k+1] = mList.mlist[k]}
! 2787: mList.mlist[i+1] = jsMath.mItem.Space(krn[nitem.nuc.c]);
! 2788: }
! 2789: }
! 2790: }
! 2791: }
! 2792: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2793: },
! 2794:
! 2795: /*
! 2796: * Handle a generalized fraction. (Rules 15 to 15e)
! 2797: */
! 2798: fraction: function (style,size,mitem) {
! 2799: var TeX = jsMath.Typeset.TeX(style,size); var t = 0;
! 2800: if (mitem.thickness != null) {t = mitem.thickness}
! 2801: else if (mitem.from.match(/over/)) {t = TeX.default_rule_thickness}
! 2802: var isD = (style.charAt(0) == 'D');
! 2803: var Cn = (style == 'D')? 'T': (style == "D'")? "T'": jsMath.Typeset.UpStyle(style);
! 2804: var Cd = (isD)? "T'": jsMath.Typeset.DownStyle(style);
! 2805: var num = jsMath.Box.Set(mitem.num,Cn,size).Remeasured();
! 2806: var den = jsMath.Box.Set(mitem.den,Cd,size).Remeasured();
! 2807:
! 2808: var u; var v; var w;
! 2809: var H = (isD)? TeX.delim1 : TeX.delim2;
! 2810: var mlist = [jsMath.Box.Delimiter(H,mitem.left,style)]
! 2811: var right = jsMath.Box.Delimiter(H,mitem.right,style);
! 2812:
! 2813: if (num.w < den.w) {
! 2814: num.x = (den.w-num.w)/2;
! 2815: den.x = -(num.w + num.x);
! 2816: w = den.w; mlist[1] = num; mlist[2] = den;
! 2817: } else {
! 2818: den.x = (num.w-den.w)/2;
! 2819: num.x = -(den.w + den.x);
! 2820: w = num.w; mlist[1] = den; mlist[2] = num;
! 2821: }
! 2822: if (isD) {u = TeX.num1; v = TeX.denom1} else {
! 2823: u = (t != 0)? TeX.num2: TeX.num3;
! 2824: v = TeX.denom2;
! 2825: }
! 2826: if (t == 0) {// atop
! 2827: var p = (isD)? 7*TeX.default_rule_thickness: 3*TeX.default_rule_thickness;
! 2828: var r = (u - num.d) - (den.h - v);
! 2829: if (r < p) {u += (p-r)/2; v += (p-r)/2}
! 2830: } else {// over
! 2831: var p = (isD)? 3*t: t; var a = TeX.axis_height;
! 2832: var r = (u-num.d)-(a+t/2); if (r < p) {u += p-r}
! 2833: r = (a-t/2)-(den.h-v); if (r < p) {v += p-r}
! 2834: var rule = jsMath.Box.Rule(w,t); rule.x = -w; rule.y = a - t/2;
! 2835: mlist[mlist.length] = rule;
! 2836: }
! 2837: num.y = u; den.y = -v;
! 2838:
! 2839: mlist[mlist.length] = right;
! 2840: mitem.nuc = jsMath.Box.SetList(mlist,style,size);
! 2841: mitem.type = 'ord'; mitem.atom = 1;
! 2842: delete mitem.num; delete mitem.den;
! 2843: jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
! 2844: },
! 2845:
! 2846: /*
! 2847: * Add subscripts and superscripts. (Rules 17-18f)
! 2848: */
! 2849: SupSub: function (style,size,mitem) {
! 2850: var TeX = jsMath.Typeset.TeX(style,size);
! 2851: var nuc = mitem.nuc;
! 2852: var box = mitem.nuc = jsMath.Box.Set(mitem.nuc,style,size,0);
! 2853: if (box.format == 'null')
! 2854: {box = mitem.nuc = jsMath.Box.Text('','normal',style,size)}
! 2855:
! 2856: if (nuc.type == 'TeX') {
! 2857: if (!mitem.textsymbol) {
! 2858: var C = jsMath.TeX[nuc.font][nuc.c];
! 2859: if (C.ic) {
! 2860: mitem.delta = C.ic * TeX.scale;
! 2861: if (!mitem.sub) {
! 2862: box = mitem.nuc = jsMath.Box.SetList([box,jsMath.Box.Space(mitem.delta)],style,size);
! 2863: mitem.delta = 0;
! 2864: }
! 2865: }
! 2866: } else {mitem.delta = 0}
! 2867: }
! 2868:
! 2869: if (!mitem.sup && !mitem.sub) return;
! 2870: mitem.nuc.Styled();
! 2871:
! 2872: var Cd = jsMath.Typeset.DownStyle(style);
! 2873: var Cu = jsMath.Typeset.UpStyle(style);
! 2874: var q = jsMath.Typeset.TeX(Cu,size).sup_drop;
! 2875: var r = jsMath.Typeset.TeX(Cd,size).sub_drop;
! 2876: var u = 0; var v = 0; var p;
! 2877: if (nuc.type != 'text' && nuc.type != 'TeX' && nuc.type != 'null')
! 2878: {u = box.h - q; v = box.d + r}
! 2879:
! 2880: if (mitem.sub) {
! 2881: var sub = jsMath.Box.Set(mitem.sub,Cd,size);
! 2882: sub = jsMath.Box.SetList([sub,jsMath.mItem.Space(TeX.scriptspace)],style,size);
! 2883: }
! 2884:
! 2885: if (!mitem.sup) {
! 2886: sub.y = -Math.max(v,TeX.sub1,sub.h-(4/5)*jsMath.Typeset.TeX(Cd,size).x_height);
! 2887: mitem.nuc = jsMath.Box.SetList([box,sub],style,size).Styled(); delete mitem.sub;
! 2888: return;
! 2889: }
! 2890:
! 2891: var sup = jsMath.Box.Set(mitem.sup,Cu,size);
! 2892: sup = jsMath.Box.SetList([sup,jsMath.mItem.Space(TeX.scriptspace)],style,size);
! 2893: if (style == 'D') {p = TeX.sup1}
! 2894: else if (style.charAt(style.length-1) == "'") {p = TeX.sup3}
! 2895: else {p = TeX.sup2}
! 2896: u = Math.max(u,p,sup.d+jsMath.Typeset.TeX(Cu,size).x_height/4);
! 2897:
! 2898: if (!mitem.sub) {
! 2899: sup.y = u;
! 2900: mitem.nuc = jsMath.Box.SetList([box,sup],style,size); delete mitem.sup;
! 2901: return;
! 2902: }
! 2903:
! 2904: v = Math.max(v,jsMath.Typeset.TeX(Cd,size).sub2);
! 2905: var t = TeX.default_rule_thickness;
! 2906: if ((u-sup.d) - (sub.h -v) < 4*t) {
! 2907: v = 4*t + sub.h - (u-sup.d);
! 2908: p = (4/5)*TeX.x_height - (u-sup.d);
! 2909: if (p > 0) {u += p; v -= p}
! 2910: }
! 2911: sup.Remeasured(); sub.Remeasured();
! 2912: sup.y = u; sub.y = -v; sup.x = mitem.delta;
! 2913: if (sup.w+sup.x > sub.w)
! 2914: {sup.x -= sub.w; mitem.nuc = jsMath.Box.SetList([box,sub,sup],style,size)} else
! 2915: {sub.x -= (sup.w+sup.x); mitem.nuc = jsMath.Box.SetList([box,sup,sub],style,size)}
! 2916:
! 2917: delete mitem.sup; delete mitem.sub;
! 2918: }
! 2919:
! 2920: });
! 2921:
! 2922:
! 2923: /***************************************************************************/
! 2924:
! 2925: /*
! 2926: * The Typeset object handles most of the TeX-specific processing
! 2927: */
! 2928:
! 2929: jsMath.Typeset = function (mlist) {
! 2930: this.type = 'typeset';
! 2931: this.mlist = mlist;
! 2932: }
! 2933:
! 2934: jsMath.Add(jsMath.Typeset,{
! 2935:
! 2936: /*
! 2937: * The "C-uparrow" style table (TeXbook, p. 441)
! 2938: */
! 2939: upStyle: {
! 2940: D: "S", T: "S", "D'": "S'", "T'": "S'",
! 2941: S: "SS", SS: "SS", "S'": "SS'", "SS'": "SS'"
! 2942: },
! 2943:
! 2944: /*
! 2945: * The "C-downarrow" style table (TeXbook, p. 441)
! 2946: */
! 2947: downStyle: {
! 2948: D: "S'", T: "S'", "D'": "S'", "T'": "S'",
! 2949: S: "SS'", SS: "SS'", "S'": "SS'", "SS'": "SS'"
! 2950: },
! 2951:
! 2952: /*
! 2953: * Get the various styles given the current style
! 2954: * (see TeXbook, p. 441)
! 2955: */
! 2956: UpStyle: function (style) {return this.upStyle[style]},
! 2957: DownStyle: function (style) {return this.downStyle[style]},
! 2958: PrimeStyle: function (style) {
! 2959: if (style.charAt(style.length-1) == "'") {return style}
! 2960: return style + "'"
! 2961: },
! 2962:
! 2963: /*
! 2964: * A value scaled to the appropriate size for scripts
! 2965: */
! 2966: StyleValue: function (style,v) {
! 2967: if (style == "S" || style == "S'") {return .7*v}
! 2968: if (style == "SS" || style == "SS'") {return .5*v}
! 2969: return v;
! 2970: },
! 2971:
! 2972: /*
! 2973: * Return the font parameter table for the given style
! 2974: */
! 2975: TeX: function (style,size) {
! 2976: if (style == "S" || style == "S'") {size = Math.max(0,size-2)}
! 2977: else if (style == "SS" || style == "SS'") {size = Math.max(0,size-4)}
! 2978: return jsMath.TeXparams[size];
! 2979: },
! 2980:
! 2981:
! 2982: /*
! 2983: * Add the CSS class for the given TeX style
! 2984: */
! 2985: AddStyle: function (style,size,html) {
! 2986: if (style == "S" || style == "S'") {size = Math.max(0,size-2)}
! 2987: else if (style == "SS" || style == "SS'") {size = Math.max(0,size-4)}
! 2988: if (size != 4) {html = '<SPAN CLASS="size'+size+'">' + html + '</SPAN>'}
! 2989: return html;
! 2990: },
! 2991:
! 2992: /*
! 2993: * Add the font class, if needed
! 2994: */
! 2995: AddClass: function (tclass,html) {
! 2996: if (tclass != '' && tclass != 'normal') {html = jsMath.HTML.Class(tclass,html)}
! 2997: return html;
! 2998: }
! 2999:
! 3000: });
! 3001:
! 3002:
! 3003: jsMath.Package(jsMath.Typeset,{
! 3004:
! 3005: /*
! 3006: * The spacing tables for inter-atom spacing
! 3007: * (See rule 20, and Chapter 18, p 170)
! 3008: */
! 3009: DTsep: {
! 3010: ord: {op: 1, bin: 2, rel: 3, inner: 1},
! 3011: op: {ord: 1, op: 1, rel: 3, inner: 1},
! 3012: bin: {ord: 2, op: 2, open: 2, inner: 2},
! 3013: rel: {ord: 3, op: 3, open: 3, inner: 3},
! 3014: open: {},
! 3015: close: {op: 1, bin:2, rel: 3, inner: 1},
! 3016: punct: {ord: 1, op: 1, rel: 1, open: 1, close: 1, punct: 1, inner: 1},
! 3017: inner: {ord: 1, op: 1, bin: 2, rel: 3, open: 1, punct: 1, inner: 1}
! 3018: },
! 3019:
! 3020: SSsep: {
! 3021: ord: {op: 1},
! 3022: op: {ord: 1, op: 1},
! 3023: bin: {},
! 3024: rel: {},
! 3025: open: {},
! 3026: close: {op: 1},
! 3027: punct: {},
! 3028: inner: {op: 1}
! 3029: },
! 3030:
! 3031: /*
! 3032: * The sizes used in the tables above
! 3033: */
! 3034: sepW: ['','thinmuskip','medmuskip','thickmuskip'],
! 3035:
! 3036:
! 3037: /*
! 3038: * Find the amount of separation to use between two adjacent
! 3039: * atoms in the given style
! 3040: */
! 3041: GetSeparation: function (l,r,style) {
! 3042: if (l && l.atom && r.atom) {
! 3043: var table = this.DTsep; if (style.charAt(0) == "S") {table = this.SSsep}
! 3044: var row = table[l.type];
! 3045: if (row && row[r.type] != null) {return jsMath.TeX[this.sepW[row[r.type]]]}
! 3046: }
! 3047: return 0;
! 3048: },
! 3049:
! 3050: /*
! 3051: * Typeset an mlist (i.e., turn it into HTML).
! 3052: * Here, text items of the same class and style are combined
! 3053: * to reduce the number of <SPAN> tags used (though it is still
! 3054: * huge). Spaces are combined, when possible.
! 3055: * ### More needs to be done with that. ###
! 3056: * The width of the final box is recomputed at the end, since
! 3057: * the final width is not necessarily the sum of the widths of
! 3058: * the individual parts (widths are in pixels, but the browsers
! 3059: * puts pieces together using sub-pixel accuracy).
! 3060: */
! 3061: Typeset: function (style,size) {
! 3062: this.style = style; this.size = size; var unset = -10000
! 3063: this.w = 0; this.h = unset; this.d = unset;
! 3064: this.bh = this.h; this.bd = this.d;
! 3065: this.tbuf = ''; this.tx = 0; this.tclass = '';
! 3066: this.cbuf = ''; this.hbuf = ''; this.hx = 0;
! 3067: var mitem = null; var prev; this.x = 0; this.dx = 0;
! 3068:
! 3069: for (var i = 0; i < this.mlist.length; i++) {
! 3070: prev = mitem; mitem = this.mlist[i];
! 3071: switch (mitem.type) {
! 3072:
! 3073: case 'size':
! 3074: this.FlushClassed();
! 3075: this.size = mitem.size;
! 3076: mitem = prev; // hide this from TeX
! 3077: break;
! 3078:
! 3079: case 'style':
! 3080: this.FlushClassed();
! 3081: if (this.style.charAt(this.style.length-1) == "'")
! 3082: {this.style = mitem.style + "'"} else {this.style = mitem.style}
! 3083: mitem = prev; // hide this from TeX
! 3084: break;
! 3085:
! 3086: case 'space':
! 3087: if (typeof(mitem.w) == 'object') {
! 3088: if (this.style.charAt(1) == 'S') {mitem.w = .5*mitem.w[0]/18}
! 3089: else if (this.style.charAt(0) == 'S') {mitem.w = .7*mitem.w[0]/18}
! 3090: else {mitem.w = mitem.w[0]/18}
! 3091: }
! 3092: this.dx += mitem.w-0; // mitem.w is sometimes a string?
! 3093: mitem = prev; // hide this from TeX
! 3094: break;
! 3095:
! 3096: case 'html':
! 3097: this.FlushClassed();
! 3098: if (this.hbuf == '') {this.hx = this.x}
! 3099: this.hbuf += mitem.html;
! 3100: mitem = prev; // hide this from TeX
! 3101: break;
! 3102:
! 3103: default: // atom
! 3104: if (!mitem.atom && mitem.type != 'box') break;
! 3105: mitem.nuc.x += this.dx + this.GetSeparation(prev,mitem,this.style);
! 3106: if (mitem.nuc.y || mitem.nuc.x) mitem.nuc.Styled();
! 3107: this.dx = 0; this.x = this.x + this.w;
! 3108: this.w += mitem.nuc.w + mitem.nuc.x;
! 3109: if (mitem.nuc.format == 'text') {
! 3110: if (this.tclass != mitem.nuc.tclass && this.tclass != '') this.FlushText();
! 3111: if (this.tbuf == '' && this.cbuf == '') {this.tx = this.x}
! 3112: this.tbuf += mitem.nuc.html; this.tclass = mitem.nuc.tclass;
! 3113: } else {
! 3114: this.FlushClassed();
! 3115: if (mitem.nuc.x || mitem.nuc.y) this.Place(mitem.nuc);
! 3116: if (this.hbuf == '') {this.hx = this.x}
! 3117: this.hbuf += mitem.nuc.html;
! 3118: }
! 3119: this.h = Math.max(this.h,mitem.nuc.h+mitem.nuc.y); this.bh = Math.max(this.bh,mitem.nuc.bh);
! 3120: this.d = Math.max(this.d,mitem.nuc.d-mitem.nuc.y); this.bd = Math.max(this.bd,mitem.nuc.bd);
! 3121: break;
! 3122: }
! 3123: }
! 3124:
! 3125: this.FlushClassed(); // make sure scaling is included
! 3126: if (this.dx) {this.hbuf += jsMath.HTML.Spacer(this.dx)}
! 3127: if (this.hbuf == '') {return jsMath.Box.Null}
! 3128: if (this.h == unset) {this.h = 0}
! 3129: if (this.d == unset) {this.d = 0}
! 3130: var box = new jsMath.Box('html',this.hbuf,this.w,this.h,this.d);
! 3131: box.bh = this.bh; box.bd = this.bd;
! 3132: return box;
! 3133: },
! 3134:
! 3135: /*
! 3136: * Add the font to the buffered text and move it to the
! 3137: * classed-text buffer.
! 3138: */
! 3139: FlushText: function () {
! 3140: if (this.tbuf == '') return;
! 3141: this.cbuf += jsMath.Typeset.AddClass(this.tclass,this.tbuf);
! 3142: this.tbuf = ''; this.tclass = '';
! 3143: },
! 3144:
! 3145: /*
! 3146: * Add the script or scriptscript style to the text and
! 3147: * move it to the HTML buffer
! 3148: */
! 3149: FlushClassed: function () {
! 3150: this.FlushText();
! 3151: if (this.cbuf == '') return;
! 3152: if (this.hbuf == '') {this.hx = this.tx}
! 3153: this.hbuf += jsMath.Typeset.AddStyle(this.style,this.size,this.cbuf);
! 3154: this.cbuf = '';
! 3155: },
! 3156:
! 3157: /*
! 3158: * Add a <SPAN> to position an item's HTML, and
! 3159: * adjust the items height and depth.
! 3160: * (This may be replaced buy one of the following browser-specific
! 3161: * versions by InitBrowser().)
! 3162: */
! 3163: Place: function (item) {
! 3164: var html = '<SPAN STYLE="position: relative;';
! 3165: if (item.x) {html += ' margin-left:'+jsMath.HTML.Em(item.x)+';'}
! 3166: if (item.y) {html += ' top:'+jsMath.HTML.Em(-item.y)+';'}
! 3167: item.html = html + '">' + item.html + '</SPAN>';
! 3168: item.h += item.y; item.d -= item.y;
! 3169: item.x = 0; item.y = 0;
! 3170: },
! 3171:
! 3172: /*
! 3173: * A replacement for Place() above that fixes a bug in MSIE.
! 3174: * (A separate <SPAN> is used to backspace, otherwise the
! 3175: * contents are clipped incorrectly.)
! 3176: */
! 3177: PlaceSeparateNegative: function (item) {
! 3178: var html = '<SPAN STYLE="position: relative;';
! 3179: // MSIE needs backspacing as separate SPAN
! 3180: if (item.x < 0)
! 3181: {html = '<SPAN STYLE="margin-left:'+jsMath.HTML.Em(item.x)+';"></SPAN>'+html}
! 3182: if (item.x > 0) {html += ' margin-left:'+jsMath.HTML.Em(item.x)+';'}
! 3183: if (item.y) {html += ' top:'+jsMath.HTML.Em(-item.y)+';'}
! 3184: item.html = html + '">' + item.html + '</SPAN>';
! 3185: item.h += item.y; item.d -= item.y;
! 3186: item.x = 0; item.y = 0;
! 3187: },
! 3188:
! 3189: /*
! 3190: * Here, the horizontal spacing is always done separately.
! 3191: */
! 3192: PlaceSeparateSkips: function (item) {
! 3193: if (item.y)
! 3194: {item.html = '<SPAN STYLE="position: relative; top:'+jsMath.HTML.Em(-item.y)+';'
! 3195: + '">' + item.html + '</SPAN>'}
! 3196: if (item.x)
! 3197: {item.html = jsMath.msieSpaceFix
! 3198: + '<SPAN STYLE="margin-left:'+jsMath.HTML.Em(item.x)+';">'
! 3199: + '</SPAN>' + item.html}
! 3200: item.h += item.y; item.d -= item.y;
! 3201: item.x = 0; item.y = 0;
! 3202: }
! 3203:
! 3204: });
! 3205:
! 3206:
! 3207:
! 3208: /***************************************************************************/
! 3209:
! 3210: /*
! 3211: * The Parse object handles the parsing of the TeX input string, and creates
! 3212: * the mList to be typeset by the Typeset object above.
! 3213: */
! 3214:
! 3215: jsMath.Parse = function (s,font,size,style) {
! 3216: var parse = new jsMath.Parser(s,font,size,style);
! 3217: parse.Parse();
! 3218: return parse;
! 3219: }
! 3220:
! 3221: jsMath.Parser = function (s,font,size,style) {
! 3222: this.string = s; this.i = 0;
! 3223: this.mlist = new jsMath.mList(null,font,size,style);
! 3224: }
! 3225:
! 3226: jsMath.Package(jsMath.Parser,{
! 3227:
! 3228: // special characters
! 3229: cmd: '\\',
! 3230: open: '{',
! 3231: close: '}',
! 3232:
! 3233: // patterns for letters and numbers
! 3234: letter: /[a-z]/i,
! 3235: number: /[0-9]/,
! 3236:
! 3237: // the \mathchar definitions (see Appendix B of the TeXbook).
! 3238: mathchar: {
! 3239: '!': 0x5021,
! 3240: '(': 0x4028,
! 3241: ')': 0x5029,
! 3242: '*': 0x2203, // \ast
! 3243: '+': 0x202B,
! 3244: ',': 0x613B,
! 3245: '-': 0x2200,
! 3246: '.': 0x013A,
! 3247: '/': 0x013D,
! 3248: ':': 0x303A,
! 3249: ';': 0x603B,
! 3250: '<': 0x313C,
! 3251: '=': 0x303D,
! 3252: '>': 0x313E,
! 3253: '?': 0x503F,
! 3254: '[': 0x405B,
! 3255: ']': 0x505D,
! 3256: // '{': 0x4266,
! 3257: // '}': 0x5267,
! 3258: '|': 0x026A
! 3259: },
! 3260:
! 3261: // handle special \catcode characters
! 3262: special: {
! 3263: '^': 'HandleSuperscript',
! 3264: '_': 'HandleSubscript',
! 3265: ' ': 'Space',
! 3266: "\t": 'Space',
! 3267: "\r": 'Space',
! 3268: "\n": 'Space',
! 3269: "'": 'Prime',
! 3270: '%': 'HandleComment',
! 3271: '&': 'HandleEntry'
! 3272: },
! 3273:
! 3274: // the \mathchardef table (see Appendix B of the TeXbook).
! 3275: mathchardef: {
! 3276: // brace parts
! 3277: braceld: 0x37A,
! 3278: bracerd: 0x37B,
! 3279: bracelu: 0x37C,
! 3280: braceru: 0x37D,
! 3281:
! 3282: // Greek letters
! 3283: alpha: 0x010B,
! 3284: beta: 0x010C,
! 3285: gamma: 0x010D,
! 3286: delta: 0x010E,
! 3287: epsilon: 0x010F,
! 3288: zeta: 0x0110,
! 3289: eta: 0x0111,
! 3290: theta: 0x0112,
! 3291: iota: 0x0113,
! 3292: kappa: 0x0114,
! 3293: lambda: 0x0115,
! 3294: mu: 0x0116,
! 3295: nu: 0x0117,
! 3296: xi: 0x0118,
! 3297: pi: 0x0119,
! 3298: rho: 0x011A,
! 3299: sigma: 0x011B,
! 3300: tau: 0x011C,
! 3301: upsilon: 0x011D,
! 3302: phi: 0x011E,
! 3303: chi: 0x011F,
! 3304: psi: 0x0120,
! 3305: omega: 0x0121,
! 3306: varepsilon: 0x0122,
! 3307: vartheta: 0x0123,
! 3308: varpi: 0x0124,
! 3309: varrho: 0x0125,
! 3310: varsigma: 0x0126,
! 3311: varphi: 0x0127,
! 3312:
! 3313: Gamma: 0x7000,
! 3314: Delta: 0x7001,
! 3315: Theta: 0x7002,
! 3316: Lambda: 0x7003,
! 3317: Xi: 0x7004,
! 3318: Pi: 0x7005,
! 3319: Sigma: 0x7006,
! 3320: Upsilon: 0x7007,
! 3321: Phi: 0x7008,
! 3322: Psi: 0x7009,
! 3323: Omega: 0x700A,
! 3324:
! 3325: // Ord symbols
! 3326: aleph: 0x0240,
! 3327: imath: 0x017B,
! 3328: jmath: 0x017C,
! 3329: ell: 0x0160,
! 3330: wp: 0x017D,
! 3331: Re: 0x023C,
! 3332: Im: 0x023D,
! 3333: partial: 0x0140,
! 3334: infty: 0x0231,
! 3335: prime: 0x0230,
! 3336: emptyset: 0x023B,
! 3337: nabla: 0x0272,
! 3338: surd: 0x1270,
! 3339: top: 0x023E,
! 3340: bot: 0x023F,
! 3341: triangle: 0x0234,
! 3342: forall: 0x0238,
! 3343: exists: 0x0239,
! 3344: neg: 0x023A,
! 3345: lnot: 0x023A,
! 3346: flat: 0x015B,
! 3347: natural: 0x015C,
! 3348: sharp: 0x015D,
! 3349: clubsuit: 0x027C,
! 3350: diamondsuit: 0x027D,
! 3351: heartsuit: 0x027E,
! 3352: spadesuit: 0x027F,
! 3353:
! 3354: // big ops
! 3355: coprod: 0x1360,
! 3356: bigvee: 0x1357,
! 3357: bigwedge: 0x1356,
! 3358: biguplus: 0x1355,
! 3359: bigcap: 0x1354,
! 3360: bigcup: 0x1353,
! 3361: intop: 0x1352,
! 3362: prod: 0x1351,
! 3363: sum: 0x1350,
! 3364: bigotimes: 0x134E,
! 3365: bigoplus: 0x134C,
! 3366: bigodot: 0x134A,
! 3367: ointop: 0x1348,
! 3368: bigsqcup: 0x1346,
! 3369: smallint: 0x1273,
! 3370:
! 3371: // binary operations
! 3372: triangleleft: 0x212F,
! 3373: triangleright: 0x212E,
! 3374: bigtriangleup: 0x2234,
! 3375: bigtriangledown: 0x2235,
! 3376: wedge: 0x225E,
! 3377: land: 0x225E,
! 3378: vee: 0x225F,
! 3379: lor: 0x225F,
! 3380: cap: 0x225C,
! 3381: cup: 0x225B,
! 3382: ddagger: 0x227A,
! 3383: dagger: 0x2279,
! 3384: sqcap: 0x2275,
! 3385: sqcup: 0x2274,
! 3386: uplus: 0x225D,
! 3387: amalg: 0x2271,
! 3388: diamond: 0x2205,
! 3389: bullet: 0x220F,
! 3390: wr: 0x226F,
! 3391: div: 0x2204,
! 3392: odot: 0x220C,
! 3393: oslash: 0x220B,
! 3394: otimes: 0x220A,
! 3395: ominus: 0x2209,
! 3396: oplus: 0x2208,
! 3397: mp: 0x2207,
! 3398: pm: 0x2206,
! 3399: circ: 0x220E,
! 3400: bigcirc: 0x220D,
! 3401: setminus: 0x226E, // for set difference A\setminus B
! 3402: cdot: 0x2201,
! 3403: ast: 0x2203,
! 3404: times: 0x2202,
! 3405: star: 0x213F,
! 3406:
! 3407: // Relations
! 3408: propto: 0x322F,
! 3409: sqsubseteq: 0x3276,
! 3410: sqsupseteq: 0x3277,
! 3411: parallel: 0x326B,
! 3412: mid: 0x326A,
! 3413: dashv: 0x3261,
! 3414: vdash: 0x3260,
! 3415: leq: 0x3214,
! 3416: le: 0x3214,
! 3417: geq: 0x3215,
! 3418: ge: 0x3215,
! 3419: succ: 0x321F,
! 3420: prec: 0x321E,
! 3421: approx: 0x3219,
! 3422: succeq: 0x3217,
! 3423: preceq: 0x3216,
! 3424: supset: 0x321B,
! 3425: subset: 0x321A,
! 3426: supseteq: 0x3213,
! 3427: subseteq: 0x3212,
! 3428: 'in': 0x3232,
! 3429: ni: 0x3233,
! 3430: owns: 0x3233,
! 3431: gg: 0x321D,
! 3432: ll: 0x321C,
! 3433: not: 0x3236,
! 3434: sim: 0x3218,
! 3435: simeq: 0x3227,
! 3436: perp: 0x323F,
! 3437: equiv: 0x3211,
! 3438: asymp: 0x3210,
! 3439: smile: 0x315E,
! 3440: frown: 0x315F,
! 3441:
! 3442: // Arrows
! 3443: Leftrightarrow: 0x322C,
! 3444: Leftarrow: 0x3228,
! 3445: Rightarrow: 0x3229,
! 3446: leftrightarrow: 0x3224,
! 3447: leftarrow: 0x3220,
! 3448: gets: 0x3220,
! 3449: rightarrow: 0x3221,
! 3450: to: 0x3221,
! 3451: mapstochar: 0x3237,
! 3452: leftharpoonup: 0x3128,
! 3453: leftharpoondown: 0x3129,
! 3454: rightharpoonup: 0x312A,
! 3455: rightharpoondown: 0x312B,
! 3456: nearrow: 0x3225,
! 3457: searrow: 0x3226,
! 3458: nwarrow: 0x322D,
! 3459: swarrow: 0x322E,
! 3460:
! 3461: hbarchar: 0x0016, // for \hbar
! 3462: lhook: 0x312C,
! 3463: rhook: 0x312D,
! 3464:
! 3465: ldotp: 0x613A, // ldot as a punctuation mark
! 3466: cdotp: 0x6201, // cdot as a punctuation mark
! 3467: colon: 0x603A, // colon as a punctuation mark
! 3468:
! 3469: '#': 0x7023,
! 3470: '$': 0x7024,
! 3471: '%': 0x7025,
! 3472: '&': 0x7026
! 3473: },
! 3474:
! 3475: // The delimiter table (see Appendix B of the TeXbook)
! 3476: delimiter: {
! 3477: '(': 0x0028300,
! 3478: ')': 0x0029301,
! 3479: '[': 0x005B302,
! 3480: ']': 0x005D303,
! 3481: '<': 0x026830A,
! 3482: '>': 0x026930B,
! 3483: '/': 0x002F30E,
! 3484: '|': 0x026A30C,
! 3485: '.': 0x0000000,
! 3486: '\\': 0x026E30F,
! 3487: '\\lmoustache': 0x437A340, // top from (, bottom from )
! 3488: '\\rmoustache': 0x537B341, // top from ), bottom from (
! 3489: '\\lgroup': 0x462833A, // extensible ( with sharper tips
! 3490: '\\rgroup': 0x562933B, // extensible ) with sharper tips
! 3491: '\\arrowvert': 0x026A33C, // arrow without arrowheads
! 3492: '\\Arrowvert': 0x026B33D, // double arrow without arrowheads
! 3493: // '\\bracevert': 0x077C33E, // the vertical bar that extends braces
! 3494: '\\bracevert': 0x026A33E, // we don't load tt, so use | instead
! 3495: '\\Vert': 0x026B30D,
! 3496: '\\|': 0x026B30D,
! 3497: '\\vert': 0x026A30C,
! 3498: '\\uparrow': 0x3222378,
! 3499: '\\downarrow': 0x3223379,
! 3500: '\\updownarrow': 0x326C33F,
! 3501: '\\Uparrow': 0x322A37E,
! 3502: '\\Downarrow': 0x322B37F,
! 3503: '\\Updownarrow': 0x326D377,
! 3504: '\\backslash': 0x026E30F, // for double coset G\backslash H
! 3505: '\\rangle': 0x526930B,
! 3506: '\\langle': 0x426830A,
! 3507: '\\rbrace': 0x5267309,
! 3508: '\\lbrace': 0x4266308,
! 3509: '\\}': 0x5267309,
! 3510: '\\{': 0x4266308,
! 3511: '\\rceil': 0x5265307,
! 3512: '\\lceil': 0x4264306,
! 3513: '\\rfloor': 0x5263305,
! 3514: '\\lfloor': 0x4262304
! 3515: },
! 3516:
! 3517: /*
! 3518: * The basic macros for plain TeX.
! 3519: *
! 3520: * When the control sequence on the left is called, the JavaScript
! 3521: * funtion on the right is called, with the name of the control sequence
! 3522: * as its first parameter (this way, the same function can be called by
! 3523: * several different control sequences to do similar actions, and the
! 3524: * function can still tell which TeX command was issued). If the right
! 3525: * is an array, the first entry is the routine to call, and the
! 3526: * remaining entries in the array are parameters to pass to the function
! 3527: * as the second parameter (they are in an array reference).
! 3528: *
! 3529: * Note: TeX macros as defined by the user are discussed below.
! 3530: */
! 3531: macros: {
! 3532: displaystyle: ['HandleStyle','D'],
! 3533: textstyle: ['HandleStyle','T'],
! 3534: scriptstyle: ['HandleStyle','S'],
! 3535: scriptscriptstyle: ['HandleStyle','SS'],
! 3536:
! 3537: rm: ['HandleFont',0],
! 3538: mit: ['HandleFont',1],
! 3539: oldstyle: ['HandleFont',1],
! 3540: cal: ['HandleFont',2],
! 3541: it: ['HandleFont',4],
! 3542: bf: ['HandleFont',6],
! 3543:
! 3544: left: 'HandleLeft',
! 3545: right: 'HandleRight',
! 3546:
! 3547: arcsin: ['NamedOp',0],
! 3548: arccos: ['NamedOp',0],
! 3549: arctan: ['NamedOp',0],
! 3550: arg: ['NamedOp',0],
! 3551: cos: ['NamedOp',0],
! 3552: cosh: ['NamedOp',0],
! 3553: cot: ['NamedOp',0],
! 3554: coth: ['NamedOp',0],
! 3555: csc: ['NamedOp',0],
! 3556: deg: ['NamedOp',0],
! 3557: det: 'NamedOp',
! 3558: dim: ['NamedOp',0],
! 3559: exp: ['NamedOp',0],
! 3560: gcd: 'NamedOp',
! 3561: hom: ['NamedOp',0],
! 3562: inf: 'NamedOp',
! 3563: ker: ['NamedOp',0],
! 3564: lg: ['NamedOp',0],
! 3565: lim: 'NamedOp',
! 3566: liminf: ['NamedOp',null,'lim<SPAN STYLE="margin-left: '+1/6+'em"></SPAN>inf'],
! 3567: limsup: ['NamedOp',null,'lim<SPAN STYLE="margin-left: '+1/6+'em"></SPAN>sup'],
! 3568: ln: ['NamedOp',0],
! 3569: log: ['NamedOp',0],
! 3570: max: 'NamedOp',
! 3571: min: 'NamedOp',
! 3572: Pr: 'NamedOp',
! 3573: sec: ['NamedOp',0],
! 3574: sin: ['NamedOp',0],
! 3575: sinh: ['NamedOp',0],
! 3576: sup: 'NamedOp',
! 3577: tan: ['NamedOp',0],
! 3578: tanh: ['NamedOp',0],
! 3579:
! 3580: vcenter: ['HandleAtom','vcenter'],
! 3581: overline: ['HandleAtom','overline'],
! 3582: underline: ['HandleAtom','underline'],
! 3583: over: 'HandleOver',
! 3584: overwithdelims: 'HandleOver',
! 3585: atop: 'HandleOver',
! 3586: atopwithdelims: 'HandleOver',
! 3587: above: 'HandleOver',
! 3588: abovewithdelims: 'HandleOver',
! 3589: brace: ['HandleOver','\\{','\\}'],
! 3590: brack: ['HandleOver','[',']'],
! 3591: choose: ['HandleOver','(',')'],
! 3592:
! 3593: overbrace: ['HandleLeaders','downbrace',1],
! 3594: underbrace: ['HandleLeaders','upbrace',1,1],
! 3595: overrightarrow: ['HandleLeaders','rightarrow'],
! 3596: overleftarrow: ['HandleLeaders','leftarrow'],
! 3597:
! 3598: llap: 'HandleLap',
! 3599: rlap: 'HandleLap',
! 3600: ulap: 'HandleLap',
! 3601: dlap: 'HandleLap',
! 3602: raise: 'RaiseLower',
! 3603: lower: 'RaiseLower',
! 3604: moveleft: 'MoveLeftRight',
! 3605: moveright: 'MoveLeftRight',
! 3606:
! 3607: frac: 'Frac',
! 3608: root: 'Root',
! 3609: sqrt: 'Sqrt',
! 3610:
! 3611: // TeX substitution macros
! 3612: hbar: ['Macro','\\hbarchar\\kern-.5em h'],
! 3613: ne: ['Macro','\\not='],
! 3614: neq: ['Macro','\\not='],
! 3615: notin: ['Macro','\\mathrel{\\rlap{\\kern2mu/}}\\in'],
! 3616: cong: ['Macro','\\mathrel{\\lower2mu{\\mathrel{{\\rlap{=}\\raise6mu\\sim}}}}'],
! 3617: bmod: ['Macro','\\mathbin{\\rm mod}'],
! 3618: pmod: ['Macro','\\kern 18mu ({\\rm mod}\\,\\,#1)',1],
! 3619: 'int': ['Macro','\\intop\\nolimits'],
! 3620: oint: ['Macro','\\ointop\\nolimits'],
! 3621: doteq: ['Macro','\\buildrel\\textstyle.\\over='],
! 3622: ldots: ['Macro','\\mathinner{\\ldotp\\ldotp\\ldotp}'],
! 3623: cdots: ['Macro','\\mathinner{\\cdotp\\cdotp\\cdotp}'],
! 3624: vdots: ['Macro','\\mathinner{\\rlap{\\raise8pt{\\rule 0pt 6pt 0pt .}}\\rlap{\\raise4pt{.}}.}'],
! 3625: ddots: ['Macro','\\mathinner{\\kern1mu\\raise7pt{\\rule 0pt 7pt 0pt .}\\kern2mu\\raise4pt{.}\\kern2mu\\raise1pt{.}\\kern1mu}'],
! 3626: joinrel: ['Macro','\\mathrel{\\kern-4mu}'],
! 3627: relbar: ['Macro','\\mathrel{\\smash-}'], // \smash, because - has the same height as +
! 3628: Relbar: ['Macro','\\mathrel='],
! 3629: bowtie: ['Macro','\\mathrel\\triangleright\\joinrel\\mathrel\\triangleleft'],
! 3630: models: ['Macro','\\mathrel|\\joinrel='],
! 3631: mapsto: ['Macro','\\mapstochar\\rightarrow'],
! 3632: rightleftharpoons: ['Macro','\\vcenter{\\mathrel{\\rlap{\\raise3mu{\\rightharpoonup}}}\\leftharpoondown}'],
! 3633: hookrightarrow: ['Macro','\\lhook\\joinrel\\rightarrow'],
! 3634: hookleftarrow: ['Macro','\\leftarrow\\joinrel\\rhook'],
! 3635: Longrightarrow: ['Macro','\\Relbar\\joinrel\\Rightarrow'],
! 3636: longrightarrow: ['Macro','\\relbar\\joinrel\\rightarrow'],
! 3637: longleftarrow: ['Macro','\\leftarrow\\joinrel\\relbar'],
! 3638: Longleftarrow: ['Macro','\\Leftarrow\\joinrel\\Relbar'],
! 3639: longmapsto: ['Macro','\\mapstochar\\char{cmsy10}{0}\\joinrel\\rightarrow'],
! 3640: longleftrightarrow: ['Macro','\\leftarrow\\joinrel\\rightarrow'],
! 3641: Longleftrightarrow: ['Macro','\\Leftarrow\\joinrel\\Rightarrow'],
! 3642: iff: ['Macro','\\;\\Longleftrightarrow\\;'],
! 3643: mathrm: ['Macro','{\\rm #1}',1],
! 3644: mathbf: ['Macro','{\\bf #1}',1],
! 3645: mathbb: ['Macro','{\\bf #1}',1],
! 3646: mathit: ['Macro','{\\it #1}',1],
! 3647:
! 3648: TeX: ['Macro','T\\kern-.1667em\\lower.5ex{E}\\kern-.125em X'],
! 3649:
! 3650: limits: ['Limits',1],
! 3651: nolimits: ['Limits',0],
! 3652:
! 3653: ',': ['Spacer',1/6],
! 3654: ':': ['Spacer',1/6], // for LaTeX
! 3655: '>': ['Spacer',2/9],
! 3656: ';': ['Spacer',5/18],
! 3657: '!': ['Spacer',-1/6],
! 3658: enspace: ['Spacer',1/2],
! 3659: quad: ['Spacer',1],
! 3660: qquad: ['Spacer',2],
! 3661: thinspace: ['Spacer',1/6],
! 3662: negthinspace: ['Spacer',-1/6],
! 3663:
! 3664: hskip: 'Hskip',
! 3665: kern: 'Hskip',
! 3666: rule: ['Rule','black'],
! 3667: space: ['Rule','blank'],
! 3668:
! 3669: big: ['MakeBig','ord',0.85],
! 3670: Big: ['MakeBig','ord',1.15],
! 3671: bigg: ['MakeBig','ord',1.45],
! 3672: Bigg: ['MakeBig','ord',1.75],
! 3673: bigl: ['MakeBig','open',0.85],
! 3674: Bigl: ['MakeBig','open',1.15],
! 3675: biggl: ['MakeBig','open',1.45],
! 3676: Biggl: ['MakeBig','open',1.75],
! 3677: bigr: ['MakeBig','close',0.85],
! 3678: Bigr: ['MakeBig','close',1.15],
! 3679: biggr: ['MakeBig','close',1.45],
! 3680: Biggr: ['MakeBig','close',1.75],
! 3681: bigm: ['MakeBig','rel',0.85],
! 3682: Bigm: ['MakeBig','rel',1.15],
! 3683: biggm: ['MakeBig','rel',1.45],
! 3684: Biggm: ['MakeBig','rel',1.75],
! 3685:
! 3686: mathord: ['HandleAtom','ord'],
! 3687: mathop: ['HandleAtom','op'],
! 3688: mathopen: ['HandleAtom','open'],
! 3689: mathclose: ['HandleAtom','close'],
! 3690: mathbin: ['HandleAtom','bin'],
! 3691: mathrel: ['HandleAtom','rel'],
! 3692: mathpunct: ['HandleAtom','punct'],
! 3693: mathinner: ['HandleAtom','inner'],
! 3694:
! 3695: mathchoice: 'MathChoice',
! 3696: buildrel: 'BuildRel',
! 3697:
! 3698: hbox: 'HBox',
! 3699: text: 'HBox',
! 3700: mbox: 'HBox',
! 3701: fbox: 'FBox',
! 3702:
! 3703: strut: 'Strut',
! 3704: mathstrut: ['Macro','\\vphantom{(}'],
! 3705: phantom: ['Phantom',1,1],
! 3706: vphantom: ['Phantom',1,0],
! 3707: hphantom: ['Phantom',0,1],
! 3708: smash: 'Smash',
! 3709:
! 3710: acute: ['MathAccent', 0x7013],
! 3711: grave: ['MathAccent', 0x7012],
! 3712: ddot: ['MathAccent', 0x707F],
! 3713: tilde: ['MathAccent', 0x707E],
! 3714: bar: ['MathAccent', 0x7016],
! 3715: breve: ['MathAccent', 0x7015],
! 3716: check: ['MathAccent', 0x7014],
! 3717: hat: ['MathAccent', 0x705E],
! 3718: vec: ['MathAccent', 0x017E],
! 3719: dot: ['MathAccent', 0x705F],
! 3720: widetilde: ['MathAccent', 0x0365],
! 3721: widehat: ['MathAccent', 0x0362],
! 3722:
! 3723: '_': ['Replace','ord','_','normal',-.4,.1],
! 3724: ' ': ['Replace','ord',' ','normal'],
! 3725: angle: ['Replace','ord','∠','normal'],
! 3726:
! 3727: matrix: 'Matrix',
! 3728: array: 'Matrix', // ### still need to do alignment options ###
! 3729: pmatrix: ['Matrix','(',')','c'],
! 3730: cases: ['Matrix','\\{','.',['l','l']],
! 3731: cr: 'HandleRow',
! 3732: '\\': 'HandleRow',
! 3733:
! 3734: // LaTeX
! 3735: begin: 'Begin',
! 3736: end: 'End',
! 3737: tiny: ['HandleSize',0],
! 3738: Tiny: ['HandleSize',1], // non-standard
! 3739: scriptsize: ['HandleSize',2],
! 3740: small: ['HandleSize',3],
! 3741: normalsize: ['HandleSize',4],
! 3742: large: ['HandleSize',5],
! 3743: Large: ['HandleSize',6],
! 3744: LARGE: ['HandleSize',7],
! 3745: huge: ['HandleSize',8],
! 3746: Huge: ['HandleSize',9],
! 3747: dots: ['Macro','\\ldots'],
! 3748:
! 3749: // Extensions to TeX
! 3750: color: 'Color',
! 3751: href: 'Href',
! 3752: 'class': 'Class',
! 3753: style: 'Style',
! 3754: unicode: 'Unicode',
! 3755:
! 3756: // debugging and test routines
! 3757: 'char': 'Char',
! 3758: test: 'Test'
! 3759: },
! 3760:
! 3761: /*
! 3762: * LaTeX environments
! 3763: */
! 3764: environments: {
! 3765: array: 'Array',
! 3766: matrix: ['Array',null,null,'c'],
! 3767: pmatrix: ['Array','(',')','c'],
! 3768: bmatrix: ['Array','[',']','c'],
! 3769: Bmatrix: ['Array','\\{','\\}','c'],
! 3770: vmatrix: ['Array','\\vert','\\vert','c'],
! 3771: Vmatrix: ['Array','\\Vert','\\Vert','c'],
! 3772: cases: ['Array','\\{','.','ll'],
! 3773: eqnarray: ['Array',null,null,'rcl',[5/18,5/18]]
! 3774: },
! 3775:
! 3776: /*
! 3777: * The horizontally stretchable delimiters
! 3778: */
! 3779: leaders: {
! 3780: downbrace: {left: 0x37A, lmid: 0x37D, rmid: 0x37C, right: 0x37B},
! 3781: upbrace: {left: 0x37C, lmid: 0x37B, rmid: 0x37A, right: 0x37D},
! 3782: leftarrow: {left: 0x220, rep: 0x200},
! 3783: rightarrow: {rep: 0x200, right: 0x221}
! 3784: },
! 3785:
! 3786:
! 3787: /***************************************************************************/
! 3788:
! 3789: /*
! 3790: * Add special characters to list above. (This makes it possible
! 3791: * to define them in a variable that the user can change.)
! 3792: */
! 3793: AddSpecial: function (obj) {
! 3794: for (var id in obj) {
! 3795: jsMath.Parser.prototype.special[jsMath.Parser.prototype[id]] = obj[id];
! 3796: }
! 3797: },
! 3798:
! 3799: /*
! 3800: * Throw an error
! 3801: */
! 3802: Error: function (s) {
! 3803: this.i = this.string.length;
! 3804: if (s.error) {this.error = s.error} else {
! 3805: if (!this.error) {this.error = s}
! 3806: }
! 3807: },
! 3808:
! 3809: /***************************************************************************/
! 3810:
! 3811: /*
! 3812: * Check if the next character is a space
! 3813: */
! 3814: nextIsSpace: function () {
! 3815: return this.string.charAt(this.i) == ' ';
! 3816: },
! 3817:
! 3818: /*
! 3819: * Parse a substring to get its mList, and return it.
! 3820: * Check that no errors occured
! 3821: */
! 3822: Process: function (arg) {
! 3823: var data = this.mlist.data;
! 3824: arg = jsMath.Parse(arg,data.font,data.size,data.style);
! 3825: if (arg.error) {this.Error(arg); return}
! 3826: if (arg.mlist.Length() == 0) {return null}
! 3827: if (arg.mlist.Length() == 1) {
! 3828: var atom = arg.mlist.Last();
! 3829: if (atom.atom && atom.type == 'ord' && atom.nuc &&
! 3830: !atom.sub && !atom.sup && (atom.nuc.type == 'text' || atom.nuc.type == 'TeX'))
! 3831: {return atom.nuc}
! 3832: }
! 3833: return {type: 'mlist', mlist: arg.mlist};
! 3834: },
! 3835:
! 3836: /*
! 3837: * Get and return a control-sequence name from the TeX string
! 3838: */
! 3839: GetCommand: function () {
! 3840: var letter = /^([a-z]+|.) ?/i;
! 3841: var cmd = letter.exec(this.string.slice(this.i));
! 3842: if (cmd) {this.i += cmd[1].length; return cmd[1]}
! 3843: this.Error("Missing control sequnece name at end of string or argument"); return
! 3844: },
! 3845:
! 3846: /*
! 3847: * Get and return a TeX argument (either a single character or control sequence,
! 3848: * or the contents of the next set of braces).
! 3849: */
! 3850: GetArgument: function (name,noneOK) {
! 3851: while (this.nextIsSpace()) {this.i++}
! 3852: if (this.i >= this.string.length) {if (!noneOK) this.Error("Missing argument for "+name); return}
! 3853: if (this.string.charAt(this.i) == this.close) {if (!noneOK) this.Error("Extra close brace"); return}
! 3854: if (this.string.charAt(this.i) == this.cmd) {this.i++; return this.cmd+this.GetCommand()}
! 3855: if (this.string.charAt(this.i) != this.open) {return this.string.charAt(this.i++)}
! 3856: var j = ++this.i; var pcount = 1; var c = '';
! 3857: while (this.i < this.string.length) {
! 3858: c = this.string.charAt(this.i++);
! 3859: if (c == this.cmd) {this.i++}
! 3860: else if (c == this.open) {pcount++}
! 3861: else if (c == this.close) {
! 3862: if (pcount == 0) {this.Error("Extra close brace"); return}
! 3863: if (--pcount == 0) {return this.string.slice(j,this.i-1)}
! 3864: }
! 3865: }
! 3866: this.Error("Missing close brace");
! 3867: },
! 3868:
! 3869: /*
! 3870: * Get an argument and process it into an mList
! 3871: */
! 3872: ProcessArg: function (name) {
! 3873: var arg = this.GetArgument(name); if (this.error) return;
! 3874: return this.Process(arg);
! 3875: },
! 3876:
! 3877: /*
! 3878: * Get the name of a delimiter (check it in the delimiter list).
! 3879: */
! 3880: GetDelimiter: function (name) {
! 3881: while (this.nextIsSpace()) {this.i++}
! 3882: var c = this.string.charAt(this.i);
! 3883: if (this.i < this.string.length) {
! 3884: this.i++;
! 3885: if (c == this.cmd) {c = '\\'+this.GetCommand(name); if (this.error) return}
! 3886: if (this.delimiter[c] != null) {return this.delimiter[c]}
! 3887: }
! 3888: this.Error("Missing or unrecognized delimiter for "+name);
! 3889: },
! 3890:
! 3891: /*
! 3892: * Get a dimension (including its units).
! 3893: * Convert the dimen to em's, except for mu's, which must be
! 3894: * converted when typeset.
! 3895: */
! 3896: GetDimen: function (name,nomu) {
! 3897: var rest = this.string.slice(this.i);
! 3898: var match = rest.match(/^\s*([-+]?(\.\d+|\d+(\.\d*)?))(pt|em|ex|mu|px)/);
! 3899: if (!match) {this.Error("Missing dimension or its units for "+name); return}
! 3900: this.i += match[0].length;
! 3901: if (this.nextIsSpace()) {this.i++}
! 3902: var d = match[1]-0;
! 3903: if (match[4] == 'px') {d /= jsMath.em}
! 3904: else if (match[4] == 'pt') {d /= 10}
! 3905: else if (match[4] == 'ex') {d *= jsMath.TeX.x_height}
! 3906: else if (match[4] == 'mu') {if (nomu) {d = d/18} else {d = [d,'mu']}}
! 3907: return d;
! 3908: },
! 3909:
! 3910: /*
! 3911: * Get the next non-space character
! 3912: */
! 3913: GetNext: function () {
! 3914: while (this.nextIsSpace()) {this.i++}
! 3915: return this.string.charAt(this.i);
! 3916: },
! 3917:
! 3918: /*
! 3919: * Get an optional LaTeX argument in brackets
! 3920: */
! 3921: GetBrackets: function (name) {
! 3922: var c = this.GetNext(); if (c != '[') return '';
! 3923: var start = ++this.i; var pcount = 0;
! 3924: while (this.i < this.string.length) {
! 3925: var c = this.string.charAt(this.i++);
! 3926: if (c == '{') {pcount++}
! 3927: else if (c == '}') {
! 3928: if (pcount == 0)
! 3929: {this.Error("Extra close brace while looking for ']'"); return}
! 3930: pcount --;
! 3931: } else if (c == this.cmd) {
! 3932: this.i++;
! 3933: } else if (c == ']') {
! 3934: if (pcount == 0) {return this.string.slice(start,this.i-1)}
! 3935: }
! 3936: }
! 3937: this.Error("Couldn't find closing ']' for argument to "+this.cmd+name);
! 3938: },
! 3939:
! 3940: /*
! 3941: * Get everything up to the given control sequence name (token)
! 3942: */
! 3943: GetUpto: function (name,token) {
! 3944: while (this.nextIsSpace()) {this.i++}
! 3945: var start = this.i; var pcount = 0;
! 3946: while (this.i < this.string.length) {
! 3947: var c = this.string.charAt(this.i++);
! 3948: if (c == '{') {pcount++}
! 3949: else if (c == '}') {
! 3950: if (pcount == 0)
! 3951: {this.Error("Extra close brace while looking for "+this.cmd+token); return}
! 3952: pcount --;
! 3953: } else if (c == this.cmd) {
! 3954: // really need separate counter for begin/end
! 3955: // and it should really be a stack (new pcount for each begin)
! 3956: if (this.string.slice(this.i,this.i+5) == "begin") {pcount++; this.i+=4}
! 3957: else if (this.string.slice(this.i,this.i+3) == "end") {
! 3958: if (pcount > 0) {pcount--; this.i += 2}
! 3959: }
! 3960: if (pcount == 0) {
! 3961: if (this.string.slice(this.i,this.i+token.length) == token) {
! 3962: c = this.string.charAt(this.i+token.length);
! 3963: if (c.match(/[^a-z]/i) || !token.match(/[a-z]/i)) {
! 3964: var arg = this.string.slice(start,this.i-1);
! 3965: this.i += token.length;
! 3966: return arg;
! 3967: }
! 3968: }
! 3969: }
! 3970: this.i++;
! 3971: }
! 3972: }
! 3973: this.Error("Couldn't find "+this.cmd+token+" for "+name);
! 3974: },
! 3975:
! 3976: /*
! 3977: * Get a parameter delimited by a control sequence, and
! 3978: * process it to get its mlist
! 3979: */
! 3980: ProcessUpto: function (name,token) {
! 3981: var arg = this.GetUpto(name,token); if (this.error) return;
! 3982: return this.Process(arg);
! 3983: },
! 3984:
! 3985: /*
! 3986: * Get everything up to \end{env}
! 3987: */
! 3988: GetEnd: function (env) {
! 3989: var body = ''; var name = '';
! 3990: while (name != env) {
! 3991: body += this.GetUpto('begin{'+env+'}','end'); if (this.error) return;
! 3992: name = this.GetArgument(this.cmd+'end'); if (this.error) return;
! 3993: }
! 3994: return body;
! 3995: },
! 3996:
! 3997:
! 3998: /***************************************************************************/
! 3999:
! 4000:
! 4001: /*
! 4002: * Ignore spaces
! 4003: */
! 4004: Space: function () {},
! 4005:
! 4006: /*
! 4007: * Collect together any primes and convert them to a superscript
! 4008: */
! 4009: Prime: function (c) {
! 4010: var base = this.mlist.Last();
! 4011: if (base == null || (!base.atom && base.type != 'box' && base.type != 'frac'))
! 4012: {base = this.mlist.Add(jsMath.mItem.Atom('ord',null))}
! 4013: if (base.sup) {this.Error("Prime causes double exponent: use braces to clarify"); return}
! 4014: var sup = '';
! 4015: while (c == "'") {sup += '\\prime'; c = this.GetNext(); if (c == "'") {this.i++}}
! 4016: base.sup = this.Process(sup);
! 4017: },
! 4018:
! 4019: /*
! 4020: * Raise or lower its parameter by a given amount
! 4021: * @@@ Note that this is different from TeX, which requires an \hbox @@@
! 4022: * ### make this work with mu's ###
! 4023: */
! 4024: RaiseLower: function (name) {
! 4025: var h = this.GetDimen(this.cmd+name,1); if (this.error) return;
! 4026: var box = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4027: if (name == 'lower') {h = -h}
! 4028: this.mlist.Add(new jsMath.mItem('raise',{nuc: box, raise: h}));
! 4029: },
! 4030:
! 4031: /*
! 4032: * Shift an expression to the right or left
! 4033: * @@@ Note that this is different from TeX, which requires a \vbox @@@
! 4034: * ### make this work with mu's ###
! 4035: */
! 4036: MoveLeftRight: function (name) {
! 4037: var x = this.GetDimen(this.cmd+name,1); if (this.error) return;
! 4038: var box = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4039: if (name == 'moveleft') {x = -x}
! 4040: this.mlist.Add(jsMath.mItem.Space(x));
! 4041: this.mlist.Add(jsMath.mItem.Atom('ord',box));
! 4042: this.mlist.Add(jsMath.mItem.Space(-x));
! 4043: },
! 4044:
! 4045: /*
! 4046: * Show the argument in a particular color
! 4047: * ### doesn't affect horizontal rules; can we fix that? ###
! 4048: */
! 4049: Color: function (name) {
! 4050: var color = this.GetArgument(this.cmd+name); if (this.error) return;
! 4051: // check that it looks like a color?
! 4052: this.AddHTML(name,['<SPAN STYLE="color: '+color+'">','</SPAN>']);
! 4053: },
! 4054:
! 4055: /*
! 4056: * Make the argument be a link
! 4057: */
! 4058: Href: function (name) {
! 4059: var href = this.GetArgument(this.cmd+name); if (this.error) return;
! 4060: this.AddHTML(name,['<A CLASS="mathlink" HREF="'+href+'">','</A>']);
! 4061: },
! 4062:
! 4063: /*
! 4064: * Apply a CSS class to the argument
! 4065: */
! 4066: Class: function (name) {
! 4067: var clss = this.GetArgument(this.cmd+name); if (this.error) return;
! 4068: this.AddHTML(name,['<SPAN CLASS="'+clss+'">','</SPAN>']);
! 4069: },
! 4070:
! 4071: /*
! 4072: * Apply a CSS style to the argument
! 4073: */
! 4074: Style: function (name) {
! 4075: var style = this.GetArgument(this.cmd+name); if (this.error) return;
! 4076: this.AddHTML(name,['<SPAN STYLE="'+style+'">','</SPAN>']);
! 4077: },
! 4078:
! 4079: /*
! 4080: * Insert some raw HTML around the argument (this will not affect
! 4081: * the spacing or other TeX features)
! 4082: */
! 4083: AddHTML: function (name,params) {
! 4084: var data = this.mlist.data;
! 4085: var arg = this.GetArgument(this.cmd+name); if (this.error) return;
! 4086: arg = jsMath.Parse(arg,data.font,data.size,data.style);
! 4087: if (arg.error) {this.Error(arg); return}
! 4088: this.mlist.Add(jsMath.mItem.HTML(params[0]));
! 4089: for (var i = 0; i < arg.mlist.Length(); i++) {this.mlist.Add(arg.mlist.Get(i))}
! 4090: this.mlist.Add(jsMath.mItem.HTML(params[1]));
! 4091: },
! 4092:
! 4093: /*
! 4094: * Insert a unicode reference as an Ord atom. Its argument should
! 4095: * be the unicode code point, e.g. \unicode{8211}, or \unicode{x203F}.
! 4096: * You can also specify the height and depth in ems, e.g.,
! 4097: * \unicode{8211,.6,-.3}
! 4098: */
! 4099: Unicode: function (name) {
! 4100: var arg = this.GetArgument(this.cmd+name); if (this.error) return;
! 4101: arg = arg.split(','); arg[0] = '&#'+arg[0]+';';
! 4102: if (!arg[1]) {arg[1] = 'normal'}
! 4103: this.mlist.Add(jsMath.mItem.TextAtom('ord',arg[0],arg[1],arg[2],arg[3]));
! 4104: },
! 4105:
! 4106: /*
! 4107: * Implements \frac{num}{den}
! 4108: */
! 4109: Frac: function (name) {
! 4110: var num = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4111: var den = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4112: this.mlist.Add(jsMath.mItem.Fraction('over',num,den));
! 4113: },
! 4114:
! 4115: /*
! 4116: * Implements \sqrt[n]{...}
! 4117: */
! 4118: Sqrt: function (name) {
! 4119: var n = this.GetBrackets(this.cmd+name); if (this.error) return;
! 4120: var arg = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4121: box = jsMath.mItem.Atom('radical',arg);
! 4122: if (this.n != '') {box.root = this.Process(n); if (this.error) return}
! 4123: this.mlist.Add(box);
! 4124: },
! 4125:
! 4126: /*
! 4127: * Implements \root...\of{...}
! 4128: */
! 4129: Root: function (name) {
! 4130: var n = this.ProcessUpto(this.cmd+name,'of'); if (this.error) return;
! 4131: var arg = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4132: box = jsMath.mItem.Atom('radical',arg);
! 4133: box.root = n; this.mlist.Add(box);
! 4134: },
! 4135:
! 4136:
! 4137: /*
! 4138: * Implements \mathchoice{}{}{}{}
! 4139: */
! 4140: MathChoice: function (name) {
! 4141: var D = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4142: var T = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4143: var S = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4144: var SS = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4145: var box = new jsMath.mItem('choice',{D: D, T: T, S: S, SS: SS});
! 4146: this.mlist.Add(new jsMath.mItem('choice',{D: D, T: T, S: S, SS: SS}));
! 4147: },
! 4148:
! 4149: /*
! 4150: * Implements \buildrel...\over{...}
! 4151: */
! 4152: BuildRel: function (name) {
! 4153: var top = this.ProcessUpto(this.cmd+name,'over'); if (this.error) return;
! 4154: var bot = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4155: var op = jsMath.mItem.Atom('op',bot);
! 4156: op.limits = 1; op.sup = top;
! 4157: this.mlist.Add(op);
! 4158: },
! 4159:
! 4160: /*
! 4161: * Create a delimiter of the type and size specified in the parameters
! 4162: */
! 4163: MakeBig: function (name,data) {
! 4164: var type = data[0]; var h = data[1] * jsMath.p_height;
! 4165: var delim = this.GetDelimiter(this.cmd+name); if (this.error) return;
! 4166: this.mlist.Add(jsMath.mItem.Atom(type,jsMath.Box.Delimiter(h,delim,'T')));
! 4167: },
! 4168:
! 4169: /*
! 4170: * Insert the specified character in the given font.
! 4171: */
! 4172: Char: function (name) {
! 4173: var font = this.GetArgument(this.cmd+name); if (this.error) return;
! 4174: var n = this.GetArgument(this.cmd+name); if (this.error) return;
! 4175: this.mlist.Add(jsMath.mItem.Typeset(jsMath.Box.TeX(n-0,font,'T',this.mlist.data.size)));
! 4176: return;
! 4177: },
! 4178:
! 4179: /*
! 4180: * Create an array or matrix.
! 4181: */
! 4182: Matrix: function (name,delim) {
! 4183: var data = this.mlist.data;
! 4184: var arg = this.GetArgument(this.cmd+name); if (this.error) return;
! 4185: var parse = new jsMath.Parser(arg+'\\\\',null,data.size);
! 4186: parse.matrix = name; parse.row = []; parse.table = [];
! 4187: parse.Parse(); if (parse.error) {this.Error(parse); return}
! 4188: parse.HandleRow(name,1); // be sure the last row is recorded
! 4189: var box = jsMath.Box.Layout(data.size,parse.table,delim[2]);
! 4190: // Add parentheses, if needed
! 4191: if (delim[0] && delim[1]) {
! 4192: var left = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[0]],'T');
! 4193: var right = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[1]],'T');
! 4194: box = jsMath.Box.SetList([left,box,right],data.style,data.size);
! 4195: }
! 4196: this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box));
! 4197: },
! 4198:
! 4199: /*
! 4200: * When we see an '&', try to add a matrix entry to the row data.
! 4201: * (Use all the data in the current mList, and then clear it)
! 4202: */
! 4203: HandleEntry: function (name) {
! 4204: if (!this.matrix)
! 4205: {this.Error(name+" can only appear in a matrix or array"); return}
! 4206: if (this.mlist.data.openI != null) {
! 4207: var open = this.mlist.Get(this.mlist.data.openI);
! 4208: if (open.left) {this.Error("Missing "+this.cmd+"right")}
! 4209: else {this.Error("Missing close brace")}
! 4210: }
! 4211: if (this.mlist.data.overI != null) {this.mlist.Over()}
! 4212: var data = this.mlist.data;
! 4213: this.mlist.Atomize('T',data.size); var box = this.mlist.Typeset('T',data.size);
! 4214: this.row[this.row.length] = box;
! 4215: this.mlist = new jsMath.mList(null,null,data.size);
! 4216: },
! 4217:
! 4218: /*
! 4219: * When we see a \cr or \\, try to add a row to the table
! 4220: */
! 4221: HandleRow: function (name,last) {
! 4222: if (!this.matrix)
! 4223: {this.Error(this.cmd+name+" can only appear in a matrix or array"); return}
! 4224: this.HandleEntry(name);
! 4225: if (!last || this.row.length > 1 || this.row[0].format != 'null')
! 4226: {this.table[this.table.length] = this.row}
! 4227: this.row = [];
! 4228: },
! 4229:
! 4230: /*
! 4231: * LaTeX array environment
! 4232: */
! 4233: Array: function (name,delim) {
! 4234: var columns = delim[2]; var cspacing = delim[3];
! 4235: if (!columns) {
! 4236: columns = this.GetArgument(this.cmd+'begin{'+name+'}');
! 4237: if (this.error) return;
! 4238: }
! 4239: columns = columns.replace(/[^clr]/g,'');
! 4240: columns = columns.split('');
! 4241: var data = this.mlist.data;
! 4242: var arg = this.GetEnd(name); if (this.error) return;
! 4243: var parse = new jsMath.Parser(arg+'\\\\',null,data.size);
! 4244: parse.matrix = name; parse.row = []; parse.table = [];
! 4245: parse.Parse(); if (parse.error) {this.Error(parse); return}
! 4246: parse.HandleRow(name,1); // be sure the last row is recorded
! 4247: var box = jsMath.Box.Layout(data.size,parse.table,columns,cspacing);
! 4248: // Add parentheses, if needed
! 4249: if (delim[0] && delim[1]) {
! 4250: var left = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[0]],'T');
! 4251: var right = jsMath.Box.Delimiter(box.h+box.d,this.delimiter[delim[1]],'T');
! 4252: box = jsMath.Box.SetList([left,box,right],data.style,data.size);
! 4253: }
! 4254: this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box));
! 4255: },
! 4256:
! 4257: /*
! 4258: * LaTeX \begin{env}
! 4259: */
! 4260: Begin: function (name) {
! 4261: var env = this.GetArgument(this.cmd+name); if (this.error) return;
! 4262: if (env.match(/[^a-z*]/i)) {this.Error('Invalid environment name "'+env+'"'); return}
! 4263: if (!this.environments[env]) {this.Error('Unknown environment "'+env+'"'); return}
! 4264: var cmd = this.environments[env];
! 4265: if (typeof(cmd) == "string") {cmd = [cmd]}
! 4266: this[cmd[0]](env,cmd.slice(1));
! 4267: },
! 4268:
! 4269: /*
! 4270: * LaTeX \end{env}
! 4271: */
! 4272: End: function (name) {
! 4273: var env = this.GetArgument(this.cmd+name); if (this.error) return;
! 4274: this.Error(this.cmd+name+'{'+env+'} without matching '+this.cmd+'begin');
! 4275: },
! 4276:
! 4277: /*
! 4278: * Debugging routine to test stretchable delimiters
! 4279: */
! 4280: Test: function () {
! 4281: var delim = this.GetDelimiter(this.cmd+'test'); if (this.error) return;
! 4282: var H = this.GetArgument(this.cmd+'test'); if (this.error) return;
! 4283: this.mlist.Add(jsMath.mItem.Typeset(jsMath.Box.Delimiter(H,delim,'T')));
! 4284: return;
! 4285:
! 4286: var leader = this.GetArgument(this.cmd+'test'); if (this.error) return;
! 4287: var W = this.GetArgument(this.cmd+'test'); if (this.error) return;
! 4288: if (this.leaders[leader] == null)
! 4289: {this.Error('Unknown leaders "'+leader+'"'); return}
! 4290: this.mlist.Add(jsMath.mItem.Typeset(jsMath.Box.Leaders(W,this.leaders[leader])));
! 4291: return;
! 4292: },
! 4293:
! 4294: /*
! 4295: * Add a fixed amount of horizontal space
! 4296: */
! 4297: Spacer: function (name,w) {
! 4298: this.mlist.Add(jsMath.mItem.Space(w-0));
! 4299: },
! 4300:
! 4301: /*
! 4302: * Add horizontal space given by the argument
! 4303: */
! 4304: Hskip: function (name) {
! 4305: var w = this.GetDimen(this.cmd+name); if (this.error) return;
! 4306: this.mlist.Add(jsMath.mItem.Space(w));
! 4307: },
! 4308:
! 4309: /*
! 4310: * Typeset the argument as plain text rather than math.
! 4311: */
! 4312: HBox: function (name) {
! 4313: var text = this.GetArgument(this.cmd+name); if (this.error) return;
! 4314: var box = jsMath.Box.InternalMath(text,this.mlist.data.size);
! 4315: this.mlist.Add(jsMath.mItem.Typeset(box));
! 4316: },
! 4317:
! 4318: /*
! 4319: * Implement \fbox{...}
! 4320: */
! 4321: FBox: function (name) {
! 4322: var text = this.GetArgument(this.cmd+name); if (this.error) return;
! 4323: var arg = jsMath.Box.InternalMath(text,this.mlist.data.size);
! 4324: var f = 0.25 * jsMath.sizes[this.mlist.data.size]/100;
! 4325: var box = jsMath.Box.Set(arg,this.mlist.data.style,this.mlist.data.size,1).Remeasured();
! 4326: var frame = jsMath.HTML.Frame(-f,-box.d-f,box.w+2*f,box.h+box.d+2*f);
! 4327: box.html = frame + box.html + jsMath.HTML.Spacer(f);
! 4328: box.h += f; box.d += f; box.w +=2*f; box.x += f;
! 4329: box.bh = Math.max(box.bh,box.h); box.bd = Math.max(box.bd,box.d);
! 4330: this.mlist.Add(jsMath.mItem.Atom('ord',box));
! 4331: },
! 4332:
! 4333: /*
! 4334: * Insert a rule of a particular width, height and depth
! 4335: * This replaces \hrule and \vrule
! 4336: * @@@ not a standard TeX command, and all three parameters must be given @@@
! 4337: */
! 4338: Rule: function (name,gif) {
! 4339: var w = this.GetDimen(this.cmd+name,1); if (this.error) return;
! 4340: var h = this.GetDimen(this.cmd+name,1); if (this.error) return;
! 4341: var d = this.GetDimen(this.cmd+name,1); if (this.error) return;
! 4342: h += d;
! 4343: if (h != 0) {h = Math.max(1.05/jsMath.em,h)}
! 4344: if (h == 0 || w == 0) {gif = "blank"}
! 4345: var html = '<IMG SRC="'+jsMath[gif]+'" STYLE="height: '+jsMath.HTML.Em(h)+'; '
! 4346: + 'width: '+jsMath.HTML.Em(w)+'">';
! 4347: if (d) {
! 4348: html = '<SPAN STYLE="vertical-align:'+jsMath.HTML.Em(-d)+'">'
! 4349: + html + '</SPAN>';
! 4350: }
! 4351: this.mlist.Add(jsMath.mItem.Typeset(new jsMath.Box('html',html,w,h-d,d)));
! 4352: },
! 4353:
! 4354: /*
! 4355: * Inserts an empty box of a specific height and depth
! 4356: */
! 4357: Strut: function () {
! 4358: var size = this.mlist.data.size;
! 4359: var box = jsMath.Box.Text('','normal','T',size).Styled();
! 4360: box.bh = box.bd = 0; box.h = .8; box.d = .3; box.w = 0;
! 4361: this.mlist.Add(jsMath.mItem.Typeset(box));
! 4362: },
! 4363:
! 4364: /*
! 4365: * Handles \phantom, \vphantom and \hphantom
! 4366: */
! 4367: Phantom: function (name,data) {
! 4368: var arg = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4369: this.mlist.Add(new jsMath.mItem('phantom',{phantom: arg, v: data[0], h: data[1]}));
! 4370: },
! 4371:
! 4372: /*
! 4373: * Implements \smash
! 4374: */
! 4375: Smash: function (name,data) {
! 4376: var arg = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4377: this.mlist.Add(new jsMath.mItem('smash',{smash: arg}));
! 4378: },
! 4379:
! 4380: /*
! 4381: * Puts an accent on the following argument
! 4382: */
! 4383: MathAccent: function (name,accent) {
! 4384: var c = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4385: var atom = jsMath.mItem.Atom('accent',c); atom.accent = accent[0];
! 4386: this.mlist.Add(atom);
! 4387: },
! 4388:
! 4389: /*
! 4390: * Handles functions and operators like sin, cos, sum, etc.
! 4391: */
! 4392: NamedOp: function (name,data) {
! 4393: var a = (name.match(/[^acegm-su-z]/)) ? 1: 0;
! 4394: var d = (name.match(/[gjpqy]/)) ? 1: 0;
! 4395: if (data[1]) {name = data[1]}
! 4396: var box = jsMath.mItem.TextAtom('op',name,'cmr10',a,d);
! 4397: if (data[0] != null) {box.limits = data[0]}
! 4398: this.mlist.Add(box);
! 4399: },
! 4400:
! 4401: /*
! 4402: * Implements \limits
! 4403: */
! 4404: Limits: function (name,data) {
! 4405: var atom = this.mlist.Last();
! 4406: if (!atom || atom.type != 'op')
! 4407: {this.Error(this.cmd+name+" is allowed only on operators"); return}
! 4408: atom.limits = data[0];
! 4409: },
! 4410:
! 4411: /*
! 4412: * Implements macros like those created by \def. The named control
! 4413: * sequence is replaced by the string given as the first data value.
! 4414: * If there is a second data value, this specifies how many arguments
! 4415: * the macro uses, and in this case, those arguments are substituted
! 4416: * for #1, #2, etc. within the replacement string.
! 4417: *
! 4418: * See the jsMath.Macro() command below for more details.
! 4419: */
! 4420: Macro: function (name,data) {
! 4421: var text = data[0]
! 4422: if (data[1]) {
! 4423: var args = [];
! 4424: for (var i = 0; i < data[1]; i++)
! 4425: {args[args.length] = this.GetArgument(this.cmd+name); if (this.error) return}
! 4426: text = ''; var c; var i = 0;
! 4427: while (i < data[0].length) {
! 4428: c = data[0].charAt(i++);
! 4429: if (c == '\\') {text += c + data[0].charAt(i++)}
! 4430: else if (c == '#') {
! 4431: c = data[0].charAt(i++);
! 4432: if (c == "#") {text += c} else {
! 4433: if (!c.match(/[1-9]/) || c > args.length)
! 4434: {this.Error("Illegal macro argument reference"); return}
! 4435: text += args[c-1];
! 4436: }
! 4437: } else {text += c}
! 4438: }
! 4439: }
! 4440: this.string = text + this.string.slice(this.i);
! 4441: this.i = 0;
! 4442: },
! 4443:
! 4444: /*
! 4445: * Replace the control sequence with the given text
! 4446: */
! 4447: Replace: function (name,data) {
! 4448: this.mlist.Add(jsMath.mItem.TextAtom(data[0],data[1],data[2],data[3]));
! 4449: },
! 4450:
! 4451: /*
! 4452: * Implements \overbrace, \underbrace, etc.
! 4453: */
! 4454: HandleLeaders: function (name,data) {
! 4455: var box = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4456: box = jsMath.Box.Set(box,'D',this.mlist.data.size).Remeasured();
! 4457: var leader = jsMath.Box.Leaders(box.w,this.leaders[data[0]]);
! 4458: if (data[2]) {leader.y = -leader.h - box.d} else {leader.y = box.h + leader.d}
! 4459: leader.x = -(leader.w + box.w)/2;
! 4460: box = jsMath.mItem.Atom(data[1]? 'op': 'inner',
! 4461: jsMath.Box.SetList([box,leader],'T',this.mlist.data.size));
! 4462: box.limits = (data[1]? 1: 0);
! 4463: this.mlist.Add(box);
! 4464: },
! 4465:
! 4466: /*
! 4467: * Implements \llap, \rlap, etc.
! 4468: */
! 4469: HandleLap: function (name) {
! 4470: var box = this.ProcessArg(); if (this.error) return;
! 4471: box = this.mlist.Add(new jsMath.mItem('lap',{nuc: box, lap: name}));
! 4472: },
! 4473:
! 4474: /*
! 4475: * Adds the argument as a specific type of atom (for commands like
! 4476: * \overline, etc.)
! 4477: */
! 4478: HandleAtom: function (name,data) {
! 4479: var arg = this.ProcessArg(this.cmd+name); if (this.error) return;
! 4480: this.mlist.Add(jsMath.mItem.Atom(data,arg));
! 4481: },
! 4482:
! 4483:
! 4484: /*
! 4485: * Process the character associated with a specific \mathcharcode
! 4486: */
! 4487: HandleMathCode: function (name,code) {
! 4488: var type = (code & 0xF000) >> 12;
! 4489: var font = (code & 0x0F00) >> 8;
! 4490: var code = code & 0x00FF;
! 4491: this.HandleTeXchar(type,font,code);
! 4492: },
! 4493:
! 4494: /*
! 4495: * Add a specific character from a TeX font (use the current
! 4496: * font if the type is 7 (variable) or the font is not specified)
! 4497: */
! 4498: HandleTeXchar: function (type,font,code) {
! 4499: if (type == 7 && this.mlist.data.font != null) {font = this.mlist.data.font}
! 4500: font = jsMath.TeX.fam[font];
! 4501: this.mlist.Add(jsMath.mItem.TeXAtom(jsMath.TeX.atom[type],code,font));
! 4502: },
! 4503:
! 4504: /*
! 4505: * Add a TeX variable character or number
! 4506: */
! 4507: HandleVariable: function (c) {this.HandleTeXchar(7,1,c.charCodeAt(0))},
! 4508: HandleNumber: function (c) {this.HandleTeXchar(7,0,c.charCodeAt(0))},
! 4509:
! 4510: /*
! 4511: * For unmapped characters, just add them in as normal
! 4512: * (non-TeX) characters
! 4513: */
! 4514: HandleOther: function (c) {
! 4515: this.mlist.Add(jsMath.mItem.TextAtom('ord',c,'normal'));
! 4516: },
! 4517:
! 4518: /*
! 4519: * Ignore comments in TeX data
! 4520: * ### Some browsers remove the newlines, so this might cause
! 4521: * extra stuff to be ignored; look into this ###
! 4522: */
! 4523: HandleComment: function () {
! 4524: var c;
! 4525: while (this.i < this.string.length) {
! 4526: c = this.string.charAt(this.i++);
! 4527: if (c == "\r" || c == "\n") return;
! 4528: }
! 4529: },
! 4530:
! 4531: /*
! 4532: * Add a style change (e.g., \displaystyle, etc)
! 4533: */
! 4534: HandleStyle: function (name,style) {
! 4535: this.mlist.data.style = style[0];
! 4536: this.mlist.Add(new jsMath.mItem('style',{style: style[0]}));
! 4537: },
! 4538:
! 4539: /*
! 4540: * Implements \small, \large, etc.
! 4541: */
! 4542: HandleSize: function (name,size) {
! 4543: this.mlist.data.size = size[0];
! 4544: this.mlist.Add(new jsMath.mItem('size',{size: size[0]}));
! 4545: },
! 4546:
! 4547: /*
! 4548: * Set the current font (e.g., \rm, etc)
! 4549: */
! 4550: HandleFont: function (name,font) {
! 4551: this.mlist.data.font = font[0];
! 4552: },
! 4553:
! 4554: /*
! 4555: * Look for and process a control sequence
! 4556: */
! 4557: HandleCS: function () {
! 4558: var cmd = this.GetCommand(); if (this.error) return;
! 4559: if (this.macros[cmd]) {
! 4560: var macro = this.macros[cmd];
! 4561: if (typeof(macro) == "string") {macro = [macro]}
! 4562: this[macro[0]](cmd,macro.slice(1)); return;
! 4563: }
! 4564: if (this.mathchardef[cmd]) {
! 4565: this.HandleMathCode(cmd,this.mathchardef[cmd]);
! 4566: return;
! 4567: }
! 4568: if (this.delimiter[this.cmd+cmd]) {
! 4569: this.HandleMathCode(cmd,this.delimiter[this.cmd+cmd]>>12)
! 4570: return;
! 4571: }
! 4572: this.Error("Unknown control sequence '"+this.cmd+cmd+"'");
! 4573: },
! 4574:
! 4575: /*
! 4576: * Process open and close braces
! 4577: */
! 4578: HandleOpen: function () {this.mlist.Open()},
! 4579: HandleClose: function () {
! 4580: if (this.mlist.data.openI == null) {this.Error("Extra close brace"); return}
! 4581: var open = this.mlist.Get(this.mlist.data.openI);
! 4582: if (!open || open.left == null) {this.mlist.Close()}
! 4583: else {this.Error("Extra close brace or missing "+this.cmd+"right"); return}
! 4584: },
! 4585:
! 4586: /*
! 4587: * Implements \left
! 4588: */
! 4589: HandleLeft: function (name) {
! 4590: var left = this.GetDelimiter(this.cmd+name); if (this.error) return;
! 4591: this.mlist.Open(left);
! 4592: },
! 4593:
! 4594: /*
! 4595: * Implements \right
! 4596: */
! 4597: HandleRight: function (name) {
! 4598: var right = this.GetDelimiter(this.cmd+name); if (this.error) return;
! 4599: var open = this.mlist.Get(this.mlist.data.openI);
! 4600: if (open && open.left != null) {this.mlist.Close(right)}
! 4601: else {this.Error("Extra open brace or missing "+this.cmd+"left");}
! 4602: },
! 4603:
! 4604: /*
! 4605: * Implements generalized fractions (\over, \above, etc.)
! 4606: */
! 4607: HandleOver: function (name,data) {
! 4608: if (this.mlist.data.overI != null)
! 4609: {this.Error('Ambiguous use of '+this.cmd+name); return}
! 4610: this.mlist.data.overI = this.mlist.Length();
! 4611: this.mlist.data.overF = {name: name};
! 4612: if (data.length > 0) {
! 4613: this.mlist.data.overF.left = this.delimiter[data[0]];
! 4614: this.mlist.data.overF.right = this.delimiter[data[1]];
! 4615: } else if (name.match(/withdelims$/)) {
! 4616: this.mlist.data.overF.left = this.GetDelimiter(this.cmd+name); if (this.error) return;
! 4617: this.mlist.data.overF.right = this.GetDelimiter(this.cmd+name); if (this.error) return;
! 4618: }
! 4619: if (name.match(/^above/))
! 4620: {
! 4621: this.mlist.data.overF.thickness = this.GetDimen(this.cmd.name,1);
! 4622: if (this.error) return;
! 4623: }
! 4624: },
! 4625:
! 4626: /*
! 4627: * Add a superscript to the preceeding atom
! 4628: */
! 4629: HandleSuperscript: function () {
! 4630: var base = this.mlist.Last();
! 4631: if (base == null || (!base.atom && base.type != 'box' && base.type != 'frac'))
! 4632: {base = this.mlist.Add(jsMath.mItem.Atom('ord',null))}
! 4633: if (base.sup) {this.Error("Double exponent: use braces to clarify"); return}
! 4634: base.sup = this.ProcessArg('superscript'); if (this.error) return;
! 4635: },
! 4636:
! 4637: /*
! 4638: * Adda subscript to the preceeding atom
! 4639: */
! 4640: HandleSubscript: function () {
! 4641: var base = this.mlist.Last();
! 4642: if (base == null || (!base.atom && base.type != 'box' && base.type != 'frac'))
! 4643: {base = this.mlist.Add(jsMath.mItem.Atom('ord',null))}
! 4644: if (base.sub) {this.Error("Double subscripts: use braces to clarify"); return}
! 4645: base.sub = this.ProcessArg('subscript'); if (this.error) return;
! 4646: },
! 4647:
! 4648: /*
! 4649: * Parse a TeX math string, handling macros, etc.
! 4650: */
! 4651: Parse: function () {
! 4652: var c;
! 4653: while (this.i < this.string.length) {
! 4654: c = this.string.charAt(this.i++);
! 4655: if (this.mathchar[c]) {this.HandleMathCode(c,this.mathchar[c])}
! 4656: else if (this.special[c]) {this[this.special[c]](c)}
! 4657: else if (this.letter.test(c)) {this.HandleVariable(c)}
! 4658: else if (this.number.test(c)) {this.HandleNumber(c)}
! 4659: else {this.HandleOther(c)}
! 4660: }
! 4661: if (this.mlist.data.openI != null) {
! 4662: var open = this.mlist.Get(this.mlist.data.openI);
! 4663: if (open.left) {this.Error("Missing "+this.cmd+"right")}
! 4664: else {this.Error("Missing close brace")}
! 4665: }
! 4666: if (this.mlist.data.overI != null) {this.mlist.Over()}
! 4667: },
! 4668:
! 4669: /*
! 4670: * Perform the processing of Appendix G
! 4671: */
! 4672: Atomize: function () {
! 4673: var data = this.mlist.init;
! 4674: if (!this.error) this.mlist.Atomize(data.style,data.size)
! 4675: },
! 4676:
! 4677: /*
! 4678: * Produce the final HTML.
! 4679: *
! 4680: * We have to wrap the HTML it appropriate <SPAN> tags to hide its
! 4681: * actual dimensions when these don't match the TeX dimensions of the
! 4682: * results. We also include an image to force the results to take up
! 4683: * the right amount of space. The results may need to be vertically
! 4684: * adjusted to make the baseline appear in the correct place.
! 4685: *
! 4686: * This is where the touchiest browser-dependent code appears.
! 4687: */
! 4688: Typeset: function () {
! 4689: var data = this.mlist.init;
! 4690: var box = this.typeset = this.mlist.Typeset(data.style,data.size);
! 4691: if (this.error) {return '<SPAN CLASS="error">'+this.error+'</SPAN>'}
! 4692: if (box.format == 'null') {return ''};
! 4693: var rules = ''; var html
! 4694:
! 4695: box.Styled().Remeasured(); var isSmall = 0; var isBig = 0;
! 4696: var w = box.w; var h = box.bh; var d = box.bd;
! 4697: if (box.bh > box.h && box.bh > jsMath.h+.001) {isSmall = 1}
! 4698: if (box.bd > box.d && box.bd > jsMath.d+.001) {isSmall = 1}
! 4699: if (box.h > jsMath.h) {isBig = 1; h = box.h}
! 4700: if (box.d > jsMath.d) {isBig = 1; d = box.d}
! 4701:
! 4702: if (jsMath.show.BBox) {rules += jsMath.HTML.Frame(0,-box.d,w,box.h+box.d,'green')}
! 4703: if (jsMath.show.Top) {rules += jsMath.HTML.Line(0,box.h,w,'red')}
! 4704: if (jsMath.show.Baseline) {rules += jsMath.HTML.Line(0,0,w,'blue')}
! 4705:
! 4706: html = box.html;
! 4707: if (isSmall) {// hide the extra size
! 4708: if (jsMath.allowAbsolute) {
! 4709: var y = jsMath.absoluteOffsetY;
! 4710: if (jsMath.absoluteHeightVaries || box.bh > jsMath.h+.001) {y += (jsMath.h - box.bh)}
! 4711: html = jsMath.HTML.Absolute(html,w,jsMath.h,0,y,jsMath.h);
! 4712: isBig = 1; h = box.h; d = box.d;
! 4713: } else {// remove line height and try to hide the depth
! 4714: var dy = jsMath.HTML.Em(Math.max(0,box.bd-jsMath.hd)/3);
! 4715: html = '<SPAN STYLE="line-height: 0;'
! 4716: + ' position: relative; top: '+dy+'; vertical-align: '+dy
! 4717: + '">'
! 4718: + html
! 4719: + '</SPAN>';
! 4720: }
! 4721: }
! 4722: html = '<NOBR>' + rules + html;
! 4723: if (isBig) {// add height and depth to the line (force a little
! 4724: // extra to separate lines if needed)
! 4725: html += '<IMG SRC="'+jsMath.blank+'" CLASS="mathHD" '
! 4726: + 'STYLE="height: '+jsMath.HTML.Em(h+d+.2)+'; '
! 4727: + 'vertical-align: '+jsMath.HTML.Em(-d-.1)+';">'
! 4728: }
! 4729: html += '<NOBR>'
! 4730: return html;
! 4731: }
! 4732:
! 4733: });
! 4734:
! 4735: /*
! 4736: * Make these characters special (and call the given routines)
! 4737: */
! 4738: jsMath.Parser.prototype.AddSpecial({
! 4739: cmd: 'HandleCS',
! 4740: open: 'HandleOpen',
! 4741: close: 'HandleClose'
! 4742: });
! 4743:
! 4744:
! 4745: /*
! 4746: * The web-page author can call jsMath.Macro to create additional
! 4747: * TeX macros for use within his or her mathematics. jsMath.Macro
! 4748: * has two required and one optional parameter. The first parameter
! 4749: * is the control sequence name that will trigger the macro, and the
! 4750: * second is the replacement string for that control sequence.
! 4751: * NOTE: since the backslash (\) has special meaning in JavaScript,
! 4752: * you must double the backslash in order to include control sequences
! 4753: * within your replacement string. E.g.,
! 4754: *
! 4755: * <SCRIPT> jsMath.Macro('R','{\\rm R}') </SCRIPT>
! 4756: *
! 4757: * would make \R produce a bold-faced R.
! 4758: *
! 4759: * The optional parameter tells how many arguments the macro
! 4760: * requires. These are substituted for #1, #2, etc. within the
! 4761: * replacement string of the macro. For example
! 4762: *
! 4763: * <SCRIPT> jsMath.Macro('x','{\vec x}_{#1}',1) </SCRIPT>
! 4764: *
! 4765: * would make \x1 produce {\vec x}_{1} and \x{i+1} produce {\vec x}_{i+1}.
! 4766: *
! 4767: * You can put several jsMath.Macro calls together into one .js file, and
! 4768: * then include that into your web page using a command of the form
! 4769: *
! 4770: * <SCRIPT SRC="..."></SCRIPT>
! 4771: *
! 4772: * in your main HTML page. This way you can include the same macros
! 4773: * into several web pages, for example.
! 4774: */
! 4775:
! 4776: jsMath.Add(jsMath,{
! 4777: Macro: function (name) {
! 4778: var macro = jsMath.Parser.prototype.macros;
! 4779: macro[name] = ['Macro'];
! 4780: for (var i = 1; i < arguments.length; i++)
! 4781: {macro[name][macro[name].length] = arguments[i]}
! 4782: }
! 4783: });
! 4784:
! 4785:
! 4786: /***************************************************************************/
! 4787:
! 4788: /*
! 4789: * These routines look through the web page for math elements to process.
! 4790: * There are two main entry points you can call:
! 4791: *
! 4792: * <SCRIPT> jsMath.Process() </SCRIPT>
! 4793: * or
! 4794: * <SCRIPT> jsMath.ProcessBeforeShowing() </SCRIPT>
! 4795: *
! 4796: * The first will process the page asynchronously (so the user can start
! 4797: * reading the top of the file while jsMath is still processing the bottom)
! 4798: * while the second does not update until all the mathematics is typeset.
! 4799: */
! 4800:
! 4801: jsMath.Add(jsMath,{
! 4802:
! 4803: /*
! 4804: * Typeset a string in \textstyle and return the HTML for it
! 4805: */
! 4806: TextMode: function (s) {
! 4807: var parse = jsMath.Parse(s,null,null,'T');
! 4808: parse.Atomize();
! 4809: var html = parse.Typeset();
! 4810: return html;
! 4811: },
! 4812:
! 4813: /*
! 4814: * Typeset a string in \displaystyle and return the HTML for it
! 4815: * ### need to give more control over whether to center, etc. ###
! 4816: */
! 4817: DisplayMode: function (s) {
! 4818: var parse = jsMath.Parse(s,null,null,'D');
! 4819: parse.Atomize();
! 4820: var html = parse.Typeset();
! 4821: return html;
! 4822: },
! 4823:
! 4824: /*
! 4825: * Return the text of a given DOM element
! 4826: */
! 4827: GetElementText: function (element) {
! 4828: var text = element.innerText;
! 4829: if (text == null) {
! 4830: text = element.textContent;
! 4831: if (text == null) {
! 4832: text = element.innerHTML;
! 4833: }
! 4834: }
! 4835: if (text.search('&')) {
! 4836: text = text.replace(/</g,'<');
! 4837: text = text.replace(/>/g,'>');
! 4838: text = text.replace(/"/g,'"');
! 4839: text = text.replace(/&/g,'&');
! 4840: }
! 4841: return text;
! 4842: },
! 4843:
! 4844: /*
! 4845: * Typeset the contents of an element in \textstyle
! 4846: */
! 4847: ConvertText: function (element) {
! 4848: var text = this.GetElementText(element);
! 4849: element.innerHTML = this.TextMode(text);
! 4850: element.className = 'typeset';
! 4851: },
! 4852:
! 4853: /*
! 4854: * Typeset the contents of an element in \displaystyle
! 4855: */
! 4856: ConvertDisplay: function (element) {
! 4857: var text = this.GetElementText(element);
! 4858: element.innerHTML = this.DisplayMode(text);
! 4859: element.className = 'typeset';
! 4860: },
! 4861:
! 4862: /*
! 4863: * Call this at the bottom of your HTML page to have the
! 4864: * mathematics typeset before the page is displayed.
! 4865: * This can take a long time, so the user could cancel the
! 4866: * page before it is complete; use it with caution, and only
! 4867: * when there is a relatively small amount of math on the page.
! 4868: */
! 4869: ProcessBeforeShowing: function () {
! 4870: if (!jsMath.initialized) {jsMath.Init()}
! 4871: var element = jsMath.GetMathElements();
! 4872: for (var i = 0; i < element.length; i++)
! 4873: {jsMath.ProcessElement(element[i])}
! 4874: jsMath.ProcessComplete();
! 4875: },
! 4876:
! 4877: /*
! 4878: * Process a math element
! 4879: */
! 4880: ProcessElement: function (element) {
! 4881: window.status = 'Processing Math...';
! 4882: if (element.tagName == 'DIV') {
! 4883: this.ConvertDisplay(element);
! 4884: } else if (element.tagName == 'SPAN') {
! 4885: this.ConvertText(element);
! 4886: }
! 4887: },
! 4888:
! 4889: /*
! 4890: * Asynchronously process all the math elements starting with
! 4891: * the k-th one
! 4892: */
! 4893: ProcessElements: function (k) {
! 4894: if (k >= this.element.length) {
! 4895: this.ProcessComplete();
! 4896: } else {
! 4897: this.ProcessElement(this.element[k])
! 4898: setTimeout('jsMath.ProcessElements('+(k+1)+')',jsMath.delay);
! 4899: }
! 4900: },
! 4901:
! 4902: /*
! 4903: * Call this at the bottom of your HTML page to have the
! 4904: * mathematics typeset asynchronously. This lets the user
! 4905: * start reading the mathematics while the rest of the page
! 4906: * is being processed.
! 4907: */
! 4908: Process: function () {
! 4909: if (!jsMath.initialized) {jsMath.Init()}
! 4910: this.element = this.GetMathElements();
! 4911: window.status = 'Processing Math...';
! 4912: setTimeout('jsMath.ProcessElements(0)',jsMath.delay);
! 4913: },
! 4914:
! 4915: element: [], // the list of math elements on the page
! 4916:
! 4917: /*
! 4918: * Look up all the math elements on the page and
! 4919: * put them in a list sorted from top to bottom of the page
! 4920: */
! 4921: GetMathElements: function () {
! 4922: var element = [];
! 4923: var math = document.getElementsByTagName('DIV');
! 4924: for (var k = 0; k < math.length; k++) {
! 4925: if (math[k].className == 'math') {
! 4926: if (jsMath.renameOK) {math[k].setAttribute('NAME','_jsMath_')}
! 4927: else {element[element.length] = math[k]}
! 4928: }
! 4929: }
! 4930: math = document.getElementsByTagName('SPAN');
! 4931: for (var k = 0; k < math.length; k++) {
! 4932: if (math[k].className == 'math') {
! 4933: if (jsMath.renameOK) {math[k].setAttribute('NAME','_jsMath_')}
! 4934: else {element[element.length] = math[k]}
! 4935: }
! 4936: }
! 4937: // this gets the SPAN and DIV elements interleaved in order
! 4938: if (jsMath.renameOK) {
! 4939: element = document.getElementsByName('_jsMath_')
! 4940: } else if (jsMath.hidden.sourceIndex) {
! 4941: element.sort(function (a,b) {return a.sourceIndex - b.sourceIndex});
! 4942: }
! 4943: return element;
! 4944: },
! 4945:
! 4946: /*
! 4947: * Remove the window message about processing math
! 4948: * and clean up any marked <SPAN> or <DIV> tags
! 4949: */
! 4950: ProcessComplete: function () {
! 4951: if (jsMath.renameOK) {
! 4952: var element = document.getElementsByName('_jsMath_');
! 4953: for (var i = element.length-1; i >= 0; i--) {
! 4954: element[i].removeAttribute('NAME');
! 4955: }
! 4956: }
! 4957: jsMath.element = [];
! 4958: window.status = 'Done';
! 4959: }
! 4960:
! 4961: });
! 4962:
! 4963: /***************************************************************************/
! 4964:
! 4965: /*
! 4966: * We use a hidden <DIV> for measuring the BBoxes of things
! 4967: */
! 4968: jsMath.hidden = '<DIV CLASS="normal" ID="jsMath.Hidden" ' +
! 4969: 'STYLE="position:absolute; top:0 left:0;"></DIV>';
! 4970: if (document.body.insertAdjacentHTML) {
! 4971: document.body.insertAdjacentHTML('AfterBegin',jsMath.hidden);
! 4972: } else {
! 4973: document.write(jsMath.hidden);
! 4974: }
! 4975: jsMath.hidden = document.getElementById("jsMath.Hidden");
! 4976:
! 4977: /*
! 4978: * Initialize everything
! 4979: */
! 4980: jsMath.InitSource();
! 4981: jsMath.InitBrowser();
! 4982: jsMath.InitStyles();
! 4983:
! 4984: //make sure browser-specific loads are done before this
! 4985: document.write('<SCRIPT>jsMath.CheckFonts()</SCRIPT>');
! 4986:
! 4987: }
! 4988:
! 4989: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>