commit 29b00ee6b7bfa02ae57e47b57167f339f8bb8bda
parent 403dca64ab2f3379286032e7c7d44dd6160756e1
Author: Emily Eisenberg <emily@khanacademy.org>
Date: Fri, 12 Sep 2014 14:41:31 -0700
Add vlist builder for more consistent stacking
Summary:
Add a way to automatically build vlists correctly. Previously, we built
vlists manually in ~4 different places, which made it difficult to manage
changes, and led to a large amount of duplication in the less. This also fixes
the vlist construction in safari, where the `display: inline-table` wasn't being
applied because of CSS specificity. This leads to the only significant change in
the huxley tests, with the vertical spacing.
Test Plan:
- Make sure the tests still work
- Make sure most of the huxley screenshots didn't change, and that the new
changes are insignificant.
- Make sure vlists now work in Safari
- Make sure the change to the VerticalSpacing screenshot is caused by the
fix-baseline span now correctly applying `display: inline-table` by creating
the construct in master and adding `display: inline-table !important` to the
`.fix-ie` css rule
Reviewers: alpert
Reviewed By: alpert
Differential Revision: http://phabricator.khanacademy.org/D13082
Diffstat:
9 files changed, 244 insertions(+), 277 deletions(-)
diff --git a/buildCommon.js b/buildCommon.js
@@ -94,11 +94,139 @@ var makeFontSizer = function(options, fontSize) {
return fontSizer;
};
+/*
+ * Makes a vertical list by stacking elements and kerns on top of each other.
+ * Allows for many different ways of specifying the positioning method.
+ *
+ * Arguments:
+ * - children: A list of child or kern nodes to be stacked on top of each other
+ * (i.e. the first element will be at the bottom, and the last at
+ * the top). Element nodes are specified as
+ * {type: "elem", elem: node}
+ * while kern nodes are specified as
+ * {type: "kern", size: size}
+ * - positionType: The method by which the vlist should be positioned. Valid
+ * values are:
+ * - "individualShift": The children list only contains elem
+ * nodes, and each node contains an extra
+ * "shift" value of how much it should be
+ * shifted (note that shifting is always
+ * moving downwards). positionData is
+ * ignored.
+ * - "top": The positionData specifies the topmost point of
+ * the vlist (note this is expected to be a height,
+ * so positive values move up)
+ * - "bottom": The positionData specifies the bottommost point
+ * of the vlist (note this is expected to be a
+ * depth, so positive values move down
+ * - "shift": The vlist will be positioned such that its
+ * baseline is positionData away from the baseline
+ * of the first child. Positive values move
+ * downwards.
+ * - "firstBaseline": The vlist will be positioned such that
+ * its baseline is aligned with the
+ * baseline of the first child.
+ * positionData is ignored. (this is
+ * equivalent to "shift" with
+ * positionData=0)
+ * - positionData: Data used in different ways depending on positionType
+ * - options: An Options object
+ *
+ */
+var makeVList = function(children, positionType, positionData, options) {
+ var depth;
+ if (positionType === "individualShift") {
+ var oldChildren = children;
+ children = [oldChildren[0]];
+
+ // Add in kerns to the list of children to get each element to be
+ // shifted to the correct specified shift
+ depth = -oldChildren[0].shift - oldChildren[0].elem.depth;
+ var currPos = depth;
+ for (var i = 1; i < oldChildren.length; i++) {
+ var diff = -oldChildren[i].shift - currPos -
+ oldChildren[i].elem.depth;
+ var size = diff -
+ (oldChildren[i - 1].elem.height +
+ oldChildren[i - 1].elem.depth);
+
+ currPos = currPos + diff;
+
+ children.push({type: "kern", size: size});
+ children.push(oldChildren[i]);
+ }
+ } else if (positionType === "top") {
+ // We always start at the bottom, so calculate the bottom by adding up
+ // all the sizes
+ var bottom = positionData;
+ for (var i = 0; i < children.length; i++) {
+ if (children[i].type === "kern") {
+ bottom -= children[i].size;
+ } else {
+ bottom -= children[i].elem.height + children[i].elem.depth;
+ }
+ }
+ depth = bottom;
+ } else if (positionType === "bottom") {
+ depth = -positionData;
+ } else if (positionType === "shift") {
+ depth = -children[0].elem.depth - positionData;
+ } else if (positionType === "firstBaseline") {
+ depth = -children[0].elem.depth;
+ } else {
+ depth = 0;
+ }
+
+ // Make the fontSizer
+ var maxFontSize = 0;
+ for (var i = 0; i < children.length; i++) {
+ if (children[i].type === "elem") {
+ maxFontSize = Math.max(maxFontSize, children[i].elem.maxFontSize);
+ }
+ }
+ var fontSizer = makeFontSizer(options, maxFontSize);
+
+ // Create a new list of actual children at the correct offsets
+ var realChildren = [];
+ var currPos = depth;
+ for (var i = 0; i < children.length; i++) {
+ if (children[i].type === "kern") {
+ currPos += children[i].size;
+ } else {
+ var child = children[i].elem;
+
+ var shift = -child.depth - currPos;
+ currPos += child.height + child.depth;
+
+ var childWrap = makeSpan([], [fontSizer, child]);
+ childWrap.height -= shift;
+ childWrap.depth += shift;
+ childWrap.style.top = shift + "em";
+
+ realChildren.push(childWrap);
+ }
+ }
+
+ // Add in an element at the end with no offset to fix the calculation of
+ // baselines in some browsers (namely IE, sometimes safari)
+ var baselineFix = makeSpan(
+ ["baseline-fix"], [fontSizer, new domTree.textNode("\u00a0")]);
+ realChildren.push(baselineFix);
+
+ var vlist = makeSpan(["vlist"], realChildren);
+ // Fix the final height and depth, in case there were kerns at the ends
+ // since the makeSpan calculation won't take that in to account.
+ vlist.height = Math.max(currPos, vlist.height);
+ vlist.depth = Math.max(-depth, vlist.depth);
+ return vlist;
+};
+
module.exports = {
makeText: makeText,
mathit: mathit,
mathrm: mathrm,
makeSpan: makeSpan,
makeFragment: makeFragment,
- makeFontSizer: makeFontSizer
+ makeFontSizer: makeFontSizer,
+ makeVList: makeVList
};
diff --git a/buildTree.js b/buildTree.js
@@ -147,12 +147,13 @@ var groupTypes = {
[options.style.reset(), options.style.sub().cls()], [sub]);
}
+ var u, v;
if (isCharacterBox(group.value.base)) {
- var u = 0;
- var v = 0;
+ u = 0;
+ v = 0;
} else {
- var u = base.height - fontMetrics.metrics.supDrop;
- var v = base.depth + fontMetrics.metrics.subDrop;
+ u = base.height - fontMetrics.metrics.supDrop;
+ v = base.depth + fontMetrics.metrics.subDrop;
}
var p;
@@ -172,43 +173,24 @@ var groupTypes = {
var supsub;
if (!group.value.sup) {
- var fontSizer = buildCommon.makeFontSizer(options, submid.maxFontSize);
- var subwrap = makeSpan(["msub"], [fontSizer, submid]);
-
v = Math.max(v, fontMetrics.metrics.sub1,
sub.height - 0.8 * fontMetrics.metrics.xHeight);
- subwrap.style.top = v + "em";
- subwrap.style.marginRight = scriptspace;
-
- subwrap.depth = subwrap.depth + v;
- subwrap.height = 0;
+ supsub = buildCommon.makeVList([
+ {type: "elem", elem: submid}
+ ], "shift", v, options);
- var fixIE = makeSpan(["fix-ie"], [fontSizer, new domTree.textNode("\u00a0")]);
-
- supsub = makeSpan(["msupsub"], [subwrap, fixIE]);
+ supsub.children[0].style.marginRight = scriptspace;
} else if (!group.value.sub) {
- var fontSizer = buildCommon.makeFontSizer(options, supmid.maxFontSize);
- var supwrap = makeSpan(["msup"], [fontSizer, supmid]);
-
u = Math.max(u, p,
sup.depth + 0.25 * fontMetrics.metrics.xHeight);
- supwrap.style.top = -u + "em";
- supwrap.style.marginRight = scriptspace;
+ supsub = buildCommon.makeVList([
+ {type: "elem", elem: supmid}
+ ], "shift", -u, options);
- supwrap.height = supwrap.height + u;
- supwrap.depth = 0;
-
- var fixIE = makeSpan(["fix-ie"], [fontSizer, new domTree.textNode("\u00a0")]);
-
- supsub = makeSpan(["msupsub"], [supwrap, fixIE]);
+ supsub.children[0].style.marginRight = scriptspace;
} else {
- var fontSizer = buildCommon.makeFontSizer(options,
- Math.max(submid.maxFontSize, supmid.maxFontSize));
- var subwrap = makeSpan(["msub"], [fontSizer, submid]);
- var supwrap = makeSpan(["msup"], [fontSizer, supmid]);
-
u = Math.max(u, p,
sup.depth + 0.25 * fontMetrics.metrics.xHeight);
v = Math.max(v, fontMetrics.metrics.sub2);
@@ -224,21 +206,13 @@ var groupTypes = {
}
}
- supwrap.style.top = -u + "em";
- subwrap.style.top = v + "em";
-
- supwrap.style.marginRight = scriptspace;
- subwrap.style.marginRight = scriptspace;
+ supsub = buildCommon.makeVList([
+ {type: "elem", elem: submid, shift: v},
+ {type: "elem", elem: supmid, shift: -u}
+ ], "individualShift", null, options);
- supwrap.height = supwrap.height + u;
- supwrap.depth = 0;
-
- subwrap.height = 0;
- subwrap.depth = subwrap.depth + v;
-
- var fixIE = makeSpan(["fix-ie"], [fontSizer, new domTree.textNode("\u00a0")]);
-
- supsub = makeSpan(["msupsub"], [supwrap, subwrap, fixIE]);
+ supsub.children[0].style.marginRight = scriptspace;
+ supsub.children[1].style.marginRight = scriptspace;
}
return makeSpan([getTypeOfGroup(group.value.base)],
@@ -273,22 +247,16 @@ var groupTypes = {
var dstyle = fstyle.fracDen();
var numer = buildGroup(group.value.numer, options.withStyle(nstyle));
- var numernumer = makeSpan([fstyle.reset(), nstyle.cls()], [numer]);
+ var numerreset = makeSpan([fstyle.reset(), nstyle.cls()], [numer]);
var denom = buildGroup(group.value.denom, options.withStyle(dstyle));
- var denomdenom = makeSpan([fstyle.reset(), dstyle.cls()], [denom])
-
- var fontSizer = buildCommon.makeFontSizer(options,
- Math.max(numer.maxFontSize, denom.maxFontSize));
-
- var line = makeSpan([options.style.reset(), Style.TEXT.cls(), "line"]);
-
- var numerrow = makeSpan(["mfracnum"], [fontSizer, numernumer]);
- var mid = makeSpan(["mfracmid"], [fontSizer, line]);
- var denomrow = makeSpan(["mfracden"], [fontSizer, denomdenom]);
+ var denomreset = makeSpan([fstyle.reset(), dstyle.cls()], [denom])
var theta = fontMetrics.metrics.defaultRuleThickness / options.style.sizeMultiplier;
+ var mid = makeSpan([options.style.reset(), Style.TEXT.cls(), "frac-line"]);
+ mid.height = theta;
+
var u, v, phi;
if (fstyle.size === Style.DISPLAY.size) {
u = fontMetrics.metrics.num1;
@@ -310,30 +278,20 @@ var groupTypes = {
v += phi - ((a - 0.5 * theta) - (denom.height - v));
}
- numerrow.style.top = -u + "em";
- mid.style.top = -(a - 0.5 * theta) + "em";
- denomrow.style.top = v + "em";
-
- numerrow.height = numerrow.height + u;
- numerrow.depth = 0;
+ var midShift = -(a - 0.5 * theta);
- denomrow.height = 0;
- denomrow.depth = denomrow.depth + v;
-
- var fixIE = makeSpan(["fix-ie"], [
- fontSizer, new domTree.textNode("\u00a0")]);
-
- var frac = makeSpan([], [numerrow, mid, denomrow, fixIE]);
+ var frac = buildCommon.makeVList([
+ {type: "elem", elem: denomreset, shift: v},
+ {type: "elem", elem: mid, shift: midShift},
+ {type: "elem", elem: numerreset, shift: -u}
+ ], "individualShift", null, options);
frac.height *= fstyle.sizeMultiplier / options.style.sizeMultiplier;
frac.depth *= fstyle.sizeMultiplier / options.style.sizeMultiplier;
- var wrap = makeSpan(
- [options.style.reset(), fstyle.cls()], [frac]);
-
- return makeSpan(["minner"], [
- makeSpan(["mfrac"], [wrap])
- ], options.getColor());
+ return makeSpan(
+ ["minner", "mfrac", options.style.reset(), fstyle.cls()],
+ [frac], options.getColor());
},
color: function(group, options, prev) {
@@ -434,26 +392,18 @@ var groupTypes = {
},
sqrt: function(group, options, prev) {
- var innerGroup = buildGroup(group.value.body,
+ var inner = buildGroup(group.value.body,
options.withStyle(options.style.cramp()));
- var fontSizer = buildCommon.makeFontSizer(
- options, Math.max(innerGroup.maxFontSize, 1.0));
-
- // The theta variable in the TeXbook
- var lineWidth = fontMetrics.metrics.defaultRuleThickness;
-
- var lineInner =
- makeSpan([options.style.reset(), Style.TEXT.cls(), "line"]);
- lineInner.maxFontSize = 1.0;
- var line = makeSpan(["sqrt-line"], [fontSizer, lineInner]);
-
- var inner = makeSpan(["sqrt-inner"], [fontSizer, innerGroup]);
- var fixIE = makeSpan(
- ["fix-ie"], [fontSizer, new domTree.textNode("\u00a0")]);
-
var theta = fontMetrics.metrics.defaultRuleThickness /
options.style.sizeMultiplier;
+
+ var line = makeSpan(
+ [options.style.reset(), Style.TEXT.cls(), "sqrt-line"], [],
+ options.getColor());
+ line.height = theta;
+ line.maxFontSize = 1.0;
+
var phi = theta;
if (options.style.id < Style.TEXT.id) {
phi = fontMetrics.metrics.xHeight;
@@ -467,18 +417,19 @@ var groupTypes = {
var delim = makeSpan(["sqrt-sign"], [
delimiter.customSizedDelim("\\surd", minDelimiterHeight,
- false, options, group.mode)]);
+ false, options, group.mode)],
+ options.getColor());
- var delimDepth = delim.height + delim.depth;
+ var delimDepth = (delim.height + delim.depth) - theta;
if (delimDepth > inner.height + inner.depth + psi) {
psi = (psi + delimDepth - inner.height - inner.depth) / 2;
}
- delim.style.top = (-inner.height - psi + delim.height - theta) + "em";
-
- line.style.top = (-inner.height - psi) + "em";
- line.height = inner.height + psi + 2 * theta;
+ delimShift = -(inner.height + psi + theta) + delim.height;
+ delim.style.top = delimShift + "em";
+ delim.height -= delimShift;
+ delim.depth += delimShift;
// We add a special case here, because even when `inner` is empty, we
// still get a line. So, we use a simple heuristic to decide if we
@@ -489,7 +440,12 @@ var groupTypes = {
if (inner.height === 0 && inner.depth === 0) {
body = makeSpan();
} else {
- body = makeSpan(["sqrt-body"], [line, inner, fixIE]);
+ body = buildCommon.makeVList([
+ {type: "elem", elem: inner},
+ {type: "kern", size: psi},
+ {type: "elem", elem: line},
+ {type: "kern", size: theta}
+ ], "firstBaseline", null, options);
}
return makeSpan(["sqrt", "mord"], [delim, body]);
@@ -499,26 +455,22 @@ var groupTypes = {
var innerGroup = buildGroup(group.value.body,
options.withStyle(options.style.cramp()));
- var fontSizer = buildCommon.makeFontSizer(options, innerGroup.maxFontSize);
-
- // The theta variable in the TeXbook
- var lineWidth = fontMetrics.metrics.defaultRuleThickness /
+ var theta = fontMetrics.metrics.defaultRuleThickness /
options.style.sizeMultiplier;
var line = makeSpan(
- ["overline-line"], [fontSizer, makeSpan([options.style.reset(), Style.TEXT.cls(), "line"])]);
- var inner = makeSpan(["overline-inner"], [fontSizer, innerGroup]);
- var fixIE = makeSpan(
- ["fix-ie"], [fontSizer, new domTree.textNode("\u00a0")]);
-
- line.style.top = (-inner.height - 3 * lineWidth) + "em";
- // The line is supposed to have 1 extra line width above it in height
- // (TeXbook pg. 443, nr. 9)
- line.height = inner.height + 5 * lineWidth;
-
- return makeSpan(["overline", "mord"], [
- line, inner, fixIE
- ], options.getColor());
+ [options.style.reset(), Style.TEXT.cls(), "overline-line"]);
+ line.height = theta;
+ line.maxFontSize = 1.0;
+
+ var vlist = buildCommon.makeVList([
+ {type: "elem", elem: innerGroup},
+ {type: "kern", size: 3 * theta},
+ {type: "elem", elem: line},
+ {type: "kern", size: theta}
+ ], "firstBaseline", null, options);
+
+ return makeSpan(["overline", "mord"], [vlist], options.getColor());
},
sizing: function(group, options, prev) {
diff --git a/delimiter.js b/delimiter.js
@@ -77,23 +77,19 @@ var makeLargeDelim = function(delim, size, center, options, mode) {
};
// Make an inner span with the given offset and in the given font
-var makeInner = function(symbol, offset, font, mode) {
+var makeInner = function(symbol, font, mode) {
var sizeClass;
if (font === "Size1-Regular") {
- sizeClass = "size1";
+ sizeClass = "delim-size1";
} else if (font === "Size4-Regular") {
- sizeClass = "size4";
+ sizeClass = "delim-size4";
}
var inner = makeSpan(
["delimsizinginner", sizeClass],
[makeSpan([], [buildCommon.makeText(symbol, font, mode)])]);
- inner.style.top = offset + "em";
- inner.height -= offset;
- inner.depth += offset;
-
- return inner;
+ return {type: "elem", elem: inner};
};
var makeStackedDelim = function(delim, heightTotal, center, options, mode) {
@@ -102,7 +98,6 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode) {
top = repeat = bottom = delim;
middle = null;
var font = "Size1-Regular";
- var overlap = false;
// We set the parts and font based on the symbol. Note that we use
// '\u23d0' instead of '|' and '\u2016' instead of '\\|' for the
@@ -123,62 +118,44 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode) {
top = "\\Uparrow";
repeat = "\u2016";
bottom = "\\Downarrow";
-
- // For some reason, the sizes of this one delimiter don't work out
- // right, so we shrink it a bit to make it now add an extraneous
- // repeating part
- if (height + depth <= 1.21) {
- height -= 0.01;
- depth -= 0.01;
- }
} else if (delim === "|" || delim === "\\vert") {
- overlap = true;
} else if (delim === "\\|" || delim === "\\Vert") {
- overlap = true;
} else if (delim === "[" || delim === "\\lbrack") {
top = "\u23a1";
repeat = "\u23a2";
bottom = "\u23a3";
font = "Size4-Regular";
- overlap = true;
} else if (delim === "]" || delim === "\\rbrack") {
top = "\u23a4";
repeat = "\u23a5";
bottom = "\u23a6";
font = "Size4-Regular";
- overlap = true;
} else if (delim === "\\lfloor") {
repeat = top = "\u23a2";
bottom = "\u23a3";
font = "Size4-Regular";
- overlap = true;
} else if (delim === "\\lceil") {
top = "\u23a1";
repeat = bottom = "\u23a2";
font = "Size4-Regular";
- overlap = true;
} else if (delim === "\\rfloor") {
repeat = top = "\u23a5";
bottom = "\u23a6";
font = "Size4-Regular";
- overlap = true;
} else if (delim === "\\rceil") {
top = "\u23a4";
repeat = bottom = "\u23a5";
font = "Size4-Regular";
- overlap = true;
} else if (delim === "(") {
top = "\u239b";
repeat = "\u239c";
bottom = "\u239d";
font = "Size4-Regular";
- overlap = true;
} else if (delim === ")") {
top = "\u239e";
repeat = "\u239f";
bottom = "\u23a0";
font = "Size4-Regular";
- overlap = true;
} else if (delim === "\\{" || delim === "\\lbrace") {
top = "\u23a7";
middle = "\u23a8";
@@ -196,7 +173,6 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode) {
bottom = "\u23b7";
repeat = "\ue000";
font = "Size4-Regular";
- overlap = true;
}
// Get the metrics of the three sections
@@ -234,32 +210,16 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode) {
// Keep a list of the inner spans
var inners = [];
- // Add the top symbol
- inners.push(
- makeInner(top, topMetrics.height - height, font, mode));
+ // Add the bottom symbol
+ inners.push(makeInner(bottom, font, mode));
if (middle === null) {
var repeatHeight = realHeightTotal - topHeightTotal - bottomHeightTotal;
var symbolCount = Math.ceil(repeatHeight / repeatHeightTotal);
- var overlapAmount;
- if (overlap) {
- // 2 * overlapAmount + repeatHeight =
- // (symbolCount - 1) * (repeatHeightTotal - overlapAmount) +
- // repeatHeightTotal
- overlapAmount = (symbolCount * repeatHeightTotal -
- repeatHeight) / (symbolCount + 1);
- } else {
- overlapAmount = 0;
- }
-
// Add repeat symbols until there's only space for the bottom symbol
- var currHeight = height - topHeightTotal + overlapAmount;
for (var i = 0; i < symbolCount; i++) {
- inners.push(
- makeInner(repeat,
- repeatMetrics.height - currHeight, font, mode));
- currHeight -= repeatHeightTotal - overlapAmount;
+ inners.push(makeInner(repeat, font, mode));
}
} else {
// When there is a middle bit, we need the middle part and two repeated
@@ -277,40 +237,25 @@ var makeStackedDelim = function(delim, heightTotal, center, options, mode) {
Math.ceil(bottomRepeatHeight / repeatHeightTotal);
// Add the top repeated part
- var currHeight = height - topHeightTotal;
for (var i = 0; i < topSymbolCount; i++) {
- inners.push(
- makeInner(repeat,
- repeatMetrics.height - currHeight, font, mode));
- currHeight -= repeatHeightTotal;
+ inners.push(makeInner(repeat, font, mode));
}
// Add the middle piece
- var midPoint = realHeightTotal / 2 - depth;
- inners.push(
- makeInner(middle,
- middleMetrics.height - midPoint - middleHeightTotal / 2,
- font, mode));
+ inners.push(makeInner(middle, font, mode));
// Add the bottom repeated part
- currHeight = midPoint - middleHeightTotal / 2;
for (var i = 0; i < bottomSymbolCount; i++) {
- inners.push(
- makeInner(repeat,
- repeatMetrics.height - currHeight, font, mode));
- currHeight -= repeatHeightTotal;
+ inners.push(makeInner(repeat, font, mode));
}
}
- // Add the bottom symbol
- inners.push(
- makeInner(bottom, depth - bottomMetrics.depth, font, mode));
+ inners.push(makeInner(top, font, mode));
- var fixIE = makeSpan(["fix-ie"], [new domTree.textNode("\u00a0")]);
- inners.push(fixIE);
+ var inner = buildCommon.makeVList(inners, "bottom", depth, options);
return styleWrap(
- makeSpan(["delimsizing", "mult"], inners, options.getColor()),
+ makeSpan(["delimsizing", "mult"], [inner], options.getColor()),
Style.TEXT, options);
};
diff --git a/static/katex.less b/static/katex.less
@@ -34,11 +34,6 @@ big parens
font-family: KaTeX_AMS;
}
- .fix-ie {
- display: inline-table;
- table-layout: fixed;
- }
-
// This value is also used in fontMetrics.js, if you change it make sure the
// values match.
@ptperem: 10.0;
@@ -171,52 +166,35 @@ big parens
position: relative;
}
- .baseline-align-hack-outer() {
+ .vlist {
display: inline-block;
- }
-
- .baseline-align-hack-middle() {
- display: block;
- height: 0;
- }
-
- .baseline-align-hack-inner() {
- display: inline-block;
- }
-
- .msupsub {
- .baseline-align-hack-outer;
- text-align: left;
- .msup,
- .msub,
- .fix-ie {
- .baseline-align-hack-middle;
+ > span {
+ display: block;
+ height: 0;
position: relative;
> span {
- .baseline-align-hack-inner;
+ display: inline-block;
}
}
+
+ .baseline-fix {
+ display: inline-table;
+ table-layout: fixed;
+ }
}
- .mfrac {
- .baseline-align-hack-outer;
+ .msupsub {
+ text-align: left;
+ }
- .mfracnum,
- .mfracmid,
- .mfracden,
- .fix-ie {
- .baseline-align-hack-middle;
- position: relative;
+ .mfrac {
+ > span > span {
text-align: center;
-
- > span {
- .baseline-align-hack-inner;
- }
}
- .mfracmid > .line {
+ .frac-line {
width: 100%;
&:before {
@@ -316,21 +294,8 @@ big parens
}
.overline {
- .baseline-align-hack-outer;
- > .overline-line,
- > .overline-inner,
- > .fix-ie {
- .baseline-align-hack-middle;
- position: relative;
- text-align: center;
-
- > span {
- .baseline-align-hack-inner;
- }
- }
-
- > .overline-line > .line {
+ .overline-line {
width: 100%;
&:before {
@@ -355,37 +320,22 @@ big parens
position: relative;
}
- > .sqrt-body {
- .baseline-align-hack-outer;
-
- > .sqrt-line,
- > .sqrt-inner,
- > .fix-ie {
- .baseline-align-hack-middle;
- position: relative;
+ .sqrt-line {
+ width: 100%;
- > span {
- .baseline-align-hack-inner;
- }
+ &:before {
+ border-bottom-style: solid;
+ border-bottom-width: 1px;
+ content: "";
+ display: block;
}
- > .sqrt-line > .line {
- width: 100%;
-
- &:before {
- border-bottom-style: solid;
- border-bottom-width: 1px;
- content: "";
- display: block;
- }
-
- &:after {
- border-bottom-style: solid;
- border-bottom-width: 0.04em;
- content: "";
- display: block;
- margin-top: -1px;
- }
+ &:after {
+ border-bottom-style: solid;
+ border-bottom-width: 0.04em;
+ content: "";
+ display: block;
+ margin-top: -1px;
}
}
}
@@ -434,19 +384,11 @@ big parens
&.size4 { font-family: KaTeX_Size4; }
&.mult {
- .baseline-align-hack-outer;
-
- > .fix-ie,
- > .delimsizinginner {
- .baseline-align-hack-middle;
- position: relative;
-
- &.size1 > span {
- font-family: Katex_Size1;
- }
- &.size4 > span {
- font-family: Katex_Size4;
- }
+ .delim-size1 > span {
+ font-family: Katex_Size1;
+ }
+ .delim-size4 > span {
+ font-family: Katex_Size4;
}
}
}
diff --git a/test/huxley/DelimiterSizing.hux/firefox-1.png b/test/huxley/DelimiterSizing.hux/firefox-1.png
Binary files differ.
diff --git a/test/huxley/DisplayStyle.hux/firefox-1.png b/test/huxley/DisplayStyle.hux/firefox-1.png
Binary files differ.
diff --git a/test/huxley/Sqrt.hux/firefox-1.png b/test/huxley/Sqrt.hux/firefox-1.png
Binary files differ.
diff --git a/test/huxley/SupSubHorizSpacing.hux/firefox-1.png b/test/huxley/SupSubHorizSpacing.hux/firefox-1.png
Binary files differ.
diff --git a/test/huxley/VerticalSpacing.hux/firefox-1.png b/test/huxley/VerticalSpacing.hux/firefox-1.png
Binary files differ.