diff --git a/src/functions/accent.js b/src/functions/accent.js index 71a3f657..a681fb54 100644 --- a/src/functions/accent.js +++ b/src/functions/accent.js @@ -209,7 +209,7 @@ defineFunction({ type: "accent", names: [ "\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve", - "\\check", "\\hat", "\\vec", "\\dot", "\\mathring", + "\\check", "\\hat", "\\vec", "\\dot", "\\mathring", "\\widecheck", "\\widehat", "\\widetilde", "\\overrightarrow", "\\overleftarrow", "\\Overrightarrow", "\\overleftrightarrow", "\\overgroup", "\\overlinesegment", "\\overleftharpoon", "\\overrightharpoon", @@ -223,7 +223,8 @@ defineFunction({ const isStretchy = !NON_STRETCHY_ACCENT_REGEX.test(context.funcName); const isShifty = !isStretchy || context.funcName === "\\widehat" || - context.funcName === "\\widetilde"; + context.funcName === "\\widetilde" || + context.funcName === "\\widecheck"; return new ParseNode("accent", { type: "accent", diff --git a/src/stretchy.js b/src/stretchy.js index e86abc54..0efab4b1 100644 --- a/src/stretchy.js +++ b/src/stretchy.js @@ -16,6 +16,7 @@ import type {DomSpan, SvgSpan} from "./domTree"; const stretchyCodePoint: {[string]: string} = { widehat: "^", + widecheck: "ˇ", widetilde: "~", utilde: "~", overleftarrow: "\u2190", @@ -180,7 +181,8 @@ const svgSpan = function( } { let viewBoxWidth = 400000; // default const label = group.value.label.substr(1); - if (utils.contains(["widehat", "widetilde", "utilde"], label)) { + if (utils.contains(["widehat", "widecheck", "widetilde", "utilde"], + label)) { // Each type in the `if` statement corresponds to one of the ParseNode // types below. This narrowing is required to access `grp.value.base`. // $FlowFixMe @@ -193,18 +195,24 @@ const svgSpan = function( let height; if (numChars > 5) { - viewBoxHeight = (label === "widehat" ? 420 : 312); - viewBoxWidth = (label === "widehat" ? 2364 : 2340); - // Next get the span height, in 1000 ems - height = (label === "widehat" ? 0.42 : 0.34); - pathName = (label === "widehat" ? "widehat" : "tilde") + "4"; + if (label === "widehat" || label === "widecheck") { + viewBoxHeight = 420; + viewBoxWidth = 2364; + height = 0.42; + pathName = label + "4"; + } else { + viewBoxHeight = 312; + viewBoxWidth = 2340; + height = 0.34; + pathName = "tilde4"; + } } else { const imgIndex = [1, 1, 2, 2, 3, 3][numChars]; - if (label === "widehat") { + if (label === "widehat" || label === "widecheck") { viewBoxWidth = [0, 1062, 2364, 2364, 2364][imgIndex]; viewBoxHeight = [0, 239, 300, 360, 420][imgIndex]; height = [0, 0.24, 0.3, 0.3, 0.36, 0.42][imgIndex]; - pathName = "widehat" + imgIndex; + pathName = label + imgIndex; } else { viewBoxWidth = [0, 600, 1033, 2339, 2340][imgIndex]; viewBoxHeight = [0, 260, 286, 306, 312][imgIndex]; diff --git a/src/svgGeometry.js b/src/svgGeometry.js index 05d5149d..b68d9806 100644 --- a/src/svgGeometry.js +++ b/src/svgGeometry.js @@ -281,6 +281,19 @@ c-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z`, widehat4: `M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10 -11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z`, + // widecheck paths are all inverted versions of widehat + widecheck1: `M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1, +-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z`, + + widecheck2: `M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, +-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`, + + widecheck3: `M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, +-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`, + + widecheck4: `M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10, +-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z`, + // baraboveleftarrow is from glyph U+21C4 in font KaTeX AMS Regular baraboveleftarrow: `M1 500c30.67-18 59-41.833 85-71.5s45-61.17 57-94.5h23 c15.33 0 23 .33 23 1 0 .67-5.33 12.67-16 36-16.67 34.67-39 67.33-67 98l-10 11 diff --git a/test/katex-spec.js b/test/katex-spec.js index 9df1c905..89a4f052 100644 --- a/test/katex-spec.js +++ b/test/katex-spec.js @@ -1865,6 +1865,7 @@ describe("An accent parser", function() { it("should parse stretchy, shifty accents", function() { expect("\\widehat{x}").toParse(); + expect("\\widecheck{x}").toParse(); }); it("should parse stretchy, non-shifty accents", function() { @@ -1892,6 +1893,7 @@ describe("An accent builder", function() { describe("A stretchy and shifty accent builder", function() { it("should not fail", function() { expect("\\widehat{AB}").toBuild(); + expect("\\widecheck{AB}").toBuild(); expect("\\widehat{AB}^2").toBuild(); expect("\\widehat{AB}_2").toBuild(); expect("\\widehat{AB}_2^2").toBuild(); diff --git a/test/screenshotter/images/StretchyAccent-chrome.png b/test/screenshotter/images/StretchyAccent-chrome.png index b6ac7c5c..d3e4e835 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 4558d18c..5b36c18d 100644 Binary files a/test/screenshotter/images/StretchyAccent-firefox.png and b/test/screenshotter/images/StretchyAccent-firefox.png differ diff --git a/test/screenshotter/ss_data.yaml b/test/screenshotter/ss_data.yaml index 0a8cf6d1..c84290f7 100644 --- a/test/screenshotter/ss_data.yaml +++ b/test/screenshotter/ss_data.yaml @@ -301,7 +301,7 @@ StretchyAccent: | \begin{array}{l} \overrightarrow{AB} \quad \overleftarrow{AB} \quad \Overrightarrow{AB} \quad \overleftrightarrow{AB} \quad \overgroup{AB} \\ \overlinesegment{AB} \quad \overleftharpoon{AB} \quad \overrightharpoon{AB} \quad \color{red}{\overrightarrow{AB}} \quad \widehat{\theta} \widetilde{A} \\ - \widehat{AB} \quad \widehat{ABC} \quad \widetilde{AB} \quad \widetilde{ABC} \\ + \widecheck{AB} \quad \widehat{ABC} \quad \widetilde{AB} \quad \widetilde{ABC} \\ \overrightarrow{F} + \overrightarrow{AB} + \overrightarrow{F}^2 + \overrightarrow{F}_2 + \overrightarrow{F}_1^2 \\ \overrightarrow{AB}^2+\frac{\overrightarrow{AB}}{\overrightarrow{AB}} + \sqrt{\overrightarrow{AB}} + \left\lvert\overrightarrow{AB}\right\rvert \end{array}