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}