';
+ if (!document.body.insertAdjacentHTML) {document.write(html)}
+ else {document.body.insertAdjacentHTML('AfterBegin',html)}
+ div = jsMath.Element(id);
+ }
+ return div;
},
/*
- * Initialize jsMath. This determines the em size, and a variety
- * of other parameters used throughout jsMath.
+ * Source a jsMath JavaScript file
*/
- Init: function() {
- this.em = this.BBoxFor('
').w/20;
- var h = this.BBoxFor('x').h; // Line height and depth to baseline
- var d = this.BBoxFor('x
').h - h;
- this.h = (h-d)/this.em; this.d = d/this.em;
- this.hd = this.h + this.d;
- this.ph = h-d; this.pd = d;
-
- this.InitTeXfonts();
-
- var x_height = this.EmBoxFor('
').w/2;
- this.TeX.M_height = x_height*(26/14);
- this.TeX.h = this.h; this.TeX.d = this.d; this.TeX.hd = this.hd;
- // factor for \big and its brethren
- this.p_height = (this.TeX.cmex10[0].h+this.TeX.cmex10[0].d) / .85;
-
- this.InitSizes();
-
- this.initialized = 1;
+ Script: function (file) {
+ if (!file.match('^([a-zA-Z]+:/)?/')) {file = jsMath.root + file}
+ document.write('');
+ },
+
+ /*
+ * Use a hidden
for measuring the BBoxes of things
+ */
+ HTML: function () {
+ jsMath.hidden = this.TopHTML("Hidden",{'class':"normal"},{
+ position:"absolute", top:0, left:0, border:0, padding:0, margin:0
+ });
+ jsMath.hiddenTop = jsMath.hidden;
+ return;
},
/*
* Find the root URL for the jsMath files (so we can load
- * the other .js and .gif files
+ * the other .js and .gif files)
*/
- InitSource: function () {
+ Source: function () {
var script = document.getElementsByTagName('SCRIPT');
- var src = script[script.length-1].getAttribute('SRC');
- if (src.match('(^|/)jsMath.js$')) {
- this.root = src.replace(/jsMath.js$/,'');
- this.blank = this.root + this.blank;
- this.black = this.root + this.black;
+ if (script) {
+ for (var i = 0; i < script.length; i++) {
+ var src = script[i].src;
+ if (src && src.match('(^|/)jsMath.js$')) {
+ jsMath.root = src.replace(/jsMath.js$/,'');
+ jsMath.Img.root = jsMath.root + "fonts/";
+ jsMath.blank = jsMath.root + jsMath.blank;
+ this.Domain();
+ return;
+ }
+ }
+ }
+ jsMath.root = ''; jsMath.Img.root = "fonts/";
+ },
+
+ /*
+ * Find the most restricted common domain for the main
+ * page and jsMath. Report an error if jsMath is outside
+ * the domain of the calling page.
+ */
+ Domain: function () {
+ var jsDomain = ''; var pageDomain = document.domain;
+ if (jsMath.root.match('://([^/]*)/')) {jsDomain = RegExp.$1}
+ jsDomain = jsDomain.replace(/:\d+$/,'');
+ if (jsDomain == "" || jsDomain == pageDomain) return;
+ //
+ // MSIE on the Mac can't change document.domain and 'try' won't
+ // catch the error (Grrr!), so exit for them
+ //
+ if (navigator.appName == 'Microsoft Internet Explorer' &&
+ navigator.platform == 'MacPPC' && navigator.onLine &&
+ navigator.userProfile && document.all) return;
+ jsDomain = jsDomain.split(/\./); pageDomain = pageDomain.split(/\./);
+ if (jsDomain.length < 2 || pageDomain.length < 2 ||
+ jsDomain[jsDomain.length-1] != pageDomain[pageDomain.length-1] ||
+ jsDomain[jsDomain.length-2] != pageDomain[pageDomain.length-2]) {
+ this.DomainWarning();
+ return;
}
+ var domain = jsDomain[jsDomain.length-2] + '.' + jsDomain[jsDomain.length-1];
+ for (var i = 3; i <= jsDomain.length && i <= pageDomain.length; i++) {
+ if (jsDomain[jsDomain.length-i] != pageDomain[pageDomain.length-i]) break;
+ domain = jsDomain[jsDomain.length-i] + '.' + domain;
+ }
+ document.domain = domain;
+ },
+
+ DomainWarning: function () {
+ alert("In order for jsMath to be able to load the additional "
+ + "components that it may need, the jsMath.js file must be "
+ + "loaded from a server in the same domain as the page that "
+ + "contains it. Because that is not the case for this page, "
+ + "the mathematics displayed here may not appear correctly.");
},
/*
* Look up the default height and depth for a TeX font
* and set the skewchar
*/
- InitTeXfont: function (name) {
- var font = this.TeX[name];
- var WH = this.EmBoxFor('
'+font[65].c+'');
+ TeXfont: function (name) {
+ var font = jsMath.TeX[name];
+ var WH = jsMath.EmBoxFor('
'+font[65].c+'');
font.hd = WH.h;
- font.d = this.EmBoxFor('
'+ font[65].c +
- '
').h
+ font.d = jsMath.EmBoxFor('
'+ font[65].c +
+ '
').h
- font.hd;
font.h = font.hd - font.d;
- font.dh = .05;
+ font.dh = .05; if (jsMath.browser == 'Safari') {font.hd *= 2};
if (name == 'cmmi10') {font.skewchar = 0177}
else if (name == 'cmsy10') {font.skewchar = 060}
},
@@ -354,75 +392,265 @@ var jsMath = {
/*
* Init all the TeX fonts
*/
- InitTeXfonts: function () {
- for (var i = 0; i < this.TeX.fam.length; i++)
- {if (this.TeX.fam[i]) {this.InitTeXfont(this.TeX.fam[i])}}
+ TeXfonts: function () {
+ for (var i = 0; i < jsMath.TeX.fam.length; i++)
+ {if (jsMath.TeX.fam[i]) {this.TeXfont(jsMath.TeX.fam[i])}}
},
/*
* Compute font parameters for various sizes
*/
- InitSizes: function () {
- this.TeXparams = [];
- for (var j=0; j < this.sizes.length; j++) {this.TeXparams[j] = {}}
- for (var i in this.TeX) {
- if (typeof(this.TeX[i]) != 'object') {
- for (var j=0; j < this.sizes.length; j++) {
- this.TeXparams[j][i] = this.sizes[j]*this.TeX[i]/100;
+ Sizes: function () {
+ jsMath.TeXparams = [];
+ for (var j=0; j < jsMath.sizes.length; j++) {jsMath.TeXparams[j] = {}}
+ for (var i in jsMath.TeX) {
+ if (typeof(jsMath.TeX[i]) != 'object') {
+ for (var j=0; j < jsMath.sizes.length; j++) {
+ jsMath.TeXparams[j][i] = jsMath.sizes[j]*jsMath.TeX[i]/100;
}
}
}
},
+
/*
- * Test for browser characteristics, and adjust the font table
+ * Send the style definitions to the browser (these may be adjusted
+ * by the browser-specific code)
+ */
+ Styles: function (styles) {
+ if (!styles) {
+ styles = jsMath.styles;
+ styles['.jsM_scale'] = 'font-size:'+jsMath.Controls.cookie.scale+'%';
+ }
+ document.writeln('');
+ },
+
+ /*
+ * Do the initialization that requires the BODY to be in place.
+ * (called automatically if the jsMath.js file is loaded in the
+ * BODY, but must be called explicitly if it is in the HEAD).
+ */
+ Body: function () {
+ if (this.inited) return;
+
+ this.inited = -1;
+
+ jsMath.Setup.HTML();
+ jsMath.Setup.Source();
+ jsMath.Browser.Init();
+ jsMath.Controls.Init();
+ jsMath.Click.Init();
+ jsMath.Setup.Styles();
+
+ jsMath.Setup.User(); // do user-specific initialization
+
+ //make sure browser-specific loads are done before this
+ document.write('');
+
+ this.inited = 1;
+ },
+
+ /*
+ * Web page author can override this to do initialization
+ * that must be done before the font check is performed
+ */
+ User: function () {}
+
+};
+
+jsMath.Update = {
+
+ /*
+ * Update specific parameters for a limited number of font entries
+ */
+ TeXfonts: function (change) {
+ for (var font in change) {
+ for (var code in change[font]) {
+ for (var id in change[font][code]) {
+ jsMath.TeX[font][code][id] = change[font][code][id];
+ }
+ }
+ }
+ },
+
+ /*
+ * Update the character code for every character in a list
+ * of fonts
+ */
+ TeXfontCodes: function (change) {
+ for (var font in change) {
+ for (var i = 0; i < change[font].length; i++) {
+ jsMath.TeX[font][i].c = change[font][i];
+ }
+ }
+ },
+
+ /*
+ * Add a collection of styles to the style list
+ */
+ Styles: function (styles) {
+ for (var i in styles) {jsMath.styles[i] = styles[i]}
+ }
+
+};
+
+/***************************************************************************/
+
+/*
+ * Implement browser-specific checks
+ */
+
+jsMath.Browser = {
+
+ allowAbsolute: 1, // tells if browser can nest absolutely positioned
+ // SPANs inside relative SPANs
+ allowAbsoluteDelim: 0, // OK to use absolute placement for building delims?
+ separateSkips: 0, // MSIE doesn't do negative left margins, and
+ // Netscape doesn't combine skips well
+
+ msieSpaceFix: '', // for MSIE spacing bug fix
+ msieCenterBugFix: '', // for MSIE centering bug with image fonts
+ msieInlineBlockFix: '', // for MSIE alignment bug in non-quirks mode
+ imgScale: 1, // MSI scales images for 120dpi screens, so compensate
+
+ renameOK: 1, // tells if brower will find a tag whose name
+ // has been set via setAttributes
+
+ delay: 1, // delay for asynchronous math processing
+
+ spaceWidth: 0, // Konqueror space fix
+ hiddenSpace: "", // ditto
+ valignBug: 0, // Konqueror doesn't nest vertical-align
+
+ operaHiddenFix: '', // for Opera to fix bug with math in tables
+
+ /*
+ * Determine if the "top" of a
is always at the same height
+ * or varies with the height of the rest of the line (MSIE).
+ */
+ TestSpanHeight: function () {
+ jsMath.hidden.innerHTML = '
';
+ var span = jsMath.hidden.getElementsByTagName('SPAN')[0];
+ var img = jsMath.hidden.getElementsByTagName('IMG')[0];
+ this.spanHeightVaries = (span.offsetHeight == img.offsetHeight);
+ jsMath.hidden.innerHTML = '';
+ },
+
+ /*
+ * Determine if the NAME attribute of a tag can be changed
+ * using the setAttribute function, and then be properly
+ * returned by getElementByName.
+ */
+ TestRenameOK: function () {
+ jsMath.hidden.innerHTML = '';
+ var test = document.getElementById('jsMath.test');
+ test.setAttribute('NAME','jsMath_test');
+ this.renameOK = (document.getElementsByName('jsMath_test').length > 0);
+ jsMath.hidden.innerHTML = '';
+ },
+
+ /*
+ * Test for browser characteristics, and adjust things
* to overcome specific browser bugs
*/
- InitBrowser: function () {
+ Init: function () {
jsMath.browser = 'unknown';
- this.isSafari = navigator.userAgent.match(/Safari/);
this.TestSpanHeight();
this.TestRenameOK();
+ this.MSIE();
+ this.Mozilla();
+ this.Opera();
+ this.OmniWeb();
+ this.Safari();
+ this.Konqueror();
+
//
- // Check for bug-filled Internet Explorer
- //
+ // Change some routines depending on the browser
+ //
+ if (this.allowAbsoluteDelim) {
+ jsMath.Box.DelimExtend = jsMath.Box.DelimExtendAbsolute;
+ jsMath.Box.Layout = jsMath.Box.LayoutAbsolute;
+ } else {
+ jsMath.Box.DelimExtend = jsMath.Box.DelimExtendRelative;
+ jsMath.Box.Layout = jsMath.Box.LayoutRelative;
+ }
+
+ if (this.separateSkips) {
+ jsMath.HTML.Place = jsMath.HTML.PlaceSeparateSkips;
+ jsMath.Typeset.prototype.Place = jsMath.Typeset.prototype.PlaceSeparateSkips;
+ }
+ },
+
+ //
+ // Handle bug-filled Internet Explorer
+ //
+ MSIE: function () {
if (this.spanHeightVaries) {
jsMath.browser = 'MSIE';
if (navigator.platform == 'Win32') {
- this.UpdateTeXfonts({
+ jsMath.Update.TeXfonts({
cmr10: {'10': {c: 'Ω', tclass: 'normal'}},
cmmi10: {
- '10': {c: 'Ω', tclass: 'normal'},
- '126': {c: '~'}
- },
- cmsy10: {'10': {c: '⊗', tclass: 'arial'}},
+ '10': {c: 'Ω', tclass: 'normal'},
+ '126': {c: '~'}
+ },
+ cmsy10: {
+ '10': {c: '⊗', tclass: 'arial'},
+ '55': {c: '7'}
+ },
cmex10: {'10': {c: 'D'}},
cmti10: {'10': {c: 'Ω', tclass: 'normal'}},
cmbx10: {'10': {c: 'Ω', tclass: 'normal'}}
});
this.allowAbsoluteDelim = 1;
- this.separateSkips = 1;
+ this.separateSkips = 1;
+ this.buttonCheck = 1;
+ this.msieDivWidthBug = 1;
this.msieFontBug = 1; this.msieIntegralBug = 1;
+ this.msieAlphaBug = 1; this.alphaPrintBug = 1;
+ this.msieCenterBugFix = 'position:relative; ';
this.msieSpaceFix = '
';
+ this.msieInlineBlockFix = ' display: inline-block;';
jsMath.Macro('joinrel','\\mathrel{\\kern-5mu}'),
- jsMath.Macro('mapsto','\\mapstochar\\kern-.54em\\rightarrow');
- jsMath.Macro('longmapsto','\\mapstochar\\kern-.54em\\char{cmsy10}{0}\\joinrel\\rightarrow');
+ jsMath.styles['.arial'] = "font-family: 'Arial unicode MS'";
+ // MSIE doesn't implement fixed positioning, so use absolute
+ jsMath.styles['.jsM_panel'] =
+ jsMath.styles['.jsM_panel'].replace(/position:fixed/,"position:absolute").replace(/width:auto/,"");
+ jsMath.styles['.jsM_button'] = 'width:1px; '
+ + jsMath.styles['.jsM_button'].replace(/position:fixed/,"position:absolute").replace(/width:auto/,"");
+ window.onscroll = jsMath.Controls.MoveButton;
+ // MSIE will rescale images if the DPIs differ
+ if (screen.deviceXDPI && screen.logicalXDPI
+ && screen.deviceXDPI != screen.logicalXDPI) {
+ this.imgScale *= screen.logicalXDPI/screen.deviceXDPI;
+ jsMath.Controls.cookie.alpha = 0;
+ }
+ // Handle bug with getting width of italic text
+ this.italicString = 'x';
+ jsMath.EmBoxFor = jsMath.EmBoxForItalics;
} else if (navigator.platform == 'MacPPC') {
- document.writeln('');
+ this.msieAbsoluteBug = 1; this.msieButtonBug = 1;
+ this.msieDivWidthBug = 1;
+ jsMath.Setup.Script('jsMath-msie-mac.js');
jsMath.Parser.prototype.macros.angle = ['Replace','ord','','normal'];
- jsMath.msieAbsoluteBug = 1;
+ jsMath.styles['.jsM_panel'] = 'width:25em; ' + jsMath.styles['.jsM_panel'].replace(/width:auto/,"");
+ jsMath.styles['.jsM_button'] = 'width:1px; ' + jsMath.styles['.jsM_button'].replace(/width:auto/,"");
}
jsMath.Macro('not','\\mathrel{\\rlap{\\kern3mu/}}');
}
+ },
- //
- // Look for Netscape/Mozilla (any flavor)
- //
- if (this.hidden.ATTRIBUTE_NODE) {
+ //
+ // Handle Netscape/Mozilla (any flavor)
+ //
+ Mozilla: function () {
+ if (jsMath.hidden.ATTRIBUTE_NODE) {
jsMath.browser = 'Mozilla';
if (navigator.platform == 'MacPPC') {
- this.UpdateTeXfonts({
+ jsMath.Update.TeXfonts({
cmr10: {'10': {c: 'Ω', tclass: 'normal'}},
cmmi10: {'10': {c: 'Ω', tclass: 'normal'}},
cmsy10: {'10': {c: '⊗', tclass: 'normal'}},
@@ -431,32 +659,38 @@ var jsMath = {
cmbx10: {'10': {c: 'Ω', tclass: 'normal'}}
});
} else {
- document.writeln('');
+ jsMath.Setup.Script('jsMath-mozilla.js');
+ this.alphaPrintBug = 1;
}
- for (var i = 0; i < this.TeX.fam.length; i++) {
- if (this.TeX.fam[i])
- {this.styles['.'+this.TeX.fam[i]] += '; position: relative'}
+ for (var i = 0; i < jsMath.TeX.fam.length; i++) {
+ if (jsMath.TeX.fam[i])
+ {jsMath.styles['.'+jsMath.TeX.fam[i]] += '; position: relative'}
}
this.allowAbsoluteDelim = 1;
this.separateSkips = 1;
jsMath.Macro('not','\\mathrel{\\rlap{\\kern3mu/}}');
}
-
- //
- // Look for OmniWeb
- //
+ },
+
+ //
+ // Handle OmniWeb
+ //
+ OmniWeb: function () {
if (navigator.accentColorName) {
jsMath.browser = 'OmniWeb';
- this.allowAbsolute = 0;
+ this.allowAbsolute = !navigator.userAgent.match("OmniWeb/v4");
+ this.allowAbsoluteDelim = this.allowAbsolute;
+ this.buttonCheck = 1;
}
+ },
- //
- // Look for Opera
- //
- if (navigator.userAgent.search(" Opera ") >= 0) {
+ //
+ // Handle Opera
+ //
+ Opera: function () {
+ if (navigator.appName == 'Opera' || navigator.userAgent.match(" Opera ")) {
jsMath.browser = 'Opera';
- this.isOpera = 1;
- this.UpdateTeXfonts({
+ jsMath.Update.TeXfonts({
cmr10: {
'10': {c: 'Ω', tclass: 'normal'},
'20': {c: 'ˇ', tclass: 'normal'}
@@ -483,109 +717,620 @@ var jsMath = {
}
});
this.allowAbsolute = 0;
- jsMath.delay = 10;
+ this.delay = 10;
+ this.operaHiddenFix = '[Processing Math]';
}
+ },
- //
- // Look for Safari
- //
- if (this.isSafari) {
+ //
+ // Handle Safari
+ //
+ Safari: function () {
+ if (navigator.appVersion.match(/Safari\//)) {
jsMath.browser = 'Safari';
- var version = navigator.userAgent.match("Safari/([0-9]+)")[1];
- if (version < 125) {this.allowAbsolute = 0; this.oldSafari = 1}
- for (var i = 0; i < this.TeX.fam.length; i++)
- {if (this.TeX.fam[i] != '') {this.TeX[this.TeX.fam[i]].dh = .1}}
- this.absoluteOffsetY = -.05;
- this.TeX.axis_height += .05;
- this.allowAbsoluteDelim = ! this.oldSafari;
+ var version = navigator.userAgent.match("Safari/([0-9]+)");
+ version = (version)? version[1] : 200; // FIXME: hack until I get Tiger
+ for (var i = 0; i < jsMath.TeX.fam.length; i++)
+ {if (jsMath.TeX.fam[i]) {jsMath.TeX[jsMath.TeX.fam[i]].dh = .1}}
+ jsMath.TeX.axis_height += .05;
+ this.allowAbsoluteDelim = version >= 125;
+ this.safariIFRAMEbug = version >= 312; // FIXME: find out if they fixed it
+ this.safariImgBug = 1;
+ this.buttonCheck = 1;
+ }
+ },
+
+ //
+ // Handle Konqueror
+ //
+ Konqueror: function () {
+ if (navigator.product && navigator.product.match("Konqueror")) {
+ jsMath.browser = 'Konqueror';
+ jsMath.Update.TeXfonts({
+ cmr10: {'20': {c: 'ˇ', tclass: 'normal'}},
+ cmmi10: {'20': {c: 'κ', tclass: 'normal'}},
+ cmsy10: {'20': {c: '≤', tclass: 'normal'}},
+ cmex10: {'20': {c: '"'}},
+ cmti10: {'20': {c: 'ˇ', tclass: 'normal'}},
+ cmbx10: {'20': {c: 'ˇ', tclass: 'normal'}}
+ });
+ this.allowAbsolute = 0;
+ this.allowAbsoluteDelim = 0;
+ if (navigator.userAgent.match(/Konqueror\/(\d+)\.(\d+)/)) {
+ if (RegExp.$1 < 3 || (RegExp.$1 == 3 && RegExp.$2 < 3)) {
+ this.separateSkips = 1;
+ this.valignBug = 1;
+ this.hiddenSpace = ' ';
+ jsMath.Box.prototype.Remeasured = function () {return this};
+ }
+ }
}
+ }
- //
- // Change some routines depending on the browser
- //
- if (this.allowAbsoluteDelim) {
- jsMath.Box.DelimExtend = jsMath.Box.DelimExtendAbsolute;
- jsMath.Box.Layout = jsMath.Box.LayoutAbsolute;
+};
+
+/***************************************************************************/
+
+/*
+ * Implement font check and messages
+ */
+jsMath.Font = {
+
+ fallback: "symbol", // the default fallback method
+
+ // the HTML for the missing font message
+ message:
+ 'No TeX fonts found -- using image fonts instead.
\n'
+ + 'These may be slow and might not print well.
\n'
+ + 'Use the jsMath control panel to get additional information.',
+
+ extra_message:
+ 'Extra TeX fonts not found:
'
+ + 'Using image fonts instead. This may be slow and might not print well.
\n'
+ + 'Use the jsMath control panel to get additional information.',
+
+ /*
+ * Look to see if a font is found. HACK!
+ * Check the character in a given position, and see if it is
+ * wider than the usual one in that position.
+ */
+ Test1: function (name,n,factor) {
+ if (n == null) {n = 124}; if (factor == null) {factor = 2}
+ var wh1 = jsMath.BBoxFor(''+jsMath.TeX[name][n].c+'');
+ var wh2 = jsMath.BBoxFor(''+jsMath.TeX[name][n].c+'');
+ //alert([wh1.w,wh2.w,wh1.h,factor*wh2.w]);
+ return (wh1.w > factor*wh2.w && wh1.h != 0);
+ },
+
+ Test2: function (name,n,factor) {
+ if (n == null) {n = 124}; if (factor == null) {factor = 2}
+ var wh1 = jsMath.BBoxFor(''+jsMath.TeX[name][n].c+'');
+ var wh2 = jsMath.BBoxFor(''+jsMath.TeX[name][n].c+'');
+ //alert([wh2.w,wh1.w,wh1.h,factor*wh1.w]);
+ return (wh2.w > factor*wh1.w && wh1.h != 0);
+ },
+
+ /*
+ * Check for the availability of TeX fonts. We do this by looking at
+ * the width and height of a character in the cmex10 font. The cmex10
+ * font has depth considerably greater than most characters' widths (the
+ * whole font has the depth of the character with greatest depth). This
+ * is not the case for most fonts, so if we can access cmex10, the
+ * height of a character should be much bigger than the width.
+ * Otherwise, if we don't have cmex10, we'll get a character in another
+ * font with normal height and width. In this case, we insert a message
+ * pointing the user to the jsMath site, and load one of the fallback
+ * definitions.
+ *
+ */
+ Check: function () {
+ var cookie = jsMath.Controls.cookie;
+ var wh = jsMath.BBoxFor(''+jsMath.TeX.cmex10[1].c+'');
+ jsMath.nofonts = ((wh.w*3 > wh.h || wh.h == 0) && !this.Test1('cmr10'));
+ if (jsMath.nofonts) {
+ if (cookie.autofont || cookie.font == 'tex') {
+ cookie.font = this.fallback;
+ if (cookie.warn) {
+ jsMath.nofontMessage = 1;
+ cookie.warn = 0; jsMath.Controls.SetCookie(0);
+ if (window.NoFontMessage) {window.NoFontMessage()}
+ else {this.Message(this.message)}
+ }
+ }
} else {
- jsMath.Box.DelimExtend = jsMath.Box.DelimExtendRelative;
- jsMath.Box.Layout = jsMath.Box.LayoutRelative;
+ if (cookie.autofont) {cookie.font = 'tex'}
+ if (cookie.font == 'tex') return;
}
-
- if (this.separateNegativeSkips) {
- jsMath.HTML.Place = jsMath.HTML.PlaceSeparateNegative;
- jsMath.Typeset.prototype.Place = jsMath.Typeset.prototype.PlaceSeparateNegative;
- } else if (this.separateSkips) {
- jsMath.HTML.Place = jsMath.HTML.PlaceSeparateSkips;
- jsMath.Typeset.prototype.Place = jsMath.Typeset.prototype.PlaceSeparateSkips;
+ if (jsMath.noImgFonts) {cookie.font = 'unicode'}
+ if (cookie.font == 'unicode') {
+ var platform = ({Win32: 'pc', MacPPC: 'mac'})[navigator.platform] || 'unix';
+ jsMath.Setup.Script('jsMath-fallback-'+platform+'.js');
+ return;
}
-
- if (this.noEmptySpans) {jsMath.HTML.Spacer = jsMath.HTML.SpacerImage}
+ if (cookie.font == 'symbol') {
+ jsMath.Setup.Script('jsMath-fallback-symbols.js');
+ return;
+ }
+ jsMath.Img.SetFont({
+ cmr10: ['all'], cmmi10: ['all'], cmsy10: ['all'],
+ cmex10: ['all'], cmbx10: ['all'], cmti10: ['all']
+ });
+ jsMath.Img.LoadFont('cm-fonts');
+ },
+ /*
+ * The message for when no TeX fonts. You can eliminate this message
+ * by including
+ *
+ *
+ *
+ * in your HTML file, before loading jsMath.js, if you want. But this
+ * means the user may not know that he or she can get a better version
+ * of your page.
+ */
+ Message: function (message) {
+ if(jsMath.Element("Warning")) return;
+ var div = jsMath.Setup.TopHTML("Warning",{'class':'jsM_Warning'},{});
+ div.innerHTML =
+ '
';
+ },
+
+ HideMessage: function () {
+ var message = jsMath.Element("Warning");
+ if (message) {message.style.display = "none"}
},
/*
- * Define some styles
+ * Register an extra font so jsMath knows about it
+ */
+ Register: function (data) {
+ if (typeof(data) == 'string') {data = {name: data}}
+ var fontname = data.name; var name = fontname.replace(/10$/,'');
+ var fontfam = jsMath.TeX.fam.length;
+ if (!data.style) {data.style = "font-family: "+fontname+", serif"}
+ if (!data.styles) {data.styles = {}}
+ if (!data.macros) {data.macros = {}}
+ /*
+ * Register font family
+ */
+ jsMath.TeX.fam[fontfam] = fontname;
+ data.macros[name] = ['HandleFont',fontfam];
+ jsMath.Add(jsMath.Parser.prototype.macros,data.macros);
+ /*
+ * Set up styles
+ */
+ data.styles['.'+fontname] = data.style;
+ jsMath.Setup.Styles(data.styles);
+ jsMath.Setup.TeXfont(fontname);
+ /*
+ * Check for font and give message if missing
+ */
+ var hasTeXfont = !jsMath.nofonts &&
+ data.test(fontname,data.testChar,data.testFactor);
+ if (hasTeXfont && jsMath.Controls.cookie.font == 'tex') {
+ if (data.tex) {data.tex(fontname,fontfam)}
+ return;
+ }
+ if (!hasTeXfont && jsMath.Controls.cookie.warn &&
+ jsMath.Controls.cookie.font == 'tex' && !jsMath.nofonts) {
+ if (!jsMath.Element("Warning")) this.Message(this.extra_message);
+ var extra = jsMath.Element("ExtraFonts");
+ if (extra) {
+ if (extra.innerHTML != "") {extra.innerHTML += ','}
+ extra.innerHTML += " " + fontname;
+ }
+ }
+ if (jsMath.Controls.cookie.font == 'unicode') {
+ if (data.fallback) {data.fallback(fontname,fontfam)}
+ return;
+ }
+ // Image fonts
+ var font = {}; font[fontname] = ['all'];
+ jsMath.Img.SetFont(font);
+ jsMath.Img.LoadFont(fontname);
+ },
+
+ /*
+ * Load a font
*/
- WriteStyles: function (styles) {
- document.writeln('');
+ Load: function (name) {jsMath.Setup.Script("fonts/"+name+"/def.js")}
+
+};
+
+/***************************************************************************/
+
+/*
+ * Implements the jsMath control panel.
+ * Much of the code is in jsMath-controls.html, which is
+ * loaded into a hidden IFRAME on demand
+ */
+jsMath.Controls = {
+
+ // Data stored in the jsMath cookie
+ cookie: {
+ scale: 100,
+ font: 'tex', autofont: 1, scaleImg: 0, alpha: 1,
+ warn: 1, button: 1,
+ print: 0, keep: '0D'
},
+ cookiePath: '/', // can also set cookieDomain
+
+
/*
- * Send the style definitions to the browser (these may be adjusted
- * by the browser-specific code)
+ * Load the control panel
*/
- InitStyles: function () {this.WriteStyles(this.styles)},
+ Panel: function () {
+ if (!this.panel) {this.panel = jsMath.Element("Controls")}
+ if (this.loaded) {this.Main()} else {
+ this.openMain = 1;
+ if (!this.iframe) {this.iframe = jsMath.Element("Frame")}
+ this.iframe.src = jsMath.root+"jsMath-controls.html";
+ }
+ },
/*
- * Update specific parameters for a limited number of font entries
+ * Create the control panel button
*/
- UpdateTeXfonts: function (change) {
- for (var font in change) {
- for (var code in change[font]) {
- for (var id in change[font][code]) {
- this.TeX[font][code][id] = change[font][code][id];
- }
+ Button: function () {
+ var button = jsMath.Setup.TopHTML("jsMath",{'class':'jsM_button'},{});
+ button.innerHTML =
+ '' +
+ 'jsMath'
+ if (!this.cookie.button) {button.style.display = "none"}
+ },
+
+ /*
+ * MSIE doesn't implement position:fixed, so redraw the button on scrolls.
+ */
+ MoveButton: function () {
+ if (!this.button) {this.button = jsMath.Element("jsMath")}
+ this.button.style.visibility = "hidden";
+ this.button.style.visibility = "visible";
+ },
+
+ /*
+ * Create the HTML needed for control panel
+ */
+ Init: function () {
+ this.document = document;
+ this.panel = jsMath.Setup.TopHTML("Controls", {'class':"jsM_panel"},{display:'none'});
+ if (!jsMath.Browser.msieButtonBug) {this.Button()}
+ else {setTimeout("jsMath.Controls.Button()",500)}
+ if (jsMath.Browser.safariIFRAMEbug) {
+ document.write(
+ '\n');
+ return;
+ }
+ try {
+ var frame = document.createElement('iframe');
+ frame.setAttribute('scrolling','no');
+ frame.style.border = '0px';
+ frame.style.width = '0px';
+ frame.style.height = '0px';
+ document.body.insertBefore(frame,this.panel);
+ this.iframe = frame;
+ } catch (err) {
+ document.write('\n');
+ }
+ },
+
+ /*
+ * Get the cookie data from the browser
+ * (for file: references, use url '?' syntax)
+ */
+ GetCookie: function () {
+ var cookies = document.cookie;
+ if (window.location.protocol == 'file:')
+ {cookies = unescape(window.location.search.substr(1))}
+ if (cookies.match(/jsMath=([^;]*)/)) {
+ var data = RegExp.$1.split(/,/);
+ for (var i = 0; i < data.length; i++) {
+ var x = data[i].match(/(.*):(.*)/);
+ if (x[2].match(/^\d+$/)) {x[2] = 1*x[2]} // convert from string
+ this.cookie[x[1]] = x[2];
}
}
},
/*
- * Update the character code for every character in a list
- * of fonts
+ * Save the cookie data in the browser
+ * (for file: urls, append data like CGI reference)
*/
- UpdateTeXfontCodes: function (change) {
- for (var font in change) {
- for (var i = 0; i < change[font].length; i++) {
- this.TeX[font][i].c = change[font][i];
+ SetCookie: function (warn) {
+ var cookie = [];
+ for (var id in this.cookie) {cookie[cookie.length] = id + ':' + this.cookie[id]}
+ cookie = cookie.join(',');
+ if (window.location.protocol == 'file:') {
+ if (!warn) return;
+ this.loaded = 0;
+ var href = window.location.href;
+ href = href.replace(/\?.*/,"") + '?jsMath=' + escape(cookie);
+ if (href != window.location.href) {window.location.replace(href)}
+ } else {
+ if (this.cookiePath) {cookie += '; path='+this.cookiePath}
+ if (this.cookieDomain) {cookie += '; domain='+this.cookieDomain}
+ if (this.cookie.keep != '0D') {
+ var ms = {
+ D: 1000*60*60*24,
+ W: 1000*60*60*24*7,
+ M: 1000*60*60*24*30,
+ Y: 1000*60*60*24*365
+ };
+ var exp = new Date;
+ exp.setTime(exp.getTime() +
+ this.cookie.keep.substr(0,1) * ms[this.cookie.keep.substr(1,1)]);
+ cookie += '; expires=' + exp.toGMTString();
}
+ document.cookie = 'jsMath='+cookie;
+ var cookies = document.cookie;
+ if (warn && !cookies.match(/jsMath=/))
+ {alert("Cookies must be enabled in order to save jsMath options")}
+ }
+ }
+
+};
+
+/***************************************************************************/
+
+/*
+ * Implements the actions for clicking and double-clicking
+ * on math formulas
+ */
+jsMath.Click = {
+
+ dragging: 0,
+
+ /*
+ * Create the hidden DIV used for the tex source window
+ */
+ Init: function () {
+ this.source = jsMath.Setup.TopHTML("Source",{'class':'jsM_float'},{display:'none'});
+ this.source.innerHTML =
+ ''
+ + '
';
+ this.drag = this.source.firstChild;
+ this.tex = this.drag.nextSibling.firstChild;
+ this.drag.firstChild.onclick = jsMath.Click.CloseSource;
+ this.drag.onmousedown = jsMath.Click.StartDragging;
+ this.drag.ondragstart = jsMath.Click.False;
+ this.drag.onselectstart = jsMath.Click.False;
+ this.source.onclick = jsMath.Click.CheckClose;
+ },
+ False: function () {return false},
+
+ /*
+ * Handle clicking on math to get control panel
+ */
+ CheckClick: function (event) {
+ if (!event) {event = window.event}
+ if (event.altKey) jsMath.Controls.Panel();
+ },
+
+ /*
+ * Handle double-click for seeing TeX code
+ */
+ CheckDblClick: function (event) {
+ if (!event) {event = window.event}
+ var event = jsMath.Click.Event(event);
+
+ var source = jsMath.Click.source
+ var tex = jsMath.Click.tex;
+
+ source.style.visibility = 'hidden';
+ source.style.display = ''; source.style.width = '';
+ source.style.left = ''; source.style.top = '';
+ tex.innerHTML = '';
+
+ var TeX = this.alt;
+ TeX = TeX.replace(/^\s+|\s+$/g,'');
+ TeX = TeX.replace(/&/g,'&');
+ TeX = TeX.replace(//g,'>');
+ TeX = TeX.replace(/\n/g,'
');
+ tex.innerHTML = TeX;
+
+ var h = source.offsetHeight; var w;
+ if (jsMath.Browser.msieDivWidthBug) {
+ tex.className = 'jsM_source'; // Work around MSIE bug where
+ w = tex.offsetWidth + 5; // DIV's don't collapse to
+ tex.className = ''; // their natural widths
+ } else {
+ w = source.offsetWidth;
}
+ w = Math.max(50,Math.min(w,.8*event.W,event.W-40));
+ var x = Math.floor(event.x-w/2); var y = Math.floor(event.y-h/2);
+ x = event.X + Math.max(Math.min(x,event.W-w-20),20);
+ y = event.Y + Math.max(Math.min(y,event.H-h-5),5);
+
+ source.style.left = x+'px'; source.style.top = y+'px';
+ source.style.width = w+'px';
+ source.style.visibility = '';
+ jsMath.Click.left = x + event.X; jsMath.Click.top = y + event.Y;
+ jsMath.Click.w = w; jsMath.Click.h = source.offsetHeight;
+
+ jsMath.Click.DeselectText(x,y);
+ return false;
+ },
+
+ /*
+ * Get window width, height, and offsets plus
+ * position of pointer relative to the window
+ */
+ Event: function (event) {
+ var W = window.innerWidth || document.body.clientWidth;
+ var H = window.innerHeight || document.body.clientHeight;
+ var X = window.pageXOffset; var Y = window.pageYOffset;
+ if (X == null) {X = document.body.clientLeft; Y = document.body.clientTop}
+ var x = event.pageX; var y = event.pageY;
+ if (x == null) {
+ x = event.clientX; y = event.clientY;
+ if (jsMath.browser == 'MSIE' && document.compatMode == 'CSS1Compat') {
+ X = document.documentElement.scrollLeft;
+ Y = document.documentElement.scrollTop;
+ W = document.documentElement.clientWidth;
+ H = document.documentElement.clientHeight;
+ } else {
+ X = document.body.scrollLeft;
+ Y = document.body.scrollTop;
+ }
+ } else {x -= X; y -= Y}
+
+ return {x: x, y: y, W: W, H: H, X: X, Y: Y};
},
/*
- * Add a collection of styles to the style list
+ * Unselect whatever text is selected (since double-clicking
+ * usually selects something)
*/
- UpdateStyles: function (styles) {
- for (var i in styles) {this.styles[i] = styles[i]}
+ DeselectText: function (x,y) {
+ if (window.getSelection && window.getSelection().removeAllRanges)
+ {window.getSelection().removeAllRanges()}
+ else if (document.getSelection && document.getSelection().removeAllRanges)
+ {document.getSelection().removeAllRanges()}
+ else if (document.selection && document.selection.empty)
+ {document.selection.empty()}
+ else {
+ /* Hack to deselect the text in Opera and Safari */
+ if (jsMath.browser == 'MSIE') return; // don't try it if MISE on Mac
+ jsMath.hiddenTop.innerHTML =
+ '';
+ jsMath.hiddenTop.firstChild.style.position = 'absolute';
+ jsMath.hiddenTop.firstChild.style.left = x+'px';
+ jsMath.hiddenTop.firstChild.style.top = y+'px';
+ setTimeout(jsMath.Click.SelectHidden,1);
+ }
+ },
+ SelectHidden: function () {
+ jsMath.hiddenTop.firstChild.focus();
+ jsMath.hiddenTop.firstChild.select();
+ jsMath.hiddenTop.innerHTML = '';
},
/*
- * Manage JavaScript objects:
- *
- * Add: simply add items to an object
- * Package: add items to an object prototype
+ * Close the TeX source window
*/
- Add: function (obj,def) {for (var id in def) {obj[id] = def[id]}},
- Package: function (obj,def) {this.Add(obj.prototype,def)}
+ CloseSource: function () {
+ jsMath.Click.tex.innerHTML = '';
+ jsMath.Click.source.style.display = 'none';
+ jsMath.Click.source.style.visibility = 'hidden';
+ jsMath.Click.StopDragging();
+ return false;
+ },
+ CheckClose: function (event) {
+ if (!event) {event = window.event}
+ if (event.altKey) {jsMath.Click.CloseSource(); return false}
+ },
-}
+ /*
+ * Set up for dragging the source panel
+ */
+ StartDragging: function (event) {
+ if (!event) {event = window.event}
+ if (jsMath.Click.dragging) {jsMath.Click.StopDragging(event)}
+ var event = jsMath.Click.Event(event);
+ jsMath.Click.dragging = 1;
+ jsMath.Click.x = event.x + 2*event.X - jsMath.Click.left;
+ jsMath.Click.y = event.y + 2*event.Y - jsMath.Click.top;
+ jsMath.Click.oldonmousemove = document.body.onmousemove;
+ jsMath.Click.oldonmouseup = document.body.onmouseup;
+ document.body.onmousemove = jsMath.Click.DragSource;
+ document.body.onmouseup = jsMath.Click.StopDragging;
+ return false;
+ },
+
+ /*
+ * Stop dragging the source window
+ */
+ StopDragging: function (event) {
+ if (jsMath.Click.dragging) {
+ document.body.onmousemove = jsMath.Click.oldonmousemove;
+ document.body.onmouseup = jsMath.Click.oldonmouseup;
+ jsMath.Click.oldonmousemove = null;
+ jsMath.Click.oldonmouseup = null;
+ jsMath.Click.dragging = 0;
+ }
+ return false;
+ },
+
+ /*
+ * Move the source window (but stay within the browser window)
+ */
+ DragSource: function (event) {
+ if (!event) {event = window.event}
+ if (jsMath.Browser.buttonCheck && !event.button) {return jsMath.Click.StopDragging(event)}
+ event = jsMath.Click.Event(event);
+ var x = event.x + event.X - jsMath.Click.x;
+ var y = event.y + event.Y - jsMath.Click.y;
+ x = Math.max(event.X,Math.min(event.W+event.X-jsMath.Click.w,x));
+ y = Math.max(event.Y,Math.min(event.H+event.Y-jsMath.Click.h,y));
+ jsMath.Click.source.style.left = x + 'px';
+ jsMath.Click.source.style.top = y + 'px';
+ jsMath.Click.left = x + event.X; jsMath.Click.top = y + event.Y;
+ return false;
+ }
+};
/***************************************************************************/
-jsMath.Add(jsMath.TeX,{
+/*
+ * The TeX font information
+ */
+jsMath.TeX = {
+ //
+ // The TeX font parameters
+ //
+ thinmuskip: 3/18,
+ medmuskip: 4/18,
+ thickmuskip: 5/18,
+
+ x_height: .430554,
+ quad: 1,
+ num1: .676508,
+ num2: .393732,
+ num3: .44373,
+ denom1: .685951,
+ denom2: .344841,
+ sup1: .412892,
+ sup2: .362892,
+ sup3: .288888,
+ sub1: .15,
+ sub2: .247217,
+ sup_drop: .386108,
+ sub_drop: .05,
+ delim1: 2.39,
+ delim2: 1.0,
+ axis_height: .25,
+ default_rule_thickness: .04,
+ big_op_spacing1: .111111,
+ big_op_spacing2: .166666,
+ big_op_spacing3: .2,
+ big_op_spacing4: .6,
+ big_op_spacing5: .1,
+
+ integer: 6553.6, // conversion of em's to TeX internal integer
+ scriptspace: .05,
+ nulldelimiterspace: .12,
+ delimiterfactor: 901,
+ delimitershortfall: .5,
+ scale: 1, // scaling factor for font dimensions
+
// The TeX math atom types (see Appendix G of the TeXbook)
atom: ['ord', 'op', 'bin', 'rel', 'open', 'close', 'punct', 'ord'],
@@ -596,7 +1341,7 @@ jsMath.Add(jsMath.TeX,{
* The following are the TeX font mappings and metrics. The metric
* information comes directly from the TeX .tfm files, and the
* character mappings are for the TrueType TeX fonts. Browser-specific
- * adjustments are made to these tables in the InitBrowser() routine
+ * adjustments are made to these tables in the Browser.Init() routine
*/
cmr10: [
// 00 - 0F
@@ -1431,7 +2176,125 @@ jsMath.Add(jsMath.TeX,{
{c: '~', h: 0.694, w: 0.575},
{c: 'Ä', h: 0.694, w: 0.575}
]
-});
+};
+
+/***************************************************************************/
+
+/*
+ * Implement image-based fonts for fallback method
+ */
+jsMath.Img = {
+
+ // font sizes available
+ fonts: [50, 60, 70, 85, 100, 120, 144, 173, 207, 249, 298, 358, 430],
+
+ // em widths for the various font size directories
+ w: {'50': 6.9, '60': 8.3, '70': 9.7, '85': 11.8, '100': 13.9,
+ '120': 16.7, '144': 20.0, '173': 24.0, '207': 28.8, '249': 34.6,
+ '298': 41.4, '358': 49.8, '430': 59.8},
+
+ // index of best font size in the fonts list
+ best: 4,
+
+ // fonts to update (see UpdateFonts below)
+ update: {},
+
+ // factor by which to shrink images (for better printing)
+ factor: 1,
+
+ // image fonts are loaded
+ loaded: 0,
+
+ // add characters to be drawn using images
+ SetFont: function (change) {
+ for (var font in change) {
+ if (!this.update[font]) {this.update[font] = []}
+ this.update[font] = this.update[font].concat(change[font]);
+ }
+ },
+
+ /*
+ * Called by the exta-font definition files to add an image font
+ * into the mix
+ */
+ AddFont: function (size,def) {
+ if (!jsMath.Img[size]) {jsMath.Img[size] = {}};
+ jsMath.Add(jsMath.Img[size],def);
+ },
+
+ /*
+ * Update font(s) to use image data rather than native fonts
+ * It looks in the jsMath.Img.update array to find the names
+ * of the fonts to udpate, and the arrays of character codes
+ * to set (or 'all' to change every character);
+ */
+ UpdateFonts: function () {
+ var change = this.update; if (!this.loaded) return;
+ var best = this[jsMath.Img.fonts[this.best]];
+ for (var font in change) {
+ for (var i = 0; i < change[font].length; i++) {
+ var c = change[font][i];
+ if (c == 'all') {for (c in jsMath.TeX[font]) {jsMath.TeX[font][c].img = {}}}
+ else {jsMath.TeX[font][c].img = {}}
+ }
+ }
+ this.update = {};
+ },
+
+ /*
+ * Find the font size that best fits our current font
+ * (this is the directory name for the img files used
+ * in some fallback modes).
+ */
+ BestSize: function () {
+ var w = jsMath.em * this.factor;
+ var m = this.w[this.fonts[0]];
+ for (var i = 1; i < this.fonts.length; i++) {
+ if (w < (this.w[this.fonts[i]] + 2*m) / 3) {return i-1}
+ m = this.w[this.fonts[i]];
+ }
+ return i-1;
+ },
+
+ /*
+ * Get the scaling factor for the image fonts
+ */
+ Scale: function () {
+ if (!this.loaded) return;
+ this.best = this.BestSize();
+ this.em = jsMath.Img.w[this.fonts[this.best]];
+ this.scale = (jsMath.em/this.em);
+ if (Math.abs(this.scale - 1) < .12) {this.scale = 1}
+ },
+
+ /*
+ * Get URL to directory for given font and size, based on the
+ * user's alpha/plain setting
+ */
+ URL: function (name,size,C) {
+ var type = (jsMath.Controls.cookie.alpha) ? '/alpha/': '/plain/';
+ if (C == null) {C = "def.js"} else {C = 'char'+C+'.png'}
+ if (size != "") {size += '/'}
+ return this.root+name+type+size+C;
+ },
+
+ /*
+ * Laod the data for an image font
+ */
+ LoadFont: function (name) {
+ if (jsMath.Controls.cookie.print) {
+ jsMath.Controls.cookie.print = 0;
+ var button = jsMath.Element("jsMath");
+ if (button) {button.style.display = "none"}
+ this.factor *= 3;
+ if (window.location.protocol != 'file:') {jsMath.Controls.SetCookie(0)}
+ if (jsMath.Browser.alphaPrintBug) {jsMath.Controls.cookie.alpha = 0}
+ }
+ document.writeln('');
+ this.loaded = 1;
+ }
+
+};
/***************************************************************************/
@@ -1459,17 +2322,10 @@ jsMath.HTML = {
*/
Spacer: function (w) {
if (w == 0) {return ''};
- return jsMath.msieSpaceFix
- + '';
- },
-
- /*
- * Use an image to create a horizontal space of width w
- */
- SpacerImage: function (w) {
- if (w == 0) {return ''};
- return '
';
+ return jsMath.Browser.msieSpaceFix
+ + ''
+ + jsMath.Browser.hiddenSpace + '';
},
/*
@@ -1485,25 +2341,13 @@ jsMath.HTML = {
{pos = 'relative; margin-right: '+this.Em(-(w+2/jsMath.em))+'; '}
return '
';
- },
-
- /*
- * Create a 1-pixel-high horizontal line at a particular
- * position, width and color.
- */
- Line: function (x,y,w,c,pos) {
- if (!c) {c = 'black'};
- if (pos) {pos = 'absolute;'} else
- {pos = 'relative; margin-right: '+this.Em(-w)+'; '}
- return '
';
+ + 'width:' +this.Em(w*jsMath.Browser.imgScale)+'; '
+ + 'height:'+this.Em(h*jsMath.Browser.imgScale)+'; '
+ + 'border: 1px solid '+c+';">';
},
/*
- * Create a black rule line for fractions, etc.
+ * Create a rule line for fractions, etc.
* Height is converted to pixels (with a minimum of 1), so that
* the line will not disappear at small font sizes. This means that
* the thickness will not change if you change the font size, or
@@ -1512,23 +2356,15 @@ jsMath.HTML = {
Rule: function (w,h) {
if (h == null) {h = jsMath.TeX.default_rule_thickness}
if (w == 0 || h == 0) return; // should make an invisible box?
- h = Math.round(h*jsMath.em);
- if (h < 1) {h = 1}
- return '
';
- },
-
- /*
- * Create a colored block of a specific size (won't always print
- * correctly).
- */
- Block: function (w,h,c) {
- if (c == null) {c = 'black'}
+ w *= jsMath.Browser.imgScale;
+ h = Math.round(h*jsMath.em*jsMath.Browser.imgScale+.25);
+ if (h < 1) {h = 1};
return '
';
+ + 'STYLE="width:'+this.Em(w)+'; height:1px; '
+ + 'vertical-align:-1px; '
+ + 'border:0px none; border-top:'+h+'px solid">';
},
-
+
/*
* Add a tag to activate a specific CSS class
*/
@@ -1555,34 +2391,19 @@ jsMath.HTML = {
/*
* For MSIE on Windows, backspacing must be done in a separate
- * , otherwise the contents will be clipped.
- */
- PlaceSeparateNegative: function (html,x,y) {
- if (Math.abs(x) < .0001) {x = 0}
- if (Math.abs(y) < .0001) {y = 0}
- if (x > 0 || y) {
- var span = '' + html + '';
- }
- if (x < 0) {
- html = jsMath.msieSpaceFix
- + '' + html;
- }
- return html;
- },
-
- /*
- * Here the x and y positioning is done in separate tags
+ * , otherwise the contents will be clipped. Netscape
+ * also doesn't combine vertical and horizontal spacing well.
+ * Here the x and y positioning are done in separate tags
*/
PlaceSeparateSkips: function (html,x,y) {
if (Math.abs(x) < .0001) {x = 0}
if (Math.abs(y) < .0001) {y = 0}
if (y) {html = '' + html + ''}
- if (x) {html = jsMath.msieSpaceFix
- + '' + html}
+ if (x) {html = jsMath.Browser.msieSpaceFix
+ + ''
+ + jsMath.Browser.hiddenSpace + '' + html}
return html;
},
@@ -1600,7 +2421,7 @@ jsMath.HTML = {
Absolute: function(html,w,h,d,y,H) {
var align = "";
- if (d) {align = ' vertical-align: '+jsMath.HTML.Em(-d)+';'}
+ if (d && d != "none") {align = ' vertical-align: '+jsMath.HTML.Em(-d)+';'}
if (y != "none") {
if (Math.abs(y) < .0001) {y = 0}
html = '';
- if (jsMath.msieAbsoluteBug) {// for MSIE (Mac)
+ html += '
';
+ if (jsMath.Browser.msieAbsoluteBug) { // for MSIE (Mac)
html = '' + html + '';
}
html = ''
+ html
+ '';
@@ -1671,9 +2494,10 @@ jsMath.Add(jsMath.Box,{
* The box is a text box (like the ones above), so that characters from
* the same font can be combined.
*/
- TeX: function (c,font,style,size) {
- c = jsMath.TeX[font][c];
+ TeX: function (C,font,style,size) {
+ var c = jsMath.TeX[font][C];
if (c.d == null) {c.d = 0}; if (c.h == null) {c.h = 0}
+ if (c.img != null && c.c != '') this.TeXIMG(font,C,jsMath.Typeset.StyleSize(style,size));
var scale = jsMath.Typeset.TeX(style,size).scale;
var h = c.h + jsMath.TeX[font].dh
var box = new jsMath.Box('text',c.c,c.w*scale,h*scale,c.d*scale);
@@ -1686,15 +2510,80 @@ jsMath.Add(jsMath.Box,{
box.tclass = font;
box.bh = scale*jsMath.TeX[font].h;
box.bd = scale*jsMath.TeX[font].d;
- if (jsMath.msieFontBug) {
+ if (jsMath.Browser.msieFontBug) {
// hack to avoid Font changing back to the default
// font when a unicode reference is not followed
// by a letter or number
box.html += 'x'
}
}
+ if (c.img != null) {
+ box.bh = c.img.bh; box.bd = c.img.bd;
+ box.tclass = "normal";
+ }
return box;
},
+
+ /*
+ * Set the character's string to the appropriate image file
+ */
+ TeXIMG: function (font,C,size) {
+ var c = jsMath.TeX[font][C];
+ if (c.img.size != null && c.img.size == size &&
+ c.img.best != null && c.img.best == jsMath.Img.best) return;
+ var mustScale = (jsMath.Img.scale != 1);
+ var id = jsMath.Img.best + size - 4;
+ if (id < 0) {id = 0; mustScale = 1} else
+ if (id >= jsMath.Img.fonts.length) {id = jsMath.Img.fonts.length-1; mustScale = 1}
+ var imgFont = jsMath.Img[jsMath.Img.fonts[id]];
+ var img = imgFont[font][C];
+ var scale = 1/jsMath.Img.w[jsMath.Img.fonts[id]];
+ if (id != jsMath.Img.best + size - 4) {
+ if (c.w != null) {scale = c.w/img[0]} else {
+ scale *= jsMath.Img.fonts[size]/jsMath.Img.fonts[4]
+ * jsMath.Img.fonts[jsMath.Img.best]/jsMath.Img.fonts[id];
+ }
+ }
+ var w = img[0]*scale; var h = img[1]*scale; var d = -img[2]*scale; var v;
+ var wadjust = (c.w == null || Math.abs(c.w-w) < .01)? "" : " margin-right:"+jsMath.HTML.Em(c.w-w)+';';
+ var resize = ""; C = this.HexCode(C);
+ if (!mustScale && !jsMath.Controls.cookie.scaleImg) {
+ if (2*w < h || (jsMath.Browser.msieAlphaBug && jsMath.Controls.cookie.alpha))
+ {resize = "height:"+(img[1]*jsMath.Browser.imgScale)+'px;'}
+ resize += " width:"+(img[0]*jsMath.Browser.imgScale)+'px;'
+ v = -img[2]+'px';
+ } else {
+ if (2*w < h || (jsMath.Browser.msieAlphaBug && jsMath.Controls.cookie.alpha))
+ {resize = "height:"+jsMath.HTML.Em(h*jsMath.Browser.imgScale)+';'}
+ resize += " width:"+jsMath.HTML.Em(w*jsMath.Browser.imgScale)+';'
+ v = jsMath.HTML.Em(d);
+ }
+ var vadjust = (Math.abs(d) < .01 && !jsMath.Browser.valignBug)?
+ "": " vertical-align:"+v+';';
+ var URL = jsMath.Img.URL(font,jsMath.Img.fonts[id],C);
+ if (jsMath.Browser.msieAlphaBug && jsMath.Controls.cookie.alpha) {
+ c.c = '
';
+ } else {
+ c.c = '
';
+ }
+ c.tclass = "normal";
+ c.img.bh = h+d; c.img.bd = -d;
+ c.img.size = size; c.img.best = jsMath.Img.best;
+ },
+
+ /*
+ * Get a two-character hex code (some browsers don't know toString(16))
+ */
+ HexCode: function (C) {
+ var codes = '0123456789ABCDEF';
+ var h = Math.floor(C/16); var l = C - 16*h;
+ return codes.charAt(h)+codes.charAt(l);
+ },
/*
* A box containing a spacer of a specific width
@@ -1713,18 +2602,12 @@ jsMath.Add(jsMath.Box,{
},
/*
- * A box containing a colored block
- */
- Block: function (w,h,c) {
- return new jsMath.Box('html',jsMath.HTML.Block(w,h,c),w,h,0);
- },
-
- /*
* Get a character from a TeX font, and make sure that it has
* its metrics specified.
*/
GetChar: function (code,font) {
var c = jsMath.TeX[font][code];
+ if (c.img != null) {this.TeXIMG(font,code,4)}
if (c.tclass == null) {c.tclass = font}
if (!c.computedW) {
c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w;
@@ -1856,9 +2739,10 @@ jsMath.Add(jsMath.Box,{
Delimiter: function (H,delim,style,nocenter) {
var size = 4; //### pass this?
var TeX = jsMath.Typeset.TeX(style,size);
- var CFSH = this.DelimBestFit(H,(delim&0xFF000)>>12,(delim&0xF00000)>>20,style);
+ if (!delim) {return this.Space(TeX.nulldelimiterspace)}
+ var CFSH = this.DelimBestFit(H,delim[2],delim[1],style);
if (CFSH == null || CFSH[3] < H)
- {CFSH = this.DelimBestFit(H,(delim&0xFF),(delim&0xF00)>>8,style)}
+ {CFSH = this.DelimBestFit(H,delim[4],delim[3],style)}
if (CFSH == null) {return this.Space(TeX.nulldelimiterspace)}
if (CFSH[2] == '')
{return this.DelimExtend(H,CFSH[0],CFSH[1],TeX.axis_height,nocenter)}
@@ -1875,9 +2759,10 @@ jsMath.Add(jsMath.Box,{
* is specified.
*/
GetCharCode: function (code) {
- var font = jsMath.TeX.fam[(code&0xF00)>>8];
+ var font = jsMath.TeX.fam[code[0]];
var Font = jsMath.TeX[font];
- var c = Font[code & 0xFF];
+ var c = Font[code[1]];
+ if (c.img != null) {this.TeXIMG(font,code[1],4)}
if (c.w == null) {c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w}
if (c.font == null) {c.font = font}
return c;
@@ -1901,7 +2786,7 @@ jsMath.Add(jsMath.Box,{
Leaders: function (W,leader) {
var h; var d; var w; var html; var font;
if (leader.lmid) {// braces
- font = jsMath.TeX.fam[(leader.left & 0xF00) >> 8];
+ font = jsMath.TeX.fam[leader.left[0]];
var left = this.GetCharCode(leader.left);
var right = this.GetCharCode(leader.right);
var lmid = this.GetCharCode(leader.lmid);
@@ -1914,7 +2799,7 @@ jsMath.Add(jsMath.Box,{
+ jsMath.HTML.Rule(w,right.h)
+ this.AddClass(right.tclass,right.c,right.font);
} else { //arrows
- font = jsMath.TeX.fam[(leader.rep &0xF00) >> 8];
+ font = jsMath.TeX.fam[leader.rep[0]];
var left = this.GetCharCode(leader.left? leader.left: leader.rep);
var rep = this.GetCharCode(leader.rep);
var right = this.GetCharCode(leader.right? leader.right: leader.rep);
@@ -1928,7 +2813,7 @@ jsMath.Add(jsMath.Box,{
html += this.AddClass(rep.tclass,ehtml,rep.font) + jsMath.HTML.Spacer(w);
ehtml = ''; for (var i = m; i < n; i++) {ehtml += ext};
html += this.AddClass(rep.tclass,ehtml,rep.font);
- if (jsMath.msieFontBug) {html += 'x'}
+ if (jsMath.Browser.msieFontBug) {html += 'x'}
html += jsMath.HTML.Place(this.AddClass(right.tclass,right.c,right.font),-.4,0);
}
w = jsMath.EmBoxFor(html).w;
@@ -2075,7 +2960,7 @@ jsMath.Add(jsMath.Box,{
for (i = 0; i < W.length; i++) {w += W[i] + cspacing[i]}
html = jsMath.HTML.Spacer(scale/6)+html+jsMath.HTML.Spacer(scale/6);
- if (jsMath.spanHeightVaries) {y = h-jsMath.h} else {y = 0}
+ if (jsMath.Browser.spanHeightVaries) {y = h-jsMath.h} else {y = 0}
html = jsMath.HTML.Absolute(html,w,h+d,d,y,H[0]);
var box = new jsMath.Box('html',html,w+scale/3,h,d);
return box;
@@ -2085,7 +2970,7 @@ jsMath.Add(jsMath.Box,{
* Look for math within \hbox and other non-math text
*/
InternalMath: function (text,size) {
- if (!text.match(/\$|\\\(/)) {return this.Text(text,'nonmath','T',size).Styled()}
+ if (!text.match(/\$|\\\(/)) {return this.Text(text,'normal','T',size).Styled()}
var i = 0; var k = 0; var c; var match = '';
var mlist = []; var parse; var html; var box;
@@ -2102,13 +2987,13 @@ jsMath.Add(jsMath.Box,{
}
match = ''; k = i;
} else {
- mlist[mlist.length] = this.Text(text.slice(k,i-1),'nonmath','T',size,1,1);
+ mlist[mlist.length] = this.Text(text.slice(k,i-1),'normal','T',size,1,1);
match = '$'; k = i;
}
} else if (c == '\\') {
c = text.charAt(i++);
if (c == '(' && match == '') {
- mlist[mlist.length] = this.Text(text.slice(k,i-2),'nonmath','T',size,1,1);
+ mlist[mlist.length] = this.Text(text.slice(k,i-2),'normal','T',size,1,1);
match = ')'; k = i;
} else if (c == ')' && match == ')') {
parse = jsMath.Parse(text.slice(k,i-2),null,size);
@@ -2122,7 +3007,7 @@ jsMath.Add(jsMath.Box,{
}
}
}
- mlist[mlist.length] = this.Text(text.slice(k),'nonmath','T',size,1,1);
+ mlist[mlist.length] = this.Text(text.slice(k),'normal','T',size,1,1);
return this.SetList(mlist,'T',size);
},
@@ -2188,10 +3073,8 @@ jsMath.Package(jsMath.Box,{
* Recompute the box width to make it more accurate.
*/
Remeasured: function () {
- if (this.w > 0) {
- if (!jsMath.spanHeightVaries || !this.html.match(/position: ?absolute/))
- {this.w = jsMath.EmBoxFor(this.html).w}
- }
+ if (this.w > 0 && !this.html.match(/position: ?absolute/))
+ {this.w = jsMath.EmBoxFor(this.html).w}
return this;
}
@@ -2201,7 +3084,7 @@ jsMath.Package(jsMath.Box,{
/***************************************************************************/
/*
- * mItems are the buiulding blocks of mLists (math lists) used to
+ * mItems are the building blocks of mLists (math lists) used to
* store the information about a mathematical expression. These are
* basically the items listed in the TeXbook in Appendix G (plus some
* minor extensions).
@@ -2429,7 +3312,7 @@ jsMath.Package(jsMath.mList,{
/*
* For a list that has boundary delimiters as its first and last
* entries, we replace the boundary atoms by open and close
- * atoms whose nuclei are the specified delimiters properly sized
+ * atoms whose nuclii are the specified delimiters properly sized
* for the contents of the list. (Rule 19)
*/
AddDelimiters: function(style,size) {
@@ -2656,7 +3539,7 @@ jsMath.Add(jsMath.mList.prototype.Atomiz
var t = TeX.default_rule_thickness;
var p = t; if (style == 'D' || style == "D'") {p = TeX.x_height}
var r = t + p/4;
- var surd = jsMath.Box.Delimiter(box.h+box.d+r+t,0x270370,style,1);
+ var surd = jsMath.Box.Delimiter(box.h+box.d+r+t,[0,2,0x70,3,0x70],style,1);
t = surd.h; // thickness of rule is height of surd character
if (surd.d > box.h+box.d+r) {r = (r+surd.d-box.h-box.d)/2}
surd.y = box.h+r;
@@ -2665,10 +3548,12 @@ jsMath.Add(jsMath.mList.prototype.Atomiz
var Cr = jsMath.Typeset.UpStyle(jsMath.Typeset.UpStyle(style));
var root = jsMath.Box.Set(mitem.root,Cr,size).Remeasured();
if (mitem.root) {
- root.y = .55*(box.h+box.d+3*t+r)-box.d; surd.x = -(11/18)*surd.w;
- root.x = Math.max((11/18)*surd.w - root.w, 0);
+ root.y = .55*(box.h+box.d+3*t+r)-box.d;
+ surd.x = Math.max(root.w-(11/18)*surd.w,0);
+ rule.x = (7/18)*surd.w;
+ root.x = -(root.w+rule.x);
}
- mitem.nuc = jsMath.Box.SetList([root,surd,rule,box],style,size);
+ mitem.nuc = jsMath.Box.SetList([surd,root,rule,box],style,size);
mitem.type = 'ord';
jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
},
@@ -2688,8 +3573,8 @@ jsMath.Add(jsMath.mList.prototype.Atomiz
}
if (s == null) {s = 0}
- var c = mitem.accent & 0xFF;
- var font = jsMath.TeX.fam[(mitem.accent&0xF00)>>8]; Font = jsMath.TeX[font];
+ var c = mitem.accent[2];
+ var font = jsMath.TeX.fam[mitem.accent[1]]; Font = jsMath.TeX[font];
while (Font[c].n && Font[Font[c].n].w <= u) {c = Font[c].n}
var delta = Math.min(box.h,TeX.x_height);
@@ -2728,11 +3613,11 @@ jsMath.Add(jsMath.mList.prototype.Atomiz
box = jsMath.Box.Set(mitem.nuc,style,size);
if (C.ic) {
mitem.delta = C.ic * TeX.scale;
- if (mitem.limits || !mitem.sub || jsMath.msieIntegralBug)
+ if (mitem.limits || !mitem.sub || jsMath.Browser.msieIntegralBug)
{box = jsMath.Box.SetList([box,jsMath.mItem.Space(mitem.delta)],style,size)}
}
box.y = -((box.h+box.d)/2 - box.d - TeX.axis_height);
- if (Math.abs(box.y) < .0001) (box.y = 0)
+ if (Math.abs(box.y) < .0001) {box.y = 0}
}
if (!box) {box = jsMath.Box.Set(mitem.nuc,style,size).Remeasured()}
@@ -2760,7 +3645,7 @@ jsMath.Add(jsMath.mList.prototype.Atomiz
mitem.nuc = jsMath.Box.SetList(mlist,style,size);
mitem.nuc.h += dh; mitem.nuc.d += dd;
} else {
- if (jsMath.msieIntegralBug && mitem.sub && C && C.ic)
+ if (jsMath.Browser.msieIntegralBug && mitem.sub && C && C.ic)
{mitem.nuc = jsMath.Box.SetList([box,jsMath.Box.Space(-C.ic*TeX.scale)],style,size)}
else if (box.y) {mitem.nuc = jsMath.Box.SetList([box],style,size)}
jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
@@ -2968,6 +3853,15 @@ jsMath.Add(jsMath.Typeset,{
if (style == "SS" || style == "SS'") {return .5*v}
return v;
},
+
+ /*
+ * Return the size associated with a given style and size
+ */
+ StyleSize: function (style,size) {
+ if (style == "S" || style == "S'") {size = Math.max(0,size-2)}
+ else if (style == "SS" || style == "SS'") {size = Math.max(0,size-4)}
+ return size;
+ },
/*
* Return the font parameter table for the given style
@@ -3123,7 +4017,7 @@ jsMath.Package(jsMath.Typeset,{
}
this.FlushClassed(); // make sure scaling is included
- if (this.dx) {this.hbuf += jsMath.HTML.Spacer(this.dx)}
+ if (this.dx) {this.hbuf += jsMath.HTML.Spacer(this.dx); this.w += this.dx}
if (this.hbuf == '') {return jsMath.Box.Null}
if (this.h == unset) {this.h = 0}
if (this.d == unset) {this.d = 0}
@@ -3156,9 +4050,9 @@ jsMath.Package(jsMath.Typeset,{
/*
* Add a to position an item's HTML, and
- * adjust the items height and depth.
+ * adjust the item's height and depth.
* (This may be replaced buy one of the following browser-specific
- * versions by InitBrowser().)
+ * versions by Browser.Init().)
*/
Place: function (item) {
var html = ''+html}
- if (item.x > 0) {html += ' margin-left:'+jsMath.HTML.Em(item.x)+';'}
- if (item.y) {html += ' top:'+jsMath.HTML.Em(-item.y)+';'}
- item.html = html + '">' + item.html + '';
- item.h += item.y; item.d -= item.y;
- item.x = 0; item.y = 0;
- },
-
- /*
- * Here, the horizontal spacing is always done separately.
+ * For MSIE on Windows, backspacing must be done in a separate
+ * , otherwise the contents will be clipped. Netscape
+ * also doesn't combine vertical and horizontal spacing well.
+ * Here, the horizontal and vertical spacing are done separately.
*/
PlaceSeparateSkips: function (item) {
- if (item.y)
- {item.html = '' + item.html + ''}
+ if (item.y) {
+ if (item.html.match(/^
]*>(<\/SPAN>)?$/i) && !item.html.match(/top:/)) {
+ item.html = item.html.replace(/STYLE="/,
+ 'STYLE="position:relative; top:'+jsMath.HTML.Em(-item.y)+';');
+ } else {
+ item.html = '' + item.html + ''
+ }
+ }
if (item.x)
- {item.html = jsMath.msieSpaceFix
- + ''
- + '' + item.html}
+ {item.html = jsMath.Browser.msieSpaceFix
+ + ''
+ + jsMath.Browser.hiddenSpace + '' + item.html}
item.h += item.y; item.d -= item.y;
item.x = 0; item.y = 0;
}
@@ -3236,26 +4124,26 @@ jsMath.Package(jsMath.Parser,{
// the \mathchar definitions (see Appendix B of the TeXbook).
mathchar: {
- '!': 0x5021,
- '(': 0x4028,
- ')': 0x5029,
- '*': 0x2203, // \ast
- '+': 0x202B,
- ',': 0x613B,
- '-': 0x2200,
- '.': 0x013A,
- '/': 0x013D,
- ':': 0x303A,
- ';': 0x603B,
- '<': 0x313C,
- '=': 0x303D,
- '>': 0x313E,
- '?': 0x503F,
- '[': 0x405B,
- ']': 0x505D,
-// '{': 0x4266,
-// '}': 0x5267,
- '|': 0x026A
+ '!': [5,0,0x21],
+ '(': [4,0,0x28],
+ ')': [5,0,0x29],
+ '*': [2,2,0x03], // \ast
+ '+': [2,0,0x2B],
+ ',': [6,1,0x3B],
+ '-': [2,2,0x00],
+ '.': [0,1,0x3A],
+ '/': [0,1,0x3D],
+ ':': [3,0,0x3A],
+ ';': [6,0,0x3B],
+ '<': [3,1,0x3C],
+ '=': [3,0,0x3D],
+ '>': [3,1,0x3E],
+ '?': [5,0,0x3F],
+ '[': [4,0,0x5B],
+ ']': [5,0,0x5D],
+// '{': [4,2,0x66],
+// '}': [5,2,0x67],
+ '|': [0,2,0x6A]
},
// handle special \catcode characters
@@ -3274,244 +4162,244 @@ jsMath.Package(jsMath.Parser,{
// the \mathchardef table (see Appendix B of the TeXbook).
mathchardef: {
// brace parts
- braceld: 0x37A,
- bracerd: 0x37B,
- bracelu: 0x37C,
- braceru: 0x37D,
+ braceld: [0,3,0x7A],
+ bracerd: [0,3,0x7B],
+ bracelu: [0,3,0x7C],
+ braceru: [0,3,0x7D],
// Greek letters
- alpha: 0x010B,
- beta: 0x010C,
- gamma: 0x010D,
- delta: 0x010E,
- epsilon: 0x010F,
- zeta: 0x0110,
- eta: 0x0111,
- theta: 0x0112,
- iota: 0x0113,
- kappa: 0x0114,
- lambda: 0x0115,
- mu: 0x0116,
- nu: 0x0117,
- xi: 0x0118,
- pi: 0x0119,
- rho: 0x011A,
- sigma: 0x011B,
- tau: 0x011C,
- upsilon: 0x011D,
- phi: 0x011E,
- chi: 0x011F,
- psi: 0x0120,
- omega: 0x0121,
- varepsilon: 0x0122,
- vartheta: 0x0123,
- varpi: 0x0124,
- varrho: 0x0125,
- varsigma: 0x0126,
- varphi: 0x0127,
+ alpha: [0,1,0x0B],
+ beta: [0,1,0x0C],
+ gamma: [0,1,0x0D],
+ delta: [0,1,0x0E],
+ epsilon: [0,1,0x0F],
+ zeta: [0,1,0x10],
+ eta: [0,1,0x11],
+ theta: [0,1,0x12],
+ iota: [0,1,0x13],
+ kappa: [0,1,0x14],
+ lambda: [0,1,0x15],
+ mu: [0,1,0x16],
+ nu: [0,1,0x17],
+ xi: [0,1,0x18],
+ pi: [0,1,0x19],
+ rho: [0,1,0x1A],
+ sigma: [0,1,0x1B],
+ tau: [0,1,0x1C],
+ upsilon: [0,1,0x1D],
+ phi: [0,1,0x1E],
+ chi: [0,1,0x1F],
+ psi: [0,1,0x20],
+ omega: [0,1,0x21],
+ varepsilon: [0,1,0x22],
+ vartheta: [0,1,0x23],
+ varpi: [0,1,0x24],
+ varrho: [0,1,0x25],
+ varsigma: [0,1,0x26],
+ varphi: [0,1,0x27],
- Gamma: 0x7000,
- Delta: 0x7001,
- Theta: 0x7002,
- Lambda: 0x7003,
- Xi: 0x7004,
- Pi: 0x7005,
- Sigma: 0x7006,
- Upsilon: 0x7007,
- Phi: 0x7008,
- Psi: 0x7009,
- Omega: 0x700A,
+ Gamma: [7,0,0x00],
+ Delta: [7,0,0x01],
+ Theta: [7,0,0x02],
+ Lambda: [7,0,0x03],
+ Xi: [7,0,0x04],
+ Pi: [7,0,0x05],
+ Sigma: [7,0,0x06],
+ Upsilon: [7,0,0x07],
+ Phi: [7,0,0x08],
+ Psi: [7,0,0x09],
+ Omega: [7,0,0x0A],
// Ord symbols
- aleph: 0x0240,
- imath: 0x017B,
- jmath: 0x017C,
- ell: 0x0160,
- wp: 0x017D,
- Re: 0x023C,
- Im: 0x023D,
- partial: 0x0140,
- infty: 0x0231,
- prime: 0x0230,
- emptyset: 0x023B,
- nabla: 0x0272,
- surd: 0x1270,
- top: 0x023E,
- bot: 0x023F,
- triangle: 0x0234,
- forall: 0x0238,
- exists: 0x0239,
- neg: 0x023A,
- lnot: 0x023A,
- flat: 0x015B,
- natural: 0x015C,
- sharp: 0x015D,
- clubsuit: 0x027C,
- diamondsuit: 0x027D,
- heartsuit: 0x027E,
- spadesuit: 0x027F,
+ aleph: [0,2,0x40],
+ imath: [0,1,0x7B],
+ jmath: [0,1,0x7C],
+ ell: [0,1,0x60],
+ wp: [0,1,0x7D],
+ Re: [0,2,0x3C],
+ Im: [0,2,0x3D],
+ partial: [0,1,0x40],
+ infty: [0,2,0x31],
+ prime: [0,2,0x30],
+ emptyset: [0,2,0x3B],
+ nabla: [0,2,0x72],
+ surd: [1,2,0x70],
+ top: [0,2,0x3E],
+ bot: [0,2,0x3F],
+ triangle: [0,2,0x34],
+ forall: [0,2,0x38],
+ exists: [0,2,0x39],
+ neg: [0,2,0x3A],
+ lnot: [0,2,0x3A],
+ flat: [0,1,0x5B],
+ natural: [0,1,0x5C],
+ sharp: [0,1,0x5D],
+ clubsuit: [0,2,0x7C],
+ diamondsuit: [0,2,0x7D],
+ heartsuit: [0,2,0x7E],
+ spadesuit: [0,2,0x7F],
// big ops
- coprod: 0x1360,
- bigvee: 0x1357,
- bigwedge: 0x1356,
- biguplus: 0x1355,
- bigcap: 0x1354,
- bigcup: 0x1353,
- intop: 0x1352,
- prod: 0x1351,
- sum: 0x1350,
- bigotimes: 0x134E,
- bigoplus: 0x134C,
- bigodot: 0x134A,
- ointop: 0x1348,
- bigsqcup: 0x1346,
- smallint: 0x1273,
+ coprod: [1,3,0x60],
+ bigvee: [1,3,0x57],
+ bigwedge: [1,3,0x56],
+ biguplus: [1,3,0x55],
+ bigcap: [1,3,0x54],
+ bigcup: [1,3,0x53],
+ intop: [1,3,0x52],
+ prod: [1,3,0x51],
+ sum: [1,3,0x50],
+ bigotimes: [1,3,0x4E],
+ bigoplus: [1,3,0x4C],
+ bigodot: [1,3,0x4A],
+ ointop: [1,3,0x48],
+ bigsqcup: [1,3,0x46],
+ smallint: [1,2,0x73],
// binary operations
- triangleleft: 0x212F,
- triangleright: 0x212E,
- bigtriangleup: 0x2234,
- bigtriangledown: 0x2235,
- wedge: 0x225E,
- land: 0x225E,
- vee: 0x225F,
- lor: 0x225F,
- cap: 0x225C,
- cup: 0x225B,
- ddagger: 0x227A,
- dagger: 0x2279,
- sqcap: 0x2275,
- sqcup: 0x2274,
- uplus: 0x225D,
- amalg: 0x2271,
- diamond: 0x2205,
- bullet: 0x220F,
- wr: 0x226F,
- div: 0x2204,
- odot: 0x220C,
- oslash: 0x220B,
- otimes: 0x220A,
- ominus: 0x2209,
- oplus: 0x2208,
- mp: 0x2207,
- pm: 0x2206,
- circ: 0x220E,
- bigcirc: 0x220D,
- setminus: 0x226E, // for set difference A\setminus B
- cdot: 0x2201,
- ast: 0x2203,
- times: 0x2202,
- star: 0x213F,
+ triangleleft: [2,1,0x2F],
+ triangleright: [2,1,0x2E],
+ bigtriangleup: [2,2,0x34],
+ bigtriangledown: [2,2,0x35],
+ wedge: [2,2,0x5E],
+ land: [2,2,0x5E],
+ vee: [2,2,0x5F],
+ lor: [2,2,0x5F],
+ cap: [2,2,0x5C],
+ cup: [2,2,0x5B],
+ ddagger: [2,2,0x7A],
+ dagger: [2,2,0x79],
+ sqcap: [2,2,0x75],
+ sqcup: [2,2,0x74],
+ uplus: [2,2,0x5D],
+ amalg: [2,2,0x71],
+ diamond: [2,2,0x05],
+ bullet: [2,2,0x0F],
+ wr: [2,2,0x6F],
+ div: [2,2,0x04],
+ odot: [2,2,0x0C],
+ oslash: [2,2,0x0B],
+ otimes: [2,2,0x0A],
+ ominus: [2,2,0x09],
+ oplus: [2,2,0x08],
+ mp: [2,2,0x07],
+ pm: [2,2,0x06],
+ circ: [2,2,0x0E],
+ bigcirc: [2,2,0x0D],
+ setminus: [2,2,0x6E], // for set difference A\setminus B
+ cdot: [2,2,0x01],
+ ast: [2,2,0x03],
+ times: [2,2,0x02],
+ star: [2,1,0x3F],
// Relations
- propto: 0x322F,
- sqsubseteq: 0x3276,
- sqsupseteq: 0x3277,
- parallel: 0x326B,
- mid: 0x326A,
- dashv: 0x3261,
- vdash: 0x3260,
- leq: 0x3214,
- le: 0x3214,
- geq: 0x3215,
- ge: 0x3215,
- succ: 0x321F,
- prec: 0x321E,
- approx: 0x3219,
- succeq: 0x3217,
- preceq: 0x3216,
- supset: 0x321B,
- subset: 0x321A,
- supseteq: 0x3213,
- subseteq: 0x3212,
- 'in': 0x3232,
- ni: 0x3233,
- owns: 0x3233,
- gg: 0x321D,
- ll: 0x321C,
- not: 0x3236,
- sim: 0x3218,
- simeq: 0x3227,
- perp: 0x323F,
- equiv: 0x3211,
- asymp: 0x3210,
- smile: 0x315E,
- frown: 0x315F,
+ propto: [3,2,0x2F],
+ sqsubseteq: [3,2,0x76],
+ sqsupseteq: [3,2,0x77],
+ parallel: [3,2,0x6B],
+ mid: [3,2,0x6A],
+ dashv: [3,2,0x61],
+ vdash: [3,2,0x60],
+ leq: [3,2,0x14],
+ le: [3,2,0x14],
+ geq: [3,2,0x15],
+ ge: [3,2,0x15],
+ succ: [3,2,0x1F],
+ prec: [3,2,0x1E],
+ approx: [3,2,0x19],
+ succeq: [3,2,0x17],
+ preceq: [3,2,0x16],
+ supset: [3,2,0x1B],
+ subset: [3,2,0x1A],
+ supseteq: [3,2,0x13],
+ subseteq: [3,2,0x12],
+ 'in': [3,2,0x32],
+ ni: [3,2,0x33],
+ owns: [3,2,0x33],
+ gg: [3,2,0x1D],
+ ll: [3,2,0x1C],
+ not: [3,2,0x36],
+ sim: [3,2,0x18],
+ simeq: [3,2,0x27],
+ perp: [3,2,0x3F],
+ equiv: [3,2,0x11],
+ asymp: [3,2,0x10],
+ smile: [3,1,0x5E],
+ frown: [3,1,0x5F],
// Arrows
- Leftrightarrow: 0x322C,
- Leftarrow: 0x3228,
- Rightarrow: 0x3229,
- leftrightarrow: 0x3224,
- leftarrow: 0x3220,
- gets: 0x3220,
- rightarrow: 0x3221,
- to: 0x3221,
- mapstochar: 0x3237,
- leftharpoonup: 0x3128,
- leftharpoondown: 0x3129,
- rightharpoonup: 0x312A,
- rightharpoondown: 0x312B,
- nearrow: 0x3225,
- searrow: 0x3226,
- nwarrow: 0x322D,
- swarrow: 0x322E,
-
- hbarchar: 0x0016, // for \hbar
- lhook: 0x312C,
- rhook: 0x312D,
-
- ldotp: 0x613A, // ldot as a punctuation mark
- cdotp: 0x6201, // cdot as a punctuation mark
- colon: 0x603A, // colon as a punctuation mark
-
- '#': 0x7023,
- '$': 0x7024,
- '%': 0x7025,
- '&': 0x7026
+ Leftrightarrow: [3,2,0x2C],
+ Leftarrow: [3,2,0x28],
+ Rightarrow: [3,2,0x29],
+ leftrightarrow: [3,2,0x24],
+ leftarrow: [3,2,0x20],
+ gets: [3,2,0x20],
+ rightarrow: [3,2,0x21],
+ to: [3,2,0x21],
+ mapstochar: [3,2,0x37],
+ leftharpoonup: [3,1,0x28],
+ leftharpoondown: [3,1,0x29],
+ rightharpoonup: [3,1,0x2A],
+ rightharpoondown: [3,1,0x2B],
+ nearrow: [3,2,0x25],
+ searrow: [3,2,0x26],
+ nwarrow: [3,2,0x2D],
+ swarrow: [3,2,0x2E],
+
+ hbarchar: [0,0,0x16], // for \hbar
+ lhook: [3,1,0x2C],
+ rhook: [3,1,0x2D],
+
+ ldotp: [6,1,0x3A], // ldot as a punctuation mark
+ cdotp: [6,2,0x01], // cdot as a punctuation mark
+ colon: [6,0,0x3A], // colon as a punctuation mark
+
+ '#': [7,0,0x23],
+ '$': [7,0,0x24],
+ '%': [7,0,0x25],
+ '&': [7,0,0x26]
},
// The delimiter table (see Appendix B of the TeXbook)
delimiter: {
- '(': 0x0028300,
- ')': 0x0029301,
- '[': 0x005B302,
- ']': 0x005D303,
- '<': 0x026830A,
- '>': 0x026930B,
- '/': 0x002F30E,
- '|': 0x026A30C,
- '.': 0x0000000,
- '\\': 0x026E30F,
- '\\lmoustache': 0x437A340, // top from (, bottom from )
- '\\rmoustache': 0x537B341, // top from ), bottom from (
- '\\lgroup': 0x462833A, // extensible ( with sharper tips
- '\\rgroup': 0x562933B, // extensible ) with sharper tips
- '\\arrowvert': 0x026A33C, // arrow without arrowheads
- '\\Arrowvert': 0x026B33D, // double arrow without arrowheads
-// '\\bracevert': 0x077C33E, // the vertical bar that extends braces
- '\\bracevert': 0x026A33E, // we don't load tt, so use | instead
- '\\Vert': 0x026B30D,
- '\\|': 0x026B30D,
- '\\vert': 0x026A30C,
- '\\uparrow': 0x3222378,
- '\\downarrow': 0x3223379,
- '\\updownarrow': 0x326C33F,
- '\\Uparrow': 0x322A37E,
- '\\Downarrow': 0x322B37F,
- '\\Updownarrow': 0x326D377,
- '\\backslash': 0x026E30F, // for double coset G\backslash H
- '\\rangle': 0x526930B,
- '\\langle': 0x426830A,
- '\\rbrace': 0x5267309,
- '\\lbrace': 0x4266308,
- '\\}': 0x5267309,
- '\\{': 0x4266308,
- '\\rceil': 0x5265307,
- '\\lceil': 0x4264306,
- '\\rfloor': 0x5263305,
- '\\lfloor': 0x4262304
+ '(': [0,0,0x28,3,0x00],
+ ')': [0,0,0x29,3,0x01],
+ '[': [0,0,0x5B,3,0x02],
+ ']': [0,0,0x5D,3,0x03],
+ '<': [0,2,0x68,3,0x0A],
+ '>': [0,2,0x69,3,0x0B],
+ '/': [0,0,0x2F,3,0x0E],
+ '|': [0,2,0x6A,3,0x0C],
+ '.': [0,0,0x00,0,0x00],
+ '\\': [0,2,0x6E,3,0x0F],
+ '\\lmoustache': [4,3,0x7A,3,0x40], // top from (, bottom from )
+ '\\rmoustache': [5,3,0x7B,3,0x41], // top from ), bottom from (
+ '\\lgroup': [4,6,0x28,3,0x3A], // extensible ( with sharper tips
+ '\\rgroup': [5,6,0x29,3,0x3B], // extensible ) with sharper tips
+ '\\arrowvert': [0,2,0x6A,3,0x3C], // arrow without arrowheads
+ '\\Arrowvert': [0,2,0x6B,3,0x3D], // double arrow without arrowheads
+// '\\bracevert': [0,7,0x7C,3,0x3E], // the vertical bar that extends braces
+ '\\bracevert': [0,2,0x6A,3,0x3E], // we don't load tt, so use | instead
+ '\\Vert': [0,2,0x6B,3,0x0D],
+ '\\|': [0,2,0x6B,3,0x0D],
+ '\\vert': [0,2,0x6A,3,0x0C],
+ '\\uparrow': [3,2,0x22,3,0x78],
+ '\\downarrow': [3,2,0x23,3,0x79],
+ '\\updownarrow': [3,2,0x6C,3,0x3F],
+ '\\Uparrow': [3,2,0x2A,3,0x7E],
+ '\\Downarrow': [3,2,0x2B,3,0x7F],
+ '\\Updownarrow': [3,2,0x6D,3,0x77],
+ '\\backslash': [0,2,0x6E,3,0x0F], // for double coset G\backslash H
+ '\\rangle': [5,2,0x69,3,0x0B],
+ '\\langle': [4,2,0x68,3,0x0A],
+ '\\rbrace': [5,2,0x67,3,0x09],
+ '\\lbrace': [4,2,0x66,3,0x08],
+ '\\}': [5,2,0x67,3,0x09],
+ '\\{': [4,2,0x66,3,0x08],
+ '\\rceil': [5,2,0x65,3,0x07],
+ '\\lceil': [4,2,0x64,3,0x06],
+ '\\rfloor': [5,2,0x63,3,0x05],
+ '\\lfloor': [4,2,0x62,3,0x04]
},
/*
@@ -3621,7 +4509,7 @@ jsMath.Package(jsMath.Parser,{
doteq: ['Macro','\\buildrel\\textstyle.\\over='],
ldots: ['Macro','\\mathinner{\\ldotp\\ldotp\\ldotp}'],
cdots: ['Macro','\\mathinner{\\cdotp\\cdotp\\cdotp}'],
- vdots: ['Macro','\\mathinner{\\rlap{\\raise8pt{\\rule 0pt 6pt 0pt .}}\\rlap{\\raise4pt{.}}.}'],
+ vdots: ['Macro','\\mathinner{\\rlap{\\raise8pt{.\\rule 0pt 6pt 0pt}}\\rlap{\\raise4pt{.}}.}'],
ddots: ['Macro','\\mathinner{\\kern1mu\\raise7pt{\\rule 0pt 7pt 0pt .}\\kern2mu\\raise4pt{.}\\kern2mu\\raise1pt{.}\\kern1mu}'],
joinrel: ['Macro','\\mathrel{\\kern-4mu}'],
relbar: ['Macro','\\mathrel{\\smash-}'], // \smash, because - has the same height as +
@@ -3663,7 +4551,7 @@ jsMath.Package(jsMath.Parser,{
hskip: 'Hskip',
kern: 'Hskip',
- rule: ['Rule','black'],
+ rule: ['Rule','colored'],
space: ['Rule','blank'],
big: ['MakeBig','ord',0.85],
@@ -3707,18 +4595,18 @@ jsMath.Package(jsMath.Parser,{
hphantom: ['Phantom',0,1],
smash: 'Smash',
- acute: ['MathAccent', 0x7013],
- grave: ['MathAccent', 0x7012],
- ddot: ['MathAccent', 0x707F],
- tilde: ['MathAccent', 0x707E],
- bar: ['MathAccent', 0x7016],
- breve: ['MathAccent', 0x7015],
- check: ['MathAccent', 0x7014],
- hat: ['MathAccent', 0x705E],
- vec: ['MathAccent', 0x017E],
- dot: ['MathAccent', 0x705F],
- widetilde: ['MathAccent', 0x0365],
- widehat: ['MathAccent', 0x0362],
+ acute: ['MathAccent', [7,0,0x13]],
+ grave: ['MathAccent', [7,0,0x12]],
+ ddot: ['MathAccent', [7,0,0x7F]],
+ tilde: ['MathAccent', [7,0,0x7E]],
+ bar: ['MathAccent', [7,0,0x16]],
+ breve: ['MathAccent', [7,0,0x15]],
+ check: ['MathAccent', [7,0,0x14]],
+ hat: ['MathAccent', [7,0,0x5E]],
+ vec: ['MathAccent', [0,1,0x7E]],
+ dot: ['MathAccent', [7,0,0x5F]],
+ widetilde: ['MathAccent', [0,3,0x65]],
+ widehat: ['MathAccent', [0,3,0x62]],
'_': ['Replace','ord','_','normal',-.4,.1],
' ': ['Replace','ord',' ','normal'],
@@ -3754,8 +4642,7 @@ jsMath.Package(jsMath.Parser,{
unicode: 'Unicode',
// debugging and test routines
- 'char': 'Char',
- test: 'Test'
+ 'char': 'Char'
},
/*
@@ -3777,10 +4664,10 @@ jsMath.Package(jsMath.Parser,{
* The horizontally stretchable delimiters
*/
leaders: {
- downbrace: {left: 0x37A, lmid: 0x37D, rmid: 0x37C, right: 0x37B},
- upbrace: {left: 0x37C, lmid: 0x37B, rmid: 0x37A, right: 0x37D},
- leftarrow: {left: 0x220, rep: 0x200},
- rightarrow: {rep: 0x200, right: 0x221}
+ downbrace: {left: [3,0x7A], lmid: [3,0x7D], rmid: [3,0x7C], right: [3,0x7B]},
+ upbrace: {left: [3,0x7C], lmid: [3,0x7B], rmid: [3,0x7A], right: [3,0x7D]},
+ leftarrow: {left: [2,0x20], rep: [2,0x00]},
+ rightarrow: {rep: [2,0x00], right: [2,0x21]}
},
@@ -3894,11 +4781,20 @@ jsMath.Package(jsMath.Parser,{
* converted when typeset.
*/
GetDimen: function (name,nomu) {
- var rest = this.string.slice(this.i);
+ var rest; var advance = 0;
+ if (this.nextIsSpace()) {this.i++}
+ if (this.string.charAt(this.i) == '{') {
+ rest = this.GetArgument(name);
+ } else {
+ rest = this.string.slice(this.i);
+ advance = 1;
+ }
var match = rest.match(/^\s*([-+]?(\.\d+|\d+(\.\d*)?))(pt|em|ex|mu|px)/);
if (!match) {this.Error("Missing dimension or its units for "+name); return}
- this.i += match[0].length;
- if (this.nextIsSpace()) {this.i++}
+ if (advance) {
+ this.i += match[0].length;
+ if (this.nextIsSpace()) {this.i++}
+ }
var d = match[1]-0;
if (match[4] == 'px') {d /= jsMath.em}
else if (match[4] == 'pt') {d /= 10}
@@ -4275,23 +5171,6 @@ jsMath.Package(jsMath.Parser,{
},
/*
- * Debugging routine to test stretchable delimiters
- */
- Test: function () {
- var delim = this.GetDelimiter(this.cmd+'test'); if (this.error) return;
- var H = this.GetArgument(this.cmd+'test'); if (this.error) return;
- this.mlist.Add(jsMath.mItem.Typeset(jsMath.Box.Delimiter(H,delim,'T')));
- return;
-
- var leader = this.GetArgument(this.cmd+'test'); if (this.error) return;
- var W = this.GetArgument(this.cmd+'test'); if (this.error) return;
- if (this.leaders[leader] == null)
- {this.Error('Unknown leaders "'+leader+'"'); return}
- this.mlist.Add(jsMath.mItem.Typeset(jsMath.Box.Leaders(W,this.leaders[leader])));
- return;
- },
-
- /*
* Add a fixed amount of horizontal space
*/
Spacer: function (name,w) {
@@ -4335,15 +5214,27 @@ jsMath.Package(jsMath.Parser,{
* This replaces \hrule and \vrule
* @@@ not a standard TeX command, and all three parameters must be given @@@
*/
- Rule: function (name,gif) {
+ Rule: function (name,style) {
var w = this.GetDimen(this.cmd+name,1); if (this.error) return;
var h = this.GetDimen(this.cmd+name,1); if (this.error) return;
var d = this.GetDimen(this.cmd+name,1); if (this.error) return;
- h += d;
+ h += d; var html;
if (h != 0) {h = Math.max(1.05/jsMath.em,h)}
- if (h == 0 || w == 0) {gif = "blank"}
- var html = '
';
+ if (h == 0 || w == 0) {style = "blank"}
+ if (w == 0) {
+ html = '
';
+ } else if (style == "blank") {
+ html = '
';
+ } else {
+ html = '
';
+ }
if (d) {
html = ''
+ html + '';
@@ -4485,10 +5376,7 @@ jsMath.Package(jsMath.Parser,{
* Process the character associated with a specific \mathcharcode
*/
HandleMathCode: function (name,code) {
- var type = (code & 0xF000) >> 12;
- var font = (code & 0x0F00) >> 8;
- var code = code & 0x00FF;
- this.HandleTeXchar(type,font,code);
+ this.HandleTeXchar(code[0],code[1],code[2]);
},
/*
@@ -4566,7 +5454,7 @@ jsMath.Package(jsMath.Parser,{
return;
}
if (this.delimiter[this.cmd+cmd]) {
- this.HandleMathCode(cmd,this.delimiter[this.cmd+cmd]>>12)
+ this.HandleMathCode(cmd,this.delimiter[this.cmd+cmd].slice(0,3))
return;
}
this.Error("Unknown control sequence '"+this.cmd+cmd+"'");
@@ -4682,52 +5570,40 @@ jsMath.Package(jsMath.Parser,{
* results. We also include an image to force the results to take up
* the right amount of space. The results may need to be vertically
* adjusted to make the baseline appear in the correct place.
- *
- * This is where the touchiest browser-dependent code appears.
*/
Typeset: function () {
var data = this.mlist.init;
var box = this.typeset = this.mlist.Typeset(data.style,data.size);
if (this.error) {return ''+this.error+''}
if (box.format == 'null') {return ''};
- var rules = ''; var html
box.Styled().Remeasured(); var isSmall = 0; var isBig = 0;
- var w = box.w; var h = box.bh; var d = box.bd;
if (box.bh > box.h && box.bh > jsMath.h+.001) {isSmall = 1}
if (box.bd > box.d && box.bd > jsMath.d+.001) {isSmall = 1}
- if (box.h > jsMath.h) {isBig = 1; h = box.h}
- if (box.d > jsMath.d) {isBig = 1; d = box.d}
+ if (box.h > jsMath.h || box.d > jsMath.d) {isBig = 1}
- if (jsMath.show.BBox) {rules += jsMath.HTML.Frame(0,-box.d,w,box.h+box.d,'green')}
- if (jsMath.show.Top) {rules += jsMath.HTML.Line(0,box.h,w,'red')}
- if (jsMath.show.Baseline) {rules += jsMath.HTML.Line(0,0,w,'blue')}
-
- html = box.html;
+ var html = box.html;
if (isSmall) {// hide the extra size
- if (jsMath.allowAbsolute) {
- var y = jsMath.absoluteOffsetY;
- if (jsMath.absoluteHeightVaries || box.bh > jsMath.h+.001) {y += (jsMath.h - box.bh)}
- html = jsMath.HTML.Absolute(html,w,jsMath.h,0,y,jsMath.h);
- isBig = 1; h = box.h; d = box.d;
- } else {// remove line height and try to hide the depth
+ if (jsMath.Browser.allowAbsolute) {
+ var y = 0;
+ if (box.bh > jsMath.h+.001) {y = jsMath.h - box.bh}
+ html = jsMath.HTML.Absolute(html,box.w,jsMath.h,0,y,jsMath.h);
+ } else if (!jsMath.Browser.valignBug) {
+ // remove line height and try to hide the depth
var dy = jsMath.HTML.Em(Math.max(0,box.bd-jsMath.hd)/3);
html = ''
- + html
- + '';
+ + ' position:relative; top:'+dy+'; vertical-align:'+dy
+ + '">' + html + '';
}
+ isBig = 1;
}
- html = '' + rules + html;
if (isBig) {// add height and depth to the line (force a little
// extra to separate lines if needed)
- html += '
'
+ html += '
'
}
- html += ''
- return html;
+ return ''+html+'';
}
});
@@ -4760,7 +5636,7 @@ jsMath.Parser.prototype.AddSpecial({
* requires. These are substituted for #1, #2, etc. within the
* replacement string of the macro. For example
*
- *
+ *
*
* would make \x1 produce {\vec x}_{1} and \x{i+1} produce {\vec x}_{i+1}.
*
@@ -4812,7 +5688,6 @@ jsMath.Add(jsMath,{
/*
* Typeset a string in \displaystyle and return the HTML for it
- * ### need to give more control over whether to center, etc. ###
*/
DisplayMode: function (s) {
var parse = jsMath.Parse(s,null,null,'D');
@@ -4826,13 +5701,11 @@ jsMath.Add(jsMath,{
*/
GetElementText: function (element) {
var text = element.innerText;
- if (text == null) {
- text = element.textContent;
- if (text == null) {
- text = element.innerHTML;
- }
+ if (text == null || text == "") {
+ try {text = element.textContent} catch (err) {}
+ if (text == null || text == "") {text = element.innerHTML}
}
- if (text.search('&')) {
+ if (text.search('&') >= 0) {
text = text.replace(/</g,'<');
text = text.replace(/>/g,'>');
text = text.replace(/"/g,'"');
@@ -4842,12 +5715,28 @@ jsMath.Add(jsMath,{
},
/*
+ * Move hidden to the location of the math element to be
+ * processed and reinitialize sizes for that location.
+ */
+ ResetHidden: function (element) {
+ element.innerHTML =
+ ''
+ + jsMath.Browser.operaHiddenFix; // needed by Opera in tables
+ element.className='';
+ jsMath.hidden = element.firstChild;
+ jsMath.ReInit();
+ },
+
+
+ /*
* Typeset the contents of an element in \textstyle
*/
ConvertText: function (element) {
var text = this.GetElementText(element);
+ this.ResetHidden(element);
element.innerHTML = this.TextMode(text);
element.className = 'typeset';
+ element.alt = text;
},
/*
@@ -4855,35 +5744,34 @@ jsMath.Add(jsMath,{
*/
ConvertDisplay: function (element) {
var text = this.GetElementText(element);
+ this.ResetHidden(element);
element.innerHTML = this.DisplayMode(text);
element.className = 'typeset';
- },
-
- /*
- * Call this at the bottom of your HTML page to have the
- * mathematics typeset before the page is displayed.
- * This can take a long time, so the user could cancel the
- * page before it is complete; use it with caution, and only
- * when there is a relatively small amount of math on the page.
- */
- ProcessBeforeShowing: function () {
- if (!jsMath.initialized) {jsMath.Init()}
- var element = jsMath.GetMathElements();
- for (var i = 0; i < element.length; i++)
- {jsMath.ProcessElement(element[i])}
- jsMath.ProcessComplete();
+ element.alt = text;
},
/*
* Process a math element
*/
ProcessElement: function (element) {
- window.status = 'Processing Math...';
- if (element.tagName == 'DIV') {
- this.ConvertDisplay(element);
- } else if (element.tagName == 'SPAN') {
- this.ConvertText(element);
- }
+ try {
+ if (element.tagName == 'DIV') {
+ this.ConvertDisplay(element);
+ } else if (element.tagName == 'SPAN') {
+ this.ConvertText(element);
+ //
+ // Overcome a bug in MSIE where were tex2math can't insert DIV's inside
+ // some elements, so fake it with SPANs, but can't fake the centering,
+ // so do that here.
+ //
+ if (element.parentNode.className == 'jsMath.recenter') {
+ element.parentNode.style.marginLeft =
+ Math.floor((element.parentNode.offsetWidth - element.offsetWidth)/2)+"px";
+ }
+ }
+ element.onclick = jsMath.Click.CheckClick;
+ element.ondblclick = jsMath.Click.CheckDblClick;
+ } catch (err) {}
},
/*
@@ -4895,7 +5783,7 @@ jsMath.Add(jsMath,{
this.ProcessComplete();
} else {
this.ProcessElement(this.element[k])
- setTimeout('jsMath.ProcessElements('+(k+1)+')',jsMath.delay);
+ setTimeout('jsMath.ProcessElements('+(k+1)+')',jsMath.Browser.delay);
}
},
@@ -4905,11 +5793,27 @@ jsMath.Add(jsMath,{
* start reading the mathematics while the rest of the page
* is being processed.
*/
- Process: function () {
+ Process: function (obj) {
if (!jsMath.initialized) {jsMath.Init()}
- this.element = this.GetMathElements();
+ this.element = this.GetMathElements(obj);
window.status = 'Processing Math...';
- setTimeout('jsMath.ProcessElements(0)',jsMath.delay);
+ setTimeout('jsMath.ProcessElements(0)',jsMath.Browser.delay);
+ },
+
+ /*
+ * Call this at the bottom of your HTML page to have the
+ * mathematics typeset before the page is displayed.
+ * This can take a long time, so the user could cancel the
+ * page before it is complete; use it with caution, and only
+ * when there is a relatively small amount of math on the page.
+ */
+ ProcessBeforeShowing: function (obj) {
+ if (!jsMath.initialized) {jsMath.Init()}
+ var element = jsMath.GetMathElements(obj);
+ window.status = 'Processing Math...';
+ for (var i = 0; i < element.length; i++)
+ {jsMath.ProcessElement(element[i])}
+ jsMath.ProcessComplete();
},
element: [], // the list of math elements on the page
@@ -4918,25 +5822,30 @@ jsMath.Add(jsMath,{
* Look up all the math elements on the page and
* put them in a list sorted from top to bottom of the page
*/
- GetMathElements: function () {
+ GetMathElements: function (obj) {
var element = [];
- var math = document.getElementsByTagName('DIV');
+ if (!obj) {obj = document}
+ if (typeof(obj) == 'string') {obj = document.getElementById(obj)}
+ if (!obj.getElementsByTagName) return
+ var math = obj.getElementsByTagName('DIV');
for (var k = 0; k < math.length; k++) {
if (math[k].className == 'math') {
- if (jsMath.renameOK) {math[k].setAttribute('NAME','_jsMath_')}
+ if (jsMath.Browser.renameOK && obj.getElementsByName)
+ {math[k].setAttribute('NAME','_jsMath_')}
else {element[element.length] = math[k]}
}
}
- math = document.getElementsByTagName('SPAN');
+ math = obj.getElementsByTagName('SPAN');
for (var k = 0; k < math.length; k++) {
if (math[k].className == 'math') {
- if (jsMath.renameOK) {math[k].setAttribute('NAME','_jsMath_')}
+ if (jsMath.Browser.renameOK && obj.getElementsByName)
+ {math[k].setAttribute('NAME','_jsMath_')}
else {element[element.length] = math[k]}
}
}
// this gets the SPAN and DIV elements interleaved in order
- if (jsMath.renameOK) {
- element = document.getElementsByName('_jsMath_')
+ if (jsMath.Browser.renameOK && obj.getElementsByName) {
+ element = obj.getElementsByName('_jsMath_');
} else if (jsMath.hidden.sourceIndex) {
element.sort(function (a,b) {return a.sourceIndex - b.sourceIndex});
}
@@ -4948,42 +5857,39 @@ jsMath.Add(jsMath,{
* and clean up any marked or tags
*/
ProcessComplete: function () {
- if (jsMath.renameOK) {
+ if (jsMath.Browser.renameOK) {
var element = document.getElementsByName('_jsMath_');
for (var i = element.length-1; i >= 0; i--) {
element[i].removeAttribute('NAME');
}
}
+ jsMath.hidden = jsMath.hiddenTop;
jsMath.element = [];
window.status = 'Done';
- }
-
+ if (jsMath.Browser.safariImgBug &&
+ (jsMath.Controls.cookie.font == 'symbol' ||
+ jsMath.Controls.cookie.font == 'image')) {
+ //
+ // For Safari, the images don't always finish
+ // updating, so nudge the window to cause a
+ // redraw. (Hack!)
+ //
+ setTimeout("window.resizeBy(-1,0); window.resizeBy(1,0);",2000);
+ }
+ },
+
+ Element: function (name) {return document.getElementById('jsMath.'+name)}
+
});
-/***************************************************************************/
-/*
- * We use a hidden
for measuring the BBoxes of things
- */
-jsMath.hidden = '
';
-if (document.body.insertAdjacentHTML) {
- document.body.insertAdjacentHTML('AfterBegin',jsMath.hidden);
-} else {
- document.write(jsMath.hidden);
-}
-jsMath.hidden = document.getElementById("jsMath.Hidden");
+/***************************************************************************/
/*
* Initialize everything
*/
-jsMath.InitSource();
-jsMath.InitBrowser();
-jsMath.InitStyles();
+jsMath.Loaded();
+jsMath.Controls.GetCookie();
+if (document.body) {jsMath.Setup.Body()}
-//make sure browser-specific loads are done before this
-document.write('');
-
-}
-
-}
+}}