Fix multiple problems with indentshift and indentalign in HTML-CSS and SVG output. (Negative values not handled properly, shift not applied to centering, SVG not handling shift past edges well, percentage shifts now in relation to container, etc.) Resolves issues #769 and #768.

This commit is contained in:
Davide P. Cervone 2014-09-09 10:28:25 -04:00
parent 82d0ea22c2
commit ea42f427f6
8 changed files with 111 additions and 84 deletions

View File

@ -169,7 +169,9 @@ MathJax.Hub.Config({
// These two parameters control the alignment and shifting of displayed equations. // These two parameters control the alignment and shifting of displayed equations.
// The first can be "left", "center", or "right", and determines the alignment of // The first can be "left", "center", or "right", and determines the alignment of
// displayed equations. When the alignment is not "center", the second determines // displayed equations. When the alignment is not "center", the second determines
// an indentation from the left or right side for the displayed equations. // an indentation from the left or right side for the displayed equations. When
// the alignment is "center", the indent allows you to shift the center to the right
// or left (negative is left).
// //
displayAlign: "center", displayAlign: "center",
displayIndent: "0em", displayIndent: "0em",

View File

@ -421,28 +421,30 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
// Place the labels, if any // Place the labels, if any
// //
if (C[LABEL]) { if (C[LABEL]) {
var mw = stack.bbox.w, dw; var mw = stack.bbox.w;
var indent = this.getValues("indentalignfirst","indentshiftfirst","indentalign","indentshift"); var indent = this.getValues("indentalignfirst","indentshiftfirst","indentalign","indentshift");
if (indent.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {indent.indentalign = indent.indentalignfirst} if (indent.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {indent.indentalign = indent.indentalignfirst}
if (indent.indentalign === MML.INDENTALIGN.AUTO) {indent.indentalign = this.displayAlign} if (indent.indentalign === MML.INDENTALIGN.AUTO) {indent.indentalign = this.displayAlign}
if (indent.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {indent.indentshift = indent.indentshiftfirst} if (indent.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {indent.indentshift = indent.indentshiftfirst}
if (indent.indentshift === "auto") {indent.indentshift = this.displayIndent} if (indent.indentshift === "auto") {indent.indentshift = "0"}
var shift = HTMLCSS.length2em(indent.indentshift,mu,HTMLCSS.cwidth);
var labelshift = HTMLCSS.length2em(values.minlabelspacing,mu,HTMLCSS.cwidth);
if (this.displayIndent !== "0") {
var indent = HTMLCSS.length2em(this.displayIndent,mu,HTMLCSS.cwidth);
shift += (indent.indentAlign === MML.INDENTALIGN.RIGHT ? -indent: indent);
}
var eqn = HTMLCSS.createStack(span,false,"100%"); var eqn = HTMLCSS.createStack(span,false,"100%");
HTMLCSS.addBox(eqn,stack); HTMLCSS.alignBox(stack,indent.indentalign,0); HTMLCSS.addBox(eqn,stack); HTMLCSS.alignBox(stack,indent.indentalign,0,shift);
if (indent.indentshift && indent.indentalign !== MML.INDENTALIGN.CENTER) {
dw = HTMLCSS.length2em(indent.indentshift,mu); mw += dw;
stack.style[indent.indentalign] = HTMLCSS.Em(dw);
}
C[LABEL].parentNode.parentNode.removeChild(C[LABEL].parentNode); C[LABEL].parentNode.parentNode.removeChild(C[LABEL].parentNode);
HTMLCSS.addBox(eqn,C[LABEL]); HTMLCSS.alignBox(C[LABEL],CALIGN[LABEL],0); HTMLCSS.addBox(eqn,C[LABEL]); HTMLCSS.alignBox(C[LABEL],CALIGN[LABEL],0);
if (HTMLCSS.msieRelativeWidthBug) {stack.style.top = C[LABEL].style.top = ""} if (HTMLCSS.msieRelativeWidthBug) {stack.style.top = C[LABEL].style.top = ""}
if (hasRelativeWidth) {stack.style.width = values.width; span.bbox.width = "100%"} if (hasRelativeWidth) {stack.style.width = values.width; span.bbox.width = "100%"}
dw = HTMLCSS.length2em(values.minlabelspacing,mu); C[LABEL].style.marginRight = C[LABEL].style.marginLeft = HTMLCSS.Em(labelshift);
C[LABEL].style.marginRight = C[LABEL].style.marginLeft = HTMLCSS.Em(dw); if (indent.indentalign === MML.INDENTALIGN.CENTER) {mw += 4*labelshift + 2*C[LABEL].bbox.w}
if (indent.indentalign === MML.INDENTALIGN.CENTER) {mw += 4*dw + 2*C[LABEL].bbox.w} else if (indent.indentalign !== CALIGN[LABEL]) {mw += 2*labelshift + C[LABEL].bbox.w}
else if (indent.indentalign !== CALIGN[LABEL]) {mw += 2*dw + C[LABEL].bbox.w}
span.style.minWidth = span.bbox.minWidth = span.style.minWidth = span.bbox.minWidth =
eqn.style.minWidth = eqn.bbox.minWidth = HTMLCSS.Em(mw); eqn.style.minWidth = eqn.bbox.minWidth = HTMLCSS.Em(Math.max(0,mw+shift));
} }
// //
// Finish the table // Finish the table

View File

@ -209,13 +209,6 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
var align = this.HTMLgetAlign(state,values), var align = this.HTMLgetAlign(state,values),
shift = this.HTMLgetShift(state,values,align); shift = this.HTMLgetShift(state,values,align);
// //
// Add in space for the shift
//
if (shift) {
HTMLCSS.createBlank(line,shift,(align !== MML.INDENTALIGN.RIGHT));
line.bbox.w += shift; line.bbox.rw += shift;
}
//
// Set the Y offset based on previous depth, leading, and current height // Set the Y offset based on previous depth, leading, and current height
// //
if (state.n > 0) { if (state.n > 0) {
@ -226,7 +219,7 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
// //
// Place the new line // Place the new line
// //
HTMLCSS.alignBox(line,align,state.Y); HTMLCSS.alignBox(line,align,state.Y,shift);
// //
// Save the values needed for the future // Save the values needed for the future
// //
@ -247,14 +240,18 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
return align; return align;
}, },
HTMLgetShift: function (state,values,align) { HTMLgetShift: function (state,values,align) {
if (align === MML.INDENTALIGN.CENTER) {return 0}
var cur = values, prev = state.values, def = state.VALUES, shift; var cur = values, prev = state.values, def = state.VALUES, shift;
if (state.n === 0) {shift = cur.indentshiftfirst || prev.indentshiftfirst || def.indentshiftfirst} if (state.n === 0) {shift = cur.indentshiftfirst || prev.indentshiftfirst || def.indentshiftfirst}
else if (state.isLast) {shift = prev.indentshiftlast || def.indentshiftlast} else if (state.isLast) {shift = prev.indentshiftlast || def.indentshiftlast}
else {shift = prev.indentshift || def.indentshift} else {shift = prev.indentshift || def.indentshift}
if (shift === MML.INDENTSHIFT.INDENTSHIFT) {shift = prev.indentshift || def.indentshift} if (shift === MML.INDENTSHIFT.INDENTSHIFT) {shift = prev.indentshift || def.indentshift}
if (shift === "auto" || shift === "") {shift = (state.isTSop ? this.displayIndent : "0")} if (shift === "auto" || shift === "") {shift = "0"}
return HTMLCSS.length2em(shift,0); shift = HTMLCSS.length2em(shift,1,HTMLCSS.cwidth);
if (state.isTop && this.displayIndent !== "0") {
var indent = HTMLCSS.length2em(this.displayIndent,1,HTMLCSS.cwidth);
shift += (align === MML.INDENTALIGN.RIGHT ? -indent : indent);
}
return shift;
}, },
/****************************************************************/ /****************************************************************/
@ -692,7 +689,7 @@ MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
// //
if (penalty >= info.penalty) {return false} if (penalty >= info.penalty) {return false}
info.penalty = penalty; info.values = values; info.W = W; info.w = w; info.penalty = penalty; info.values = values; info.W = W; info.w = w;
values.lineleading = HTMLCSS.length2em(values.lineleading,state.VALUES.lineleading); values.lineleading = HTMLCSS.length2em(values.lineleading,1,state.VALUES.lineleading);
values.id = this.spanID; values.id = this.spanID;
return true; return true;
} }

View File

@ -543,7 +543,7 @@
preTranslate: function (state) { preTranslate: function (state) {
var scripts = state.jax[this.id], i, m = scripts.length, var scripts = state.jax[this.id], i, m = scripts.length,
script, prev, span, div, test, jax, ex, em, scale, maxwidth, relwidth = false, script, prev, span, div, test, jax, ex, em, scale, maxwidth, relwidth = false, cwidth,
linebreak = this.config.linebreaks.automatic, width = this.config.linebreaks.width; linebreak = this.config.linebreaks.automatic, width = this.config.linebreaks.width;
if (linebreak) { if (linebreak) {
relwidth = (width.match(/^\s*(\d+(\.\d*)?%\s*)?container\s*$/) != null); relwidth = (width.match(/^\s*(\d+(\.\d*)?%\s*)?container\s*$/) != null);
@ -593,7 +593,7 @@
// Add the test span for determining scales and linebreak widths // Add the test span for determining scales and linebreak widths
// //
script.parentNode.insertBefore(this.EmExSpan.cloneNode(true),script); script.parentNode.insertBefore(this.EmExSpan.cloneNode(true),script);
if (relwidth) {div.parentNode.insertBefore(this.linebreakSpan.cloneNode(true),div)} div.parentNode.insertBefore(this.linebreakSpan.cloneNode(true),div)
} }
// //
// Determine the scaling factors for each script // Determine the scaling factors for each script
@ -605,19 +605,21 @@
jax = script.MathJax.elementJax; if (!jax) continue; jax = script.MathJax.elementJax; if (!jax) continue;
ex = test.firstChild.offsetHeight/60; ex = test.firstChild.offsetHeight/60;
em = test.lastChild.firstChild.offsetHeight/60; em = test.lastChild.firstChild.offsetHeight/60;
if (relwidth) {maxwidth = div.previousSibling.firstChild.offsetWidth} cwidth = div.previousSibling.firstChild.offsetWidth;
if (relwidth) {maxwidth = cwidth}
if (ex === 0 || ex === "NaN") { if (ex === 0 || ex === "NaN") {
// can't read width, so move to hidden div for processing // can't read width, so move to hidden div for processing
// (this will cause a reflow for each math element that is hidden) // (this will cause a reflow for each math element that is hidden)
this.hiddenDiv.appendChild(div); this.hiddenDiv.appendChild(div);
jax.HTMLCSS.isHidden = true; jax.HTMLCSS.isHidden = true;
ex = this.defaultEx; em = this.defaultEm; ex = this.defaultEx; em = this.defaultEm; cwidth = this.defaultWidth;
if (relwidth) {maxwidth = this.defaultWidth} if (relwidth) {maxwidth = cwidth}
} }
scale = (this.config.matchFontHeight ? ex/this.TeX.x_height/em : 1); scale = (this.config.matchFontHeight ? ex/this.TeX.x_height/em : 1);
scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale)*this.config.scale); scale = Math.floor(Math.max(this.config.minScaleAdjust/100,scale)*this.config.scale);
jax.HTMLCSS.scale = scale/100; jax.HTMLCSS.fontSize = 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.em = jax.HTMLCSS.outerEm = em; this.em = em * scale/100; jax.HTMLCSS.ex = ex;
jax.HTMLCSS.cwidth = cwidth/this.em;
jax.HTMLCSS.lineWidth = (linebreak ? this.length2em(width,1,maxwidth/this.em) : 1000000); jax.HTMLCSS.lineWidth = (linebreak ? this.length2em(width,1,maxwidth/this.em) : 1000000);
} }
// //
@ -627,11 +629,9 @@
script = scripts[i]; if (!script.parentNode) continue; script = scripts[i]; if (!script.parentNode) continue;
test = scripts[i].previousSibling; test = scripts[i].previousSibling;
jax = scripts[i].MathJax.elementJax; if (!jax) continue; jax = scripts[i].MathJax.elementJax; if (!jax) continue;
if (relwidth) { span = test.previousSibling;
span = test.previousSibling; if (!jax.HTMLCSS.isHidden) {span = span.previousSibling}
if (!jax.HTMLCSS.isHidden) {span = span.previousSibling} span.parentNode.removeChild(span);
span.parentNode.removeChild(span);
}
test.parentNode.removeChild(test); test.parentNode.removeChild(test);
} }
// //
@ -665,6 +665,7 @@
// //
this.em = MML.mbase.prototype.em = jax.HTMLCSS.em * jax.HTMLCSS.scale; this.em = MML.mbase.prototype.em = jax.HTMLCSS.em * jax.HTMLCSS.scale;
this.outerEm = jax.HTMLCSS.em; this.scale = jax.HTMLCSS.scale; this.outerEm = jax.HTMLCSS.em; this.scale = jax.HTMLCSS.scale;
this.cwidth = jax.HTMLCSS.cwidth;
this.linebreakWidth = jax.HTMLCSS.lineWidth; this.linebreakWidth = jax.HTMLCSS.lineWidth;
if (this.scale !== 1) {span.style.fontSize = jax.HTMLCSS.fontSize} if (this.scale !== 1) {span.style.fontSize = jax.HTMLCSS.fontSize}
// //
@ -1029,6 +1030,7 @@
isMathJax: true, isMathJax: true,
style: {display:"inline-block", overflow:"hidden", height:"1px", width:this.Em(w)} style: {display:"inline-block", overflow:"hidden", height:"1px", width:this.Em(w)}
}); });
if (w < 0) {blank.style.marginRight = blank.style.width; blank.style.width = 0}
if (before) {span.insertBefore(blank,span.firstChild)} else {span.appendChild(blank)} if (before) {span.insertBefore(blank,span.firstChild)} else {span.appendChild(blank)}
return blank; return blank;
}, },
@ -1203,8 +1205,9 @@
} }
} }
}, },
alignBox: function (span,align,y) { alignBox: function (span,align,y,dx) {
this.placeBox(span,0,y); // set y position (and left aligned) if (dx == null) {dx = 0}
this.placeBox(span,dx,y); // set y position (and left aligned)
if (this.msiePlaceBoxBug) { if (this.msiePlaceBoxBug) {
// //
// placeBox() adds an extra &nbsp;, so remove it here. // placeBox() adds an extra &nbsp;, so remove it here.
@ -1215,12 +1218,15 @@
} }
var bbox = span.bbox; if (bbox.isMultiline) return; var bbox = span.bbox; if (bbox.isMultiline) return;
var isRelative = bbox.width != null && !bbox.isFixed; var isRelative = bbox.width != null && !bbox.isFixed;
var r = 0, c = -bbox.w/2, l = "50%"; var r = 0, c = dx-bbox.w/2, l = "50%";
if (this.initialSkipBug) {r = bbox.w-bbox.rw-.1; c += bbox.lw} 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 (this.msieMarginScaleBug) {c = (c*this.em) + "px"} else {c = this.Em(c)}
if (isRelative) {c = ""; l = (50 - parseFloat(bbox.width)/2) + "%"} if (isRelative) {
c = (dx === 0 ? "" : this.Em(dx));
l = (50 - parseFloat(bbox.width)/2) + "%";
}
HUB.Insert(span.style,({ HUB.Insert(span.style,({
right: {left:"", right: this.Em(r)}, right: {left:"", right: this.Em(r-dx)},
center: {left:l, marginLeft: c} center: {left:l, marginLeft: c}
})[align]); })[align]);
}, },
@ -2812,13 +2818,23 @@
var values = this.getValues("indentalignfirst","indentshiftfirst","indentalign","indentshift"); var values = this.getValues("indentalignfirst","indentshiftfirst","indentalign","indentshift");
if (values.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {values.indentalign = values.indentalignfirst} if (values.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {values.indentalign = values.indentalignfirst}
if (values.indentalign === MML.INDENTALIGN.AUTO) {values.indentalign = this.displayAlign} if (values.indentalign === MML.INDENTALIGN.AUTO) {values.indentalign = this.displayAlign}
node.style.textAlign = values.indentalign;
if (values.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {values.indentshift = values.indentshiftfirst} if (values.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {values.indentshift = values.indentshiftfirst}
if (values.indentshift === "auto") {values.indentshift = this.displayIndent} if (values.indentshift === "auto") {values.indentshift = "0"}
if (values.indentshift && values.indentalign !== MML.INDENTALIGN.CENTER) { var shift = HTMLCSS.length2em(values.indentshift,1,HTMLCSS.cwidth);
span.style[{left:"marginLeft",right:"marginRight"}[values.indentalign]] = if (this.displayIndent !== "0") {
HTMLCSS.Em(HTMLCSS.length2em(values.indentshift)); var indent = HTMLCSS.length2em(this.displayIndent,1,HTMLCSS.cwidth);
} shift += (values.indentalign === MML.INDENTALIGN.RIGHT ? -indent : indent);
}
node.style.textAlign = values.indentalign;
// ### FIXME: make percentage widths respond to changes in container
if (shift) {
shift *= HTMLCSS.scale * HTMLCSS.em/HTMLCSS.outerEm;
HUB.Insert(span.style,({
left: {marginLeft: HTMLCSS.Em(shift)},
right: {marginLeft: HTMLCSS.Em(Math.max(0,span.bbox.w+shift)), marginRight: HTMLCSS.Em(-shift)},
center: {marginLeft: HTMLCSS.Em(shift), marginRight: HTMLCSS.Em(-shift)}
})[values.indentalign]);
}
} }
return span; return span;
}, },
@ -2862,7 +2878,7 @@
// We also need to wait for the onload handler to run, since the loadComplete // We also need to wait for the onload handler to run, since the loadComplete
// will call Config and Startup, which need to modify the body. // will call Config and Startup, which need to modify the body.
// //
MathJax.Hub.Register.StartupHook("onLoad",function () { HUB.Register.StartupHook("onLoad",function () {
setTimeout(MathJax.Callback(["loadComplete",HTMLCSS,"jax.js"]),0); setTimeout(MathJax.Callback(["loadComplete",HTMLCSS,"jax.js"]),0);
}); });
}); });

View File

@ -159,7 +159,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
var math = this; while (math.type !== "math") {math = math.inherit} var math = this; while (math.type !== "math") {math = math.inherit}
var jax = MathJax.Hub.getJaxFor(math.inputID); var jax = MathJax.Hub.getJaxFor(math.inputID);
this.em = MML.mbase.prototype.em = jax.SVG.em; this.ex = jax.SVG.ex; this.em = MML.mbase.prototype.em = jax.SVG.em; this.ex = jax.SVG.ex;
this.linebreakWidth = jax.SVG.lineWidth * 1000; this.cwidth = jax.SVG.cwidth; this.linebreakWidth = jax.SVG.lineWidth; this.cwidth = jax.SVG.cwidth;
// //
// Make a new math element and temporarily move the tooltip to it // Make a new math element and temporarily move the tooltip to it

View File

@ -41,7 +41,8 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
"align","useHeight","width","side","minlabelspacing"); "align","useHeight","width","side","minlabelspacing");
// Handle relative width as fixed width in relation to container // Handle relative width as fixed width in relation to container
if (values.width.match(/%$/)) if (values.width.match(/%$/))
{svg.width = values.width = Math.floor(SVG.cwidth*parseFloat(values.width)/100)+"px"} {svg.width = values.width = SVG.Em((SVG.cwidth/1000)*(parseFloat(values.width)/100))}
var mu = this.SVGgetMu(svg); var mu = this.SVGgetMu(svg);
var LABEL = -1; var LABEL = -1;
@ -327,21 +328,18 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
if (indent.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {indent.indentalign = indent.indentalignfirst} if (indent.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {indent.indentalign = indent.indentalignfirst}
if (indent.indentalign === MML.INDENTALIGN.AUTO) {indent.indentalign = this.displayAlign} if (indent.indentalign === MML.INDENTALIGN.AUTO) {indent.indentalign = this.displayAlign}
if (indent.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {indent.indentshift = indent.indentshiftfirst} if (indent.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {indent.indentshift = indent.indentshiftfirst}
if (indent.indentshift === "auto") {indent.indentshift = this.displayIndent} if (indent.indentshift === "auto" || indent.indentshift === "") {indent.indentshift = "0"}
var shift = (indent.indentshift ? SVG.length2em(indent.indentshift,mu) : 0); var shift = SVG.length2em(indent.indentshift,mu,SVG.cwidth);
var labelshift = SVG.length2em(values.minlabelspacing,mu); var labelshift = SVG.length2em(values.minlabelspacing,mu,SVG.cwidth);
var eqn = svg; svg = this.SVG(); if (this.displayIndent !== "0") {
if (indent.indentalign === MML.INDENTALIGN.CENTER) { var indent = SVG.length2em(this.displayIndent,mu,SVG.cwidth);
svg.w = svg.r = SVG.length2em(SVG.cwidth+"px"); shift = 0; svg.hasIndent = true; shift += (indent.indentAlign === MML.INDENTALIGN.RIGHT ? -indent: indent);
} else if (CALIGN[LABEL] !== indent.indentalign) {
svg.w = svg.r = SVG.length2em(SVG.cwidth+"px") - shift - labelshift;
shift = labelshift = 0;
} else {
svg.w = svg.r = eqn.w + shift;
svg.hasIndent = true;
} }
svg.Align(eqn,indent.indentalign,shift,0); var eqn = svg; svg = this.SVG();
eqn.x = shift; svg.w = svg.r = SVG.cwidth; svg.hasIndent = true;
svg.Align(C[LABEL],CALIGN[LABEL],labelshift,0); svg.Align(C[LABEL],CALIGN[LABEL],labelshift,0);
svg.Align(eqn,indent.indentalign,0,0);
svg.w = SVG.cwidth; // in case the equation extends past the right
} }
this.SVGsaveData(svg); this.SVGsaveData(svg);

View File

@ -91,7 +91,8 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
svg = this.SVG(); svg = this.SVG();
if (isTop && parent.type !== "mtd") { if (isTop && parent.type !== "mtd") {
if (SVG.linebreakWidth < SVG.BIGDIMEN) {svg.w = SVG.linebreakWidth} if (SVG.linebreakWidth < SVG.BIGDIMEN) {svg.w = SVG.linebreakWidth}
else {svg.w = SVG.cwidth/SVG.em * 1000} else {svg.w = SVG.cwidth}
svg.lw = svg.w;
} }
var state = { var state = {
@ -213,10 +214,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
// //
// Add in space for the shift // Add in space for the shift
// //
if (shift) { line.x = shift;
if (align === MML.INDENTALIGN.LEFT) {line.x = shift} else
if (align === MML.INDENTALIGN.RIGHT) {line.w += shift; line.r = line.w}
}
// //
// Set the Y offset based on previous depth, leading, and current height // Set the Y offset based on previous depth, leading, and current height
// //
@ -229,6 +227,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
// Place the new line // Place the new line
// //
svg.Align(line,align,0,state.Y); svg.Align(line,align,0,state.Y);
svg.w = svg.lw; // in case a line extends past the right
// //
// Save the values needed for the future // Save the values needed for the future
// //
@ -249,14 +248,18 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
return align; return align;
}, },
SVGgetShift: function (state,values,align) { SVGgetShift: function (state,values,align) {
if (align === MML.INDENTALIGN.CENTER) {return 0}
var cur = values, prev = state.values, def = state.VALUES, shift; var cur = values, prev = state.values, def = state.VALUES, shift;
if (state.n === 0) {shift = cur.indentshiftfirst || prev.indentshiftfirst || def.indentshiftfirst} if (state.n === 0) {shift = cur.indentshiftfirst || prev.indentshiftfirst || def.indentshiftfirst}
else if (state.isLast) {shift = prev.indentshiftlast || def.indentshiftlast} else if (state.isLast) {shift = prev.indentshiftlast || def.indentshiftlast}
else {shift = prev.indentshift || def.indentshift} else {shift = prev.indentshift || def.indentshift}
if (shift === MML.INDENTSHIFT.INDENTSHIFT) {shift = prev.indentshift || def.indentshift} if (shift === MML.INDENTSHIFT.INDENTSHIFT) {shift = prev.indentshift || def.indentshift}
if (shift === "auto" || shift === "") {shift = (state.isTSop ? this.displayIndent : "0")} if (shift === "auto" || shift === "") {shift = "0"}
return SVG.length2em(shift,0); shift = SVG.length2em(shift,1,SVG.cwidth);
if (state.isTop && this.displayIndent !== "0") {
var indent = SVG.length2em(this.displayIndent,1,SVG.cwidth);
shift += (align === MML.INDENTALIGN.RIGHT ? -indent: indent);
}
return shift;
}, },
/****************************************************************/ /****************************************************************/
@ -617,7 +620,7 @@ MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
// //
if (penalty >= info.penalty) {return false} if (penalty >= info.penalty) {return false}
info.penalty = penalty; info.values = values; info.W = W; info.w = w; info.penalty = penalty; info.values = values; info.W = W; info.w = w;
values.lineleading = SVG.length2em(values.lineleading,state.VALUES.lineleading); values.lineleading = SVG.length2em(values.lineleading,1,state.VALUES.lineleading);
values.last = this; values.last = this;
return true; return true;
} }

View File

@ -257,11 +257,12 @@
this.hiddenDiv.appendChild(div); this.hiddenDiv.appendChild(div);
jax.SVG.isHidden = true; jax.SVG.isHidden = true;
ex = this.defaultEx; cwidth = this.defaultWidth; ex = this.defaultEx; cwidth = this.defaultWidth;
if (relwidth) {maxwidth = this.defaultWidth} if (relwidth) {maxwidth = cwidth}
} }
jax.SVG.ex = ex; jax.SVG.cwidth = cwidth; jax.SVG.ex = ex;
jax.SVG.em = em = ex / SVG.TeX.x_height * 1000; // scale ex to x_height jax.SVG.em = em = ex / SVG.TeX.x_height * 1000; // scale ex to x_height
jax.SVG.lineWidth = (linebreak ? this.length2em(width,1,maxwidth/em) : 1000000); jax.SVG.cwidth = cwidth/em * 1000;
jax.SVG.lineWidth = (linebreak ? this.length2em(width,1,maxwidth/em*1000) : SVG.BIGDIMEN);
} }
// //
// Remove the test spans used for determining scales and linebreak widths // Remove the test spans used for determining scales and linebreak widths
@ -305,7 +306,7 @@
// Set the font metrics // Set the font metrics
// //
this.em = MML.mbase.prototype.em = jax.SVG.em; this.ex = jax.SVG.ex; this.em = MML.mbase.prototype.em = jax.SVG.em; this.ex = jax.SVG.ex;
this.linebreakWidth = jax.SVG.lineWidth * 1000; this.cwidth = jax.SVG.cwidth; this.linebreakWidth = jax.SVG.lineWidth; this.cwidth = jax.SVG.cwidth;
// //
// Typeset the math // Typeset the math
// //
@ -431,7 +432,7 @@
var emex = span.appendChild(this.ExSpan.cloneNode(true)); var emex = span.appendChild(this.ExSpan.cloneNode(true));
var ex = emex.firstChild.offsetHeight/60; var ex = emex.firstChild.offsetHeight/60;
this.em = MML.mbase.prototype.em = ex / SVG.TeX.x_height * 1000; this.em = MML.mbase.prototype.em = ex / SVG.TeX.x_height * 1000;
this.cwidth = .85*SVG.defaultWidth; this.cwidth = .85*SVG.defaultWidth/this.em * 1000;
emex.parentNode.removeChild(emex); emex.parentNode.removeChild(emex);
span.appendChild(this.textSVG); span.appendChild(this.textSVG);
@ -2044,7 +2045,7 @@
style.marginLeft = SVG.Ex(-l); style.marginRight = SVG.Ex(-r); style.marginLeft = SVG.Ex(-l); style.marginRight = SVG.Ex(-r);
svg.element.setAttribute("viewBox",SVG.Fixed(-l,1)+" "+SVG.Fixed(-svg.H-SVG.em,1)+" "+ svg.element.setAttribute("viewBox",SVG.Fixed(-l,1)+" "+SVG.Fixed(-svg.H-SVG.em,1)+" "+
SVG.Fixed(l+svg.w+r,1)+" "+SVG.Fixed(svg.H+svg.D+2*SVG.em,1)); SVG.Fixed(l+svg.w+r,1)+" "+SVG.Fixed(svg.H+svg.D+2*SVG.em,1));
svg.element.style.margin="1px 0px"; // 1px above and below to prevent lines from touching style.marginTop = style.marginBottom = "1px"; // 1px above and below to prevent lines from touching
// //
// If there is extra height or depth, hide that // If there is extra height or depth, hide that
// //
@ -2060,17 +2061,25 @@
// //
// Handle indentalign and indentshift for single-line displays // Handle indentalign and indentshift for single-line displays
// //
if (!this.isMultiline && this.Get("display") === "block") { if (!this.isMultiline && this.Get("display") === "block" && !svg.hasIndent) {
var values = this.getValues("indentalignfirst","indentshiftfirst","indentalign","indentshift"); var values = this.getValues("indentalignfirst","indentshiftfirst","indentalign","indentshift");
if (values.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {values.indentalign = values.indentalignfirst} if (values.indentalignfirst !== MML.INDENTALIGN.INDENTALIGN) {values.indentalign = values.indentalignfirst}
if (values.indentalign === MML.INDENTALIGN.AUTO) {values.indentalign = this.displayAlign} if (values.indentalign === MML.INDENTALIGN.AUTO) {values.indentalign = this.displayAlign}
div.style.textAlign = values.indentalign;
if (values.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {values.indentshift = values.indentshiftfirst} if (values.indentshiftfirst !== MML.INDENTSHIFT.INDENTSHIFT) {values.indentshift = values.indentshiftfirst}
if (values.indentshift === "auto") {values.indentshift = this.displayIndent} if (values.indentshift === "auto") {values.indentshift = "0"}
if (values.indentshift && values.indentalign !== MML.INDENTALIGN.CENTER && !svg.hasIndent) { var shift = SVG.length2em(values.indentshift,1,SVG.cwidth);
span.style[{left:"marginLeft",right:"marginRight"}[values.indentalign]] = if (this.displayIndent !== "0") {
SVG.Ex(SVG.length2em(values.indentshift)); var indent = SVG.length2em(this.displayIndent,1,SVG.cwidth);
} shift += (values.indentalign === MML.INDENTALIGN.RIGHT ? -indent : indent);
}
div.style.textAlign = values.indentalign;
if (shift) {
HUB.Insert(style,({
left: {marginLeft: SVG.Ex(shift)},
right: {marginRight: SVG.Ex(-shift)},
center: {marginLeft: SVG.Ex(shift), marginRight: SVG.Ex(-shift)}
})[values.indentalign]);
}
} }
} }
return span; return span;