diff --git a/src/buildHTML.js b/src/buildHTML.js
index 631f5f19..e9556ec8 100644
--- a/src/buildHTML.js
+++ b/src/buildHTML.js
@@ -1533,43 +1533,63 @@ groupTypes.accentUnder = function(group, options) {
};
groupTypes.enclose = function(group, options) {
- // \cancel, \bcancel, \xcancel, \sout, \fbox
+ // \cancel, \bcancel, \xcancel, \sout, \fbox, \colorbox, \fcolorbox
const inner = buildGroup(group.value.body, options);
const label = group.value.label.substr(1);
const scale = options.sizeMultiplier;
let img;
- let pad = 0;
let imgShift = 0;
+ const isColorbox = /color/.test(label);
if (label === "sout") {
img = makeSpan(["stretchy", "sout"]);
img.height = options.fontMetrics().defaultRuleThickness / scale;
imgShift = -0.5 * options.fontMetrics().xHeight;
+
} else {
// Add horizontal padding
- inner.classes.push((label === "fbox" ? "boxpad" : "cancel-pad"));
+ inner.classes.push(/cancel/.test(label) ? "cancel-pad" : "boxpad");
// Add vertical padding
- const isCharBox = (isCharacterBox(group.value.body));
+ let vertPad = 0;
// ref: LaTeX source2e: \fboxsep = 3pt; \fboxrule = .4pt
// ref: cancel package: \advance\totalheight2\p@ % "+2"
- pad = (label === "fbox" ? 0.34 : (isCharBox ? 0.2 : 0));
- imgShift = inner.depth + pad;
+ if (/box/.test(label)) {
+ vertPad = label === "colorbox" ? 0.3 : 0.34;
+ } else {
+ vertPad = isCharacterBox(group.value.body) ? 0.2 : 0;
+ }
- img = stretchy.encloseSpan(inner, label, pad, options);
+ img = stretchy.encloseSpan(inner, label, vertPad, options);
+ imgShift = inner.depth + vertPad;
+
+ if (isColorbox) {
+ img.style.backgroundColor = group.value.backgroundColor.value;
+ if (label === "fcolorbox") {
+ img.style.borderColor = group.value.borderColor.value;
+ }
+ }
}
- const vlist = buildCommon.makeVList([
- {type: "elem", elem: inner, shift: 0},
- {type: "elem", elem: img, shift: imgShift},
- ], "individualShift", null, options);
-
- if (label !== "fbox") {
- vlist.children[0].children[0].children[1].classes.push("svg-align");
+ let vlist;
+ if (isColorbox) {
+ vlist = buildCommon.makeVList([
+ // Put the color background behind inner;
+ {type: "elem", elem: img, shift: imgShift},
+ {type: "elem", elem: inner, shift: 0},
+ ], "individualShift", null, options);
+ } else {
+ vlist = buildCommon.makeVList([
+ // Write the \cancel stroke on top of inner.
+ {type: "elem", elem: inner, shift: 0},
+ {type: "elem", elem: img, shift: imgShift},
+ ], "individualShift", null, options);
}
if (/cancel/.test(label)) {
+ vlist.children[0].children[0].children[1].classes.push("svg-align");
+
// cancel does not create horiz space for its line extension.
// That is, not when adjacent to a mord.
return makeSpan(["mord", "cancel-lap"], [vlist], options);
diff --git a/src/buildMathML.js b/src/buildMathML.js
index c2607b13..c632b93c 100644
--- a/src/buildMathML.js
+++ b/src/buildMathML.js
@@ -505,21 +505,33 @@ groupTypes.accentUnder = function(group, options) {
groupTypes.enclose = function(group, options) {
const node = new mathMLTree.MathNode(
"menclose", [buildGroup(group.value.body, options)]);
- let notation = "";
switch (group.value.label) {
+ case "\\cancel":
+ node.setAttribute("notation", "updiagonalstrike");
+ break;
case "\\bcancel":
- notation = "downdiagonalstrike";
+ node.setAttribute("notation", "downdiagonalstrike");
break;
case "\\sout":
- notation = "horizontalstrike";
+ node.setAttribute("notation", "horizontalstrike");
break;
case "\\fbox":
- notation = "box";
+ node.setAttribute("notation", "box");
+ break;
+ case "\\colorbox":
+ node.setAttribute("mathbackground",
+ group.value.backgroundColor.value);
+ break;
+ case "\\fcolorbox":
+ node.setAttribute("mathbackground",
+ group.value.backgroundColor.value);
+ // TODO(ron): I don't know any way to set the border color.
+ node.setAttribute("notation", "box");
break;
default:
- notation = "updiagonalstrike";
+ // xcancel
+ node.setAttribute("notation", "updiagonalstrike downdiagonalstrike");
}
- node.setAttribute("notation", notation);
return node;
};
diff --git a/src/functions.js b/src/functions.js
index 91c6a542..fc293e7d 100644
--- a/src/functions.js
+++ b/src/functions.js
@@ -88,6 +88,42 @@ defineFunction(["\\color"], {
argTypes: ["color"],
}, null);
+// colorbox
+defineFunction(["\\colorbox"], {
+ numArgs: 2,
+ allowedInText: true,
+ greediness: 3,
+ argTypes: ["color", "text"],
+}, function(context, args) {
+ const color = args[0];
+ const body = args[1];
+ return {
+ type: "enclose",
+ label: context.funcName,
+ backgroundColor: color,
+ body: body,
+ };
+});
+
+// fcolorbox
+defineFunction(["\\fcolorbox"], {
+ numArgs: 3,
+ allowedInText: true,
+ greediness: 3,
+ argTypes: ["color", "color", "text"],
+}, function(context, args) {
+ const borderColor = args[0];
+ const backgroundColor = args[1];
+ const body = args[2];
+ return {
+ type: "enclose",
+ label: context.funcName,
+ backgroundColor: backgroundColor,
+ borderColor: borderColor,
+ body: body,
+ };
+});
+
// An overline
defineFunction(["\\overline"], {
numArgs: 1,
diff --git a/src/stretchy.js b/src/stretchy.js
index 3e2e16f1..7a3e3c21 100644
--- a/src/stretchy.js
+++ b/src/stretchy.js
@@ -254,11 +254,13 @@ const encloseSpan = function(inner, label, pad, options) {
let img;
const totalHeight = inner.height + inner.depth + 2 * pad;
- if (label === "fbox") {
+ if (/(fbox)|(color)/.test(label)) {
img = buildCommon.makeSpan(["stretchy", label], [], options);
- if (options.color) {
+
+ if (label === "fbox" && options.color) {
img.style.borderColor = options.getColor();
}
+
} else {
// \cancel, \bcancel, or \xcancel
// Since \cancel's SVG is inline and it omits the viewBox attribute,
diff --git a/static/katex.less b/static/katex.less
index b009b7bf..f7fad196 100644
--- a/static/katex.less
+++ b/static/katex.less
@@ -593,6 +593,10 @@
box-sizing: border-box;
border: 0.04em solid black; // \fboxrule = 0.4pt
}
+ .fcolorbox {
+ box-sizing: border-box;
+ border: 0.04em solid; // \fboxrule = 0.4pt
+ }
.cancel-pad {
padding: 0 0.2em 0 0.2em; // ref: cancel package \advance\dimen@ 2\p@ % "+2"
}
diff --git a/test/__snapshots__/mathml-spec.js.snap b/test/__snapshots__/mathml-spec.js.snap
index 2b52ca14..3edca120 100644
--- a/test/__snapshots__/mathml-spec.js.snap
+++ b/test/__snapshots__/mathml-spec.js.snap
@@ -74,6 +74,27 @@ exports[`A MathML builder should make prime operators into nodes 1`] = `
`;
+exports[`A MathML builder should use for colorbox 1`] = `
+
+
+
+`;
+
exports[`A MathML builder should use for raisebox 1`] = `