diff --git a/src/buildHTML.js b/src/buildHTML.js
index e9556ec8..0ec022db 100644
--- a/src/buildHTML.js
+++ b/src/buildHTML.js
@@ -1115,6 +1115,10 @@ groupTypes.sqrt = function(group, options) {
// First, we do the same steps as in overline to build the inner group
// and line
let inner = buildGroup(group.value.body, options.havingCrampedStyle());
+ if (inner.height === 0) {
+ // Render a small surd.
+ inner.height = options.fontMetrics().xHeight;
+ }
// Some groups can return document fragments. Handle those by wrapping
// them in a span.
@@ -1159,26 +1163,16 @@ groupTypes.sqrt = function(group, options) {
// Shift the sqrt image
const imgShift = img.height - inner.height - lineClearance - ruleWidth;
- // 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
- // should omit the body entirely. (note this doesn't work for something
- // like `\sqrt{\rlap{x}}`, but if someone is doing that they deserve for
- // it not to work.
- let body;
- if (inner.height === 0 && inner.depth === 0) {
- body = makeSpan();
- } else {
- inner.style.paddingLeft = img.surdWidth + "em";
+ inner.style.paddingLeft = img.advanceWidth + "em";
- // Overlay the image and the argument.
- body = buildCommon.makeVList([
- {type: "elem", elem: inner},
- {type: "kern", size: -(inner.height + imgShift)},
- {type: "elem", elem: img},
- {type: "kern", size: ruleWidth},
- ], "firstBaseline", null, options);
- body.children[0].children[0].classes.push("svg-align");
- }
+ // Overlay the image and the argument.
+ const body = buildCommon.makeVList([
+ {type: "elem", elem: inner},
+ {type: "kern", size: -(inner.height + imgShift)},
+ {type: "elem", elem: img},
+ {type: "kern", size: ruleWidth},
+ ], "firstBaseline", null, options);
+ body.children[0].children[0].classes.push("svg-align");
if (!group.value.index) {
return makeSpan(["mord", "sqrt"], [body], options);
diff --git a/src/delimiter.js b/src/delimiter.js
index 2c4d226a..98ee924f 100644
--- a/src/delimiter.js
+++ b/src/delimiter.js
@@ -329,14 +329,13 @@ const sqrtSvg = function(sqrtName, height, viewBoxHeight, options) {
}
const pathNode = new domTree.pathNode(sqrtName, alternate);
- let attributes = [["width", "100%"], ["height", height + "em"]];
+ // Note: 1000:1 ratio of viewBox to document em width.
+ const attributes = [["width", "400em"], ["height", height + "em"]];
attributes.push(["viewBox", "0 0 400000 " + viewBoxHeight]);
attributes.push(["preserveAspectRatio", "xMinYMin slice"]);
- const innerSVG = new domTree.svgNode([pathNode], attributes);
+ const svg = new domTree.svgNode([pathNode], attributes);
- attributes = [["width", "100%"], ["height", height + "em"]];
- const svg = new domTree.svgNode([innerSVG], attributes);
- return buildCommon.makeSpan([], [svg], options);
+ return buildCommon.makeSpan(["hide-tail"], [svg], options);
};
const sqrtSpan = function(height, delim, options) {
@@ -353,22 +352,25 @@ const sqrtSpan = function(height, delim, options) {
sizeMultiplier = newOptions.sizeMultiplier / options.sizeMultiplier;
spanHeight = 1 * sizeMultiplier;
span = sqrtSvg("sqrtMain", spanHeight, viewBoxHeight, options);
- span.surdWidth = 0.833 * sizeMultiplier; // from the font.
+ span.style.minWidth = "0.853em";
+ span.advanceWidth = 0.833 * sizeMultiplier; // from the font.
} else if (delim.type === "large") {
// These SVGs come from fonts: KaTeX_Size1, _Size2, etc.
viewBoxHeight = 1000 * sizeToMaxHeight[delim.size];
spanHeight = sizeToMaxHeight[delim.size] / sizeMultiplier;
span = sqrtSvg("sqrtSize" + delim.size, spanHeight, viewBoxHeight, options);
- span.surdWidth = 1.0 / sizeMultiplier; // from the font
+ span.style.minWidth = "1.02em";
+ span.advanceWidth = 1.0 / sizeMultiplier; // from the font
} else {
// Tall sqrt. In TeX, this would be stacked using multiple glyphs.
// We'll use a single SVG to accomplish the same thing.
spanHeight = height / sizeMultiplier;
- viewBoxHeight = Math.floor(1000 * spanHeight);
+ viewBoxHeight = Math.floor(1000 * height);
span = sqrtSvg("sqrtTall", spanHeight, viewBoxHeight, options);
- span.surdWidth = 1.056 / sizeMultiplier;
+ span.style.minWidth = "0.742em";
+ span.advanceWidth = 1.056 / sizeMultiplier;
}
span.height = spanHeight;
diff --git a/src/stretchy.js b/src/stretchy.js
index 7a3e3c21..0a71b10b 100644
--- a/src/stretchy.js
+++ b/src/stretchy.js
@@ -158,6 +158,7 @@ const svgSpan = function(group, options) {
let path;
let pathName;
let svgNode;
+ const classNames = [];
if (utils.contains(["widehat", "widetilde", "undertilde"], label)) {
// There are four SVG images available for each function.
@@ -208,7 +209,7 @@ const svgSpan = function(group, options) {
attributes = [];
if (numSvgChildren === 1) {
- width = "100%";
+ width = "400em";
align = alignOne;
} else if (numSvgChildren === 2) {
// small overlap to prevent a 1 pixel gap.
@@ -231,13 +232,22 @@ const svgSpan = function(group, options) {
attributes.push(["viewBox", `0 0 ${viewBoxWidth} ${vbHeight}`]);
attributes.push(["preserveAspectRatio", align + " slice"]);
- innerSVGs.push(new domTree.svgNode([path], attributes));
+ if (numSvgChildren > 1) {
+ innerSVGs.push(new domTree.svgNode([path], attributes));
+ } else {
+ // The single svgChild is a child of a hide-tail span, not the
+ // child of another svg.
+ svgNode = new domTree.svgNode([path], attributes);
+ classNames.push("hide-tail");
+ }
+ }
+ if (numSvgChildren > 1) {
+ attributes = [["width", "100%"], ["height", height + "em"]];
+ svgNode = new domTree.svgNode(innerSVGs, attributes);
}
- attributes = [["width", "100%"], ["height", height + "em"]];
- svgNode = new domTree.svgNode(innerSVGs, attributes);
}
- const span = buildCommon.makeSpan([], [svgNode], options);
+ const span = buildCommon.makeSpan(classNames, [svgNode], options);
// Note that we are returning span.depth = 0.
// Any adjustments relative to the baseline must be done in buildHTML.
span.height = height;
diff --git a/static/katex.less b/static/katex.less
index f7fad196..9d9425d7 100644
--- a/static/katex.less
+++ b/static/katex.less
@@ -575,6 +575,13 @@
}
}
+ // Hide the long tail of a stretchy SVG.
+ .hide-tail {
+ width: 100%; // necessary only to get IE to work properly
+ position: relative; // ditto
+ overflow: hidden; // This line applies to all browsers.
+ }
+
// Lengthen the extensible arrows via padding.
.x-arrow-pad {
padding: 0 0.5em;
diff --git a/test/screenshotter/images/DisplayStyle-chrome.png b/test/screenshotter/images/DisplayStyle-chrome.png
index be2e8524..65619e34 100644
Binary files a/test/screenshotter/images/DisplayStyle-chrome.png and b/test/screenshotter/images/DisplayStyle-chrome.png differ
diff --git a/test/screenshotter/images/ExtensibleArrows-chrome.png b/test/screenshotter/images/ExtensibleArrows-chrome.png
index bce71b0c..2f516662 100644
Binary files a/test/screenshotter/images/ExtensibleArrows-chrome.png and b/test/screenshotter/images/ExtensibleArrows-chrome.png differ
diff --git a/test/screenshotter/images/ExtensibleArrows-firefox.png b/test/screenshotter/images/ExtensibleArrows-firefox.png
index 524d679b..ab8cac64 100644
Binary files a/test/screenshotter/images/ExtensibleArrows-firefox.png and b/test/screenshotter/images/ExtensibleArrows-firefox.png differ
diff --git a/test/screenshotter/images/LowerAccent-chrome.png b/test/screenshotter/images/LowerAccent-chrome.png
index d46e9c04..249f97c3 100644
Binary files a/test/screenshotter/images/LowerAccent-chrome.png and b/test/screenshotter/images/LowerAccent-chrome.png differ
diff --git a/test/screenshotter/images/LowerAccent-firefox.png b/test/screenshotter/images/LowerAccent-firefox.png
index 4b1127e4..f3319345 100644
Binary files a/test/screenshotter/images/LowerAccent-firefox.png and b/test/screenshotter/images/LowerAccent-firefox.png differ
diff --git a/test/screenshotter/images/OverUnderset-chrome.png b/test/screenshotter/images/OverUnderset-chrome.png
index 762da945..a51f8a6b 100644
Binary files a/test/screenshotter/images/OverUnderset-chrome.png and b/test/screenshotter/images/OverUnderset-chrome.png differ
diff --git a/test/screenshotter/images/Raisebox-chrome.png b/test/screenshotter/images/Raisebox-chrome.png
index 004e41c7..fc8da117 100644
Binary files a/test/screenshotter/images/Raisebox-chrome.png and b/test/screenshotter/images/Raisebox-chrome.png differ
diff --git a/test/screenshotter/images/Raisebox-firefox.png b/test/screenshotter/images/Raisebox-firefox.png
index a2623731..f5ca0a6d 100644
Binary files a/test/screenshotter/images/Raisebox-firefox.png and b/test/screenshotter/images/Raisebox-firefox.png differ
diff --git a/test/screenshotter/images/Smash-chrome.png b/test/screenshotter/images/Smash-chrome.png
index 2be9b9b8..4fa5c919 100644
Binary files a/test/screenshotter/images/Smash-chrome.png and b/test/screenshotter/images/Smash-chrome.png differ
diff --git a/test/screenshotter/images/Sqrt-chrome.png b/test/screenshotter/images/Sqrt-chrome.png
index 1e99e73a..401d4def 100644
Binary files a/test/screenshotter/images/Sqrt-chrome.png and b/test/screenshotter/images/Sqrt-chrome.png differ
diff --git a/test/screenshotter/images/Sqrt-firefox.png b/test/screenshotter/images/Sqrt-firefox.png
index 9c5a5158..d395f85d 100644
Binary files a/test/screenshotter/images/Sqrt-firefox.png and b/test/screenshotter/images/Sqrt-firefox.png differ
diff --git a/test/screenshotter/images/SqrtRoot-chrome.png b/test/screenshotter/images/SqrtRoot-chrome.png
index 35ec9171..70fa0da7 100644
Binary files a/test/screenshotter/images/SqrtRoot-chrome.png and b/test/screenshotter/images/SqrtRoot-chrome.png differ
diff --git a/test/screenshotter/images/SqrtRoot-firefox.png b/test/screenshotter/images/SqrtRoot-firefox.png
index 61f2336e..fc0bef09 100644
Binary files a/test/screenshotter/images/SqrtRoot-firefox.png and b/test/screenshotter/images/SqrtRoot-firefox.png differ
diff --git a/test/screenshotter/images/StretchyAccent-chrome.png b/test/screenshotter/images/StretchyAccent-chrome.png
index da2cc8cf..82640f42 100644
Binary files a/test/screenshotter/images/StretchyAccent-chrome.png and b/test/screenshotter/images/StretchyAccent-chrome.png differ
diff --git a/test/screenshotter/images/StretchyAccent-firefox.png b/test/screenshotter/images/StretchyAccent-firefox.png
index 503bd6ee..ccb75dde 100644
Binary files a/test/screenshotter/images/StretchyAccent-firefox.png and b/test/screenshotter/images/StretchyAccent-firefox.png differ
diff --git a/test/screenshotter/images/StretchyAccentColor-chrome.png b/test/screenshotter/images/StretchyAccentColor-chrome.png
index 4623ff7f..a6bfcb9c 100644
Binary files a/test/screenshotter/images/StretchyAccentColor-chrome.png and b/test/screenshotter/images/StretchyAccentColor-chrome.png differ
diff --git a/test/screenshotter/images/StretchyAccentColor-firefox.png b/test/screenshotter/images/StretchyAccentColor-firefox.png
index bb70bede..209802ab 100644
Binary files a/test/screenshotter/images/StretchyAccentColor-firefox.png and b/test/screenshotter/images/StretchyAccentColor-firefox.png differ
diff --git a/test/screenshotter/images/UnsupportedCmds-chrome.png b/test/screenshotter/images/UnsupportedCmds-chrome.png
index 3594301d..824bdedf 100644
Binary files a/test/screenshotter/images/UnsupportedCmds-chrome.png and b/test/screenshotter/images/UnsupportedCmds-chrome.png differ
diff --git a/test/screenshotter/images/UnsupportedCmds-firefox.png b/test/screenshotter/images/UnsupportedCmds-firefox.png
index a28a4e3d..f33aa70c 100644
Binary files a/test/screenshotter/images/UnsupportedCmds-firefox.png and b/test/screenshotter/images/UnsupportedCmds-firefox.png differ