version 1.1, 2005/02/25 04:57:49
|
version 1.2, 2005/12/07 18:57:45
|
Line 2
|
Line 2
|
* |
* |
* jsMath: Mathematics on the Web |
* jsMath: Mathematics on the Web |
* |
* |
* Version: 1.7e |
|
* |
|
* This jsMath package makes it possible to display mathematics in HTML pages |
* This jsMath package makes it possible to display mathematics in HTML pages |
* that are viewable by a wide range of browsers on both the Mac and the IBM PC, |
* that are viewable by a wide range of browsers on both the Mac and the IBM PC, |
* including browsers that don't process MathML. See |
* including browsers that don't process MathML. See |
Line 33
|
Line 31
|
/* |
/* |
* Prevent running everything again if this file is loaded twice |
* Prevent running everything again if this file is loaded twice |
*/ |
*/ |
if (!window.jsMath) { |
if (!jsMath || !jsMath.loaded) { |
|
var jsMath_old = jsMath; // save user customizations |
|
|
// |
// |
// debugging routine |
// debugging routine |
Line 66 if (!document.getElementById || !documen
|
Line 65 if (!document.getElementById || !documen
|
/***************************************************************************/ |
/***************************************************************************/ |
|
|
var jsMath = { |
var jsMath = { |
|
|
|
version: "2.4b", // change this if you edit the file |
|
|
// |
// |
// Name of image files |
// Name of image files |
// |
// |
blank: "blank.gif", |
blank: "blank.gif", |
black: "black.gif", |
|
|
|
// |
|
// The TeX font parameters |
|
// |
|
TeX: { |
|
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 |
|
}, |
|
|
|
|
defaultH: 0, // default height for characters with none specified |
|
|
// Font sizes for \tiny, \small, etc. (must match styles below) |
// Font sizes for \tiny, \small, etc. (must match styles below) |
sizes: [50, 60, 70, 85, 100, 120, 144, 173, 207, 249], |
sizes: [50, 60, 70, 85, 100, 120, 144, 173, 207, 249], |
|
|
allowAbsolute: 1, // tells if browser can nest absolutely positioned |
|
// SPANs inside relative SPANs |
|
absoluteOffsetY: 0, // vertical adjustment when absolute position is used |
|
allowAbsoluteDelim: 0, // OK to use absolute placement for building delims? |
|
renameOK: 1, // tells if brower will find a tag whose name |
|
// has been set via setAttributes |
|
separateNetgativeSkips: 0, // MSIE doesn't do negative left margins |
|
separateSkips: 0, // Netscape doesn't combine skips well |
|
noEmptySpans: 0, // empty spans are/aren't allowed |
|
msieSpaceFix: '', // for MSIE spacing bug fix |
|
|
|
delay: 1, // delay for asynchronous math processing |
|
|
|
defaultH: 0, // default height for characters with no height specified |
|
|
|
// |
|
// Debugging flags |
|
// |
|
show: { |
|
BBox: false, |
|
Baseline: false, |
|
Top: false |
|
}, |
|
|
|
// |
// |
// The styles needed for the TeX fonts |
// The styles needed for the TeX fonts |
// |
// |
Line 155 var jsMath = {
|
Line 93 var jsMath = {
|
'.size8': 'font-size: 207%', // huge |
'.size8': 'font-size: 207%', // huge |
'.size9': 'font-size: 249%', // Huge |
'.size9': 'font-size: 249%', // Huge |
|
|
'.cmr10': 'font-family: cmr10', |
'.cmr10': 'font-family: cmr10, serif', |
'.cmbx10': 'font-family: cmbx10, cmr10', |
'.cmbx10': 'font-family: cmbx10, cmr10', |
'.cmti10': 'font-family: cmti10, cmr10', |
'.cmti10': 'font-family: cmti10, cmr10', |
'.cmmi10': 'font-family: cmmi10', |
'.cmmi10': 'font-family: cmmi10', |
'.cmsy10': 'font-family: cmsy10', |
'.cmsy10': 'font-family: cmsy10', |
'.cmex10': 'font-family: cmex10', |
'.cmex10': 'font-family: cmex10', |
'.arial': 'font-family: Arial unicode MS', // for MSIE |
|
|
'.math': 'font-family: serif; font-style: normal; font-weight: normal', |
'.normal': 'font-family: serif; font-style: normal', |
'.typeset': 'font-family: serif; font-style: normal; font-weight: normal', |
'.math': 'font-family: serif; font-style: normal', |
'.normal': 'font-family: serif; font-style: normal; font-weight: normal; ' |
'.typeset': 'font-family: serif; font-style: normal', |
+ 'padding:0px; border:0px; margin:0px;', |
'span.typeset': 'font-family: serif; font-style: normal', |
'span.typeset': '', |
'div.typeset': 'font-family: serif; font-style: normal; text-align: center; margin-top: 1em; margin-bottom: 1em', |
'div.typeset': 'text-align: center; margin: 1em 0px;', |
'.mathlink': 'text-decoration: none', |
'.mathlink': 'text-decoration: none', |
'.mathHD': 'border-width: 0; width: 1px; margin-right: -1px', |
'.mathHD': 'border-width:0px; width: 1px; margin-right: -1px', |
|
|
'.error': 'font-size: 10pt; font-style: italic; ' |
'.error': 'font-size: 10pt; font-style: italic; ' |
+ 'background-color: #FFFFCC; padding: 1; ' |
+ 'background-color: #FFFFCC; padding: 1px; ' |
+ 'border-width: 1; border-style: solid; border-color: #CC0000' |
+ 'border: 1px solid #CC0000', |
}, |
|
|
|
|
'.jsM_panel': 'position:fixed; bottom:1.5em; right:1.5em; padding: 10px 20px; ' |
|
+ 'background-color:#DDDDDD; border: outset 2px; ' |
|
+ 'z-index:103; width:auto;', |
|
'.jsM_button': 'position:fixed; bottom:1px; right:2px; background-color:white; ' |
|
+ 'border: solid 1px #959595; margin:0px; padding: 0px 3px 1px 3px; ' |
|
+ 'z-index:102; color:black; text-decoration:none; font-size:x-small; width:auto;', |
|
'.jsM_float': 'position:absolute; top:0px; left:0px; max-width:80%; ' |
|
+ 'z-index:101; width:auto; height:auto;', |
|
'.jsM_drag': 'background-color:#DDDDDD; border: outset 1px; height:12px; font-size: 1px;', |
|
'.jsM_close': 'background-color:#E6E6E6; border: inset 1px; width:8px; height:8px; margin: 1px 2px;', |
|
'.jsM_source': 'background-color:#E2E2E2; border: outset 1px; ' |
|
+ 'width:auto; height:auto; padding: 8px 15px; ' |
|
+ 'font-family: courier, fixed; font-size: 90%', |
|
'.jsM_noFont': 'text-align: center; padding: 10px 20px; border: 3px solid #DD0000; ' |
|
+ ' background-color: #FFF8F8; color: #AA0000; font-size:small; width:auto;', |
|
'.jsM_fontLink': 'padding: 0px 5px 2px 5px; text-decoration:none; color:black;' |
|
+ ' border: 2px outset; background-color:#E8E8E8; font-size:80%; width:auto;' |
|
}, |
|
|
|
|
/***************************************************************************/ |
/***************************************************************************/ |
|
|
/* |
/* |
* Get the width and height (in pixels) of an HTML string |
* Get the width and height (in pixels) of an HTML string |
*/ |
*/ |
BBoxFor: function (s) { |
BBoxFor: function (s) { |
this.hidden.innerHTML = s; |
this.hidden.innerHTML = '<NOBR><SPAN CLASS="jsM_scale">'+s+'</SPAN></NOBR>'; |
var bbox = {w: this.hidden.offsetWidth, h: this.hidden.offsetHeight}; |
var bbox = {w: this.hidden.offsetWidth, h: this.hidden.offsetHeight}; |
this.hidden.innerHTML = ''; // avoid MSIE bug on the Mac |
this.hidden.innerHTML = ''; |
return bbox; |
return bbox; |
}, |
}, |
|
|
Line 198 var jsMath = {
|
Line 154 var jsMath = {
|
}, |
}, |
|
|
/* |
/* |
* Determine if the "top" of a <SPAN> is always at the same height |
* For browsers that don't handle sizes of italics properly (MSIE) |
* or varies with the height of the rest of the line (MSIE). |
|
*/ |
*/ |
TestSpanHeight: function () { |
EmBoxForItalics: function (s) { |
this.hidden.innerHTML = '<SPAN><IMG SRC="'+jsMath.blank+'" STYLE="height: 2em"></SPAN>'; |
var bbox = this.BBoxFor(s); |
var span = this.hidden.getElementsByTagName('SPAN')[0]; |
if (s.match(/<I>|CLASS="icm/i)) { |
var img = this.hidden.getElementsByTagName('IMG')[0]; |
bbox.w = this.BBoxFor(s+jsMath.Browser.italicString).w |
this.spanHeightVaries = (span.offsetHeight == img.offsetHeight); |
- jsMath.Browser.italicCorrection; |
this.hidden.innerHTML = ''; |
} |
|
return {w: bbox.w/this.em, h: bbox.h/this.em}; |
}, |
}, |
|
|
/* |
/* |
* Determine if the NAME attribute of a tag can be changed |
* Initialize jsMath. This determines the em size, and a variety |
* using the setAttribute function, and then be properly |
* of other parameters used throughout jsMath. |
* returned by getElementByName. |
|
*/ |
*/ |
TestRenameOK: function () { |
Init: function () { |
this.hidden.innerHTML = '<SPAN ID="jsMath.test"></SPAN>'; |
if (jsMath.Setup.inited != 1) { |
var test = document.getElementById('jsMath.test'); |
if (jsMath.Setup.inited) { |
test.setAttribute('NAME','jsMath_test'); |
alert("It looks like jsMath failed to set up properly."); |
this.renameOK = (document.getElementsByName('jsMath_test').length > 0); |
} else { |
this.hidden.innerHTML = ''; |
alert("You must call jsMath.Setup.Body() explicitly when jsMath is" + |
}, |
"loaded as part of the <HEAD> section"); |
|
} |
|
jsMath.Setup.Init(); // may fail to load fallback files properly |
|
} |
|
this.em = this.BBoxFor('<IMG SRC="'+jsMath.blank+'" STYLE="width:10em; height:1em">').w/10; |
|
if (jsMath.Browser.italicString) |
|
jsMath.Browser.italicCorrection = jsMath.BBoxFor(jsMath.Browser.italicString).w; |
|
if (jsMath.Browser.hiddenSpace != '') { |
|
jsMath.Browser.spaceWidth = |
|
this.EmBoxFor(jsMath.Browser.hiddenSpace + |
|
jsMath.Browser.hiddenSpace + |
|
jsMath.Browser.hiddenSpace + |
|
jsMath.Browser.hiddenSpace + |
|
jsMath.Browser.hiddenSpace).w/5; |
|
} |
|
var bb = this.BBoxFor('x'); var h = bb.h; |
|
var d = this.BBoxFor('x<IMG SRC="'+jsMath.blank+'" HEIGHT="'+(h*jsMath.Browser.imgScale)+'" WIDTH="1">').h - h; |
|
this.h = (h-d)/this.em; this.d = d/this.em; |
|
this.hd = this.h + this.d; |
|
this.xWidth = bb.w; // used to tell if scale has changed |
|
|
|
this.Setup.TeXfonts(); |
|
|
|
var x_height = this.EmBoxFor('<SPAN CLASS="cmr10">M</SPAN>').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; |
|
|
|
this.Img.Scale(); |
|
if (!this.initialized) { |
|
this.Setup.Sizes(); |
|
this.Img.UpdateFonts(); |
|
} |
|
|
|
// factor for \big and its brethren |
|
this.p_height = (this.TeX.cmex10[0].h + this.TeX.cmex10[0].d) / .85; |
|
|
|
this.initialized = 1; |
|
}, |
|
|
/* |
/* |
* Look to see if a font is found. HACK! |
* Get the xWidth size and if it has changed, reinitialize the sizes |
* Check the character in the '|' position, and see if it is |
|
* wider than the usual '|'. |
|
*/ |
*/ |
TestFont: function (name,n,factor) { |
ReInit: function () { |
if (n == null) {n = 124}; if (factor == null) {factor = 2} |
var w = this.BBoxFor('x').w; |
var wh1 = this.BBoxFor('<SPAN STYLE="font-family: '+name+', serif">'+this.TeX[name][n].c+'</SPAN>'); |
if (w != this.xWidth) {this.Init()} |
var wh2 = this.BBoxFor('<SPAN STYLE="font-family: serif">'+this.TeX[name][n].c+'</SPAN>'); |
|
return (wh1.w > factor*wh2.w && wh1.h != 0); |
|
}, |
}, |
|
|
TestFont2: function (name,n,factor) { |
/* |
if (n == null) {n = 124}; if (factor == null) {factor = 2} |
* Mark jsMath as loaded and copy any user-provided overrides |
var wh1 = this.BBoxFor('<SPAN STYLE="font-family: '+name+', serif">'+this.TeX[name][n].c+'</SPAN>'); |
*/ |
var wh2 = this.BBoxFor('<SPAN STYLE="font-family: serif">'+this.TeX[name][n].c+'</SPAN>'); |
Loaded: function () { |
return (wh2.w > factor*wh1.w && wh1.h != 0); |
this.Insert(jsMath,jsMath_old); |
|
jsMath_old = null; |
|
jsMath.loaded = 1; |
}, |
}, |
|
|
/* |
/* |
* Check for the availability of TeX fonts. We do this by looking at |
* Manage JavaScript objects: |
* 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. |
|
* |
* |
*/ |
* Add: add/replace items in an object |
CheckFonts: function () { |
* Insert: add items to an object |
jsMath.nofonts = 0; |
* Package: add items to an object prototype |
var wh = this.BBoxFor('<SPAN STYLE="font-family: cmex10">'+this.TeX.cmex10[1].c+'</SPAN>'); |
*/ |
if (wh.w*3 < wh.h && wh.h != 0) return; |
Add: function (dst,src) {for (var id in src) {dst[id] = src[id]}}, |
if (this.TestFont('cmr10')) return; |
Insert: function (dst,src) { |
if (window.NoFontMessage) {window.NoFontMessage()} else {this.NoFontMessage()} |
for (var id in src) { |
if (navigator.platform == 'Win32') { |
if (dst[id] && typeof(src[id]) == 'object' |
document.writeln('<SCRIPT SRC="'+this.root+'jsMath-fallback-pc.js"></SCRIPT>'); |
&& (typeof(dst[id]) == 'object' |
} else if (navigator.platform == 'MacPPC') { |
|| typeof(dst[id]) == 'function')) { |
document.writeln('<SCRIPT SRC="'+this.root+'jsMath-fallback-mac.js"></SCRIPT>'); |
this.Insert(dst[id],src[id]); |
} else { |
} else { |
// default to unix? Is there a better way to tell if unix? |
dst[id] = src[id]; |
document.writeln('<SCRIPT SRC="'+this.root+'jsMath-fallback-unix.js"></SCRIPT>'); |
} |
} |
} |
jsMath.nofonts = 1; |
|
}, |
}, |
|
Package: function (obj,def) {this.Insert(obj.prototype,def)} |
|
|
|
} |
|
|
|
/***************************************************************************/ |
|
|
|
/* |
|
* Miscellaneous setup and initialization |
|
*/ |
|
jsMath.Setup = { |
|
|
/* |
/* |
* The message for when no TeX fonts. You can eliminate this message |
* Insert a DIV at the top of the page with given ID, |
* by including |
* attributes, and style settings |
* |
|
* <SCRIPT>function NoFontMessage() {}</SCRIPT> |
|
* |
|
* in your HTML file, if you want. But this means the user may not know |
|
* that he or she can get a better version of your page. |
|
*/ |
*/ |
NoFontMessage: function () { |
TopHTML: function (id,attributes,styles) { |
document.writeln |
try { |
('<CENTER><DIV STYLE="padding: 10; border-style: solid; border-width:3;' |
var div = document.createElement('div'); |
+' border-color: #DD0000; background-color: #FFF8F8; width: 75%; text-align: left">' |
div.setAttribute("id",'jsMath.'+id); |
+'<SMALL><FONT COLOR="#AA0000"><B>Warning:</B>\n' |
for (var i in attributes) { |
+'It looks like you don\'t have the TeX math fonts installed.\n' |
div.setAttribute(i,attributes[i]); |
+'The mathematics on this page may not look right without them.\n' |
if (i == "class") {div.setAttribute('className',attributes[i])} // MSIE |
+'The <A HREF="http://www.math.union.edu/locate/jsMath/" TARGET="_blank">' |
} |
+'jsMath Home Page</A> has information on how to download the\n' |
for (var i in styles) {div.style[i]= styles[i]} |
+'needed fonts. In the meantime, we will do the best we can\n' |
if (!document.body.hasChildNodes) {document.body.appendChild(div)} |
+'with the fonts you have, but it may not be pretty and some equations\n' |
else {document.body.insertBefore(div,document.body.firstChild)} |
+'may not be rendered correctly.\n' |
} catch (err) { |
+'</FONT></SMALL></DIV></CENTER><p><HR><p>'); |
var html = '<DIV ID="jsMath.'+id+'"'; |
|
for (var id in attributes) {html += ' '+id+'="'+attributes[id]+'"'} |
|
if (styles) { |
|
html += ' STYLE="'; |
|
for (var id in styles) {html += ' '+id+':'+styles[id]+';'} |
|
html += '"'; |
|
} |
|
html += '</DIV>'; |
|
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 |
* Source a jsMath JavaScript file |
* of other parameters used throughout jsMath. |
|
*/ |
*/ |
Init: function() { |
Script: function (file) { |
this.em = this.BBoxFor('<DIV STYLE="width: 20em; height: 1em"></DIV>').w/20; |
if (!file.match('^([a-zA-Z]+:/)?/')) {file = jsMath.root + file} |
var h = this.BBoxFor('x').h; // Line height and depth to baseline |
document.write('<SCRIPT SRC="'+file+'"></SCRIPT>'); |
var d = this.BBoxFor('x<IMG SRC="'+jsMath.black+'" HEIGHT="'+h+'" WIDTH="1">').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; |
* Use a hidden <DIV> for measuring the BBoxes of things |
|
*/ |
this.InitTeXfonts(); |
HTML: function () { |
|
jsMath.hidden = this.TopHTML("Hidden",{'class':"normal"},{ |
var x_height = this.EmBoxFor('<SPAN CLASS="cmr10">M</SPAN>').w/2; |
position:"absolute", top:0, left:0, border:0, padding:0, margin:0 |
this.TeX.M_height = x_height*(26/14); |
}); |
this.TeX.h = this.h; this.TeX.d = this.d; this.TeX.hd = this.hd; |
jsMath.hiddenTop = jsMath.hidden; |
// factor for \big and its brethren |
return; |
this.p_height = (this.TeX.cmex10[0].h+this.TeX.cmex10[0].d) / .85; |
|
|
|
this.InitSizes(); |
|
|
|
this.initialized = 1; |
|
}, |
}, |
|
|
/* |
/* |
* Find the root URL for the jsMath files (so we can load |
* 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 script = document.getElementsByTagName('SCRIPT'); |
var src = script[script.length-1].getAttribute('SRC'); |
if (script) { |
if (src.match('(^|/)jsMath.js$')) { |
for (var i = 0; i < script.length; i++) { |
this.root = src.replace(/jsMath.js$/,''); |
var src = script[i].src; |
this.blank = this.root + this.blank; |
if (src && src.match('(^|/)jsMath.js$')) { |
this.black = this.root + this.black; |
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 |
* Look up the default height and depth for a TeX font |
* and set the skewchar |
* and set the skewchar |
*/ |
*/ |
InitTeXfont: function (name) { |
TeXfont: function (name) { |
var font = this.TeX[name]; |
var font = jsMath.TeX[name]; |
var WH = this.EmBoxFor('<SPAN CLASS="'+name+'">'+font[65].c+'</SPAN>'); |
var WH = jsMath.EmBoxFor('<SPAN CLASS="'+name+'">'+font[65].c+'</SPAN>'); |
font.hd = WH.h; |
font.hd = WH.h; |
font.d = this.EmBoxFor('<SPAN CLASS="'+name+'">'+ font[65].c + |
font.d = jsMath.EmBoxFor('<SPAN CLASS="'+name+'">'+ font[65].c + |
'<IMG SRC="'+jsMath.black+'" STYLE="height:'+font.hd+'em; width:1"></SPAN>').h |
'<IMG SRC="'+jsMath.blank+'" STYLE="height:'+(font.hd*jsMath.Browser.imgScale)+'em; width:1px;"></SPAN>').h |
- font.hd; |
- font.hd; |
font.h = font.hd - font.d; |
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} |
if (name == 'cmmi10') {font.skewchar = 0177} |
else if (name == 'cmsy10') {font.skewchar = 060} |
else if (name == 'cmsy10') {font.skewchar = 060} |
}, |
}, |
Line 354 var jsMath = {
|
Line 392 var jsMath = {
|
/* |
/* |
* Init all the TeX fonts |
* Init all the TeX fonts |
*/ |
*/ |
InitTeXfonts: function () { |
TeXfonts: function () { |
for (var i = 0; i < this.TeX.fam.length; i++) |
for (var i = 0; i < jsMath.TeX.fam.length; i++) |
{if (this.TeX.fam[i]) {this.InitTeXfont(this.TeX.fam[i])}} |
{if (jsMath.TeX.fam[i]) {this.TeXfont(jsMath.TeX.fam[i])}} |
}, |
}, |
|
|
/* |
/* |
* Compute font parameters for various sizes |
* Compute font parameters for various sizes |
*/ |
*/ |
InitSizes: function () { |
Sizes: function () { |
this.TeXparams = []; |
jsMath.TeXparams = []; |
for (var j=0; j < this.sizes.length; j++) {this.TeXparams[j] = {}} |
for (var j=0; j < jsMath.sizes.length; j++) {jsMath.TeXparams[j] = {}} |
for (var i in this.TeX) { |
for (var i in jsMath.TeX) { |
if (typeof(this.TeX[i]) != 'object') { |
if (typeof(jsMath.TeX[i]) != 'object') { |
for (var j=0; j < this.sizes.length; j++) { |
for (var j=0; j < jsMath.sizes.length; j++) { |
this.TeXparams[j][i] = this.sizes[j]*this.TeX[i]/100; |
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('<STYLE TYPE="text/css" ID="jsMath.styles">'); |
|
for (var id in styles) {document.writeln(' '+id+' {'+styles[id]+'}')} |
|
document.writeln('</STYLE>'); |
|
}, |
|
|
|
/* |
|
* 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('<SCRIPT>jsMath.Font.Check()</SCRIPT>'); |
|
|
|
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 <SPAN> is always at the same height |
|
* or varies with the height of the rest of the line (MSIE). |
|
*/ |
|
TestSpanHeight: function () { |
|
jsMath.hidden.innerHTML = '<SPAN><IMG SRC="'+jsMath.blank+'" STYLE="height: 2em"></SPAN>'; |
|
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 = '<SPAN ID="jsMath.test"></SPAN>'; |
|
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 |
* to overcome specific browser bugs |
*/ |
*/ |
InitBrowser: function () { |
Init: function () { |
jsMath.browser = 'unknown'; |
jsMath.browser = 'unknown'; |
this.isSafari = navigator.userAgent.match(/Safari/); |
|
this.TestSpanHeight(); |
this.TestSpanHeight(); |
this.TestRenameOK(); |
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) { |
if (this.spanHeightVaries) { |
jsMath.browser = 'MSIE'; |
jsMath.browser = 'MSIE'; |
if (navigator.platform == 'Win32') { |
if (navigator.platform == 'Win32') { |
this.UpdateTeXfonts({ |
jsMath.Update.TeXfonts({ |
cmr10: {'10': {c: 'Ω', tclass: 'normal'}}, |
cmr10: {'10': {c: 'Ω', tclass: 'normal'}}, |
cmmi10: { |
cmmi10: { |
'10': {c: '<I>Ω</I>', tclass: 'normal'}, |
'10': {c: '<I>Ω</I>', tclass: 'normal'}, |
'126': {c: '~<SPAN STYLE="margin-left:.1em"></SPAN>'} |
'126': {c: '~<SPAN STYLE="margin-left:.1em"></SPAN>'} |
}, |
}, |
cmsy10: {'10': {c: '⊗', tclass: 'arial'}}, |
cmsy10: { |
|
'10': {c: '⊗', tclass: 'arial'}, |
|
'55': {c: '<SPAN STYLE="margin-right:-.54em">7</SPAN>'} |
|
}, |
cmex10: {'10': {c: '<SPAN STYLE="font-size: 67%">D</SPAN>'}}, |
cmex10: {'10': {c: '<SPAN STYLE="font-size: 67%">D</SPAN>'}}, |
cmti10: {'10': {c: '<I>Ω</I>', tclass: 'normal'}}, |
cmti10: {'10': {c: '<I>Ω</I>', tclass: 'normal'}}, |
cmbx10: {'10': {c: '<B>Ω</B>', tclass: 'normal'}} |
cmbx10: {'10': {c: '<B>Ω</B>', tclass: 'normal'}} |
}); |
}); |
this.allowAbsoluteDelim = 1; |
this.allowAbsoluteDelim = 1; |
this.separateSkips = 1; |
this.separateSkips = 1; |
|
this.buttonCheck = 1; |
|
this.msieDivWidthBug = 1; |
this.msieFontBug = 1; this.msieIntegralBug = 1; |
this.msieFontBug = 1; this.msieIntegralBug = 1; |
|
this.msieAlphaBug = 1; this.alphaPrintBug = 1; |
|
this.msieCenterBugFix = 'position:relative; '; |
this.msieSpaceFix = '<IMG SRC="'+jsMath.blank+'" CLASS="mathHD">'; |
this.msieSpaceFix = '<IMG SRC="'+jsMath.blank+'" CLASS="mathHD">'; |
|
this.msieInlineBlockFix = ' display: inline-block;'; |
jsMath.Macro('joinrel','\\mathrel{\\kern-5mu}'), |
jsMath.Macro('joinrel','\\mathrel{\\kern-5mu}'), |
jsMath.Macro('mapsto','\\mapstochar\\kern-.54em\\rightarrow'); |
jsMath.styles['.arial'] = "font-family: 'Arial unicode MS'"; |
jsMath.Macro('longmapsto','\\mapstochar\\kern-.54em\\char{cmsy10}{0}\\joinrel\\rightarrow'); |
// 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 = '<I>x</I>'; |
|
jsMath.EmBoxFor = jsMath.EmBoxForItalics; |
} else if (navigator.platform == 'MacPPC') { |
} else if (navigator.platform == 'MacPPC') { |
document.writeln('<SCRIPT SRC="'+this.root+'jsMath-msie-mac.js"></SCRIPT>'); |
this.msieAbsoluteBug = 1; this.msieButtonBug = 1; |
|
this.msieDivWidthBug = 1; |
|
jsMath.Setup.Script('jsMath-msie-mac.js'); |
jsMath.Parser.prototype.macros.angle = ['Replace','ord','<FONT FACE="Symbol">‹</FONT>','normal']; |
jsMath.Parser.prototype.macros.angle = ['Replace','ord','<FONT FACE="Symbol">‹</FONT>','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/}}'); |
jsMath.Macro('not','\\mathrel{\\rlap{\\kern3mu/}}'); |
} |
} |
|
}, |
|
|
// |
// |
// Look for Netscape/Mozilla (any flavor) |
// Handle Netscape/Mozilla (any flavor) |
// |
// |
if (this.hidden.ATTRIBUTE_NODE) { |
Mozilla: function () { |
|
if (jsMath.hidden.ATTRIBUTE_NODE) { |
jsMath.browser = 'Mozilla'; |
jsMath.browser = 'Mozilla'; |
if (navigator.platform == 'MacPPC') { |
if (navigator.platform == 'MacPPC') { |
this.UpdateTeXfonts({ |
jsMath.Update.TeXfonts({ |
cmr10: {'10': {c: 'Ω', tclass: 'normal'}}, |
cmr10: {'10': {c: 'Ω', tclass: 'normal'}}, |
cmmi10: {'10': {c: '<I>Ω</I>', tclass: 'normal'}}, |
cmmi10: {'10': {c: '<I>Ω</I>', tclass: 'normal'}}, |
cmsy10: {'10': {c: '⊗', tclass: 'normal'}}, |
cmsy10: {'10': {c: '⊗', tclass: 'normal'}}, |
Line 431 var jsMath = {
|
Line 659 var jsMath = {
|
cmbx10: {'10': {c: '<B>Ω</B>', tclass: 'normal'}} |
cmbx10: {'10': {c: '<B>Ω</B>', tclass: 'normal'}} |
}); |
}); |
} else { |
} else { |
document.writeln('<SCRIPT SRC="'+this.root+'jsMath-mozilla.js"></SCRIPT>'); |
jsMath.Setup.Script('jsMath-mozilla.js'); |
|
this.alphaPrintBug = 1; |
} |
} |
for (var i = 0; i < this.TeX.fam.length; i++) { |
for (var i = 0; i < jsMath.TeX.fam.length; i++) { |
if (this.TeX.fam[i]) |
if (jsMath.TeX.fam[i]) |
{this.styles['.'+this.TeX.fam[i]] += '; position: relative'} |
{jsMath.styles['.'+jsMath.TeX.fam[i]] += '; position: relative'} |
} |
} |
this.allowAbsoluteDelim = 1; |
this.allowAbsoluteDelim = 1; |
this.separateSkips = 1; |
this.separateSkips = 1; |
jsMath.Macro('not','\\mathrel{\\rlap{\\kern3mu/}}'); |
jsMath.Macro('not','\\mathrel{\\rlap{\\kern3mu/}}'); |
} |
} |
|
}, |
// |
|
// Look for OmniWeb |
// |
// |
// Handle OmniWeb |
|
// |
|
OmniWeb: function () { |
if (navigator.accentColorName) { |
if (navigator.accentColorName) { |
jsMath.browser = 'OmniWeb'; |
jsMath.browser = 'OmniWeb'; |
this.allowAbsolute = 0; |
this.allowAbsolute = !navigator.userAgent.match("OmniWeb/v4"); |
|
this.allowAbsoluteDelim = this.allowAbsolute; |
|
this.buttonCheck = 1; |
} |
} |
|
}, |
|
|
// |
// |
// Look for Opera |
// Handle Opera |
// |
// |
if (navigator.userAgent.search(" Opera ") >= 0) { |
Opera: function () { |
|
if (navigator.appName == 'Opera' || navigator.userAgent.match(" Opera ")) { |
jsMath.browser = 'Opera'; |
jsMath.browser = 'Opera'; |
this.isOpera = 1; |
jsMath.Update.TeXfonts({ |
this.UpdateTeXfonts({ |
|
cmr10: { |
cmr10: { |
'10': {c: 'Ω', tclass: 'normal'}, |
'10': {c: 'Ω', tclass: 'normal'}, |
'20': {c: 'ˇ', tclass: 'normal'} |
'20': {c: 'ˇ', tclass: 'normal'} |
Line 483 var jsMath = {
|
Line 717 var jsMath = {
|
} |
} |
}); |
}); |
this.allowAbsolute = 0; |
this.allowAbsolute = 0; |
jsMath.delay = 10; |
this.delay = 10; |
|
this.operaHiddenFix = '[Processing Math]'; |
} |
} |
|
}, |
|
|
// |
// |
// Look for Safari |
// Handle Safari |
// |
// |
if (this.isSafari) { |
Safari: function () { |
|
if (navigator.appVersion.match(/Safari\//)) { |
jsMath.browser = 'Safari'; |
jsMath.browser = 'Safari'; |
var version = navigator.userAgent.match("Safari/([0-9]+)")[1]; |
var version = navigator.userAgent.match("Safari/([0-9]+)"); |
if (version < 125) {this.allowAbsolute = 0; this.oldSafari = 1} |
version = (version)? version[1] : 200; // FIXME: hack until I get Tiger |
for (var i = 0; i < this.TeX.fam.length; i++) |
for (var i = 0; i < jsMath.TeX.fam.length; i++) |
{if (this.TeX.fam[i] != '') {this.TeX[this.TeX.fam[i]].dh = .1}} |
{if (jsMath.TeX.fam[i]) {jsMath.TeX[jsMath.TeX.fam[i]].dh = .1}} |
this.absoluteOffsetY = -.05; |
jsMath.TeX.axis_height += .05; |
this.TeX.axis_height += .05; |
this.allowAbsoluteDelim = version >= 125; |
this.allowAbsoluteDelim = ! this.oldSafari; |
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: '<SPAN STYLE="font-size: 84%">"</SPAN>'}}, |
|
cmti10: {'20': {c: '<I>ˇ</I>', tclass: 'normal'}}, |
|
cmbx10: {'20': {c: '<B>ˇ</B>', 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: |
|
'<B>No TeX fonts found</B> -- using image fonts instead.<BR>\n' |
|
+ 'These may be slow and might not print well.<BR>\n' |
|
+ 'Use the jsMath control panel to get additional information.', |
|
|
|
extra_message: |
|
'Extra TeX fonts not found: <B><SPAN ID="jsMath.ExtraFonts"></SPAN></B><BR>' |
|
+ 'Using image fonts instead. This may be slow and might not print well.<BR>\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('<SPAN STYLE="font-family: '+name+', serif">'+jsMath.TeX[name][n].c+'</SPAN>'); |
|
var wh2 = jsMath.BBoxFor('<SPAN STYLE="font-family: serif">'+jsMath.TeX[name][n].c+'</SPAN>'); |
|
//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('<SPAN STYLE="font-family: '+name+', serif">'+jsMath.TeX[name][n].c+'</SPAN>'); |
|
var wh2 = jsMath.BBoxFor('<SPAN STYLE="font-family: serif">'+jsMath.TeX[name][n].c+'</SPAN>'); |
|
//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('<SPAN STYLE="font-family: cmex10">'+jsMath.TeX.cmex10[1].c+'</SPAN>'); |
|
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 { |
} else { |
jsMath.Box.DelimExtend = jsMath.Box.DelimExtendRelative; |
if (cookie.autofont) {cookie.font = 'tex'} |
jsMath.Box.Layout = jsMath.Box.LayoutRelative; |
if (cookie.font == 'tex') return; |
} |
} |
|
if (jsMath.noImgFonts) {cookie.font = 'unicode'} |
if (this.separateNegativeSkips) { |
if (cookie.font == 'unicode') { |
jsMath.HTML.Place = jsMath.HTML.PlaceSeparateNegative; |
var platform = ({Win32: 'pc', MacPPC: 'mac'})[navigator.platform] || 'unix'; |
jsMath.Typeset.prototype.Place = jsMath.Typeset.prototype.PlaceSeparateNegative; |
jsMath.Setup.Script('jsMath-fallback-'+platform+'.js'); |
} else if (this.separateSkips) { |
return; |
jsMath.HTML.Place = jsMath.HTML.PlaceSeparateSkips; |
|
jsMath.Typeset.prototype.Place = jsMath.Typeset.prototype.PlaceSeparateSkips; |
|
} |
} |
|
if (cookie.font == 'symbol') { |
if (this.noEmptySpans) {jsMath.HTML.Spacer = jsMath.HTML.SpacerImage} |
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 |
|
* |
|
* <SCRIPT>jsMath = {Font: {Message: function () {}}}</SCRIPT> |
|
* |
|
* 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 = |
|
'<CENTER><TABLE><TR><TD>' |
|
+ '<DIV CLASS="jsM_noFont">' + message |
|
+ '<DIV STYLE="text-align:left"><SPAN STYLE="float:left; margin: 8px 0px 0px 20px">' |
|
+ '<A HREF="javascript:jsMath.Controls.Panel()" CLASS="jsM_fontLink">jsMath Control Panel</A>' |
|
+ '</SPAN><SPAN STYLE="margin: 8px 20px 0px 0px; float:right">' |
|
+ '<A HREF="javascript:jsMath.Font.HideMessage()" CLASS="jsM_fontLink">Hide this Message</A>' |
|
+ '</SPAN></DIV><BR CLEAR="ALL"></DIV>' |
|
+ '<DIV STYLE="width:22em; height:1px"></DIV>' |
|
+ '</TD></TR></TABLE></CENTER><HR>'; |
|
}, |
|
|
|
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) { |
Load: function (name) {jsMath.Setup.Script("fonts/"+name+"/def.js")} |
document.writeln('<STYLE TYPE="text/css">'); |
|
for (var id in styles) {document.writeln(' '+id+' {'+styles[id]+'}')} |
}; |
document.writeln('</STYLE>'); |
|
|
/***************************************************************************/ |
|
|
|
/* |
|
* 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 |
* Load the control panel |
* by the browser-specific code) |
|
*/ |
*/ |
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) { |
Button: function () { |
for (var font in change) { |
var button = jsMath.Setup.TopHTML("jsMath",{'class':'jsM_button'},{}); |
for (var code in change[font]) { |
button.innerHTML = |
for (var id in change[font][code]) { |
'<A HREF="javascript:jsMath.Controls.Panel()" '+ |
this.TeX[font][code][id] = change[font][code][id]; |
'STYLE="text-decoration:inherit; color:inherit">' + |
} |
'<SPAN TITLE="Open jsMath Control Panel">jsMath</SPAN></A>' |
|
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( |
|
'<IFRAME SRC="'+jsMath.root+'jsMath-controls.html" ' |
|
+ 'ID="jsMath.Frame" SCROLLING="no" ' |
|
+ 'STYLE="visibility:hidden; position:absolute; width:1em; height:1em;">' |
|
+ '</IFRAME>\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('<IFRAME SRC="" ID="jsMath.Frame" SCROLLING="no" ' |
|
+ 'STYLE="visibility:hidden; position:absolute; width:1em; height:1em;">' |
|
+ '</IFRAME>\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 |
* Save the cookie data in the browser |
* of fonts |
* (for file: urls, append data like CGI reference) |
*/ |
*/ |
UpdateTeXfontCodes: function (change) { |
SetCookie: function (warn) { |
for (var font in change) { |
var cookie = []; |
for (var i = 0; i < change[font].length; i++) { |
for (var id in this.cookie) {cookie[cookie.length] = id + ':' + this.cookie[id]} |
this.TeX[font][i].c = change[font][i]; |
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 = |
|
'<DIV CLASS="jsM_drag"><DIV CLASS="jsM_close"></DIV></DIV>' |
|
+ '<DIV CLASS="jsM_source"><SPAN></SPAN></DIV>'; |
|
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(/>/g,'>'); |
|
TeX = TeX.replace(/\n/g,'<BR>'); |
|
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) { |
DeselectText: function (x,y) { |
for (var i in styles) {this.styles[i] = styles[i]} |
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 = |
|
'<textarea style="visibility:hidden" ROWS="1" COLS="1">a</textarea>'; |
|
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: |
* Close the TeX source window |
* |
|
* Add: simply add items to an object |
|
* Package: add items to an object prototype |
|
*/ |
*/ |
Add: function (obj,def) {for (var id in def) {obj[id] = def[id]}}, |
CloseSource: function () { |
Package: function (obj,def) {this.Add(obj.prototype,def)} |
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) |
// The TeX math atom types (see Appendix G of the TeXbook) |
atom: ['ord', 'op', 'bin', 'rel', 'open', 'close', 'punct', 'ord'], |
atom: ['ord', 'op', 'bin', 'rel', 'open', 'close', 'punct', 'ord'], |
|
|
Line 596 jsMath.Add(jsMath.TeX,{
|
Line 1341 jsMath.Add(jsMath.TeX,{
|
* The following are the TeX font mappings and metrics. The metric |
* The following are the TeX font mappings and metrics. The metric |
* information comes directly from the TeX .tfm files, and the |
* information comes directly from the TeX .tfm files, and the |
* character mappings are for the TrueType TeX fonts. Browser-specific |
* 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: [ |
cmr10: [ |
// 00 - 0F |
// 00 - 0F |
Line 1431 jsMath.Add(jsMath.TeX,{
|
Line 2176 jsMath.Add(jsMath.TeX,{
|
{c: '~', h: 0.694, w: 0.575}, |
{c: '~', h: 0.694, w: 0.575}, |
{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('<SCRIPT SRC="'+this.URL(name,"")+'"></SCRIPT>'); |
|
this.loaded = 1; |
|
} |
|
|
|
}; |
|
|
/***************************************************************************/ |
/***************************************************************************/ |
|
|
Line 1459 jsMath.HTML = {
|
Line 2322 jsMath.HTML = {
|
*/ |
*/ |
Spacer: function (w) { |
Spacer: function (w) { |
if (w == 0) {return ''}; |
if (w == 0) {return ''}; |
return jsMath.msieSpaceFix |
return jsMath.Browser.msieSpaceFix |
+ '<SPAN STYLE="margin-left: '+this.Em(w)+'"></SPAN>'; |
+ '<SPAN STYLE="margin-left: ' |
}, |
+ this.Em(w-jsMath.Browser.spaceWidth)+'">' |
|
+ jsMath.Browser.hiddenSpace + '</SPAN>'; |
/* |
|
* Use an image to create a horizontal space of width w |
|
*/ |
|
SpacerImage: function (w) { |
|
if (w == 0) {return ''}; |
|
return '<IMG SRC="'+jsMath.blank+'" STYLE="' |
|
+ ' width: 0; margin-left: '+this.Em(w)+'">'; |
|
}, |
}, |
|
|
/* |
/* |
Line 1485 jsMath.HTML = {
|
Line 2341 jsMath.HTML = {
|
{pos = 'relative; margin-right: '+this.Em(-(w+2/jsMath.em))+'; '} |
{pos = 'relative; margin-right: '+this.Em(-(w+2/jsMath.em))+'; '} |
return '<IMG SRC="'+jsMath.blank+'" STYLE="position:' + pos |
return '<IMG SRC="'+jsMath.blank+'" STYLE="position:' + pos |
+ 'vertical-align: '+this.Em(y)+'; left: '+this.Em(x)+'; ' |
+ 'vertical-align: '+this.Em(y)+'; left: '+this.Em(x)+'; ' |
+ 'width:'+this.Em(w)+'; height: '+this.Em(h)+'; ' |
+ 'width:' +this.Em(w*jsMath.Browser.imgScale)+'; ' |
+ 'border-color: '+c+'; border-style: solid; border-width: 1px;">'; |
+ 'height:'+this.Em(h*jsMath.Browser.imgScale)+'; ' |
}, |
+ 'border: 1px solid '+c+';">'; |
|
|
/* |
|
* 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 '<IMG SRC="'+jsMath.blank+'" STYLE="position:'+pos |
|
+ 'top: '+this.Em(-y)+'; left:'+this.Em(x)+'; ' |
|
+ 'width:'+this.Em(w)+'; height:1px; background-color: '+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 |
* 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 line will not disappear at small font sizes. This means that |
* the thickness will not change if you change the font size, or |
* the thickness will not change if you change the font size, or |
Line 1512 jsMath.HTML = {
|
Line 2356 jsMath.HTML = {
|
Rule: function (w,h) { |
Rule: function (w,h) { |
if (h == null) {h = jsMath.TeX.default_rule_thickness} |
if (h == null) {h = jsMath.TeX.default_rule_thickness} |
if (w == 0 || h == 0) return; // should make an invisible box? |
if (w == 0 || h == 0) return; // should make an invisible box? |
h = Math.round(h*jsMath.em); |
w *= jsMath.Browser.imgScale; |
if (h < 1) {h = 1} |
h = Math.round(h*jsMath.em*jsMath.Browser.imgScale+.25); |
return '<IMG SRC="'+jsMath.black+'" HSPACE="0" VSPACE="0" ' |
if (h < 1) {h = 1}; |
+ 'STYLE="width:'+this.Em(w)+'; height: '+h+'px">'; |
|
}, |
|
|
|
/* |
|
* Create a colored block of a specific size (won't always print |
|
* correctly). |
|
*/ |
|
Block: function (w,h,c) { |
|
if (c == null) {c = 'black'} |
|
return '<IMG SRC="'+jsMath.blank+'" HSPACE="0" VSPACE="0" ' |
return '<IMG SRC="'+jsMath.blank+'" HSPACE="0" VSPACE="0" ' |
+ 'STYLE="width:'+this.Em(w)+'; height: '+this.Em(h)+'; ' |
+ 'STYLE="width:'+this.Em(w)+'; height:1px; ' |
+ 'background-color: '+c+'">'; |
+ 'vertical-align:-1px; ' |
|
+ 'border:0px none; border-top:'+h+'px solid">'; |
}, |
}, |
|
|
/* |
/* |
* Add a <SPAN> tag to activate a specific CSS class |
* Add a <SPAN> tag to activate a specific CSS class |
*/ |
*/ |
Line 1555 jsMath.HTML = {
|
Line 2391 jsMath.HTML = {
|
|
|
/* |
/* |
* For MSIE on Windows, backspacing must be done in a separate |
* For MSIE on Windows, backspacing must be done in a separate |
* <SPAN>, otherwise the contents will be clipped. |
* <SPAN>, otherwise the contents will be clipped. Netscape |
*/ |
* also doesn't combine vertical and horizontal spacing well. |
PlaceSeparateNegative: function (html,x,y) { |
* Here the x and y positioning are done in separate <SPAN> tags |
if (Math.abs(x) < .0001) {x = 0} |
|
if (Math.abs(y) < .0001) {y = 0} |
|
if (x > 0 || y) { |
|
var span = '<SPAN STYLE="position: relative;'; |
|
if (x > 0) {span += ' margin-left:'+this.Em(x)+';'} |
|
if (y) {span += ' top:'+this.Em(-y)+';'} |
|
html = span + '">' + html + '</SPAN>'; |
|
} |
|
if (x < 0) { |
|
html = jsMath.msieSpaceFix |
|
+ '<SPAN STYLE="margin-left:'+this.Em(x)+';"></SPAN>' + html; |
|
} |
|
return html; |
|
}, |
|
|
|
/* |
|
* Here the x and y positioning is done in separate <SPAN> tags |
|
*/ |
*/ |
PlaceSeparateSkips: function (html,x,y) { |
PlaceSeparateSkips: function (html,x,y) { |
if (Math.abs(x) < .0001) {x = 0} |
if (Math.abs(x) < .0001) {x = 0} |
if (Math.abs(y) < .0001) {y = 0} |
if (Math.abs(y) < .0001) {y = 0} |
if (y) {html = '<SPAN STYLE="position: relative; top:'+this.Em(-y)+';' |
if (y) {html = '<SPAN STYLE="position: relative; top:'+this.Em(-y)+';' |
+ '">' + html + '</SPAN>'} |
+ '">' + html + '</SPAN>'} |
if (x) {html = jsMath.msieSpaceFix |
if (x) {html = jsMath.Browser.msieSpaceFix |
+ '<SPAN STYLE="margin-left:'+this.Em(x)+';"></SPAN>' + html} |
+ '<SPAN STYLE="margin-left:' |
|
+ this.Em(x-jsMath.Browser.spaceWidth)+';">' |
|
+ jsMath.Browser.hiddenSpace + '</SPAN>' + html} |
return html; |
return html; |
}, |
}, |
|
|
Line 1600 jsMath.HTML = {
|
Line 2421 jsMath.HTML = {
|
|
|
Absolute: function(html,w,h,d,y,H) { |
Absolute: function(html,w,h,d,y,H) { |
var align = ""; |
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 (y != "none") { |
if (Math.abs(y) < .0001) {y = 0} |
if (Math.abs(y) < .0001) {y = 0} |
html = '<SPAN STYLE="position: absolute; ' |
html = '<SPAN STYLE="position: absolute; ' |
Line 1608 jsMath.HTML = {
|
Line 2429 jsMath.HTML = {
|
+ html + ' ' // space normalizes line height in script styles |
+ html + ' ' // space normalizes line height in script styles |
+ '</SPAN>'; |
+ '</SPAN>'; |
} |
} |
html += '<IMG SRC="'+jsMath.blank+'" STYLE="width: '+jsMath.HTML.Em(w)+'; ' |
html += '<IMG SRC="'+jsMath.blank+'" STYLE="' |
+ 'height: '+jsMath.HTML.Em(h)+';'+align+'">'; |
+ 'width:' +jsMath.HTML.Em(w*jsMath.Browser.imgScale)+'; ' |
if (jsMath.msieAbsoluteBug) {// for MSIE (Mac) |
+ 'height:'+jsMath.HTML.Em(h*jsMath.Browser.imgScale)+';'+align+'">'; |
|
if (jsMath.Browser.msieAbsoluteBug) { // for MSIE (Mac) |
html = '<SPAN STYLE="position: relative;">' + html + '</SPAN>'; |
html = '<SPAN STYLE="position: relative;">' + html + '</SPAN>'; |
} |
} |
html = '<SPAN STYLE="position: relative;' |
html = '<SPAN STYLE="position: relative;' |
+ ' width: '+jsMath.HTML.Em(w)+';' // for MSIE |
+ ' width: '+jsMath.HTML.Em(w)+';' // for MSIE |
+ ' height: '+jsMath.HTML.Em(H)+';' // for MSIE |
+ ' height: '+jsMath.HTML.Em(H)+';' // for MSIE |
|
+ jsMath.Browser.msieInlineBlockFix // for MSIE |
+ '">' |
+ '">' |
+ html |
+ html |
+ '</SPAN>'; |
+ '</SPAN>'; |
Line 1671 jsMath.Add(jsMath.Box,{
|
Line 2494 jsMath.Add(jsMath.Box,{
|
* The box is a text box (like the ones above), so that characters from |
* The box is a text box (like the ones above), so that characters from |
* the same font can be combined. |
* the same font can be combined. |
*/ |
*/ |
TeX: function (c,font,style,size) { |
TeX: function (C,font,style,size) { |
c = jsMath.TeX[font][c]; |
var c = jsMath.TeX[font][C]; |
if (c.d == null) {c.d = 0}; if (c.h == null) {c.h = 0} |
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 scale = jsMath.Typeset.TeX(style,size).scale; |
var h = c.h + jsMath.TeX[font].dh |
var h = c.h + jsMath.TeX[font].dh |
var box = new jsMath.Box('text',c.c,c.w*scale,h*scale,c.d*scale); |
var box = new jsMath.Box('text',c.c,c.w*scale,h*scale,c.d*scale); |
Line 1686 jsMath.Add(jsMath.Box,{
|
Line 2510 jsMath.Add(jsMath.Box,{
|
box.tclass = font; |
box.tclass = font; |
box.bh = scale*jsMath.TeX[font].h; |
box.bh = scale*jsMath.TeX[font].h; |
box.bd = scale*jsMath.TeX[font].d; |
box.bd = scale*jsMath.TeX[font].d; |
if (jsMath.msieFontBug) { |
if (jsMath.Browser.msieFontBug) { |
// hack to avoid Font changing back to the default |
// hack to avoid Font changing back to the default |
// font when a unicode reference is not followed |
// font when a unicode reference is not followed |
// by a letter or number |
// by a letter or number |
box.html += '<SPAN STYLE="display: none">x</SPAN>' |
box.html += '<SPAN STYLE="display: none">x</SPAN>' |
} |
} |
} |
} |
|
if (c.img != null) { |
|
box.bh = c.img.bh; box.bd = c.img.bd; |
|
box.tclass = "normal"; |
|
} |
return box; |
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 = '<IMG SRC="'+jsMath.blank+'" ' |
|
+ 'STYLE="'+jsMath.Browser.msieCenterBugFix |
|
+ resize + vadjust + wadjust |
|
+ ' filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + "'" |
|
+ URL + "', sizingMethod='scale'" + ');">'; |
|
} else { |
|
c.c = '<IMG SRC="'+URL+'" STYLE="'+jsMath.Browser.msieCenterBugFix |
|
+ resize + vadjust + wadjust + '">'; |
|
} |
|
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 |
* A box containing a spacer of a specific width |
Line 1713 jsMath.Add(jsMath.Box,{
|
Line 2602 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 |
* Get a character from a TeX font, and make sure that it has |
* its metrics specified. |
* its metrics specified. |
*/ |
*/ |
GetChar: function (code,font) { |
GetChar: function (code,font) { |
var c = jsMath.TeX[font][code]; |
var c = jsMath.TeX[font][code]; |
|
if (c.img != null) {this.TeXIMG(font,code,4)} |
if (c.tclass == null) {c.tclass = font} |
if (c.tclass == null) {c.tclass = font} |
if (!c.computedW) { |
if (!c.computedW) { |
c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w; |
c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w; |
Line 1856 jsMath.Add(jsMath.Box,{
|
Line 2739 jsMath.Add(jsMath.Box,{
|
Delimiter: function (H,delim,style,nocenter) { |
Delimiter: function (H,delim,style,nocenter) { |
var size = 4; //### pass this? |
var size = 4; //### pass this? |
var TeX = jsMath.Typeset.TeX(style,size); |
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) |
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 == null) {return this.Space(TeX.nulldelimiterspace)} |
if (CFSH[2] == '') |
if (CFSH[2] == '') |
{return this.DelimExtend(H,CFSH[0],CFSH[1],TeX.axis_height,nocenter)} |
{return this.DelimExtend(H,CFSH[0],CFSH[1],TeX.axis_height,nocenter)} |
Line 1875 jsMath.Add(jsMath.Box,{
|
Line 2759 jsMath.Add(jsMath.Box,{
|
* is specified. |
* is specified. |
*/ |
*/ |
GetCharCode: function (code) { |
GetCharCode: function (code) { |
var font = jsMath.TeX.fam[(code&0xF00)>>8]; |
var font = jsMath.TeX.fam[code[0]]; |
var Font = jsMath.TeX[font]; |
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.w == null) {c.w = jsMath.EmBoxFor(jsMath.Typeset.AddClass(c.tclass,c.c)).w} |
if (c.font == null) {c.font = font} |
if (c.font == null) {c.font = font} |
return c; |
return c; |
Line 1901 jsMath.Add(jsMath.Box,{
|
Line 2786 jsMath.Add(jsMath.Box,{
|
Leaders: function (W,leader) { |
Leaders: function (W,leader) { |
var h; var d; var w; var html; var font; |
var h; var d; var w; var html; var font; |
if (leader.lmid) {// braces |
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 left = this.GetCharCode(leader.left); |
var right = this.GetCharCode(leader.right); |
var right = this.GetCharCode(leader.right); |
var lmid = this.GetCharCode(leader.lmid); |
var lmid = this.GetCharCode(leader.lmid); |
Line 1914 jsMath.Add(jsMath.Box,{
|
Line 2799 jsMath.Add(jsMath.Box,{
|
+ jsMath.HTML.Rule(w,right.h) |
+ jsMath.HTML.Rule(w,right.h) |
+ this.AddClass(right.tclass,right.c,right.font); |
+ this.AddClass(right.tclass,right.c,right.font); |
} else { //arrows |
} 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 left = this.GetCharCode(leader.left? leader.left: leader.rep); |
var rep = this.GetCharCode(leader.rep); |
var rep = this.GetCharCode(leader.rep); |
var right = this.GetCharCode(leader.right? leader.right: leader.rep); |
var right = this.GetCharCode(leader.right? leader.right: leader.rep); |
Line 1928 jsMath.Add(jsMath.Box,{
|
Line 2813 jsMath.Add(jsMath.Box,{
|
html += this.AddClass(rep.tclass,ehtml,rep.font) + jsMath.HTML.Spacer(w); |
html += this.AddClass(rep.tclass,ehtml,rep.font) + jsMath.HTML.Spacer(w); |
ehtml = ''; for (var i = m; i < n; i++) {ehtml += ext}; |
ehtml = ''; for (var i = m; i < n; i++) {ehtml += ext}; |
html += this.AddClass(rep.tclass,ehtml,rep.font); |
html += this.AddClass(rep.tclass,ehtml,rep.font); |
if (jsMath.msieFontBug) {html += '<SPAN STYLE="display: none">x</SPAN>'} |
if (jsMath.Browser.msieFontBug) {html += '<SPAN STYLE="display: none">x</SPAN>'} |
html += jsMath.HTML.Place(this.AddClass(right.tclass,right.c,right.font),-.4,0); |
html += jsMath.HTML.Place(this.AddClass(right.tclass,right.c,right.font),-.4,0); |
} |
} |
w = jsMath.EmBoxFor(html).w; |
w = jsMath.EmBoxFor(html).w; |
Line 2075 jsMath.Add(jsMath.Box,{
|
Line 2960 jsMath.Add(jsMath.Box,{
|
for (i = 0; i < W.length; i++) {w += W[i] + cspacing[i]} |
for (i = 0; i < W.length; i++) {w += W[i] + cspacing[i]} |
|
|
html = jsMath.HTML.Spacer(scale/6)+html+jsMath.HTML.Spacer(scale/6); |
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]); |
html = jsMath.HTML.Absolute(html,w,h+d,d,y,H[0]); |
var box = new jsMath.Box('html',html,w+scale/3,h,d); |
var box = new jsMath.Box('html',html,w+scale/3,h,d); |
return box; |
return box; |
Line 2085 jsMath.Add(jsMath.Box,{
|
Line 2970 jsMath.Add(jsMath.Box,{
|
* Look for math within \hbox and other non-math text |
* Look for math within \hbox and other non-math text |
*/ |
*/ |
InternalMath: function (text,size) { |
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 i = 0; var k = 0; var c; var match = ''; |
var mlist = []; var parse; var html; var box; |
var mlist = []; var parse; var html; var box; |
Line 2102 jsMath.Add(jsMath.Box,{
|
Line 2987 jsMath.Add(jsMath.Box,{
|
} |
} |
match = ''; k = i; |
match = ''; k = i; |
} else { |
} 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; |
match = '$'; k = i; |
} |
} |
} else if (c == '\\') { |
} else if (c == '\\') { |
c = text.charAt(i++); |
c = text.charAt(i++); |
if (c == '(' && match == '') { |
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; |
match = ')'; k = i; |
} else if (c == ')' && match == ')') { |
} else if (c == ')' && match == ')') { |
parse = jsMath.Parse(text.slice(k,i-2),null,size); |
parse = jsMath.Parse(text.slice(k,i-2),null,size); |
Line 2122 jsMath.Add(jsMath.Box,{
|
Line 3007 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); |
return this.SetList(mlist,'T',size); |
}, |
}, |
|
|
Line 2188 jsMath.Package(jsMath.Box,{
|
Line 3073 jsMath.Package(jsMath.Box,{
|
* Recompute the box width to make it more accurate. |
* Recompute the box width to make it more accurate. |
*/ |
*/ |
Remeasured: function () { |
Remeasured: function () { |
if (this.w > 0) { |
if (this.w > 0 && !this.html.match(/position: ?absolute/)) |
if (!jsMath.spanHeightVaries || !this.html.match(/position: ?absolute/)) |
{this.w = jsMath.EmBoxFor(this.html).w} |
{this.w = jsMath.EmBoxFor(this.html).w} |
|
} |
|
return this; |
return this; |
} |
} |
|
|
Line 2201 jsMath.Package(jsMath.Box,{
|
Line 3084 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 |
* store the information about a mathematical expression. These are |
* basically the items listed in the TeXbook in Appendix G (plus some |
* basically the items listed in the TeXbook in Appendix G (plus some |
* minor extensions). |
* minor extensions). |
Line 2429 jsMath.Package(jsMath.mList,{
|
Line 3312 jsMath.Package(jsMath.mList,{
|
/* |
/* |
* For a list that has boundary delimiters as its first and last |
* For a list that has boundary delimiters as its first and last |
* entries, we replace the boundary atoms by open and close |
* 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) |
* for the contents of the list. (Rule 19) |
*/ |
*/ |
AddDelimiters: function(style,size) { |
AddDelimiters: function(style,size) { |
Line 2656 jsMath.Add(jsMath.mList.prototype.Atomiz
|
Line 3539 jsMath.Add(jsMath.mList.prototype.Atomiz
|
var t = TeX.default_rule_thickness; |
var t = TeX.default_rule_thickness; |
var p = t; if (style == 'D' || style == "D'") {p = TeX.x_height} |
var p = t; if (style == 'D' || style == "D'") {p = TeX.x_height} |
var r = t + p/4; |
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 |
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} |
if (surd.d > box.h+box.d+r) {r = (r+surd.d-box.h-box.d)/2} |
surd.y = box.h+r; |
surd.y = box.h+r; |
Line 2665 jsMath.Add(jsMath.mList.prototype.Atomiz
|
Line 3548 jsMath.Add(jsMath.mList.prototype.Atomiz
|
var Cr = jsMath.Typeset.UpStyle(jsMath.Typeset.UpStyle(style)); |
var Cr = jsMath.Typeset.UpStyle(jsMath.Typeset.UpStyle(style)); |
var root = jsMath.Box.Set(mitem.root,Cr,size).Remeasured(); |
var root = jsMath.Box.Set(mitem.root,Cr,size).Remeasured(); |
if (mitem.root) { |
if (mitem.root) { |
root.y = .55*(box.h+box.d+3*t+r)-box.d; surd.x = -(11/18)*surd.w; |
root.y = .55*(box.h+box.d+3*t+r)-box.d; |
root.x = Math.max((11/18)*surd.w - root.w, 0); |
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'; |
mitem.type = 'ord'; |
jsMath.mList.prototype.Atomize.SupSub(style,size,mitem); |
jsMath.mList.prototype.Atomize.SupSub(style,size,mitem); |
}, |
}, |
Line 2688 jsMath.Add(jsMath.mList.prototype.Atomiz
|
Line 3573 jsMath.Add(jsMath.mList.prototype.Atomiz
|
} |
} |
if (s == null) {s = 0} |
if (s == null) {s = 0} |
|
|
var c = mitem.accent & 0xFF; |
var c = mitem.accent[2]; |
var font = jsMath.TeX.fam[(mitem.accent&0xF00)>>8]; Font = jsMath.TeX[font]; |
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} |
while (Font[c].n && Font[Font[c].n].w <= u) {c = Font[c].n} |
|
|
var delta = Math.min(box.h,TeX.x_height); |
var delta = Math.min(box.h,TeX.x_height); |
Line 2728 jsMath.Add(jsMath.mList.prototype.Atomiz
|
Line 3613 jsMath.Add(jsMath.mList.prototype.Atomiz
|
box = jsMath.Box.Set(mitem.nuc,style,size); |
box = jsMath.Box.Set(mitem.nuc,style,size); |
if (C.ic) { |
if (C.ic) { |
mitem.delta = C.ic * TeX.scale; |
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 = jsMath.Box.SetList([box,jsMath.mItem.Space(mitem.delta)],style,size)} |
} |
} |
box.y = -((box.h+box.d)/2 - box.d - TeX.axis_height); |
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()} |
if (!box) {box = jsMath.Box.Set(mitem.nuc,style,size).Remeasured()} |
Line 2760 jsMath.Add(jsMath.mList.prototype.Atomiz
|
Line 3645 jsMath.Add(jsMath.mList.prototype.Atomiz
|
mitem.nuc = jsMath.Box.SetList(mlist,style,size); |
mitem.nuc = jsMath.Box.SetList(mlist,style,size); |
mitem.nuc.h += dh; mitem.nuc.d += dd; |
mitem.nuc.h += dh; mitem.nuc.d += dd; |
} else { |
} 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)} |
{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)} |
else if (box.y) {mitem.nuc = jsMath.Box.SetList([box],style,size)} |
jsMath.mList.prototype.Atomize.SupSub(style,size,mitem); |
jsMath.mList.prototype.Atomize.SupSub(style,size,mitem); |
Line 2968 jsMath.Add(jsMath.Typeset,{
|
Line 3853 jsMath.Add(jsMath.Typeset,{
|
if (style == "SS" || style == "SS'") {return .5*v} |
if (style == "SS" || style == "SS'") {return .5*v} |
return 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 |
* Return the font parameter table for the given style |
Line 3123 jsMath.Package(jsMath.Typeset,{
|
Line 4017 jsMath.Package(jsMath.Typeset,{
|
} |
} |
|
|
this.FlushClassed(); // make sure scaling is included |
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.hbuf == '') {return jsMath.Box.Null} |
if (this.h == unset) {this.h = 0} |
if (this.h == unset) {this.h = 0} |
if (this.d == unset) {this.d = 0} |
if (this.d == unset) {this.d = 0} |
Line 3156 jsMath.Package(jsMath.Typeset,{
|
Line 4050 jsMath.Package(jsMath.Typeset,{
|
|
|
/* |
/* |
* Add a <SPAN> to position an item's HTML, and |
* Add a <SPAN> 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 |
* (This may be replaced buy one of the following browser-specific |
* versions by InitBrowser().) |
* versions by Browser.Init().) |
*/ |
*/ |
Place: function (item) { |
Place: function (item) { |
var html = '<SPAN STYLE="position: relative;'; |
var html = '<SPAN STYLE="position: relative;'; |
Line 3170 jsMath.Package(jsMath.Typeset,{
|
Line 4064 jsMath.Package(jsMath.Typeset,{
|
}, |
}, |
|
|
/* |
/* |
* A replacement for Place() above that fixes a bug in MSIE. |
* For MSIE on Windows, backspacing must be done in a separate |
* (A separate <SPAN> is used to backspace, otherwise the |
* <SPAN>, otherwise the contents will be clipped. Netscape |
* contents are clipped incorrectly.) |
* also doesn't combine vertical and horizontal spacing well. |
*/ |
* Here, the horizontal and vertical spacing are done separately. |
PlaceSeparateNegative: function (item) { |
|
var html = '<SPAN STYLE="position: relative;'; |
|
// MSIE needs backspacing as separate SPAN |
|
if (item.x < 0) |
|
{html = '<SPAN STYLE="margin-left:'+jsMath.HTML.Em(item.x)+';"></SPAN>'+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 + '</SPAN>'; |
|
item.h += item.y; item.d -= item.y; |
|
item.x = 0; item.y = 0; |
|
}, |
|
|
|
/* |
|
* Here, the horizontal spacing is always done separately. |
|
*/ |
*/ |
PlaceSeparateSkips: function (item) { |
PlaceSeparateSkips: function (item) { |
if (item.y) |
if (item.y) { |
{item.html = '<SPAN STYLE="position: relative; top:'+jsMath.HTML.Em(-item.y)+';' |
if (item.html.match(/^<IMG[^>]*>(<SPAN STYLE="margin-left: [-0-9.]*em"><\/SPAN>)?$/i) && !item.html.match(/top:/)) { |
+ '">' + item.html + '</SPAN>'} |
item.html = item.html.replace(/STYLE="/, |
|
'STYLE="position:relative; top:'+jsMath.HTML.Em(-item.y)+';'); |
|
} else { |
|
item.html = '<SPAN STYLE="position: relative; ' |
|
+ 'top:'+jsMath.HTML.Em(-item.y)+';' |
|
+ '">' + item.html + '</SPAN>' |
|
} |
|
} |
if (item.x) |
if (item.x) |
{item.html = jsMath.msieSpaceFix |
{item.html = jsMath.Browser.msieSpaceFix |
+ '<SPAN STYLE="margin-left:'+jsMath.HTML.Em(item.x)+';">' |
+ '<SPAN STYLE="margin-left:' |
+ '</SPAN>' + item.html} |
+ jsMath.HTML.Em(item.x-jsMath.Browser.spaceWidth)+';">' |
|
+ jsMath.Browser.hiddenSpace + '</SPAN>' + item.html} |
item.h += item.y; item.d -= item.y; |
item.h += item.y; item.d -= item.y; |
item.x = 0; item.y = 0; |
item.x = 0; item.y = 0; |
} |
} |
Line 3236 jsMath.Package(jsMath.Parser,{
|
Line 4124 jsMath.Package(jsMath.Parser,{
|
|
|
// the \mathchar definitions (see Appendix B of the TeXbook). |
// the \mathchar definitions (see Appendix B of the TeXbook). |
mathchar: { |
mathchar: { |
'!': 0x5021, |
'!': [5,0,0x21], |
'(': 0x4028, |
'(': [4,0,0x28], |
')': 0x5029, |
')': [5,0,0x29], |
'*': 0x2203, // \ast |
'*': [2,2,0x03], // \ast |
'+': 0x202B, |
'+': [2,0,0x2B], |
',': 0x613B, |
',': [6,1,0x3B], |
'-': 0x2200, |
'-': [2,2,0x00], |
'.': 0x013A, |
'.': [0,1,0x3A], |
'/': 0x013D, |
'/': [0,1,0x3D], |
':': 0x303A, |
':': [3,0,0x3A], |
';': 0x603B, |
';': [6,0,0x3B], |
'<': 0x313C, |
'<': [3,1,0x3C], |
'=': 0x303D, |
'=': [3,0,0x3D], |
'>': 0x313E, |
'>': [3,1,0x3E], |
'?': 0x503F, |
'?': [5,0,0x3F], |
'[': 0x405B, |
'[': [4,0,0x5B], |
']': 0x505D, |
']': [5,0,0x5D], |
// '{': 0x4266, |
// '{': [4,2,0x66], |
// '}': 0x5267, |
// '}': [5,2,0x67], |
'|': 0x026A |
'|': [0,2,0x6A] |
}, |
}, |
|
|
// handle special \catcode characters |
// handle special \catcode characters |
Line 3274 jsMath.Package(jsMath.Parser,{
|
Line 4162 jsMath.Package(jsMath.Parser,{
|
// the \mathchardef table (see Appendix B of the TeXbook). |
// the \mathchardef table (see Appendix B of the TeXbook). |
mathchardef: { |
mathchardef: { |
// brace parts |
// brace parts |
braceld: 0x37A, |
braceld: [0,3,0x7A], |
bracerd: 0x37B, |
bracerd: [0,3,0x7B], |
bracelu: 0x37C, |
bracelu: [0,3,0x7C], |
braceru: 0x37D, |
braceru: [0,3,0x7D], |
|
|
// Greek letters |
// Greek letters |
alpha: 0x010B, |
alpha: [0,1,0x0B], |
beta: 0x010C, |
beta: [0,1,0x0C], |
gamma: 0x010D, |
gamma: [0,1,0x0D], |
delta: 0x010E, |
delta: [0,1,0x0E], |
epsilon: 0x010F, |
epsilon: [0,1,0x0F], |
zeta: 0x0110, |
zeta: [0,1,0x10], |
eta: 0x0111, |
eta: [0,1,0x11], |
theta: 0x0112, |
theta: [0,1,0x12], |
iota: 0x0113, |
iota: [0,1,0x13], |
kappa: 0x0114, |
kappa: [0,1,0x14], |
lambda: 0x0115, |
lambda: [0,1,0x15], |
mu: 0x0116, |
mu: [0,1,0x16], |
nu: 0x0117, |
nu: [0,1,0x17], |
xi: 0x0118, |
xi: [0,1,0x18], |
pi: 0x0119, |
pi: [0,1,0x19], |
rho: 0x011A, |
rho: [0,1,0x1A], |
sigma: 0x011B, |
sigma: [0,1,0x1B], |
tau: 0x011C, |
tau: [0,1,0x1C], |
upsilon: 0x011D, |
upsilon: [0,1,0x1D], |
phi: 0x011E, |
phi: [0,1,0x1E], |
chi: 0x011F, |
chi: [0,1,0x1F], |
psi: 0x0120, |
psi: [0,1,0x20], |
omega: 0x0121, |
omega: [0,1,0x21], |
varepsilon: 0x0122, |
varepsilon: [0,1,0x22], |
vartheta: 0x0123, |
vartheta: [0,1,0x23], |
varpi: 0x0124, |
varpi: [0,1,0x24], |
varrho: 0x0125, |
varrho: [0,1,0x25], |
varsigma: 0x0126, |
varsigma: [0,1,0x26], |
varphi: 0x0127, |
varphi: [0,1,0x27], |
|
|
Gamma: 0x7000, |
Gamma: [7,0,0x00], |
Delta: 0x7001, |
Delta: [7,0,0x01], |
Theta: 0x7002, |
Theta: [7,0,0x02], |
Lambda: 0x7003, |
Lambda: [7,0,0x03], |
Xi: 0x7004, |
Xi: [7,0,0x04], |
Pi: 0x7005, |
Pi: [7,0,0x05], |
Sigma: 0x7006, |
Sigma: [7,0,0x06], |
Upsilon: 0x7007, |
Upsilon: [7,0,0x07], |
Phi: 0x7008, |
Phi: [7,0,0x08], |
Psi: 0x7009, |
Psi: [7,0,0x09], |
Omega: 0x700A, |
Omega: [7,0,0x0A], |
|
|
// Ord symbols |
// Ord symbols |
aleph: 0x0240, |
aleph: [0,2,0x40], |
imath: 0x017B, |
imath: [0,1,0x7B], |
jmath: 0x017C, |
jmath: [0,1,0x7C], |
ell: 0x0160, |
ell: [0,1,0x60], |
wp: 0x017D, |
wp: [0,1,0x7D], |
Re: 0x023C, |
Re: [0,2,0x3C], |
Im: 0x023D, |
Im: [0,2,0x3D], |
partial: 0x0140, |
partial: [0,1,0x40], |
infty: 0x0231, |
infty: [0,2,0x31], |
prime: 0x0230, |
prime: [0,2,0x30], |
emptyset: 0x023B, |
emptyset: [0,2,0x3B], |
nabla: 0x0272, |
nabla: [0,2,0x72], |
surd: 0x1270, |
surd: [1,2,0x70], |
top: 0x023E, |
top: [0,2,0x3E], |
bot: 0x023F, |
bot: [0,2,0x3F], |
triangle: 0x0234, |
triangle: [0,2,0x34], |
forall: 0x0238, |
forall: [0,2,0x38], |
exists: 0x0239, |
exists: [0,2,0x39], |
neg: 0x023A, |
neg: [0,2,0x3A], |
lnot: 0x023A, |
lnot: [0,2,0x3A], |
flat: 0x015B, |
flat: [0,1,0x5B], |
natural: 0x015C, |
natural: [0,1,0x5C], |
sharp: 0x015D, |
sharp: [0,1,0x5D], |
clubsuit: 0x027C, |
clubsuit: [0,2,0x7C], |
diamondsuit: 0x027D, |
diamondsuit: [0,2,0x7D], |
heartsuit: 0x027E, |
heartsuit: [0,2,0x7E], |
spadesuit: 0x027F, |
spadesuit: [0,2,0x7F], |
|
|
// big ops |
// big ops |
coprod: 0x1360, |
coprod: [1,3,0x60], |
bigvee: 0x1357, |
bigvee: [1,3,0x57], |
bigwedge: 0x1356, |
bigwedge: [1,3,0x56], |
biguplus: 0x1355, |
biguplus: [1,3,0x55], |
bigcap: 0x1354, |
bigcap: [1,3,0x54], |
bigcup: 0x1353, |
bigcup: [1,3,0x53], |
intop: 0x1352, |
intop: [1,3,0x52], |
prod: 0x1351, |
prod: [1,3,0x51], |
sum: 0x1350, |
sum: [1,3,0x50], |
bigotimes: 0x134E, |
bigotimes: [1,3,0x4E], |
bigoplus: 0x134C, |
bigoplus: [1,3,0x4C], |
bigodot: 0x134A, |
bigodot: [1,3,0x4A], |
ointop: 0x1348, |
ointop: [1,3,0x48], |
bigsqcup: 0x1346, |
bigsqcup: [1,3,0x46], |
smallint: 0x1273, |
smallint: [1,2,0x73], |
|
|
// binary operations |
// binary operations |
triangleleft: 0x212F, |
triangleleft: [2,1,0x2F], |
triangleright: 0x212E, |
triangleright: [2,1,0x2E], |
bigtriangleup: 0x2234, |
bigtriangleup: [2,2,0x34], |
bigtriangledown: 0x2235, |
bigtriangledown: [2,2,0x35], |
wedge: 0x225E, |
wedge: [2,2,0x5E], |
land: 0x225E, |
land: [2,2,0x5E], |
vee: 0x225F, |
vee: [2,2,0x5F], |
lor: 0x225F, |
lor: [2,2,0x5F], |
cap: 0x225C, |
cap: [2,2,0x5C], |
cup: 0x225B, |
cup: [2,2,0x5B], |
ddagger: 0x227A, |
ddagger: [2,2,0x7A], |
dagger: 0x2279, |
dagger: [2,2,0x79], |
sqcap: 0x2275, |
sqcap: [2,2,0x75], |
sqcup: 0x2274, |
sqcup: [2,2,0x74], |
uplus: 0x225D, |
uplus: [2,2,0x5D], |
amalg: 0x2271, |
amalg: [2,2,0x71], |
diamond: 0x2205, |
diamond: [2,2,0x05], |
bullet: 0x220F, |
bullet: [2,2,0x0F], |
wr: 0x226F, |
wr: [2,2,0x6F], |
div: 0x2204, |
div: [2,2,0x04], |
odot: 0x220C, |
odot: [2,2,0x0C], |
oslash: 0x220B, |
oslash: [2,2,0x0B], |
otimes: 0x220A, |
otimes: [2,2,0x0A], |
ominus: 0x2209, |
ominus: [2,2,0x09], |
oplus: 0x2208, |
oplus: [2,2,0x08], |
mp: 0x2207, |
mp: [2,2,0x07], |
pm: 0x2206, |
pm: [2,2,0x06], |
circ: 0x220E, |
circ: [2,2,0x0E], |
bigcirc: 0x220D, |
bigcirc: [2,2,0x0D], |
setminus: 0x226E, // for set difference A\setminus B |
setminus: [2,2,0x6E], // for set difference A\setminus B |
cdot: 0x2201, |
cdot: [2,2,0x01], |
ast: 0x2203, |
ast: [2,2,0x03], |
times: 0x2202, |
times: [2,2,0x02], |
star: 0x213F, |
star: [2,1,0x3F], |
|
|
// Relations |
// Relations |
propto: 0x322F, |
propto: [3,2,0x2F], |
sqsubseteq: 0x3276, |
sqsubseteq: [3,2,0x76], |
sqsupseteq: 0x3277, |
sqsupseteq: [3,2,0x77], |
parallel: 0x326B, |
parallel: [3,2,0x6B], |
mid: 0x326A, |
mid: [3,2,0x6A], |
dashv: 0x3261, |
dashv: [3,2,0x61], |
vdash: 0x3260, |
vdash: [3,2,0x60], |
leq: 0x3214, |
leq: [3,2,0x14], |
le: 0x3214, |
le: [3,2,0x14], |
geq: 0x3215, |
geq: [3,2,0x15], |
ge: 0x3215, |
ge: [3,2,0x15], |
succ: 0x321F, |
succ: [3,2,0x1F], |
prec: 0x321E, |
prec: [3,2,0x1E], |
approx: 0x3219, |
approx: [3,2,0x19], |
succeq: 0x3217, |
succeq: [3,2,0x17], |
preceq: 0x3216, |
preceq: [3,2,0x16], |
supset: 0x321B, |
supset: [3,2,0x1B], |
subset: 0x321A, |
subset: [3,2,0x1A], |
supseteq: 0x3213, |
supseteq: [3,2,0x13], |
subseteq: 0x3212, |
subseteq: [3,2,0x12], |
'in': 0x3232, |
'in': [3,2,0x32], |
ni: 0x3233, |
ni: [3,2,0x33], |
owns: 0x3233, |
owns: [3,2,0x33], |
gg: 0x321D, |
gg: [3,2,0x1D], |
ll: 0x321C, |
ll: [3,2,0x1C], |
not: 0x3236, |
not: [3,2,0x36], |
sim: 0x3218, |
sim: [3,2,0x18], |
simeq: 0x3227, |
simeq: [3,2,0x27], |
perp: 0x323F, |
perp: [3,2,0x3F], |
equiv: 0x3211, |
equiv: [3,2,0x11], |
asymp: 0x3210, |
asymp: [3,2,0x10], |
smile: 0x315E, |
smile: [3,1,0x5E], |
frown: 0x315F, |
frown: [3,1,0x5F], |
|
|
// Arrows |
// Arrows |
Leftrightarrow: 0x322C, |
Leftrightarrow: [3,2,0x2C], |
Leftarrow: 0x3228, |
Leftarrow: [3,2,0x28], |
Rightarrow: 0x3229, |
Rightarrow: [3,2,0x29], |
leftrightarrow: 0x3224, |
leftrightarrow: [3,2,0x24], |
leftarrow: 0x3220, |
leftarrow: [3,2,0x20], |
gets: 0x3220, |
gets: [3,2,0x20], |
rightarrow: 0x3221, |
rightarrow: [3,2,0x21], |
to: 0x3221, |
to: [3,2,0x21], |
mapstochar: 0x3237, |
mapstochar: [3,2,0x37], |
leftharpoonup: 0x3128, |
leftharpoonup: [3,1,0x28], |
leftharpoondown: 0x3129, |
leftharpoondown: [3,1,0x29], |
rightharpoonup: 0x312A, |
rightharpoonup: [3,1,0x2A], |
rightharpoondown: 0x312B, |
rightharpoondown: [3,1,0x2B], |
nearrow: 0x3225, |
nearrow: [3,2,0x25], |
searrow: 0x3226, |
searrow: [3,2,0x26], |
nwarrow: 0x322D, |
nwarrow: [3,2,0x2D], |
swarrow: 0x322E, |
swarrow: [3,2,0x2E], |
|
|
hbarchar: 0x0016, // for \hbar |
hbarchar: [0,0,0x16], // for \hbar |
lhook: 0x312C, |
lhook: [3,1,0x2C], |
rhook: 0x312D, |
rhook: [3,1,0x2D], |
|
|
ldotp: 0x613A, // ldot as a punctuation mark |
ldotp: [6,1,0x3A], // ldot as a punctuation mark |
cdotp: 0x6201, // cdot as a punctuation mark |
cdotp: [6,2,0x01], // cdot as a punctuation mark |
colon: 0x603A, // colon as a punctuation mark |
colon: [6,0,0x3A], // colon as a punctuation mark |
|
|
'#': 0x7023, |
'#': [7,0,0x23], |
'$': 0x7024, |
'$': [7,0,0x24], |
'%': 0x7025, |
'%': [7,0,0x25], |
'&': 0x7026 |
'&': [7,0,0x26] |
}, |
}, |
|
|
// The delimiter table (see Appendix B of the TeXbook) |
// The delimiter table (see Appendix B of the TeXbook) |
delimiter: { |
delimiter: { |
'(': 0x0028300, |
'(': [0,0,0x28,3,0x00], |
')': 0x0029301, |
')': [0,0,0x29,3,0x01], |
'[': 0x005B302, |
'[': [0,0,0x5B,3,0x02], |
']': 0x005D303, |
']': [0,0,0x5D,3,0x03], |
'<': 0x026830A, |
'<': [0,2,0x68,3,0x0A], |
'>': 0x026930B, |
'>': [0,2,0x69,3,0x0B], |
'/': 0x002F30E, |
'/': [0,0,0x2F,3,0x0E], |
'|': 0x026A30C, |
'|': [0,2,0x6A,3,0x0C], |
'.': 0x0000000, |
'.': [0,0,0x00,0,0x00], |
'\\': 0x026E30F, |
'\\': [0,2,0x6E,3,0x0F], |
'\\lmoustache': 0x437A340, // top from (, bottom from ) |
'\\lmoustache': [4,3,0x7A,3,0x40], // top from (, bottom from ) |
'\\rmoustache': 0x537B341, // top from ), bottom from ( |
'\\rmoustache': [5,3,0x7B,3,0x41], // top from ), bottom from ( |
'\\lgroup': 0x462833A, // extensible ( with sharper tips |
'\\lgroup': [4,6,0x28,3,0x3A], // extensible ( with sharper tips |
'\\rgroup': 0x562933B, // extensible ) with sharper tips |
'\\rgroup': [5,6,0x29,3,0x3B], // extensible ) with sharper tips |
'\\arrowvert': 0x026A33C, // arrow without arrowheads |
'\\arrowvert': [0,2,0x6A,3,0x3C], // arrow without arrowheads |
'\\Arrowvert': 0x026B33D, // double arrow without arrowheads |
'\\Arrowvert': [0,2,0x6B,3,0x3D], // double arrow without arrowheads |
// '\\bracevert': 0x077C33E, // the vertical bar that extends braces |
// '\\bracevert': [0,7,0x7C,3,0x3E], // the vertical bar that extends braces |
'\\bracevert': 0x026A33E, // we don't load tt, so use | instead |
'\\bracevert': [0,2,0x6A,3,0x3E], // we don't load tt, so use | instead |
'\\Vert': 0x026B30D, |
'\\Vert': [0,2,0x6B,3,0x0D], |
'\\|': 0x026B30D, |
'\\|': [0,2,0x6B,3,0x0D], |
'\\vert': 0x026A30C, |
'\\vert': [0,2,0x6A,3,0x0C], |
'\\uparrow': 0x3222378, |
'\\uparrow': [3,2,0x22,3,0x78], |
'\\downarrow': 0x3223379, |
'\\downarrow': [3,2,0x23,3,0x79], |
'\\updownarrow': 0x326C33F, |
'\\updownarrow': [3,2,0x6C,3,0x3F], |
'\\Uparrow': 0x322A37E, |
'\\Uparrow': [3,2,0x2A,3,0x7E], |
'\\Downarrow': 0x322B37F, |
'\\Downarrow': [3,2,0x2B,3,0x7F], |
'\\Updownarrow': 0x326D377, |
'\\Updownarrow': [3,2,0x6D,3,0x77], |
'\\backslash': 0x026E30F, // for double coset G\backslash H |
'\\backslash': [0,2,0x6E,3,0x0F], // for double coset G\backslash H |
'\\rangle': 0x526930B, |
'\\rangle': [5,2,0x69,3,0x0B], |
'\\langle': 0x426830A, |
'\\langle': [4,2,0x68,3,0x0A], |
'\\rbrace': 0x5267309, |
'\\rbrace': [5,2,0x67,3,0x09], |
'\\lbrace': 0x4266308, |
'\\lbrace': [4,2,0x66,3,0x08], |
'\\}': 0x5267309, |
'\\}': [5,2,0x67,3,0x09], |
'\\{': 0x4266308, |
'\\{': [4,2,0x66,3,0x08], |
'\\rceil': 0x5265307, |
'\\rceil': [5,2,0x65,3,0x07], |
'\\lceil': 0x4264306, |
'\\lceil': [4,2,0x64,3,0x06], |
'\\rfloor': 0x5263305, |
'\\rfloor': [5,2,0x63,3,0x05], |
'\\lfloor': 0x4262304 |
'\\lfloor': [4,2,0x62,3,0x04] |
}, |
}, |
|
|
/* |
/* |
Line 3621 jsMath.Package(jsMath.Parser,{
|
Line 4509 jsMath.Package(jsMath.Parser,{
|
doteq: ['Macro','\\buildrel\\textstyle.\\over='], |
doteq: ['Macro','\\buildrel\\textstyle.\\over='], |
ldots: ['Macro','\\mathinner{\\ldotp\\ldotp\\ldotp}'], |
ldots: ['Macro','\\mathinner{\\ldotp\\ldotp\\ldotp}'], |
cdots: ['Macro','\\mathinner{\\cdotp\\cdotp\\cdotp}'], |
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}'], |
ddots: ['Macro','\\mathinner{\\kern1mu\\raise7pt{\\rule 0pt 7pt 0pt .}\\kern2mu\\raise4pt{.}\\kern2mu\\raise1pt{.}\\kern1mu}'], |
joinrel: ['Macro','\\mathrel{\\kern-4mu}'], |
joinrel: ['Macro','\\mathrel{\\kern-4mu}'], |
relbar: ['Macro','\\mathrel{\\smash-}'], // \smash, because - has the same height as + |
relbar: ['Macro','\\mathrel{\\smash-}'], // \smash, because - has the same height as + |
Line 3663 jsMath.Package(jsMath.Parser,{
|
Line 4551 jsMath.Package(jsMath.Parser,{
|
|
|
hskip: 'Hskip', |
hskip: 'Hskip', |
kern: 'Hskip', |
kern: 'Hskip', |
rule: ['Rule','black'], |
rule: ['Rule','colored'], |
space: ['Rule','blank'], |
space: ['Rule','blank'], |
|
|
big: ['MakeBig','ord',0.85], |
big: ['MakeBig','ord',0.85], |
Line 3707 jsMath.Package(jsMath.Parser,{
|
Line 4595 jsMath.Package(jsMath.Parser,{
|
hphantom: ['Phantom',0,1], |
hphantom: ['Phantom',0,1], |
smash: 'Smash', |
smash: 'Smash', |
|
|
acute: ['MathAccent', 0x7013], |
acute: ['MathAccent', [7,0,0x13]], |
grave: ['MathAccent', 0x7012], |
grave: ['MathAccent', [7,0,0x12]], |
ddot: ['MathAccent', 0x707F], |
ddot: ['MathAccent', [7,0,0x7F]], |
tilde: ['MathAccent', 0x707E], |
tilde: ['MathAccent', [7,0,0x7E]], |
bar: ['MathAccent', 0x7016], |
bar: ['MathAccent', [7,0,0x16]], |
breve: ['MathAccent', 0x7015], |
breve: ['MathAccent', [7,0,0x15]], |
check: ['MathAccent', 0x7014], |
check: ['MathAccent', [7,0,0x14]], |
hat: ['MathAccent', 0x705E], |
hat: ['MathAccent', [7,0,0x5E]], |
vec: ['MathAccent', 0x017E], |
vec: ['MathAccent', [0,1,0x7E]], |
dot: ['MathAccent', 0x705F], |
dot: ['MathAccent', [7,0,0x5F]], |
widetilde: ['MathAccent', 0x0365], |
widetilde: ['MathAccent', [0,3,0x65]], |
widehat: ['MathAccent', 0x0362], |
widehat: ['MathAccent', [0,3,0x62]], |
|
|
'_': ['Replace','ord','_','normal',-.4,.1], |
'_': ['Replace','ord','_','normal',-.4,.1], |
' ': ['Replace','ord',' ','normal'], |
' ': ['Replace','ord',' ','normal'], |
Line 3754 jsMath.Package(jsMath.Parser,{
|
Line 4642 jsMath.Package(jsMath.Parser,{
|
unicode: 'Unicode', |
unicode: 'Unicode', |
|
|
// debugging and test routines |
// debugging and test routines |
'char': 'Char', |
'char': 'Char' |
test: 'Test' |
|
}, |
}, |
|
|
/* |
/* |
Line 3777 jsMath.Package(jsMath.Parser,{
|
Line 4664 jsMath.Package(jsMath.Parser,{
|
* The horizontally stretchable delimiters |
* The horizontally stretchable delimiters |
*/ |
*/ |
leaders: { |
leaders: { |
downbrace: {left: 0x37A, lmid: 0x37D, rmid: 0x37C, right: 0x37B}, |
downbrace: {left: [3,0x7A], lmid: [3,0x7D], rmid: [3,0x7C], right: [3,0x7B]}, |
upbrace: {left: 0x37C, lmid: 0x37B, rmid: 0x37A, right: 0x37D}, |
upbrace: {left: [3,0x7C], lmid: [3,0x7B], rmid: [3,0x7A], right: [3,0x7D]}, |
leftarrow: {left: 0x220, rep: 0x200}, |
leftarrow: {left: [2,0x20], rep: [2,0x00]}, |
rightarrow: {rep: 0x200, right: 0x221} |
rightarrow: {rep: [2,0x00], right: [2,0x21]} |
}, |
}, |
|
|
|
|
Line 3894 jsMath.Package(jsMath.Parser,{
|
Line 4781 jsMath.Package(jsMath.Parser,{
|
* converted when typeset. |
* converted when typeset. |
*/ |
*/ |
GetDimen: function (name,nomu) { |
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)/); |
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} |
if (!match) {this.Error("Missing dimension or its units for "+name); return} |
this.i += match[0].length; |
if (advance) { |
if (this.nextIsSpace()) {this.i++} |
this.i += match[0].length; |
|
if (this.nextIsSpace()) {this.i++} |
|
} |
var d = match[1]-0; |
var d = match[1]-0; |
if (match[4] == 'px') {d /= jsMath.em} |
if (match[4] == 'px') {d /= jsMath.em} |
else if (match[4] == 'pt') {d /= 10} |
else if (match[4] == 'pt') {d /= 10} |
Line 4275 jsMath.Package(jsMath.Parser,{
|
Line 5171 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 |
* Add a fixed amount of horizontal space |
*/ |
*/ |
Spacer: function (name,w) { |
Spacer: function (name,w) { |
Line 4335 jsMath.Package(jsMath.Parser,{
|
Line 5214 jsMath.Package(jsMath.Parser,{
|
* This replaces \hrule and \vrule |
* This replaces \hrule and \vrule |
* @@@ not a standard TeX command, and all three parameters must be given @@@ |
* @@@ 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 w = this.GetDimen(this.cmd+name,1); if (this.error) return; |
var h = 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; |
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) {h = Math.max(1.05/jsMath.em,h)} |
if (h == 0 || w == 0) {gif = "blank"} |
if (h == 0 || w == 0) {style = "blank"} |
var html = '<IMG SRC="'+jsMath[gif]+'" STYLE="height: '+jsMath.HTML.Em(h)+'; ' |
if (w == 0) { |
+ 'width: '+jsMath.HTML.Em(w)+'">'; |
html = '<IMG SRC="'+jsMath.blank+'" STYLE="' |
|
+ 'border:0px none; width:1px; margin-right:-1px; ' |
|
+ 'height:'+jsMath.HTML.Em(h*jsMath.Browser.imgScale)+'">'; |
|
} else if (style == "blank") { |
|
html = '<IMG SRC="'+jsMath.blank+'" STYLE="border:0px none; ' |
|
+ 'height:'+jsMath.HTML.Em(h*jsMath.Browser.imgScale)+'; ' |
|
+ 'width:' +jsMath.HTML.Em(w*jsMath.Browser.imgScale)+'">'; |
|
} else { |
|
html = '<IMG SRC="'+jsMath.blank+'" STYLE="' |
|
+ 'position: relative; top:1px; height:1px; border:0px none; ' |
|
+ 'border-top:'+jsMath.HTML.Em(h*jsMath.Browser.imgScale)+' solid; ' |
|
+ 'width:' +jsMath.HTML.Em(w*jsMath.Browser.imgScale)+'">'; |
|
} |
if (d) { |
if (d) { |
html = '<SPAN STYLE="vertical-align:'+jsMath.HTML.Em(-d)+'">' |
html = '<SPAN STYLE="vertical-align:'+jsMath.HTML.Em(-d)+'">' |
+ html + '</SPAN>'; |
+ html + '</SPAN>'; |
Line 4485 jsMath.Package(jsMath.Parser,{
|
Line 5376 jsMath.Package(jsMath.Parser,{
|
* Process the character associated with a specific \mathcharcode |
* Process the character associated with a specific \mathcharcode |
*/ |
*/ |
HandleMathCode: function (name,code) { |
HandleMathCode: function (name,code) { |
var type = (code & 0xF000) >> 12; |
this.HandleTeXchar(code[0],code[1],code[2]); |
var font = (code & 0x0F00) >> 8; |
|
var code = code & 0x00FF; |
|
this.HandleTeXchar(type,font,code); |
|
}, |
}, |
|
|
/* |
/* |
Line 4566 jsMath.Package(jsMath.Parser,{
|
Line 5454 jsMath.Package(jsMath.Parser,{
|
return; |
return; |
} |
} |
if (this.delimiter[this.cmd+cmd]) { |
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; |
return; |
} |
} |
this.Error("Unknown control sequence '"+this.cmd+cmd+"'"); |
this.Error("Unknown control sequence '"+this.cmd+cmd+"'"); |
Line 4682 jsMath.Package(jsMath.Parser,{
|
Line 5570 jsMath.Package(jsMath.Parser,{
|
* results. We also include an image to force the results to take up |
* 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 |
* the right amount of space. The results may need to be vertically |
* adjusted to make the baseline appear in the correct place. |
* adjusted to make the baseline appear in the correct place. |
* |
|
* This is where the touchiest browser-dependent code appears. |
|
*/ |
*/ |
Typeset: function () { |
Typeset: function () { |
var data = this.mlist.init; |
var data = this.mlist.init; |
var box = this.typeset = this.mlist.Typeset(data.style,data.size); |
var box = this.typeset = this.mlist.Typeset(data.style,data.size); |
if (this.error) {return '<SPAN CLASS="error">'+this.error+'</SPAN>'} |
if (this.error) {return '<SPAN CLASS="error">'+this.error+'</SPAN>'} |
if (box.format == 'null') {return ''}; |
if (box.format == 'null') {return ''}; |
var rules = ''; var html |
|
|
|
box.Styled().Remeasured(); var isSmall = 0; var isBig = 0; |
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.bh > box.h && box.bh > jsMath.h+.001) {isSmall = 1} |
if (box.bd > box.d && box.bd > jsMath.d+.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.h > jsMath.h || box.d > jsMath.d) {isBig = 1} |
if (box.d > jsMath.d) {isBig = 1; d = box.d} |
|
|
|
if (jsMath.show.BBox) {rules += jsMath.HTML.Frame(0,-box.d,w,box.h+box.d,'green')} |
var html = box.html; |
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; |
|
if (isSmall) {// hide the extra size |
if (isSmall) {// hide the extra size |
if (jsMath.allowAbsolute) { |
if (jsMath.Browser.allowAbsolute) { |
var y = jsMath.absoluteOffsetY; |
var y = 0; |
if (jsMath.absoluteHeightVaries || box.bh > jsMath.h+.001) {y += (jsMath.h - box.bh)} |
if (box.bh > jsMath.h+.001) {y = jsMath.h - box.bh} |
html = jsMath.HTML.Absolute(html,w,jsMath.h,0,y,jsMath.h); |
html = jsMath.HTML.Absolute(html,box.w,jsMath.h,0,y,jsMath.h); |
isBig = 1; h = box.h; d = box.d; |
} else if (!jsMath.Browser.valignBug) { |
} else {// remove line height and try to hide the depth |
// remove line height and try to hide the depth |
var dy = jsMath.HTML.Em(Math.max(0,box.bd-jsMath.hd)/3); |
var dy = jsMath.HTML.Em(Math.max(0,box.bd-jsMath.hd)/3); |
html = '<SPAN STYLE="line-height: 0;' |
html = '<SPAN STYLE="line-height: 0;' |
+ ' position: relative; top: '+dy+'; vertical-align: '+dy |
+ ' position:relative; top:'+dy+'; vertical-align:'+dy |
+ '">' |
+ '">' + html + '</SPAN>'; |
+ html |
|
+ '</SPAN>'; |
|
} |
} |
|
isBig = 1; |
} |
} |
html = '<NOBR>' + rules + html; |
|
if (isBig) {// add height and depth to the line (force a little |
if (isBig) {// add height and depth to the line (force a little |
// extra to separate lines if needed) |
// extra to separate lines if needed) |
html += '<IMG SRC="'+jsMath.blank+'" CLASS="mathHD" ' |
html += '<IMG SRC="'+jsMath.blank+'" CLASS="mathHD" STYLE="' |
+ 'STYLE="height: '+jsMath.HTML.Em(h+d+.2)+'; ' |
+ 'height:'+jsMath.HTML.Em((box.h+box.d+.1)*jsMath.Browser.imgScale)+'; ' |
+ 'vertical-align: '+jsMath.HTML.Em(-d-.1)+';">' |
+ 'vertical-align:'+jsMath.HTML.Em(-box.d-.05)+';">' |
} |
} |
html += '<NOBR>' |
return '<NOBR><SPAN CLASS="jsM_scale">'+html+'</SPAN></NOBR>'; |
return html; |
|
} |
} |
|
|
}); |
}); |
Line 4760 jsMath.Parser.prototype.AddSpecial({
|
Line 5636 jsMath.Parser.prototype.AddSpecial({
|
* requires. These are substituted for #1, #2, etc. within the |
* requires. These are substituted for #1, #2, etc. within the |
* replacement string of the macro. For example |
* replacement string of the macro. For example |
* |
* |
* <SCRIPT> jsMath.Macro('x','{\vec x}_{#1}',1) </SCRIPT> |
* <SCRIPT> jsMath.Macro('x','{\\vec x}_{#1}',1) </SCRIPT> |
* |
* |
* would make \x1 produce {\vec x}_{1} and \x{i+1} produce {\vec x}_{i+1}. |
* would make \x1 produce {\vec x}_{1} and \x{i+1} produce {\vec x}_{i+1}. |
* |
* |
Line 4812 jsMath.Add(jsMath,{
|
Line 5688 jsMath.Add(jsMath,{
|
|
|
/* |
/* |
* Typeset a string in \displaystyle and return the HTML for it |
* Typeset a string in \displaystyle and return the HTML for it |
* ### need to give more control over whether to center, etc. ### |
|
*/ |
*/ |
DisplayMode: function (s) { |
DisplayMode: function (s) { |
var parse = jsMath.Parse(s,null,null,'D'); |
var parse = jsMath.Parse(s,null,null,'D'); |
Line 4826 jsMath.Add(jsMath,{
|
Line 5701 jsMath.Add(jsMath,{
|
*/ |
*/ |
GetElementText: function (element) { |
GetElementText: function (element) { |
var text = element.innerText; |
var text = element.innerText; |
if (text == null) { |
if (text == null || text == "") { |
text = element.textContent; |
try {text = element.textContent} catch (err) {} |
if (text == null) { |
if (text == null || text == "") {text = element.innerHTML} |
text = element.innerHTML; |
|
} |
|
} |
} |
if (text.search('&')) { |
if (text.search('&') >= 0) { |
text = text.replace(/</g,'<'); |
text = text.replace(/</g,'<'); |
text = text.replace(/>/g,'>'); |
text = text.replace(/>/g,'>'); |
text = text.replace(/"/g,'"'); |
text = text.replace(/"/g,'"'); |
Line 4842 jsMath.Add(jsMath,{
|
Line 5715 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 = |
|
'<SPAN CLASS="normal" STYLE="position:absolute; top:0px;left:0px;"></SPAN>' |
|
+ jsMath.Browser.operaHiddenFix; // needed by Opera in tables |
|
element.className=''; |
|
jsMath.hidden = element.firstChild; |
|
jsMath.ReInit(); |
|
}, |
|
|
|
|
|
/* |
* Typeset the contents of an element in \textstyle |
* Typeset the contents of an element in \textstyle |
*/ |
*/ |
ConvertText: function (element) { |
ConvertText: function (element) { |
var text = this.GetElementText(element); |
var text = this.GetElementText(element); |
|
this.ResetHidden(element); |
element.innerHTML = this.TextMode(text); |
element.innerHTML = this.TextMode(text); |
element.className = 'typeset'; |
element.className = 'typeset'; |
|
element.alt = text; |
}, |
}, |
|
|
/* |
/* |
Line 4855 jsMath.Add(jsMath,{
|
Line 5744 jsMath.Add(jsMath,{
|
*/ |
*/ |
ConvertDisplay: function (element) { |
ConvertDisplay: function (element) { |
var text = this.GetElementText(element); |
var text = this.GetElementText(element); |
|
this.ResetHidden(element); |
element.innerHTML = this.DisplayMode(text); |
element.innerHTML = this.DisplayMode(text); |
element.className = 'typeset'; |
element.className = 'typeset'; |
}, |
element.alt = text; |
|
|
/* |
|
* 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(); |
|
}, |
}, |
|
|
/* |
/* |
* Process a math element |
* Process a math element |
*/ |
*/ |
ProcessElement: function (element) { |
ProcessElement: function (element) { |
window.status = 'Processing Math...'; |
try { |
if (element.tagName == 'DIV') { |
if (element.tagName == 'DIV') { |
this.ConvertDisplay(element); |
this.ConvertDisplay(element); |
} else if (element.tagName == 'SPAN') { |
} else if (element.tagName == 'SPAN') { |
this.ConvertText(element); |
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) {} |
}, |
}, |
|
|
/* |
/* |
Line 4895 jsMath.Add(jsMath,{
|
Line 5783 jsMath.Add(jsMath,{
|
this.ProcessComplete(); |
this.ProcessComplete(); |
} else { |
} else { |
this.ProcessElement(this.element[k]) |
this.ProcessElement(this.element[k]) |
setTimeout('jsMath.ProcessElements('+(k+1)+')',jsMath.delay); |
setTimeout('jsMath.ProcessElements('+(k+1)+')',jsMath.Browser.delay); |
} |
} |
}, |
}, |
|
|
Line 4905 jsMath.Add(jsMath,{
|
Line 5793 jsMath.Add(jsMath,{
|
* start reading the mathematics while the rest of the page |
* start reading the mathematics while the rest of the page |
* is being processed. |
* is being processed. |
*/ |
*/ |
Process: function () { |
Process: function (obj) { |
if (!jsMath.initialized) {jsMath.Init()} |
if (!jsMath.initialized) {jsMath.Init()} |
this.element = this.GetMathElements(); |
this.element = this.GetMathElements(obj); |
window.status = 'Processing Math...'; |
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 |
element: [], // the list of math elements on the page |
Line 4918 jsMath.Add(jsMath,{
|
Line 5822 jsMath.Add(jsMath,{
|
* Look up all the math elements on the page and |
* Look up all the math elements on the page and |
* put them in a list sorted from top to bottom of the page |
* put them in a list sorted from top to bottom of the page |
*/ |
*/ |
GetMathElements: function () { |
GetMathElements: function (obj) { |
var element = []; |
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++) { |
for (var k = 0; k < math.length; k++) { |
if (math[k].className == 'math') { |
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]} |
else {element[element.length] = math[k]} |
} |
} |
} |
} |
math = document.getElementsByTagName('SPAN'); |
math = obj.getElementsByTagName('SPAN'); |
for (var k = 0; k < math.length; k++) { |
for (var k = 0; k < math.length; k++) { |
if (math[k].className == 'math') { |
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]} |
else {element[element.length] = math[k]} |
} |
} |
} |
} |
// this gets the SPAN and DIV elements interleaved in order |
// this gets the SPAN and DIV elements interleaved in order |
if (jsMath.renameOK) { |
if (jsMath.Browser.renameOK && obj.getElementsByName) { |
element = document.getElementsByName('_jsMath_') |
element = obj.getElementsByName('_jsMath_'); |
} else if (jsMath.hidden.sourceIndex) { |
} else if (jsMath.hidden.sourceIndex) { |
element.sort(function (a,b) {return a.sourceIndex - b.sourceIndex}); |
element.sort(function (a,b) {return a.sourceIndex - b.sourceIndex}); |
} |
} |
Line 4948 jsMath.Add(jsMath,{
|
Line 5857 jsMath.Add(jsMath,{
|
* and clean up any marked <SPAN> or <DIV> tags |
* and clean up any marked <SPAN> or <DIV> tags |
*/ |
*/ |
ProcessComplete: function () { |
ProcessComplete: function () { |
if (jsMath.renameOK) { |
if (jsMath.Browser.renameOK) { |
var element = document.getElementsByName('_jsMath_'); |
var element = document.getElementsByName('_jsMath_'); |
for (var i = element.length-1; i >= 0; i--) { |
for (var i = element.length-1; i >= 0; i--) { |
element[i].removeAttribute('NAME'); |
element[i].removeAttribute('NAME'); |
} |
} |
} |
} |
|
jsMath.hidden = jsMath.hiddenTop; |
jsMath.element = []; |
jsMath.element = []; |
window.status = 'Done'; |
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 <DIV> for measuring the BBoxes of things |
|
*/ |
|
jsMath.hidden = '<DIV CLASS="normal" ID="jsMath.Hidden" ' + |
|
'STYLE="position:absolute; top:0 left:0;"></DIV>'; |
|
if (document.body.insertAdjacentHTML) { |
|
document.body.insertAdjacentHTML('AfterBegin',jsMath.hidden); |
|
} else { |
|
document.write(jsMath.hidden); |
|
} |
|
jsMath.hidden = document.getElementById("jsMath.Hidden"); |
|
|
|
/* |
/* |
* Initialize everything |
* Initialize everything |
*/ |
*/ |
jsMath.InitSource(); |
jsMath.Loaded(); |
jsMath.InitBrowser(); |
jsMath.Controls.GetCookie(); |
jsMath.InitStyles(); |
if (document.body) {jsMath.Setup.Body()} |
|
|
//make sure browser-specific loads are done before this |
}} |
document.write('<SCRIPT>jsMath.CheckFonts()</SCRIPT>'); |
|
|
|
} |
|
|
|
} |
|