diff --git a/src/buildCommon.js b/src/buildCommon.js index 6d26beed..1e05dcd5 100644 --- a/src/buildCommon.js +++ b/src/buildCommon.js @@ -728,8 +728,6 @@ const svgData: { oiintSize2: ["oiintSize2", 1.472, 0.659], oiiintSize1: ["oiiintSize1", 1.304, 0.499], oiiintSize2: ["oiiintSize2", 1.98, 0.659], - leftParenInner: ["leftParenInner", 0.875, 0.3], - rightParenInner: ["rightParenInner", 0.875, 0.3], }; const staticSvg = function(value: string, options: Options): SvgSpan { diff --git a/src/delimiter.js b/src/delimiter.js index cc3a4d93..7c688a00 100644 --- a/src/delimiter.js +++ b/src/delimiter.js @@ -25,11 +25,12 @@ import ParseError from "./ParseError"; import Style from "./Style"; import {PathNode, SvgNode, SymbolNode} from "./domTree"; -import {sqrtPath} from "./svgGeometry"; +import {sqrtPath, innerPath} from "./svgGeometry"; import buildCommon from "./buildCommon"; import {getCharacterMetrics} from "./fontMetrics"; import symbols from "./symbols"; import utils from "./utils"; +import fontMetricsData from "../submodules/katex-fonts/fontMetricsData"; import type Options from "./Options"; import type {CharacterMetrics} from "./fontMetrics"; @@ -153,10 +154,10 @@ const makeLargeDelim = function(delim, }; /** - * Make an inner span with the given offset and in the given font. This is used - * in `makeStackedDelim` to make the stacking pieces for the delimiter. + * Make a span from a font glyph with the given offset and in the given font. + * This is used in makeStackedDelim to make the stacking pieces for the delimiter. */ -const makeInner = function( +const makeGlyphSpan = function( symbol: string, font: "Size1-Regular" | "Size4-Regular", mode: Mode, @@ -169,17 +170,45 @@ const makeInner = function( sizeClass = "delim-size4"; } - const inner = buildCommon.makeSpan( + const corner = buildCommon.makeSpan( ["delimsizinginner", sizeClass], [buildCommon.makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]); // Since this will be passed into `makeVList` in the end, wrap the element // in the appropriate tag that VList uses. - return {type: "elem", elem: inner}; + return {type: "elem", elem: corner}; }; -// Helper for makeStackedDelim -const lap = {type: "kern", size: -0.005}; +const makeInner = function( + ch: string, + height: number, + options: Options +): VListElem { + // Create a span with inline SVG for the inner part of a tall stacked delimiter. + const width = fontMetricsData['Size4-Regular'][ch.charCodeAt(0)] + ? fontMetricsData['Size4-Regular'][ch.charCodeAt(0)][4].toFixed(3) + : fontMetricsData['Size1-Regular'][ch.charCodeAt(0)][4].toFixed(3); + const path = new PathNode("inner", innerPath(ch, Math.round(1000 * height))); + const svgNode = new SvgNode([path], { + "width": width + "em", + "height": height + "em", + // Override CSS rule `.katex svg { width: 100% }` + "style": "width:" + width + "em", + "viewBox": "0 0 " + 1000 * width + " " + Math.round(1000 * height), + "preserveAspectRatio": "xMinYMin", + }); + const span = buildCommon.makeSvgSpan([], [svgNode], options); + span.height = height; + span.style.height = height + "em"; + span.style.width = width + "em"; + return {type: "elem", elem: span}; +}; + +// Helpers for makeStackedDelim +const lapInEms = 0.008; +const lap = {type: "kern", size: -1 * lapInEms}; +const verts = ["|", "\\lvert", "\\rvert", "\\vert"]; +const doubleVerts = ["\\|", "\\lVert", "\\rVert", "\\Vert"]; /** * Make a stacked delimiter out of a given delimiter, with the total height at @@ -223,6 +252,10 @@ const makeStackedDelim = function( top = "\\Uparrow"; repeat = "\u2016"; bottom = "\\Downarrow"; + } else if (utils.contains(verts, delim)) { + repeat = "\u2223"; + } else if (utils.contains(doubleVerts, delim)) { + repeat = "\u2225"; } else if (delim === "[" || delim === "\\lbrack") { top = "\u23a1"; repeat = "\u23a2"; @@ -331,74 +364,44 @@ const makeStackedDelim = function( // Calculate the depth const depth = realHeightTotal / 2 - axisHeight; - // This function differs from the TeX procedure in one way. - // We shift each repeat element downwards by 0.005em, to prevent a gap - // due to browser floating point rounding error. - // Then, at the last element-to element joint, we add one extra repeat - // element to cover the gap created by the shifts. - // Find the shift needed to align the upper end of the extra element at a point - // 0.005em above the lower end of the top element. - const shiftOfExtraElement = (repeatCount + 1) * 0.005 - repeatHeightTotal; // Now, we start building the pieces that will go into the vlist - - // Keep a list of the inner pieces - const inners = []; + // Keep a list of the pieces of the stacked delimiter + const stack = []; // Add the bottom symbol - inners.push(makeInner(bottom, font, mode)); + stack.push(makeGlyphSpan(bottom, font, mode)); + stack.push(lap); // overlap if (middle === null) { - // Add that many symbols - for (let i = 0; i < repeatCount; i++) { - inners.push(lap); // overlap - inners.push(makeInner(repeat, font, mode)); - } + // The middle section will be an SVG. Make it an extra 0.016em tall. + // We'll overlap by 0.008em at top and bottom. + const innerHeight = realHeightTotal - topHeightTotal - bottomHeightTotal + + 2 * lapInEms; + stack.push(makeInner(repeat, innerHeight, options)); } else { // When there is a middle bit, we need the middle part and two repeated // sections - for (let i = 0; i < repeatCount; i++) { - inners.push(lap); - inners.push(makeInner(repeat, font, mode)); - } - // Insert one extra repeat element. - inners.push({type: "kern", size: shiftOfExtraElement}); - inners.push(makeInner(repeat, font, mode)); - inners.push(lap); + const innerHeight = (realHeightTotal - topHeightTotal - bottomHeightTotal - + middleHeightTotal) / 2 + 2 * lapInEms; + stack.push(makeInner(repeat, innerHeight, options)); // Now insert the middle of the brace. - inners.push(makeInner(middle, font, mode)); - for (let i = 0; i < repeatCount; i++) { - inners.push(lap); - inners.push(makeInner(repeat, font, mode)); - } - } - - // To cover the gap create by the overlaps, insert one more repeat element, - // at a position that juts 0.005 above the bottom of the top element. - if ((repeat === "\u239c" || repeat === "\u239f") && repeatCount === 0) { - // Parentheses need a short repeat element in order to avoid an overrun. - // We'll make a 0.3em tall element from a SVG. - const overlap = buildCommon.svgData.leftParenInner[2] / 2; - inners.push({type: "kern", size: -overlap}); - const pathName = repeat === "\u239c" ? "leftParenInner" : "rightParenInner"; - const innerSpan = buildCommon.staticSvg(pathName, options); - inners.push({type: "elem", elem: innerSpan}); - inners.push({type: "kern", size: -overlap}); - } else { - inners.push({type: "kern", size: shiftOfExtraElement}); - inners.push(makeInner(repeat, font, mode)); - inners.push(lap); + stack.push(lap); + stack.push(makeGlyphSpan(middle, font, mode)); + stack.push(lap); + stack.push(makeInner(repeat, innerHeight, options)); } // Add the top symbol - inners.push(makeInner(top, font, mode)); + stack.push(lap); + stack.push(makeGlyphSpan(top, font, mode)); // Finally, build the vlist const newOptions = options.havingBaseStyle(Style.TEXT); const inner = buildCommon.makeVList({ positionType: "bottom", positionData: depth, - children: inners, + children: stack, }, newOptions); return styleWrap( diff --git a/src/domTree.js b/src/domTree.js index 9439bb14..4425b796 100644 --- a/src/domTree.js +++ b/src/domTree.js @@ -533,7 +533,7 @@ export class PathNode implements VirtualNode { constructor(pathName: string, alternate?: string) { this.pathName = pathName; - this.alternate = alternate; // Used only for \sqrt and \phase + this.alternate = alternate; // Used only for \sqrt, \phase, & tall delims } toNode(): Node { diff --git a/src/svgGeometry.js b/src/svgGeometry.js index 00018e2b..8307cb05 100644 --- a/src/svgGeometry.js +++ b/src/svgGeometry.js @@ -151,11 +151,35 @@ export const sqrtPath = function( return path; }; -export const path: {[string]: string} = { - // Two paths that cover gaps in built-up parentheses. - leftParenInner: `M291 0 H417 V300 H291 z`, - rightParenInner: `M457 0 H583 V300 H457 z`, +export const innerPath = function(name: string, height: number): string { + // The inner part of stretchy tall delimiters + switch (name) { + case "\u239c": + return `M291 0 H417 V${height} H291z M291 0 H417 V${height} H291z`; + case "\u2223": + return `M145 0 H188 V${height} H145z M145 0 H188 V${height} H145z`; + case "\u2225": + return `M145 0 H188 V${height} H145z M145 0 H188 V${height} H145z` + + `M367 0 H410 V${height} H367z M367 0 H410 V${height} H367z`; + case "\u239f": + return `M457 0 H583 V${height} H457z M457 0 H583 V${height} H457z`; + case "\u23a2": + return `M319 0 H403 V${height} H319z M319 0 H403 V${height} H319z`; + case "\u23a5": + return `M263 0 H347 V${height} H263z M263 0 H347 V${height} H263z`; + case "\u23aa": + return `M384 0 H504 V${height} H384z M384 0 H504 V${height} H384z`; + case "\u23d0": + return `M312 0 H355 V${height} H312z M312 0 H355 V${height} H312z`; + case "\u2016": + return `M257 0 H300 V${height} H257z M257 0 H300 V${height} H257z` + + `M478 0 H521 V${height} H478z M478 0 H521 V${height} H478z`; + default: + return ""; + } +}; +export const path: {[string]: string} = { // The doubleleftarrow geometry is from glyph U+21D0 in the font KaTeX Main doubleleftarrow: `M262 157 l10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3 diff --git a/test/screenshotter/images/Arrays-chrome.png b/test/screenshotter/images/Arrays-chrome.png index 8cf6bcfc..670bcc88 100644 Binary files a/test/screenshotter/images/Arrays-chrome.png and b/test/screenshotter/images/Arrays-chrome.png differ diff --git a/test/screenshotter/images/Arrays-firefox.png b/test/screenshotter/images/Arrays-firefox.png index a50d679a..143a13d0 100644 Binary files a/test/screenshotter/images/Arrays-firefox.png and b/test/screenshotter/images/Arrays-firefox.png differ diff --git a/test/screenshotter/images/Arrays-safari.png b/test/screenshotter/images/Arrays-safari.png index e3496281..4ddd8c95 100644 Binary files a/test/screenshotter/images/Arrays-safari.png and b/test/screenshotter/images/Arrays-safari.png differ diff --git a/test/screenshotter/images/CD-chrome.png b/test/screenshotter/images/CD-chrome.png index 7ea84ba4..dbb4ac4c 100644 Binary files a/test/screenshotter/images/CD-chrome.png and b/test/screenshotter/images/CD-chrome.png differ diff --git a/test/screenshotter/images/CD-firefox.png b/test/screenshotter/images/CD-firefox.png index 4829ae8f..f03dbd4c 100644 Binary files a/test/screenshotter/images/CD-firefox.png and b/test/screenshotter/images/CD-firefox.png differ diff --git a/test/screenshotter/images/CD-safari.png b/test/screenshotter/images/CD-safari.png index af634dcc..c11702d9 100644 Binary files a/test/screenshotter/images/CD-safari.png and b/test/screenshotter/images/CD-safari.png differ diff --git a/test/screenshotter/images/Cases-chrome.png b/test/screenshotter/images/Cases-chrome.png index fb9669ce..e66ad48c 100644 Binary files a/test/screenshotter/images/Cases-chrome.png and b/test/screenshotter/images/Cases-chrome.png differ diff --git a/test/screenshotter/images/Cases-firefox.png b/test/screenshotter/images/Cases-firefox.png index 637ffb54..0a33c841 100644 Binary files a/test/screenshotter/images/Cases-firefox.png and b/test/screenshotter/images/Cases-firefox.png differ diff --git a/test/screenshotter/images/Cases-safari.png b/test/screenshotter/images/Cases-safari.png index 7f61b0c0..5ccf3e68 100644 Binary files a/test/screenshotter/images/Cases-safari.png and b/test/screenshotter/images/Cases-safari.png differ diff --git a/test/screenshotter/images/DeepFontSizing-chrome.png b/test/screenshotter/images/DeepFontSizing-chrome.png index a66ad501..0f720475 100644 Binary files a/test/screenshotter/images/DeepFontSizing-chrome.png and b/test/screenshotter/images/DeepFontSizing-chrome.png differ diff --git a/test/screenshotter/images/DeepFontSizing-firefox.png b/test/screenshotter/images/DeepFontSizing-firefox.png index ea6e6f9b..f294d18c 100644 Binary files a/test/screenshotter/images/DeepFontSizing-firefox.png and b/test/screenshotter/images/DeepFontSizing-firefox.png differ diff --git a/test/screenshotter/images/DeepFontSizing-safari.png b/test/screenshotter/images/DeepFontSizing-safari.png index 1791f344..7fec5602 100644 Binary files a/test/screenshotter/images/DeepFontSizing-safari.png and b/test/screenshotter/images/DeepFontSizing-safari.png differ diff --git a/test/screenshotter/images/DelimiterSizing-chrome.png b/test/screenshotter/images/DelimiterSizing-chrome.png index 375936d6..81c4e2a9 100644 Binary files a/test/screenshotter/images/DelimiterSizing-chrome.png and b/test/screenshotter/images/DelimiterSizing-chrome.png differ diff --git a/test/screenshotter/images/DelimiterSizing-firefox.png b/test/screenshotter/images/DelimiterSizing-firefox.png index a7f7ae7b..04ea266f 100644 Binary files a/test/screenshotter/images/DelimiterSizing-firefox.png and b/test/screenshotter/images/DelimiterSizing-firefox.png differ diff --git a/test/screenshotter/images/DelimiterSizing-safari.png b/test/screenshotter/images/DelimiterSizing-safari.png index 97955997..7dd5de41 100644 Binary files a/test/screenshotter/images/DelimiterSizing-safari.png and b/test/screenshotter/images/DelimiterSizing-safari.png differ diff --git a/test/screenshotter/images/ExtensibleArrows-chrome.png b/test/screenshotter/images/ExtensibleArrows-chrome.png index 38c1d51f..a40b475e 100644 Binary files a/test/screenshotter/images/ExtensibleArrows-chrome.png and b/test/screenshotter/images/ExtensibleArrows-chrome.png differ diff --git a/test/screenshotter/images/ExtensibleArrows-firefox.png b/test/screenshotter/images/ExtensibleArrows-firefox.png index bdc060da..20b78d42 100644 Binary files a/test/screenshotter/images/ExtensibleArrows-firefox.png and b/test/screenshotter/images/ExtensibleArrows-firefox.png differ diff --git a/test/screenshotter/images/ExtensibleArrows-safari.png b/test/screenshotter/images/ExtensibleArrows-safari.png index 00e9d20d..74491a6d 100644 Binary files a/test/screenshotter/images/ExtensibleArrows-safari.png and b/test/screenshotter/images/ExtensibleArrows-safari.png differ diff --git a/test/screenshotter/images/LowerAccent-chrome.png b/test/screenshotter/images/LowerAccent-chrome.png index 13cb0699..3106a663 100644 Binary files a/test/screenshotter/images/LowerAccent-chrome.png and b/test/screenshotter/images/LowerAccent-chrome.png differ diff --git a/test/screenshotter/images/LowerAccent-firefox.png b/test/screenshotter/images/LowerAccent-firefox.png index 6ed9e27a..03049256 100644 Binary files a/test/screenshotter/images/LowerAccent-firefox.png and b/test/screenshotter/images/LowerAccent-firefox.png differ diff --git a/test/screenshotter/images/LowerAccent-safari.png b/test/screenshotter/images/LowerAccent-safari.png index 2dc0a319..8c813e66 100644 Binary files a/test/screenshotter/images/LowerAccent-safari.png and b/test/screenshotter/images/LowerAccent-safari.png differ diff --git a/test/screenshotter/images/StretchyAccent-chrome.png b/test/screenshotter/images/StretchyAccent-chrome.png index bd8fb53c..43b0c016 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 6522d6f7..f49a4209 100644 Binary files a/test/screenshotter/images/StretchyAccent-firefox.png and b/test/screenshotter/images/StretchyAccent-firefox.png differ diff --git a/test/screenshotter/images/StretchyAccent-safari.png b/test/screenshotter/images/StretchyAccent-safari.png index a2d3336e..a10dec9a 100644 Binary files a/test/screenshotter/images/StretchyAccent-safari.png and b/test/screenshotter/images/StretchyAccent-safari.png differ diff --git a/test/screenshotter/images/SupSubHorizSpacing-chrome.png b/test/screenshotter/images/SupSubHorizSpacing-chrome.png index b6931aaa..9aeaea2a 100644 Binary files a/test/screenshotter/images/SupSubHorizSpacing-chrome.png and b/test/screenshotter/images/SupSubHorizSpacing-chrome.png differ diff --git a/test/screenshotter/images/SupSubHorizSpacing-firefox.png b/test/screenshotter/images/SupSubHorizSpacing-firefox.png index ee9a0fe0..9b2761d2 100644 Binary files a/test/screenshotter/images/SupSubHorizSpacing-firefox.png and b/test/screenshotter/images/SupSubHorizSpacing-firefox.png differ diff --git a/test/screenshotter/images/SupSubHorizSpacing-safari.png b/test/screenshotter/images/SupSubHorizSpacing-safari.png index 9c4fbb7c..f5d8bce4 100644 Binary files a/test/screenshotter/images/SupSubHorizSpacing-safari.png and b/test/screenshotter/images/SupSubHorizSpacing-safari.png differ