/talk2/mathjax/unpacked/jax/output/HTML-CSS/jax.js
JavaScript | 2835 lines | 2516 code | 123 blank | 196 comment | 946 complexity | 3c116987da8483df9c7c8141e7dc5ee5 MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0, MIT
Large files files are truncated, but you can click here to view the full file
- /*************************************************************
- *
- * MathJax/jax/output/HTML-CSS/jax.js
- *
- * Implements the HTML-CSS OutputJax that displays mathematics
- * using HTML and CSS to position the characters from math fonts
- * in their proper locations.
- *
- * ---------------------------------------------------------------------
- *
- * Copyright (c) 2009-2012 Design Science, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- (function (AJAX,HUB,HTMLCSS) {
- var MML, isMobile = HUB.Browser.isMobile;
-
- var FONTTEST = MathJax.Object.Subclass({
- timeout: (isMobile? 15:8)*1000, // timeout for loading web fonts
- FontInfo: {
- STIX: {family: "STIXSizeOneSym", testString: "() {} []"},
- TeX: {family: "MathJax_Size1", testString: "() {} []"}
- },
- comparisonFont: ["sans-serif","monospace","script","Times","Courier","Arial","Helvetica"],
- testSize: ["40px","50px","60px","30px","20px"],
- Init: function () {
- this.div = MathJax.HTML.addElement(document.body,"div",{
- id: "MathJax_Font_Test",
- style: {position:"absolute", visibility:"hidden", top:0, left:0, width: "auto",
- padding:0, border:0, margin:0, whiteSpace:"nowrap",
- textAlign:"left", textIndent:0, textTransform:"none",
- lineHeight:"normal", letterSpacing:"normal", wordSpacing:"normal",
- fontSize:this.testSize[0], fontWeight:"normal", fontStyle:"normal",
- fontSizeAdjust:"none"}
- },[""]);
- this.text = this.div.firstChild;
- },
- findFont: function (fonts,pref) {
- if (pref && this.testCollection(pref)) {return pref}
- for (var i = 0, m = fonts.length; i < m; i++) {
- if (fonts[i] === pref) continue;
- if (this.testCollection(fonts[i])) {return fonts[i]}
- }
- return null;
- },
- testCollection: function (name) {return this.testFont(this.FontInfo[name])},
- testFont: function (font) {
- if (font.isWebFont && HTMLCSS.FontFaceBug) {
- this.div.style.fontWeight = this.div.style.fontStyle = "normal";
- } else {
- this.div.style.fontWeight = (font.weight||"normal");
- this.div.style.fontStyle = (font.style||"normal");
- }
- var W = this.getComparisonWidths(font.testString,font.noStyleChar);
- if (W) {
- this.div.style.fontFamily = "'"+font.family+"',"+this.comparisonFont[0];
- if (this.div.offsetWidth == W[0]) {
- this.div.style.fontFamily = "'"+font.family+"',"+this.comparisonFont[W[2]];
- if (this.div.offsetWidth == W[1]) {return false}
- }
- if (this.div.offsetWidth != W[3] || this.div.offsetHeight != W[4]) {
- if (font.noStyleChar || !HTMLCSS.FONTDATA || !HTMLCSS.FONTDATA.hasStyleChar) {return true}
- for (var i = 0, m = this.testSize.length; i < m; i++)
- {if (this.testStyleChar(font,this.testSize[i])) {return true}}
- }
- }
- return false;
- },
- styleChar: "\uEFFD", // width encodes style
- versionChar: "\uEFFE", // width encodes version
- compChar: "\uEFFF", // "standard" width to compare to
- testStyleChar: function (font,size) {
- var n = 3 + (font.weight ? 2 : 0) + (font.style ? 4 : 0);
- var extra = "", dw = 0;
- var SIZE = this.div.style.fontSize; this.div.style.fontSize = size;
- if (HTMLCSS.msieItalicWidthBug && font.style === "italic") {
- this.text.nodeValue = extra = this.compChar;
- dw = this.div.offsetWidth;
- }
- if (HTMLCSS.safariTextNodeBug) {this.div.innerHTML = this.compChar+extra}
- else {this.text.nodeValue = this.compChar+extra}
- var W = this.div.offsetWidth-dw;
- if (HTMLCSS.safariTextNodeBug) {this.div.innerHTML = this.styleChar+extra}
- else {this.text.nodeValue = this.styleChar+extra}
- var N = Math.floor((this.div.offsetWidth-dw)/W+.5);
- if (N === n) {
- if (HTMLCSS.safariTextNodeBug) {this.div.innerHTML = this.versionChar+extra}
- else {this.text.nodeValue = this.versionChar+extra}
- font.version = Math.floor((this.div.offsetWidth-dw)/W+1.5)/2;
- }
- this.div.style.fontSize = SIZE;
- return (N === n);
- },
- getComparisonWidths: function (string,noStyleChar) {
- if (HTMLCSS.FONTDATA && HTMLCSS.FONTDATA.hasStyleChar && !noStyleChar)
- {string += this.styleChar + " " + this.compChar}
- if (HTMLCSS.safariTextNodeBug) {this.div.innerHTML = string}
- else {this.text.nodeValue = string}
- this.div.style.fontFamily = this.comparisonFont[0];
- var W = this.div.offsetWidth;
- this.div.style.fontFamily = HTMLCSS.webFontDefault;
- var sW = this.div.offsetWidth, sH = this.div.offsetHeight;
- for (var i = 1, m = this.comparisonFont.length; i < m; i++) {
- this.div.style.fontFamily = this.comparisonFont[i];
- if (this.div.offsetWidth != W) {return [W,this.div.offsetWidth,i,sW,sH]}
- }
- return null;
- },
- loadWebFont: function (font) {
- HUB.Startup.signal.Post("HTML-CSS Jax - Web-Font "+HTMLCSS.fontInUse+"/"+font.directory);
- var n = MathJax.Message.File("Web-Font "+HTMLCSS.fontInUse+"/"+font.directory);
- var done = MathJax.Callback({}); // called when font is loaded
- var callback = MathJax.Callback(["loadComplete",this,font,n,done]);
- AJAX.timer.start(AJAX,[this.checkWebFont,font,callback],0,this.timeout);
- return done;
- },
- loadComplete: function (font,n,done,status) {
- MathJax.Message.Clear(n);
- if (status === AJAX.STATUS.OK) {this.webFontLoaded = true; done(); return}
- this.loadError(font);
- if (HUB.Browser.isFirefox && HTMLCSS.allowWebFonts) {
- var host = document.location.protocol + "//" + document.location.hostname;
- if (document.location.port != "") {host += ":" + document.location.port}
- host += "/";
- if (AJAX.fileURL(HTMLCSS.webfontDir).substr(0,host.length) !== host)
- {this.firefoxFontError(font)}
- }
- if (!this.webFontLoaded) {HTMLCSS.loadWebFontError(font,done)} else {done()}
- },
- loadError: function (font) {
- MathJax.Message.Set("Can't load web font "+HTMLCSS.fontInUse+"/"+font.directory,null,2000);
- HUB.Startup.signal.Post(["HTML-CSS Jax - web font error",HTMLCSS.fontInUse+"/"+font.directory,font]);
- },
- firefoxFontError: function (font) {
- MathJax.Message.Set("Firefox can't load web fonts from a remote host",null,3000);
- HUB.Startup.signal.Post("HTML-CSS Jax - Firefox web fonts on remote host error");
- },
- checkWebFont: function (check,font,callback) {
- if (check.time(callback)) return;
- if (HTMLCSS.Font.testFont(font)) {callback(check.STATUS.OK)}
- else {setTimeout(check,check.delay)}
- },
- fontFace: function (name) {
- var type = HTMLCSS.allowWebFonts;
- var FONT = HTMLCSS.FONTDATA.FONTS[name];
- if (HTMLCSS.msieFontCSSBug && !FONT.family.match(/-Web$/)) {FONT.family += "-Web"}
- var dir = AJAX.fileURL(HTMLCSS.webfontDir+"/"+type);
- var fullname = name.replace(/-b/,"-B").replace(/-i/,"-I").replace(/-Bold-/,"-Bold");
- if (!fullname.match(/-/)) {fullname += "-Regular"}
- if (type === "svg") {fullname += ".svg#"+fullname} else {fullname += "."+type}
- var def = {
- "font-family": FONT.family,
- src: "url('"+dir+"/"+fullname+"')"
- };
- if (type === "otf") {
- def.src += " format('opentype')";
- dir = AJAX.fileURL(HTMLCSS.webfontDir+"/woff"); // add woff fonts as well
- def.src = "url('"+dir+"/"+fullname.replace(/otf$/,"woff")+"') format('woff'), "+def.src;
- } else if (type !== "eot") {def.src += " format('"+type+"')"}
- if (!(HTMLCSS.FontFaceBug && FONT.isWebFont)) {
- if (name.match(/-bold/)) {def["font-weight"] = "bold"}
- if (name.match(/-italic/)) {def["font-style"] = "italic"}
- }
- return def;
- }
- });
-
- var EVENT, TOUCH, HOVER; // filled in later
-
- HTMLCSS.Augment({
- config: {
- styles: {
- ".MathJax": {
- "display": "inline",
- "font-style": "normal",
- "font-weight": "normal",
- "line-height": "normal",
- "font-size": "100%",
- "font-size-adjust":"none",
- "text-indent": 0,
- "text-align": "left",
- "text-transform": "none",
- "letter-spacing": "normal",
- "word-spacing": "normal",
- "word-wrap": "normal",
- "white-space": "nowrap",
- "float": "none",
- "direction": "ltr",
- border: 0, padding: 0, margin: 0
- },
- ".MathJax_Display": {
- position: "relative",
- display: "block",
- width: "100%"
- },
- ".MathJax img, .MathJax nobr, .MathJax a": {
- border: 0, padding: 0, margin: 0, "max-width": "none", "max-height": "none",
- "vertical-align": 0, "line-height": "normal",
- "text-decoration": "none"
- },
- "img.MathJax_strut": {
- border:"0 !important", padding:"0 !important", margin: "0 !important",
- "vertical-align": "0 !important"
- },
-
- ".MathJax span": {
- display: "inline", position: "static",
- border: 0, padding: 0, margin: 0,
- "vertical-align": 0, "line-height": "normal",
- "text-decoration": "none"
- },
- ".MathJax nobr": {
- "white-space": "nowrap ! important"
- },
-
- ".MathJax img": {
- display: "inline ! important",
- "float": "none ! important"
- },
- ".MathJax_Processing": {
- visibility: "hidden", position:"fixed",
- width: 0, height: 0, overflow:"hidden"
- },
- ".MathJax_Processed": {display:"none!important"},
-
- ".MathJax_ExBox": {
- display:"block", overflow:"hidden",
- width:"1px", height:"60ex"
- },
- ".MathJax .MathJax_EmBox": {
- display:"block", overflow:"hidden",
- width:"1px", height:"60em"
- },
-
- ".MathJax .MathJax_HitBox": {
- cursor: "text",
- background: "white",
- opacity:0, filter:"alpha(opacity=0)"
- },
- ".MathJax .MathJax_HitBox *": {
- filter: "none", opacity:1, background:"transparent" // for IE
- },
-
- "#MathJax_Tooltip": {
- position: "absolute", left: 0, top: 0,
- width: "auto", height: "auto",
- display: "none"
- },
- "#MathJax_Tooltip *": {
- filter: "none", opacity:1, background:"transparent" // for IE
- },
-
- //
- // Used for testing web fonts against the default font used while
- // web fonts are loading
- //
- "@font-face": {
- "font-family": "MathJax_Blank",
- "src": "url('about:blank')"
- }
- }
- },
- settings: HUB.config.menuSettings,
- hideProcessedMath: true, // use display:none until all math is processed
- Font: null, // created by Config() below
- webFontDefault: "MathJax_Blank",
- allowWebFonts: "otf", // assume browser can use OTF web fonts
- Config: function () {
- if (!this.require) {this.require = []}
- this.Font = FONTTEST();
- this.SUPER(arguments).Config.call(this); var settings = this.settings;
- if (this.adjustAvailableFonts) {this.adjustAvailableFonts(this.config.availableFonts)}
- if (settings.scale) {this.config.scale = settings.scale}
- if (settings.font && settings.font !== "Auto") {
- if (settings.font === "TeX (local)")
- {this.config.availableFonts = ["TeX"]; this.config.preferredFont = "TeX"; this.config.webFont = "TeX"}
- else if (settings.font === "STIX (local)")
- {this.config.availableFonts = ["STIX"]; this.config.preferredFont = "STIX"; this.config.webFont = "TeX"}
- else if (settings.font === "TeX (web)") {this.config.availableFonts = []; this.config.preferredFont = ""; this.config.webFont = "TeX"}
- else if (settings.font === "TeX (image)") {this.config.availableFonts = []; this.config.preferredFont = ""; this.config.webFont = ""}
- }
- var font = this.Font.findFont(this.config.availableFonts,this.config.preferredFont);
- if (!font && this.allowWebFonts) {font = this.config.webFont; if (font) {this.webFonts = true}}
- if (!font && this.config.imageFont) {font = this.config.imageFont; this.imgFonts = true}
- if (font) {
- this.fontInUse = font; this.fontDir += "/" + font; this.webfontDir += "/" + font;
- this.require.push(this.fontDir+"/fontdata.js");
- if (this.imgFonts) {
- this.require.push(this.directory+"/imageFonts.js");
- HUB.Startup.signal.Post("HTML-CSS Jax - using image fonts");
- }
- } else {
- MathJax.Message.Set("Can't find a valid font using ["+this.config.availableFonts.join(", ")+"]",null,3000);
- this.FONTDATA = {
- TeX_factor: 1, baselineskip: 1.2, lineH: .8, lineD: .2, ffLineH: .8,
- FONTS: {}, VARIANT: {normal: {fonts:[]}}, RANGES: [],
- DELIMITERS: {}, RULECHAR: 0x2D, REMAP: {}
- };
- if (MathJax.InputJax.TeX && MathJax.InputJax.TeX.Definitions) {
- MathJax.InputJax.TeX.Definitions.macros.overline[1] = "002D";
- MathJax.InputJax.TeX.Definitions.macros.underline[1] = "002D";
- }
- HUB.Startup.signal.Post("HTML-CSS Jax - no valid font");
- }
- this.require.push(MathJax.OutputJax.extensionDir+"/MathEvents.js");
- },
- Startup: function () {
- // Set up event handling
- EVENT = MathJax.Extension.MathEvents.Event;
- TOUCH = MathJax.Extension.MathEvents.Touch;
- HOVER = MathJax.Extension.MathEvents.Hover;
- this.ContextMenu = EVENT.ContextMenu;
- this.Mousedown = EVENT.AltContextMenu;
- this.Mouseover = HOVER.Mouseover;
- this.Mouseout = HOVER.Mouseout;
- this.Mousemove = HOVER.Mousemove;
- // Make hidden div for when math is in a display:none block
- this.hiddenDiv = this.Element("div",{
- style:{visibility:"hidden", overflow:"hidden", position:"absolute", top:0,
- height:"1px", width: "auto", padding:0, border:0, margin:0,
- textAlign:"left", textIndent:0, textTransform:"none",
- lineHeight:"normal", letterSpacing:"normal", wordSpacing:"normal"}
- });
- if (!document.body.firstChild) {document.body.appendChild(this.hiddenDiv)}
- else {document.body.insertBefore(this.hiddenDiv,document.body.firstChild)}
- this.hiddenDiv = this.addElement(this.hiddenDiv,"div",{id:"MathJax_Hidden"});
- // Determine pixels per inch
- var div = this.addElement(this.hiddenDiv,"div",{style:{width:"5in"}});
- this.pxPerInch = div.offsetWidth/5; this.hiddenDiv.removeChild(div);
- // Markers used by getW
- this.startMarker = this.createStrut(this.Element("span"),10,true);
- this.endMarker = this.addText(this.Element("span"),"x").parentNode;
- // Used in getHD
- this.HDspan = this.Element("span");
- if (this.operaHeightBug) {this.createStrut(this.HDspan,0)}
- if (this.msieInlineBlockAlignBug) {
- this.HDimg = this.addElement(this.HDspan,"img",{style:{height:"0px", width:"1px"}});
- try {this.HDimg.src = "about:blank"} catch(err) {}
- } else {
- this.HDimg = this.createStrut(this.HDspan,0);
- }
- // Used in preTranslate to get scaling factors
- this.EmExSpan = this.Element("span",
- {style:{position:"absolute","font-size-adjust":"none"}},
- [
- ["span",{className:"MathJax_ExBox"}],
- ["span",{className:"MathJax"},
- [["span",{className:"MathJax_EmBox"}]]
- ]
- ]
- );
- // Used in preTranslate to get linebreak width
- this.linebreakSpan = this.Element("span",null,
- [["hr",{style: {width:"100%", size:1, padding:0, border:0, margin:0}}]]);
- // Set up styles and preload web fonts
- return AJAX.Styles(this.config.styles,["InitializeHTML",this]);
- },
-
- removeSTIXfonts: function (fonts) {
- //
- // Opera doesn't display large chunks of the STIX fonts, and
- // Safari/Windows doesn't display Plane1,
- // so disable STIX for these browsers.
- //
- for (var i = 0, m = fonts.length; i < m; i++)
- {if (fonts[i] === "STIX") {fonts.splice(i,1); m--; i--;}}
- if (this.config.preferredFont === "STIX") {this.config.preferredFont = fonts[0]}
- },
- PreloadWebFonts: function () {
- if (!HTMLCSS.allowWebFonts || !HTMLCSS.config.preloadWebFonts) return;
- for (var i = 0, m = HTMLCSS.config.preloadWebFonts.length; i < m; i++) {
- var FONT = HTMLCSS.FONTDATA.FONTS[HTMLCSS.config.preloadWebFonts[i]];
- if (!FONT.available) {HTMLCSS.Font.testFont(FONT)}
- }
- },
-
- //
- // Handle initialization that requires styles to be set up
- //
- InitializeHTML: function () {
- this.PreloadWebFonts();
- //
- // Get the default sizes (need styles in place to do this)
- //
- document.body.appendChild(this.EmExSpan);
- document.body.appendChild(this.linebreakSpan);
- this.defaultEx = this.EmExSpan.firstChild.offsetHeight/60;
- this.defaultEm = this.EmExSpan.lastChild.firstChild.offsetHeight/60;
- this.defaultWidth = this.linebreakSpan.firstChild.offsetWidth;
- document.body.removeChild(this.linebreakSpan);
- document.body.removeChild(this.EmExSpan);
- },
-
- preTranslate: function (state) {
- var scripts = state.jax[this.id], i, m = scripts.length,
- script, prev, span, div, test, jax, ex, em, scale, maxwidth, relwidth = false,
- linebreak = this.config.linebreaks.automatic, width = this.config.linebreaks.width;
- if (linebreak) {
- relwidth = (width.match(/^\s*(\d+(\.\d*)?%\s*)?container\s*$/) != null);
- if (relwidth) {width = width.replace(/\s*container\s*/,"")}
- else {maxwidth = this.defaultWidth}
- if (width === "") {width = "100%"}
- } else {maxwidth = 100000} // a big width, so no implicit line breaks
- //
- // Loop through the scripts
- //
- for (i = 0; i < m; i++) {
- script = scripts[i]; if (!script.parentNode) continue;
- //
- // Remove any existing output
- //
- prev = script.previousSibling;
- if (prev && String(prev.className).match(/^MathJax(_Display)?( MathJax_Processing)?$/))
- {prev.parentNode.removeChild(prev)}
- //
- // Add the span, and a div if in display mode,
- // then set the role and mark it as being processed
- //
- jax = script.MathJax.elementJax; if (!jax) continue;
- jax.HTMLCSS = {display: (jax.root.Get("display") === "block")}
- span = div = this.Element("span",{
- className:"MathJax", id:jax.inputID+"-Frame", isMathJax:true, jaxID:this.id,
- oncontextmenu:EVENT.Menu, onmousedown: EVENT.Mousedown,
- onmouseover:EVENT.Mouseover, onmouseout:EVENT.Mouseout, onmousemove:EVENT.Mousemove,
- onclick:EVENT.Click, ondblclick:EVENT.DblClick
- });
- if (HUB.Browser.noContextMenu) {
- span.ontouchstart = TOUCH.start;
- span.ontouchend = TOUCH.end;
- }
- if (jax.HTMLCSS.display) {
- div = this.Element("div",{className:"MathJax_Display"});
- div.appendChild(span);
- } else if (this.msieDisappearingBug) {span.style.display = "inline-block"}
- //
- // Mark math for screen readers
- // (screen readers don't know about role="math" yet, so use "textbox" instead)
- //
- div.setAttribute("role","textbox"); div.setAttribute("aria-readonly","true");
- div.className += " MathJax_Processing";
- script.parentNode.insertBefore(div,script);
- //
- // Add the test span for determining scales and linebreak widths
- //
- script.parentNode.insertBefore(this.EmExSpan.cloneNode(true),script);
- if (relwidth) {div.parentNode.insertBefore(this.linebreakSpan.cloneNode(true),div)}
- }
- //
- // Determine the scaling factors for each script
- // (this only requires one reflow rather than a reflow for each equation)
- //
- for (i = 0; i < m; i++) {
- script = scripts[i]; if (!script.parentNode) continue;
- test = script.previousSibling; div = test.previousSibling;
- jax = script.MathJax.elementJax; if (!jax) continue;
- ex = test.firstChild.offsetHeight/60;
- em = test.lastChild.firstChild.offsetHeight/60;
- if (relwidth) {maxwidth = div.previousSibling.firstChild.offsetWidth}
- if (ex === 0 || ex === "NaN") {
- // can't read width, so move to hidden div for processing
- // (this will cause a reflow for each math element that is hidden)
- this.hiddenDiv.appendChild(div);
- jax.HTMLCSS.isHidden = true;
- ex = this.defaultEx; em = this.defaultEm;
- if (relwidth) {maxwidth = this.defaultWidth}
- }
- scale = Math.floor(Math.max(this.config.minScaleAdjust/100,(ex/this.TeX.x_height)/em) * this.config.scale);
- jax.HTMLCSS.scale = scale/100; jax.HTMLCSS.fontSize = scale+"%";
- jax.HTMLCSS.em = jax.HTMLCSS.outerEm = em; this.em = em * scale/100; jax.HTMLCSS.ex = ex;
- jax.HTMLCSS.lineWidth = (linebreak ? this.length2em(width,1,maxwidth/this.em) : 1000000);
- }
- //
- // Remove the test spans used for determining scales and linebreak widths
- //
- for (i = 0; i < m; i++) {
- script = scripts[i]; if (!script.parentNode) continue;
- test = scripts[i].previousSibling;
- jax = scripts[i].MathJax.elementJax; if (!jax) continue;
- if (relwidth) {
- span = test.previousSibling;
- if (!jax.HTMLCSS.isHidden) {span = span.previousSibling}
- span.parentNode.removeChild(span);
- }
- test.parentNode.removeChild(test);
- }
- //
- // Set state variables used for displaying equations in chunks
- //
- state.HTMLCSSeqn = state.HTMLCSSlast = 0; state.HTMLCSSi = -1;
- state.HTMLCSSchunk = this.config.EqnChunk;
- state.HTMLCSSdelay = false;
- },
- Translate: function (script,state) {
- if (!script.parentNode) return;
- //
- // If we are supposed to do a chunk delay, do it
- //
- if (state.HTMLCSSdelay) {
- state.HTMLCSSdelay = false;
- HUB.RestartAfter(MathJax.Callback.Delay(this.config.EqnChunkDelay));
- }
- //
- // Get the data about the math
- //
- var jax = script.MathJax.elementJax, math = jax.root,
- span = document.getElementById(jax.inputID+"-Frame"),
- div = (jax.HTMLCSS.display ? span.parentNode : span);
- //
- // Set the font metrics
- //
- this.em = MML.mbase.prototype.em = jax.HTMLCSS.em * jax.HTMLCSS.scale;
- this.outerEm = jax.HTMLCSS.em; this.scale = jax.HTMLCSS.scale;
- this.linebreakWidth = jax.HTMLCSS.lineWidth;
- span.style.fontSize = jax.HTMLCSS.fontSize;
- //
- // Typeset the math
- //
- this.initImg(span);
- this.initHTML(math,span);
- math.setTeXclass();
- try {math.toHTML(span,div)} catch (err) {
- if (err.restart) {while (span.firstChild) {span.removeChild(span.firstChild)}}
- throw err;
- }
- //
- // Put it in place, and remove the processing marker
- //
- if (jax.HTMLCSS.isHidden) {script.parentNode.insertBefore(div,script)}
- div.className = div.className.split(/ /)[0];
- //
- // Check if we are hiding the math until more is processed
- //
- if (this.hideProcessedMath) {
- //
- // Hide the math and don't let its preview be removed
- //
- div.className += " MathJax_Processed";
- if (script.MathJax.preview) {
- jax.HTMLCSS.preview = script.MathJax.preview;
- delete script.MathJax.preview;
- }
- //
- // Check if we should show this chunk of equations
- //
- state.HTMLCSSeqn += (state.i - state.HTMLCSSi); state.HTMLCSSi = state.i;
- if (state.HTMLCSSeqn >= state.HTMLCSSlast + state.HTMLCSSchunk) {
- this.postTranslate(state);
- state.HTMLCSSchunk = Math.floor(state.HTMLCSSchunk*this.config.EqnChunkFactor);
- state.HTMLCSSdelay = true; // delay if there are more scripts
- }
- }
- },
- postTranslate: function (state) {
- var scripts = state.jax[this.id];
- if (!this.hideProcessedMath) return;
- //
- // Reveal this chunk of math
- //
- for (var i = state.HTMLCSSlast, m = state.HTMLCSSeqn; i < m; i++) {
- var script = scripts[i];
- if (script && script.MathJax.elementJax) {
- //
- // Remove the processed marker
- //
- script.previousSibling.className = script.previousSibling.className.split(/ /)[0];
- var data = script.MathJax.elementJax.HTMLCSS;
- //
- // Remove the preview, if any
- //
- if (data.preview) {
- data.preview.innerHTML = "";
- script.MathJax.preview = data.preview;
- delete data.preview;
- }
- }
- }
- if (this.forceReflow) {
- // WebKit can misplace some elements that should wrap to the next line
- // but gets them right ona reflow, so force reflow by toggling a stylesheet
- var sheet = (document.styleSheets||[])[0]||{};
- sheet.disabled = true; sheet.disabled = false;
- }
- //
- // Save our place so we know what is revealed
- //
- state.HTMLCSSlast = state.HTMLCSSeqn;
- },
- getJaxFromMath: function (math) {
- if (math.parentNode.className === "MathJax_Display") {math = math.parentNode}
- do {math = math.nextSibling} while (math && math.nodeName.toLowerCase() !== "script");
- return HUB.getJaxFor(math);
- },
- getHoverSpan: function (jax,math) {return jax.root.HTMLspanElement()},
- getHoverBBox: function (jax,span,math) {
- var bbox = span.bbox, em = jax.HTMLCSS.outerEm;
- var BBOX = {w:bbox.w*em, h:bbox.h*em, d:bbox.d*em};
- if (bbox.width) {BBOX.width = bbox.width}
- return BBOX;
- },
-
- Zoom: function (jax,span,math,Mw,Mh) {
- //
- // Re-render at larger size
- //
- span.className = "MathJax";
- span.style.fontSize = jax.HTMLCSS.fontSize;
- //
- // get em sizes (taken from HTMLCSS.preTranslate)
- //
- var emex = span.appendChild(this.EmExSpan.cloneNode(true));
- var em = emex.lastChild.firstChild.offsetHeight/60;
- this.em = MML.mbase.prototype.em = em;
- this.outerEm = em / jax.HTMLCSS.scale;
- emex.parentNode.removeChild(emex);
- this.idPostfix = "-zoom"; jax.root.toHTML(span,span); this.idPostfix = "";
- var width = jax.root.HTMLspanElement().bbox.width;
- if (width) {
- // Handle full-width displayed equations
- // FIXME: this is a hack for now
- span.style.width = Math.floor(Mw-1.5*HTMLCSS.em)+"px"; span.style.display="inline-block";
- var id = (jax.root.id||"MathJax-Span-"+jax.root.spanID)+"-zoom";
- var child = document.getElementById(id).firstChild;
- while (child && child.style.width !== width) {child = child.nextSibling}
- if (child) {child.style.width = "100%"}
- }
- //
- // Get height and width of zoomed math and original math
- //
- span.style.position = math.style.position = "absolute";
- var zW = span.offsetWidth, zH = span.offsetHeight,
- mH = math.offsetHeight, mW = math.offsetWidth;
- if (mW === 0) {mW = math.parentNode.offsetWidth}; // IE7 gets mW == 0?
- span.style.position = math.style.position = "";
- //
- return {Y:-EVENT.getBBox(span).h, mW:mW, mH:mH, zW:zW, zH:zH};
- },
- initImg: function (span) {},
- initHTML: function (math,span) {},
- initFont: function (name) {
- var FONTS = HTMLCSS.FONTDATA.FONTS, AVAIL = HTMLCSS.config.availableFonts;
- if (AVAIL && AVAIL.length && HTMLCSS.Font.testFont(FONTS[name]))
- {FONTS[name].available = true; return null}
- if (!this.allowWebFonts) {return null}
- FONTS[name].isWebFont = true;
- if (HTMLCSS.FontFaceBug) {
- FONTS[name].family = name;
- if (HTMLCSS.msieFontCSSBug) {FONTS[name].family += "-Web"}
- }
- return AJAX.Styles({"@font-face":this.Font.fontFace(name)});
- },
- Remove: function (jax) {
- var span = document.getElementById(jax.inputID+"-Frame");
- if (span) {
- if (jax.HTMLCSS.display) {span = span.parentNode}
- span.parentNode.removeChild(span);
- }
- delete jax.HTMLCSS;
- },
-
- getHD: function (span) {
- var position = span.style.position;
- span.style.position = "absolute";
- this.HDimg.style.height = "0px";
- span.appendChild(this.HDspan);
- var HD = {h:span.offsetHeight};
- this.HDimg.style.height = HD.h+"px";
- HD.d = span.offsetHeight - HD.h; HD.h -= HD.d;
- HD.h /= this.em; HD.d /= this.em;
- span.removeChild(this.HDspan);
- span.style.position = position;
- return HD;
- },
- getW: function (span) {
- var W, H, w = (span.bbox||{}).w, start = span;
- if (span.bbox && span.bbox.exactW) {return w}
- if ((span.bbox && w >= 0 && !this.initialSkipBug) || this.negativeBBoxes || !span.firstChild) {
- W = span.offsetWidth; H = span.parentNode.offsetHeight;
- } else if (span.bbox && w < 0 && this.msieNegativeBBoxBug) {
- W = -span.offsetWidth, H = span.parentNode.offsetHeight;
- } else {
- // IE can't deal with a space at the beginning, so put something else first
- if (this.initialSkipBug) {
- var position = span.style.position; span.style.position = "absolute";
- start = this.startMarker; span.insertBefore(start,span.firstChild)
- }
- span.appendChild(this.endMarker);
- W = this.endMarker.offsetLeft - start.offsetLeft;
- span.removeChild(this.endMarker);
- if (this.initialSkipBug) {span.removeChild(start); span.style.position = position}
- }
- if (H != null) {span.parentNode.HH = H/this.em}
- return W/this.em;
- },
- Measured: function (span,parent) {
- var bbox = span.bbox;
- if (bbox.width == null && bbox.w && !bbox.isMultiline) {
- var w = this.getW(span);
- bbox.rw += w - bbox.w;
- bbox.w = w; bbox.exactW = true;
- }
- if (!parent) {parent = span.parentNode}
- if (!parent.bbox) {parent.bbox = bbox}
- return span;
- },
- Remeasured: function (span,parent) {
- parent.bbox = this.Measured(span,parent).bbox;
- },
- MeasureSpans: function (SPANS) {
- var spans = [], span, i, m, bbox, start, end, W;
- //
- // Insert the needed markers
- //
- for (i = 0, m = SPANS.length; i < m; i++) {
- span = SPANS[i]; if (!span) continue;
- bbox = span.bbox;
- if (bbox.exactW || bbox.width || bbox.w === 0 || bbox.isMultiline) {
- if (!span.parentNode.bbox) {span.parentNode.bbox = bbox}
- continue;
- }
- if (this.negativeBBoxes || !span.firstChild || (bbox.w >= 0 && !this.initialSkipBug) ||
- (bbox.w < 0 && this.msieNegativeBBoxBug)) {
- spans.push([span]);
- } else if (this.initialSkipBug) {
- start = this.startMarker.cloneNode(true); end = this.endMarker.cloneNode(true);
- span.insertBefore(start,span.firstChild); span.appendChild(end);
- spans.push([span,start,end,span.style.position]); span.style.position = "absolute";
- } else {
- end = this.endMarker.cloneNode(true);
- span.appendChild(end); spans.push([span,null,end]);
- }
- }
- //
- // Read the widths and heights
- //
- for (i = 0, m = spans.length; i < m; i++) {
- span = spans[i][0]; bbox = span.bbox; var parent = span.parentNode;
- if ((bbox.w >= 0 && !this.initialSkipBug) || this.negativeBBoxes || !span.firstChild) {
- W = span.offsetWidth; parent.HH = span.parentNode.offsetHeight/this.em;
- } else if (bbox.w < 0 && this.msieNegativeBBoxBug) {
- W = -span.offsetWidth, parent.HH = span.parentNode.offsetHeight/this.em;
- } else {
- W = spans[i][2].offsetLeft - ((spans[i][1]||{}).offsetLeft||0);
- }
- W /= this.em;
- bbox.rw += W - bbox.w;
- bbox.w = W; bbox.exactW = true;
- if (!parent.bbox) {parent.bbox = bbox}
- }
- //
- // Remove markers
- //
- for (i = 0, m = spans.length; i < m; i++) {
- span = spans[i];
- if (span[1]) {span[1].parentNode.removeChild(span[1]), span[0].style.position = span[3]}
- if (span[2]) {span[2].parentNode.removeChild(span[2])}
- }
- },
- Em: function (m) {
- if (Math.abs(m) < .0006) {return "0em"}
- return m.toFixed(3).replace(/\.?0+$/,"") + "em";
- },
- unEm: function (m) {
- return parseFloat(m);
- },
- Px: function (m) {
- m *= this.em; var s = (m < 0? "-" : "");
- return s+Math.abs(m).toFixed(1).replace(/\.?0+$/,"") + "px";
- },
- unPx: function (m) {
- return parseFloat(m)/this.em;
- },
- Percent: function (m) {
- return (100*m).toFixed(1).replace(/\.?0+$/,"") + "%";
- },
- length2em: function (length,mu,size) {
- if (typeof(length) !== "string") {length = length.toString()}
- if (length === "") {return ""}
- if (length === MML.SIZE.NORMAL) {return 1}
- if (length === MML.SIZE.BIG) {return 2}
- if (length === MML.SIZE.SMALL) {return .71}
- if (length === "infinity") {return HTMLCSS.BIGDIMEN}
- var factor = this.FONTDATA.TeX_factor;
- if (length.match(/mathspace$/)) {return HTMLCSS.MATHSPACE[length]*factor}
- var match = length.match(/^\s*([-+]?(?:\.\d+|\d+(?:\.\d*)?))?(pt|em|ex|mu|px|pc|in|mm|cm|%)?/);
- var m = parseFloat(match[1]||"1"), unit = match[2];
- if (size == null) {size = 1}; if (mu == null) {mu = 1}
- if (unit === "em") {return m * factor}
- if (unit === "ex") {return m * HTMLCSS.TeX.x_height * factor}
- if (unit === "%") {return m / 100 * size}
- if (unit === "px") {return m / HTMLCSS.em}
- if (unit === "pt") {return m / 10 * factor} // 10 pt to an em
- if (unit === "pc") {return m * 1.2 * factor} // 12 pt to a pc
- if (unit === "in") {return m * this.pxPerInch / HTMLCSS.em}
- if (unit === "cm") {return m * this.pxPerInch / HTMLCSS.em / 2.54} // 2.54 cm to an inch
- if (unit === "mm") {return m * this.pxPerInch / HTMLCSS.em / 25.4} // 10 mm to a cm
- if (unit === "mu") {return m / 18 * factor * mu} // 18mu to an em for the scriptlevel
- return m*factor*size; // relative to given size (or 1em as default)
- },
- thickness2em: function (length,mu) {
- var thick = HTMLCSS.TeX.rule_thickness;
- if (length === MML.LINETHICKNESS.MEDIUM) {return thick}
- if (length === MML.LINETHICKNESS.THIN) {return .67*thick}
- if (length === MML.LINETHICKNESS.THICK) {return 1.67*thick}
- return this.length2em(length,mu,thick);
- },
-
- getPadding: function (span) {
- var padding = {top:0, right:0, bottom:0, left:0}, has = false;
- for (var id in padding) {if (padding.hasOwnProperty(id)) {
- var pad = span.style["padding"+id.charAt(0).toUpperCase()+id.substr(1)];
- if (pad) {padding[id] = this.length2em(pad); has = true;}
- }}
- return (has ? padding : false);
- },
- getBorders: function (span) {
- var border = {top:0, right:0, bottom:0, left:0}, css = {}, has = false;
- for (var id in border) {if (border.hasOwnProperty(id)) {
- var ID = "border"+id.charAt(0).toUpperCase()+id.substr(1);
- var style = span.style[ID+"Style"];
- if (style) {
- has = true;
- border[id] = this.length2em(span.style[ID+"Width"]);
- css[ID] = [span.style[ID+"Width"],span.style[ID+"Style"],span.style[ID+"Color"]].join(" ");
- }
- }}
- border.css = css;
- return (has ? border : false);
- },
- setBorders: function (span,borders) {
- if (borders) {
- for (var id in borders.css) {if (borders.css.hasOwnProperty(id)) {
- span.style[id] = borders.css[id];
- }}
- }
- },
- createStrut: function (span,h,before) {
- var strut = this.Element("span",{
- isMathJax: true,
- style:{display:"inline-block", overflow:"hidden", height:h+"px",
- width:"1px", marginRight:"-1px"}
- });
- if (before) {span.insertBefore(strut,span.firstChild)} else {span.appendChild(strut)}
- return strut;
- },
- createBlank: function (span,w,before) {
- var blank = this.Element("span",{
- isMathJax: true,
- style: {display:"inline-block", overflow:"hidden", height:"1px", width:this.Em(w)}
- });
- if (before) {span.insertBefore(blank,span.firstChild)} else {span.appendChild(blank)}
- return blank;
- },
- createShift: function (span,w,before) {
- var space = this.Element("span",{style:{marginLeft:this.Em(w)}, isMathJax:true});
- if (before) {span.insertBefore(space,span.firstChild)} else {span.appendChild(space)}
- return space;
- },
- createSpace: function (span,h,d,w,color,isSpace) {
- if (h < -d) {d = -h} // make sure h is above d
- var H = this.Em(h+d), D = this.Em(-d);
- if (this.msieInlineBlockAlignBug) {D = this.Em(HTMLCSS.getHD(span.parentNode).d-d)}
- if (span.isBox || isSpace) {
- var scale = (span.scale == null ? 1 : span.scale);
- span.bbox = {exactW: true, h: h*scale, d: d*scale, w: w*scale, rw: w*scale, lw: 0};
- span.style.height = H; span.style.verticalAlign = D;
- span.HH = (h+d)*scale;
- } else {
- span = this.addElement(span,"span",{style: {height:H, verticalAlign:D}, isMathJax:true});
- }
- if (w >= 0) {
- span.style.width = this.Em(w);
- span.style.display = "inline-block";
- span.style.overflow = "hidden"; // for IE in quirks mode
- } else {
- if (this.msieNegativeSpaceBug) {span.style.height = ""}
- span.style.marginLeft = this.Em(w);
- if (HTMLCSS.safariNegativeSpaceBug && span.parentNode.firstChild == span)
- {this.createBlank(span,0,true)}
- }
- if (color && color !== MML.COLOR.TRANSPARENT) {
- span.style.backgroundColor = color;
- span.style.position = "relative"; // make sure it covers earlier items
- }
- return span;
- },
- createRule: function (span,h,d,w,color) {
- if (h < -d) {d = -h} // make sure h is above d
- var min = HTMLCSS.TeX.min_rule_thickness, f = 1;
- // If rule is very thin, make it at least min_rule_thickness so it doesn't disappear
- if (w > 0 && w*this.em < min) {w = min/this.em}
- if (h+d > 0 && (h+d)*this.em < min) {f = 1/(h+d)*(min/this.em); h *= f; d *= f}
- if (!color) {color = "solid"} else {color = "solid "+color}
- color = this.Em(w)+" "+color;
- var H = (f === 1 ? this.Em(h+d) : min+"px"), D = this.Em(-d);
- var rule = this.addElement(span,"span",{
- style: {borderLeft: color, display: "inline-block", overflow:"hidden",
- width:0, height:H, verticalAlign:D},
- bbox: {h:h, d:d, w:w, rw:w, lw:0, exactW:true}, noAdjust:true, HH:h+d, isMathJax:true
- });
- if (w > 0 && rule.offsetWidth == 0) {rule.style.width = this.Em(w)}
- if (span.isBox || span.className == "mspace") {span.bbox = rule.bbox, span.HH = h+d}
- return rule;
- },
- createFrame: function (span,h,d,w,t,style) {
- if (h < -d) {d = -h} // make sure h is above d
- var T = 2*t;
- if (this.msieFrameSizeBug) {if (w < T) {w = T}; if (h+d < T) {h = T-d}}
- if (this.msieBorderWidthBug) {T = 0}
- var H = this.Em(h+d-T), D = this.Em(-d-t), W = this.Em(w-T);
- var B = this.Em(t)+" "+style;
- var frame = this.addElement(span,"span",{
- style: {border: B, display:"inline-block", overflow:"hidden", width:W, height:H},
- bbox: {h:h, d:d, w:w, rw:w, lw:0, exactW:true}, noAdjust: true, HH:h+d, isMathJax:true
- });
- if (D) {frame.style.verticalAlign = D}
- return frame;
- },
- createStack: function (span,nobbox,w) {
- if (this.msiePaddingWidthBug) {this.createStrut(span,0)}
- var relativeW = String(w).match(/%$/);
- var W = (!relativeW && w != null ? w : 0);
- span = this.addElement(span,"span",{
- noAdjust: true, HH: 0, isMathJax: true,
- style: {display:"inline-block", position:"relative",
- width:(relativeW ? "100%" : this.Em(W)), height:0}
- });
- if (!nobbox) {
- span.parentNode.bbox = span.bbox = {
- exactW: true,
- h: -this.BIGDIMEN, d: -this.BIGDIMEN,
- w:W, lw: this.BIGDIMEN, rw: (!relativeW && w != null ? w : -this.BIGDIMEN)
- };
- if (relativeW) {span.bbox.width = w}
- }
- return span;
- },
- createBox: function (span,w) {
- var box = this.addElement(span,"span",{style:{position:"absolute"}, isBox: true, isMathJax:true});
- if (w != null) {box.style.width = w}
- return box;
- },
- addBox: function (span,box) {
- box.style.position = "absolute"; box.isBox = box.isMathJax = true;
- return span.appendChild(box);
- },
- placeBox: function (span,x,y,noclip) {
- span.isMathJax = true;
- var parent = span.parentNode, bbox = span.bbox, BBOX = parent.bbox;
- if (this.msiePlaceBoxBug) {this.addText(span,this.NBSP)}
- if (this.imgSpaceBug) {this.addText(span,this.imgSpace)}
- // Place the box
- var HH, dx = 0;
- if (span.HH != null) {HH = span.HH}
- else if (bbox) {HH = Math.max(3,bbox.h+bbox.d)}
- else {HH = span.offsetHeight/this.em}
- if (!span.noAdjust) {
- HH += 1;
- HH = Math.round(HH*this.em)/this.em; // make this an integer number of pixels (for Chrome)
- if (this.msieInlineBlockAlignBug) {
- this.addElement(span,"img",{
- className:"MathJax_strut", border:0, src:"about:blank", isMathJax:true,
- style:{width:0,height:this.Em(HH)}
- });
- } else {
- this.addElement(span,"span",{
- isMathJax: true, style:{display:"inline-block",width:0,height:this.Em(HH)}
- });
- if (HTMLCSS.chromeHeightBug)
- {HH -= (span.lastChild.offsetHeight - Math.round(HH*this.em))/this.em}
- }
- }
- // Clip so that bbox doesn't include extra height and depth
- if (bbox) {
- if (this.initialSkipBug) {
- if (bbox.lw < 0) {dx = bbox.lw; HTMLCSS.createBlank(span,-dx,true)}
- if (bbox.rw > bbox.w) {HTMLCSS.createBlank(span,bbox.rw-bbox.w+.1)}
- }
- if (!this.msieClipRectBug && !bbox.noclip && !noclip) {
- var dd = 3/this.em;
- var H = (bbox.H == null ? bbox.h : bbox.H), D = (bbox.D == null ? bbox.d : bbox.D);
- var t = HH - H - dd, b = HH + D + dd, l = bbox.lw - 3*dd, r = 1000;
- if (this.initialSkipBug && bbox.lw < 0) {l = -3*dd}
- if (bbox.isFixed) {r = bbox.width-l}
- span.style.clip = "rect("+this.Em(t)+" "+this.Em(r)+" "+this.Em(b)+" "+this.Em(l)+")";
- }
- }
- // Place the box
- span.style.top = this.Em(-y-HH);
- span.style.left = this.Em(x+dx);
- // Update the bounding box
- if (bbox && BBOX) {
- if (bbox.H != null && (BBOX.H == null || bbox.H + y > BBOX.H)) {BBOX.H = bbox.H + y}
- if (bbox.D != null && (BBOX.D == null || bbox.D - y > BBOX.D)) {BBOX.D = bbox.D - y}
- if (bbox.h + y > BBOX.h) {BBOX.h = bbox.h + y}
- if (bbox.d - y > BBOX.d) {BBOX.d = bbox.d - y}
- if (BBOX.H != null && BBOX.H <= BBOX.h) {delete BBOX.H}
- if (BBOX.D != null && BBOX.D <= BBOX.d) {delete BBOX.D}
- if (bbox.w + x > BBOX.w) {
- BBOX.w = bbox.w + x;
- if (BBOX.width == null) {parent.style.width = this.Em(BBOX.w)}
- }
- if (bbox.rw + x > BBOX.rw) {BBOX.rw = bbox.rw + x}
- if (bbox.lw + x < BBOX.lw) {BBOX.lw = bbox.lw + x}
- if (bbox.width != null && !bbox.isFixed) {
- if (BBOX.width == null) {parent.style.width = BBOX.width = "100%"}
- span.style.width = bbox.width;
- }
- }
- },
- alignBox: function (span,align,y) {
- this.placeBox(span,0,y); // set y position (and left aligned)
- var bbox = span.bbox; if (bbox.isMultiline) return;
- var isRelative = bbox.width != null && !bbox.isFixed;
- var r = 0, c = -bbox.w/2, l = "50%";
- if (this.initialSkipBug) {r = bbox.w-bbox.rw-.1; c += bbox.lw}
- if (this.msieMarginScaleBug) {c = (c*this.em) + "px"} else {c = this.Em(c)}
- if (isRelative) {c = ""; l = (50 - parseFloat(bbox.width)/2) + "%"}
- HUB.Insert(span.style,({
- right: {left:"", right: this.Em(r)},
- center: {left:l, marginLeft: c}
- })[align]);
- },
- setStackWidth: function (span,w) {
- if (typeof(w) === "number") {
- span.style.width = this.Em(Math.max(0,w));
- var bbox = span.bbox; if (bbox) {bbox.w = w; bbox.exactW = true};
- bbox = span.parentNode.bbox; if (bbox) {bbox.w = w; bbox.exactW = true};
- } else {
- span.style.width = span.parentNode.style.width = "100%";
- if (span.bbox) {span.bbox.width = w}
- if (span.parentNode.bbox) {span.parentNode.bbox.width = w}
- }
- },
- createDelimiter: function (span,code,HW,scale,font) {
- if (!code) {
- span.bbox = {h:0, d:0, w:this.TeX.nulldelimiterspace, lw: 0};
- span.bbox.rw = span.bbox.w;
- this.createSpace(span,span.bbox.h,span.bbox.d,span.bbox.w);
- return;
- }
- if (!scale) {scale = 1};
- if (!(HW instanceof Array)) {HW = [HW,HW]}
- var hw = HW[1]; HW = HW[0];
- var delim = {alias: code};
- while (delim.alias) {
- code = delim.alias; delim = this.FONTDATA.DELIMITERS[code];
- if (!delim) {delim = {HW: [0,this.FONTDATA.VARIANT[MML.VARIANT.NORMAL]]}}
- }
- if (delim.load) {HUB.RestartAfter(AJAX.Require(this.fontDir+"/fontdata-"+delim.load+".js"))}
- for (var i = 0, m = delim.HW.length; i < m; i++) {
- if (delim.HW[i][0]*scale >= HW-.01 || (i == m-1 && !delim.stretch)) {
- if (delim.HW[i][2]) {scale *= delim.HW[i][2]}
- if (delim.HW[i][3]) {code = delim.HW[i][3]}
- var chr = this.addElement(span,"span");
- this.createChar(chr,[code,delim.HW[i][1]],scale,font);
- span.bbox = chr.bbox;
- span.offset = .65 * span.bbox.w;
- span.scale = scale;
- return;
- }
- }
- if (delim.stretch) {this["extendDelimiter"+delim.dir](span,hw,delim.stretch,scale,font)}
- },
- extendDelimiterV: function (span,H,delim,scale,font) {
- var stack = this.createStack(span,true);
- var top = this.createBox(stack), bot = this.createBox(stack);
- this.createChar(top,(delim.top||delim.ext),scale,font);
- this.createChar(bot,(delim.bot||delim.ext),scale,font);
- var ext = {bbox:{w:0,lw:0,rw:0}}, mid = ext, EXT;
- var h = top.bbox.h + top.bbox.d + bot.bbox.h + bot.bbox.d;
- var y = -top.bbox.h; this.placeBox(top,0,y,true); y -= top.bbox.d;
- if (delim.mid) {
- mid = this.createBox(stack); this.createChar(mid,delim.mid,scale,font);
- h += mid.bbox.h + mid.bbox.d;
- }
- if (delim.min && H < h*delim.min) {H = h*delim.min}
- if (H > h) {
- ext = this.Element("span"); this.createChar(ext,delim.ext,scale,font);
- var eH = ext.bbox.h + ext.bbox.d, eh = eH - .05, n, N, k = (delim.mid ? 2 : 1);
- N = n = Math.ceil((H-h)/(k*eh));
- if (!delim.fullExtenders) {eh = (H-h)/(k*n)}
- var dy = (n/(n+1))*(eH - eh); eh = eH - dy; y += dy + eh - ext.bbox.h;
- while (k-- > 0) {
- while (n-- > 0) {
- if (!this.msieCloneNodeBug) {EXT = ext.cloneNode(true)}
- else {EXT = this.Element("span"); this.createChar(EXT,delim.ext,scale,font)}
- EXT.bbox = ext.bbox;
- y -= eh; this.placeBox(this.addBox(stack,EXT),0,y,true);
- }
- y += dy - ext.bbox.d;
- if (delim.mid && k) {
- this.placeBox(mid,0,y-mid.bbox.h,true); n = N;
- y += -(mid.bbox.h + mid.bbox.d) + dy + eh - ext.bbox.h;
- }
- }
- } else {
- y += (h - H)/2;
- if (delim.mid) {this.placeBox(mid,0,y-mid.bbox.h,true); y += -(mid.bbox.h + mid.bbox.d)}
- y += (h - H)/2;
- }
- this.placeBox(bot,0,y-bot.bbox.h,true); y -= bot.bbox.h + bot.bbox.d;
- span.bbox = {
- w: Math.max(top.bbox.w,ext.bbox.w,bot.bbox.w,mid.bbox.w),
- lw: Math.min(top.bbox.lw,ext.bbox.lw,bot.bbox.lw,mid.bbox.lw),
- rw: Math.max(top.bbox.rw,ext.bbox.rw,bot.bbox.rw,mid.bbox.rw),
- h: 0, d: -y, exactW: true
- }
- span.scale = scale;
- span.offset = .55 * span.bbox.w;
- span.isMultiChar = true;
- this.setStackWidth(stack,span.bbox.w);
- },
- extendDelimiterH: function (span,W,delim,scale,font) {
- var stack = this.createStack(span,true);
- var left = this.createBox(stack), right = this.createBox(stack);
- this.createChar(left,(delim.left||delim.rep),scale,font);
- this.createChar(right,(delim.right||delim.rep),scale,font);
- var rep = this.Element("span"); this.createChar(rep,delim.rep,scale,font);
- var mid = {bbox: {h:-this.BIGDIMEN, d:-this.BIGDIMEN}}, REP;
- this.placeBox(left,-left.bbox.lw,0,true);
- var w = (…
Large files files are truncated, but you can click here to view the full file