diff --git a/src/buildHTML.js b/src/buildHTML.js
index 5deb4fa5..4180b1bf 100644
--- a/src/buildHTML.js
+++ b/src/buildHTML.js
@@ -49,6 +49,23 @@ const isBinRightCanceller = function(node, isRealGroup) {
}
};
+/**
+ * Splice out any spaces from `children` starting at position `i`, and return
+ * the spliced-out array. Returns null if `children[i]` does not exist or is not
+ * a space.
+ */
+const spliceSpaces = function(children, i) {
+ let j = i;
+ while (j < children.length && isSpace(children[j])) {
+ j++;
+ }
+ if (j === i) {
+ return null;
+ } else {
+ return children.splice(i, j - i);
+ }
+};
+
/**
* Take a list of nodes, build them in order, and return a list of the built
* nodes. documentFragments are flattened into their contents, so the
@@ -74,24 +91,18 @@ const buildExpression = function(expression, options, isRealGroup) {
// spacing (e.g., "add thick space between mord and mrel"). Since CSS
// adjacency rules implement atom spacing, spaces should be invisible to
// CSS. So we splice them out of `groups` and into the atoms themselves.
- let spaces = null;
for (let i = 0; i < groups.length; i++) {
- if (isSpace(groups[i])) {
- spaces = spaces || [];
- spaces.push(groups[i]);
- groups.splice(i, 1);
- i--;
- } else if (spaces) {
+ const spaces = spliceSpaces(groups, i);
+ if (spaces && i < groups.length) {
if (groups[i] instanceof domTree.symbolNode) {
groups[i] = makeSpan([].concat(groups[i].classes), [groups[i]]);
}
buildCommon.prependChildren(groups[i], spaces);
- spaces = null;
+ } else if (spaces) {
+ Array.prototype.push.apply(groups, spaces);
+ break;
}
}
- if (spaces) {
- Array.prototype.push.apply(groups, spaces);
- }
// Binary operators change to ordinary symbols in some contexts.
for (let i = 0; i < groups.length; i++) {
@@ -1278,11 +1289,17 @@ groupTypes.leftright = function(group, options) {
// Handle middle delimiters
if (hadMiddle) {
for (let i = 1; i < inner.length; i++) {
- if (inner[i].isMiddle) {
+ const middleDelim = inner[i];
+ if (middleDelim.isMiddle) {
// Apply the options that were active when \middle was called
inner[i] = delimiter.leftRightDelim(
- inner[i].isMiddle.value, innerHeight, innerDepth,
- inner[i].isMiddle.options, group.mode, []);
+ middleDelim.isMiddle.value, innerHeight, innerDepth,
+ middleDelim.isMiddle.options, group.mode, []);
+ // Add back spaces shifted into the delimiter
+ const spaces = spliceSpaces(middleDelim.children, 0);
+ if (spaces) {
+ buildCommon.prependChildren(inner[i], spaces);
+ }
}
}
}
diff --git a/test/screenshotter/images/LeftRightMiddle-chrome.png b/test/screenshotter/images/LeftRightMiddle-chrome.png
index f731f146..34ed45ed 100644
Binary files a/test/screenshotter/images/LeftRightMiddle-chrome.png and b/test/screenshotter/images/LeftRightMiddle-chrome.png differ
diff --git a/test/screenshotter/images/LeftRightMiddle-firefox.png b/test/screenshotter/images/LeftRightMiddle-firefox.png
index 4fe9d8c6..64a49f19 100644
Binary files a/test/screenshotter/images/LeftRightMiddle-firefox.png and b/test/screenshotter/images/LeftRightMiddle-firefox.png differ
diff --git a/test/screenshotter/ss_data.yaml b/test/screenshotter/ss_data.yaml
index 51e6373d..fc1e86cd 100644
--- a/test/screenshotter/ss_data.yaml
+++ b/test/screenshotter/ss_data.yaml
@@ -86,7 +86,7 @@ Kern:
Lap: ab\llap{f}cd\rlap{g}h
LeftRight: \left( x^2 \right) \left\{ x^{x^{x^{x^x}}} \right.
LeftRightListStyling: a+\left(x+y\right)-x
-LeftRightMiddle: \left( x^2 \middle/ \right) \left\{ x^{x^{x^{x^x}}} \middle/ y \right.
+LeftRightMiddle: \left( x^2 \middle/ \right) \left\{ x^{x^{x^{x^x}}} \middle/ y \right.\left(x\middle|y\,\middle|\,z\right)
LeftRightStyleSizing: |
+\left\{\rule{0.1em}{1em}\right.
x^{+\left\{\rule{0.1em}{1em}\right.