Revert frac-lines to borders (#1249)

* Revert frac-lines to borders

This PR reverts the rendering of frac-lines from SVG paths back to span borders. This solves the thick grey bar reported by @mbourne in issue #1173.

The result is a frac-line similar to KaTeX v0.9.0-alpha1. The frac-lines are span borders and the CSS contains a `min-width: 1px;` rule to keep those borders visible.

There is one difference between this PR and v0.9.0-alpha1. The earlier work contained a second CSS rule:
```
@media screen and (-webkit-min-device-pixel-ratio: 2), screen and (min-resolution: 192dpi) {
      .katex.mfra.fracline {
            min-height:0.5px;
        }
    }

That second CSS rule did not help much. Instead, it caused some lines to disappear. In the thread to issue 1173, people tested the rendering from the proposed approach and reported that frac-lines disappeared only at sized that were already too small to read.

* Fix lint errors

* Remove superfluous SVG paths.

* Remove superfluous CSS

* Removed `rulespan` from `stretchy.js`

* Support Unicode \ll and \lll

Fixes issue #1271

* Fix indent

* update screenshots for fracLineBorder

* Update Arrays-chrome screenshot for fracLineBorder
This commit is contained in:
Ron Kok
2018-05-10 00:05:24 -07:00
committed by ylemkimon
parent 7b7b532fb6
commit c2ae9e0da6
56 changed files with 32 additions and 95 deletions

View File

@@ -9,7 +9,6 @@ import domTree from "./domTree";
import fontMetrics from "./fontMetrics";
import symbols from "./symbols";
import utils from "./utils";
import stretchy from "./stretchy";
import {wideCharacterFont} from "./wide-character";
import {calculateSize} from "./units";
@@ -346,14 +345,11 @@ const makeSvgSpan = (
const makeLineSpan = function(
className: string,
options: Options,
thickness?: number,
) {
// Return a span with an SVG image of a horizontal line. The SVG path
// fills the middle fifth of the span. We want an extra tall span
// because Chrome will sometimes not display a span that is 0.04em tall.
const lineHeight = options.fontMetrics().defaultRuleThickness;
const line = stretchy.ruleSpan(className, lineHeight, options);
line.height = lineHeight;
line.style.height = 5 * line.height + "em";
const line = makeSpan([className], [], options);
line.height = thickness || options.fontMetrics().defaultRuleThickness;
line.style.borderBottomWidth = line.height + "em";
line.maxFontSize = 1.0;
return line;
};

View File

@@ -6,7 +6,6 @@ import ParseError from "../ParseError";
import ParseNode from "../ParseNode";
import {calculateSize} from "../units";
import utils from "../utils";
import stretchy from "../stretchy";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -203,8 +202,9 @@ const htmlBuilder = function(group, options) {
}
if (colDescr.separator === "|") {
const separator = stretchy.ruleSpan("vertical-separator", 0.05,
options);
const separator = buildCommon.makeSpan(
["vertical-separator"], [], options
);
separator.style.height = totalHeight + "em";
separator.style.verticalAlign =
-(totalHeight - offset) + "em";

View File

@@ -166,12 +166,7 @@ defineFunction({
positionType: "individualShift",
children: [
{type: "elem", elem: denomm, shift: denomShift},
// The next line would ordinarily contain "shift: midShift".
// But we put the rule into a a span that is 5 rules tall,
// to overcome a Chrome rendering issue. Put another way,
// we've replaced a kern of width = 2 * ruleWidth with a
// bottom padding inside the SVG = 2 * ruleWidth.
{type: "elem", elem: rule, shift: midShift + 2 * ruleWidth},
{type: "elem", elem: rule, shift: midShift},
{type: "elem", elem: numerm, shift: -numShift},
],
}, options);

View File

@@ -34,13 +34,9 @@ defineFunction({
positionType: "firstBaseline",
children: [
{type: "elem", elem: innerGroup},
// The kern on the next line would ordinarily be 3 * line.height
// But we put the line into a span that is 5 lines tall, to
// overcome a Chrome rendering issue. The SVG has a space in
// the bottom that is 2 lines high. That and the 1-line-high
// kern sum up to the same distance as the old 3 line kern.
{type: "kern", size: line.height},
{type: "kern", size: 3 * line.height},
{type: "elem", elem: line},
{type: "kern", size: line.height},
],
}, options);

View File

@@ -33,11 +33,9 @@ defineFunction({
positionType: "top",
positionData: innerGroup.height,
children: [
// The SVG image is 5x as tall as the line.
// The bottom 2/5 of the image is blank and acts like a kern.
// So we omit the kern that would otherwise go at the bottom.
{type: "kern", size: line.height},
{type: "elem", elem: line},
{type: "kern", size: 5 * line.height},
{type: "kern", size: 3 * line.height},
{type: "elem", elem: innerGroup},
],
}, options);

View File

@@ -3,6 +3,20 @@
// The mu unit is defined as 1/18 em
@mu: 1.0/18.0em;
@media screen {
.katex {
.mtable .vertical-separator {
min-width: 1px;
}
.mfrac .frac-line,
.overline .overline-line,
.underline .underline-line {
min-height: 1px;
}
}
}
.katex-display {
display: block;
margin: 1em 0;
@@ -211,6 +225,7 @@
.frac-line {
display: inline-block;
width: 100%;
border-bottom-style: solid;
}
}
@@ -305,6 +320,7 @@
.underline .underline-line {
display: inline-block;
width: 100%;
border-bottom-style: solid;
}
.sqrt {
@@ -419,10 +435,8 @@
.mtable {
.vertical-separator {
display: inline-block;
margin: 0 -0.125em; // The ink in the rule is actually 0.05em wide.
width: 0.25em; // We put it in a 0.25em wide span to overcome
overflow: hidden; // a Chrome rendering issue.
position: relative;
margin: 0 -0.025em;
border-right: 0.05em solid;
}
.arraycolsep {
@@ -478,10 +492,6 @@
stroke-opacity: 1;
}
.vertical-separator svg {
width: 0.25em;
}
// Define CSS for image whose width will match its span width.
.stretchy {
width: 100%;

View File

@@ -346,54 +346,8 @@ const encloseSpan = function(
return img;
};
const ruleSpan = function(
className: string,
lineThickness: number,
options: Options,
): SvgSpan {
// Get a span with an SVG path that fills the middle fifth of the span.
// We're using an extra wide span so Chrome won't round it down to zero.
let path;
let svgNode;
let parentClass = "stretchy"; // default
if (className === "vertical-separator") {
path = new domTree.pathNode("vertSeparator");
svgNode = new domTree.svgNode([path], {
"width": "0.25em", // contains a path that is 0.05 ems wide.
"height": "400em",
"viewBox": "0 0 250 400000",
"preserveAspectRatio": "xMinYMin slice",
});
parentClass = "vertical-separator";
} else {
// The next two lines are the only place in KaTeX where SVG paths are
// put into a viewBox that is not always exactly a 1000:1 scale to the
// document em size. Instead, the path is a horizontal line set to
// take up the middle fifth of the viewBox and span. If the context is
// normalsize/textstyle then the line will be 0.04em and the usual
// 1000:1 ratio holds. But if the context is scriptstyle, then
// lineThickness > 0.04em and we have a ratio somewhat different than
// 1000:1.
path = new domTree.pathNode("stdHorizRule");
svgNode = new domTree.svgNode([path], {
"width": "400em",
"height": 5 * lineThickness + "em",
"viewBox": "0 0 400000 200",
"preserveAspectRatio": "xMinYMin slice",
});
}
return buildCommon.makeSvgSpan([parentClass], [svgNode], options);
};
export default {
encloseSpan,
mathMLnode,
ruleSpan,
svgSpan,
};

View File

@@ -4,23 +4,11 @@
* It's a storehouse of path geometry for SVG images.
*/
// We do frac-lines, underlines, and overlines with an SVG path and we put that
// path is into a viewBox that is 5 times as thick as the line. That way,
// any browser rounding error on the size of the surrounding span will
// not pinch the ink of the line. Think of it as padding for the line.
// As usual, the viewBox-to-em scale is 1000.
// In all paths below, the viewBox-to-em scale is 1000:1.
const hLinePad = 80; // padding above and below a std 0.04em horiz rule.
const vLinePad = 100; // padding on either side of a std vert 0.05em rule.
const hLinePad = 80; // padding above a sqrt viniculum.
const path: {[string]: string} = {
// stdHorizRule is used for frac-lines, underlines, and overlines.
// It is 0.04em thick if the line comes from normalsize/textstyle.
stdHorizRule: `M0 ${hLinePad}H400000 v40H0z M0 ${hLinePad}H400000 v40H0z`,
// vertSeparator is used in arrays. It is 0.05em wide in a 0.25em viewBox.
vertSeparator: `M${vLinePad} 0h50V400000h-50zM${vLinePad} 0h50V400000h-50z`,
// sqrtMain path geometry is from glyph U221A in the font KaTeX Main
// All surds have 80 units padding above the viniculumn.
sqrtMain: `M95,${622 + hLinePad}c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB