diff --git a/src/buildHTML.js b/src/buildHTML.js
index dbd33a3fc..42c33a6c4 100644
--- a/src/buildHTML.js
+++ b/src/buildHTML.js
@@ -51,6 +51,7 @@ var groupToType = {
op: "mop",
katex: "mord",
overline: "mord",
+ underline: "mord",
rule: "mord",
leftright: "minner",
sqrt: "mord",
@@ -928,6 +929,32 @@ groupTypes.overline = function(group, options, prev) {
return makeSpan(["overline", "mord"], [vlist], options.getColor());
};
+groupTypes.underline = function(group, options, prev) {
+ // Underlines are handled in the TeXbook pg 443, Rule 10.
+
+ // Build the inner group.
+ var innerGroup = buildGroup(group.value.body, options);
+
+ var ruleWidth = fontMetrics.metrics.defaultRuleThickness /
+ options.style.sizeMultiplier;
+
+ // Create the line above the body
+ var line = makeSpan(
+ [options.style.reset(), Style.TEXT.cls(), "underline-line"]);
+ line.height = ruleWidth;
+ line.maxFontSize = 1.0;
+
+ // Generate the vlist, with the appropriate kerns
+ var vlist = buildCommon.makeVList([
+ {type: "kern", size: ruleWidth},
+ {type: "elem", elem: line},
+ {type: "kern", size: 3 * ruleWidth},
+ {type: "elem", elem: innerGroup},
+ ], "top", innerGroup.height, options);
+
+ return makeSpan(["underline", "mord"], [vlist], options.getColor());
+};
+
groupTypes.sqrt = function(group, options, prev) {
// Square roots are handled in the TeXbook pg. 443, Rule 11.
diff --git a/src/buildMathML.js b/src/buildMathML.js
index f3c7c5e1c..7bf38e86a 100644
--- a/src/buildMathML.js
+++ b/src/buildMathML.js
@@ -422,6 +422,20 @@ groupTypes.overline = function(group, options) {
return node;
};
+groupTypes.underline = function(group, options) {
+ var operator = new mathMLTree.MathNode(
+ "mo", [new mathMLTree.TextNode("\u203e")]);
+ operator.setAttribute("stretchy", "true");
+
+ var node = new mathMLTree.MathNode(
+ "munder",
+ [buildGroup(group.value.body, options),
+ operator]);
+ node.setAttribute("accentunder", "true");
+
+ return node;
+};
+
groupTypes.rule = function(group) {
// TODO(emily): Figure out if there's an actual way to draw black boxes
// in MathML.
diff --git a/src/functions.js b/src/functions.js
index 2fa124d3b..08d8874d0 100644
--- a/src/functions.js
+++ b/src/functions.js
@@ -170,6 +170,17 @@ defineFunction("\\overline", {
};
});
+// An underline
+defineFunction("\\underline", {
+ numArgs: 1,
+}, function(context, args) {
+ var body = args[0];
+ return {
+ type: "underline",
+ body: body,
+ };
+});
+
// A box of the width and height
defineFunction("\\rule", {
numArgs: 2,
diff --git a/static/katex.less b/static/katex.less
index affddcaac..b7c8f84d9 100644
--- a/static/katex.less
+++ b/static/katex.less
@@ -352,25 +352,23 @@
position: relative;
}
- .overline {
+ .overline .overline-line,
+ .underline .underline-line {
+ width: 100%;
- .overline-line {
- width: 100%;
+ &:before {
+ border-bottom-style: solid;
+ border-bottom-width: 1px;
+ content: "";
+ display: block;
+ }
- &: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;
}
}
diff --git a/test/screenshotter/images/OverUnderline-chrome.png b/test/screenshotter/images/OverUnderline-chrome.png
new file mode 100644
index 000000000..abefb60e3
Binary files /dev/null and b/test/screenshotter/images/OverUnderline-chrome.png differ
diff --git a/test/screenshotter/images/OverUnderline-firefox.png b/test/screenshotter/images/OverUnderline-firefox.png
new file mode 100644
index 000000000..672af18fa
Binary files /dev/null and b/test/screenshotter/images/OverUnderline-firefox.png differ
diff --git a/test/screenshotter/images/Overline-chrome.png b/test/screenshotter/images/Overline-chrome.png
deleted file mode 100644
index 981892388..000000000
Binary files a/test/screenshotter/images/Overline-chrome.png and /dev/null differ
diff --git a/test/screenshotter/images/Overline-firefox.png b/test/screenshotter/images/Overline-firefox.png
deleted file mode 100644
index d301a884b..000000000
Binary files a/test/screenshotter/images/Overline-firefox.png and /dev/null differ
diff --git a/test/screenshotter/ss_data.yaml b/test/screenshotter/ss_data.yaml
index d5e8736fa..964fc6d7c 100644
--- a/test/screenshotter/ss_data.yaml
+++ b/test/screenshotter/ss_data.yaml
@@ -85,7 +85,7 @@ NullDelimiterInteraction: a \bigl. + 2 \quad \left. + a \right)
OpLimits: |
{\sin_2^2 \lim_2^2 \int_2^2 \sum_2^2}
{\displaystyle \lim_2^2 \int_2^2 \intop_2^2 \sum_2^2}
-Overline: \overline{x}\overline{x}\overline{x^{x^{x^x}}} \blue{\overline{y}}
+OverUnderline: x\underline{x}\underline{\underline{x}}\underline{x_{x_{x_x}}}\underline{x^{x^{x^x}}}\overline{x}\overline{x}\overline{x^{x^{x^x}}} \blue{\overline{\underline{x}}\underline{\overline{x}}}
Phantom: \dfrac{1+\phantom{x^{\blue{2}}} = x}{1+x^{\blue{2}} = x}
PrimeSpacing: f'+f_2'+f^{f'}
RlapBug: \frac{\rlap{x}}{2}