fix: round dimensions to 4 places (#2460)

* Round distances to 4 places

* Revert numbers in mathMLTree.js

* Update Jest test

* fix: round dimension to 4 places via makeEm

* test: update screenshots

* docs: add link to this PR

Co-authored-by: ylemkimon <y@ylem.kim>
This commit is contained in:
Ron Kok
2021-10-30 11:28:45 -07:00
committed by GitHub
parent f007358c0f
commit 09ee1c8867
121 changed files with 137 additions and 115 deletions

View File

@@ -9,7 +9,7 @@ import {SymbolNode, Anchor, Span, PathNode, SvgNode, createClass} from "./domTre
import {getCharacterMetrics} from "./fontMetrics";
import symbols, {ligatures} from "./symbols";
import {wideCharacterFont} from "./wide-character";
import {calculateSize} from "./units";
import {calculateSize, makeEm} from "./units";
import {DocumentFragment} from "./tree";
import type Options from "./Options";
@@ -364,7 +364,7 @@ const makeLineSpan = function(
thickness || options.fontMetrics().defaultRuleThickness,
options.minRuleThickness,
);
line.style.borderBottomWidth = line.height + "em";
line.style.borderBottomWidth = makeEm(line.height);
line.maxFontSize = 1.0;
return line;
};
@@ -550,7 +550,7 @@ const makeVList = function(params: VListParam, options: Options): DomSpan {
}
pstrutSize += 2;
const pstrut = makeSpan(["pstrut"], []);
pstrut.style.height = pstrutSize + "em";
pstrut.style.height = makeEm(pstrutSize);
// Create a new list of actual children at the correct offsets
const realChildren = [];
@@ -567,7 +567,7 @@ const makeVList = function(params: VListParam, options: Options): DomSpan {
const style = child.wrapperStyle || {};
const childWrap = makeSpan(classes, [pstrut, elem], undefined, style);
childWrap.style.top = (-pstrutSize - currPos - elem.depth) + "em";
childWrap.style.top = makeEm(-pstrutSize - currPos - elem.depth);
if (child.marginLeft) {
childWrap.style.marginLeft = child.marginLeft;
}
@@ -586,7 +586,7 @@ const makeVList = function(params: VListParam, options: Options): DomSpan {
// This cell's bottom edge will determine the containing table's baseline
// without overly expanding the containing line-box.
const vlist = makeSpan(["vlist"], realChildren);
vlist.style.height = maxPos + "em";
vlist.style.height = makeEm(maxPos);
// A second row is used if necessary to represent the vlist's depth.
let rows;
@@ -598,7 +598,7 @@ const makeVList = function(params: VListParam, options: Options): DomSpan {
// So we put another empty span inside the depth strut span.
const emptySpan = makeSpan([], []);
const depthStrut = makeSpan(["vlist"], [emptySpan]);
depthStrut.style.height = -minPos + "em";
depthStrut.style.height = makeEm(-minPos);
// Safari wants the first row to have inline content; otherwise it
// puts the bottom of the *second* row on the baseline.
@@ -626,7 +626,7 @@ const makeGlue = (measurement: Measurement, options: Options): DomSpan => {
// Make an empty span for the space
const rule = makeSpan(["mspace"], [], options);
const size = calculateSize(measurement, options);
rule.style.marginRight = `${size}em`;
rule.style.marginRight = makeEm(size);
return rule;
};
@@ -744,17 +744,17 @@ const staticSvg = function(value: string, options: Options): SvgSpan {
const [pathName, width, height] = svgData[value];
const path = new PathNode(pathName);
const svgNode = new SvgNode([path], {
"width": width + "em",
"height": height + "em",
"width": makeEm(width),
"height": makeEm(height),
// Override CSS rule `.katex svg { width: 100% }`
"style": "width:" + width + "em",
"style": "width:" + makeEm(width),
"viewBox": "0 0 " + 1000 * width + " " + 1000 * height,
"preserveAspectRatio": "xMinYMin",
});
const span = makeSvgSpan(["overlay"], [svgNode], options);
span.height = height;
span.style.height = height + "em";
span.style.width = width + "em";
span.style.height = makeEm(height);
span.style.width = makeEm(width);
return span;
};

View File

@@ -11,6 +11,7 @@ import Style from "./Style";
import buildCommon from "./buildCommon";
import {Span, Anchor} from "./domTree";
import utils from "./utils";
import {makeEm} from "./units";
import {spacings, tightSpacings} from "./spacingData";
import {_htmlGroupBuilders as groupBuilders} from "./defineFunction";
import {DocumentFragment} from "./tree";
@@ -299,9 +300,9 @@ function buildHTMLUnbreakable(children, options) {
// the height of the expression, and the bottom of the HTML element
// falls at the depth of the expression.
const strut = makeSpan(["strut"]);
strut.style.height = (body.height + body.depth) + "em";
strut.style.height = makeEm(body.height + body.depth);
if (body.depth) {
strut.style.verticalAlign = -body.depth + "em";
strut.style.verticalAlign = makeEm(-body.depth);
}
body.children.unshift(strut);
@@ -395,9 +396,9 @@ export default function buildHTML(tree: AnyParseNode[], options: Options): DomSp
// (the height of the enclosing htmlNode) for proper vertical alignment.
if (tagChild) {
const strut = tagChild.children[0];
strut.style.height = (htmlNode.height + htmlNode.depth) + "em";
strut.style.height = makeEm(htmlNode.height + htmlNode.depth);
if (htmlNode.depth) {
strut.style.verticalAlign = (-htmlNode.depth) + "em";
strut.style.verticalAlign = makeEm(-htmlNode.depth);
}
}

View File

@@ -30,6 +30,7 @@ import buildCommon from "./buildCommon";
import {getCharacterMetrics} from "./fontMetrics";
import symbols from "./symbols";
import utils from "./utils";
import {makeEm} from "./units";
import fontMetricsData from "./fontMetricsData";
import type Options from "./Options";
@@ -93,7 +94,7 @@ const centerSpan = function(
options.fontMetrics().axisHeight;
span.classes.push("delimcenter");
span.style.top = shift + "em";
span.style.top = makeEm(shift);
span.height -= shift;
span.depth += shift;
};
@@ -186,21 +187,21 @@ const makeInner = function(
): 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);
? fontMetricsData['Size4-Regular'][ch.charCodeAt(0)][4]
: fontMetricsData['Size1-Regular'][ch.charCodeAt(0)][4];
const path = new PathNode("inner", innerPath(ch, Math.round(1000 * height)));
const svgNode = new SvgNode([path], {
"width": width + "em",
"height": height + "em",
"width": makeEm(width),
"height": makeEm(height),
// Override CSS rule `.katex svg { width: 100% }`
"style": "width:" + width + "em",
"style": "width:" + makeEm(width),
"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";
span.style.height = makeEm(height);
span.style.width = makeEm(width);
return {type: "elem", elem: span};
};
@@ -427,7 +428,7 @@ const sqrtSvg = function(
const svg = new SvgNode([pathNode], {
// Note: 1000:1 ratio of viewBox to document em width.
"width": "400em",
"height": height + "em",
"height": makeEm(height),
"viewBox": "0 0 400000 " + viewBoxHeight,
"preserveAspectRatio": "xMinYMin slice",
});
@@ -514,7 +515,7 @@ const makeSqrtImage = function(
}
span.height = texHeight;
span.style.height = spanHeight + "em";
span.style.height = makeEm(spanHeight);
return {
span,

View File

@@ -16,6 +16,7 @@ import utils from "./utils";
import {path} from "./svgGeometry";
import type Options from "./Options";
import {DocumentFragment} from "./tree";
import {makeEm} from "./units";
import type {VirtualNode} from "./tree";
@@ -406,7 +407,7 @@ export class SymbolNode implements HtmlDomNode {
if (this.italic > 0) {
span = document.createElement("span");
span.style.marginRight = this.italic + "em";
span.style.marginRight = makeEm(this.italic);
}
if (this.classes.length > 0) {

View File

@@ -8,7 +8,7 @@ import mathMLTree from "../mathMLTree";
import ParseError from "../ParseError";
import {assertNodeType, assertSymbolNodeType} from "../parseNode";
import {checkSymbolNodeType} from "../parseNode";
import {calculateSize} from "../units";
import {calculateSize, makeEm} from "../units";
import utils from "../utils";
import * as html from "../buildHTML";
@@ -368,7 +368,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
if (!firstSeparator) {
colSep = buildCommon.makeSpan(["arraycolsep"], []);
colSep.style.width =
options.fontMetrics().doubleRuleSep + "em";
makeEm(options.fontMetrics().doubleRuleSep);
cols.push(colSep);
}
@@ -377,13 +377,13 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
const separator = buildCommon.makeSpan(
["vertical-separator"], [], options
);
separator.style.height = totalHeight + "em";
separator.style.borderRightWidth = `${ruleThickness}em`;
separator.style.height = makeEm(totalHeight);
separator.style.borderRightWidth = makeEm(ruleThickness);
separator.style.borderRightStyle = lineType;
separator.style.margin = `0 -${ruleThickness / 2}em`;
separator.style.margin = `0 ${makeEm(-ruleThickness / 2)}`;
const shift = totalHeight - offset;
if (shift) {
separator.style.verticalAlign = -shift + "em";
separator.style.verticalAlign = makeEm(-shift);
}
cols.push(separator);
@@ -406,7 +406,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
sepwidth = utils.deflt(colDescr.pregap, arraycolsep);
if (sepwidth !== 0) {
colSep = buildCommon.makeSpan(["arraycolsep"], []);
colSep.style.width = sepwidth + "em";
colSep.style.width = makeEm(sepwidth);
cols.push(colSep);
}
}
@@ -437,7 +437,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
sepwidth = utils.deflt(colDescr.postgap, arraycolsep);
if (sepwidth !== 0) {
colSep = buildCommon.makeSpan(["arraycolsep"], []);
colSep.style.width = sepwidth + "em";
colSep.style.width = makeEm(sepwidth);
cols.push(colSep);
}
}
@@ -523,7 +523,7 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
const gap = (group.arraystretch === 0.5)
? 0.1 // {smallmatrix}, {subarray}
: 0.16 + group.arraystretch - 1 + (group.addJot ? 0.09 : 0);
table.setAttribute("rowspacing", gap.toFixed(4) + "em");
table.setAttribute("rowspacing", makeEm(gap));
// MathML table lines go only between cells.
// To place a line on an edge we'll use <menclose>, if necessary.

View File

@@ -6,6 +6,7 @@ import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import {assertSymbolNodeType} from "../parseNode";
import ParseError from "../ParseError";
import {makeEm} from "../units";
import type Parser from "../Parser";
import type {ParseNode, AnyParseNode} from "../parseNode";
@@ -257,7 +258,7 @@ defineFunction({
const label = buildCommon.wrapFragment(
html.buildGroup(group.label, newOptions, options), options);
label.classes.push("cd-label-" + group.side);
label.style.bottom = (0.8 - label.depth) + "em";
label.style.bottom = makeEm(0.8 - label.depth);
// Zero out label height & depth, so vertical align of arrow is set
// by the arrow height, not by the label.
label.height = 0;

View File

@@ -6,6 +6,7 @@ import utils from "../utils";
import stretchy from "../stretchy";
import {assertNodeType} from "../parseNode";
import {assertSpan, assertSymbolDomNode} from "../domTree";
import {makeEm} from "../units";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -131,7 +132,7 @@ export const htmlBuilder: HtmlBuilderSupSub<"accent"> = (grp, options) => {
left -= width / 2;
}
accentBody.style.left = left + "em";
accentBody.style.left = makeEm(left);
// \textcircled uses the \bigcirc glyph, so it needs some
// vertical adjustment to match LaTeX.
@@ -161,8 +162,8 @@ export const htmlBuilder: HtmlBuilderSupSub<"accent"> = (grp, options) => {
wrapperClasses: ["svg-align"],
wrapperStyle: skew > 0
? {
width: `calc(100% - ${2 * skew}em)`,
marginLeft: `${(2 * skew)}em`,
width: `calc(100% - ${makeEm(2 * skew)})`,
marginLeft: makeEm(2 * skew),
}
: undefined,
},

View File

@@ -4,7 +4,7 @@
import defineFunction from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import {calculateSize} from "../units";
import {calculateSize, makeEm} from "../units";
import {assertNodeType} from "../parseNode";
// \DeclareRobustCommand\\{...\@xnewline}
@@ -41,7 +41,7 @@ defineFunction({
span.classes.push("newline");
if (group.size) {
span.style.marginTop =
calculateSize(group.size, options) + "em";
makeEm(calculateSize(group.size, options));
}
}
return span;
@@ -53,7 +53,7 @@ defineFunction({
node.setAttribute("linebreak", "newline");
if (group.size) {
node.setAttribute("height",
calculateSize(group.size, options) + "em");
makeEm(calculateSize(group.size, options)));
}
}
return node;

View File

@@ -6,6 +6,7 @@ import mathMLTree from "../mathMLTree";
import ParseError from "../ParseError";
import utils from "../utils";
import {assertNodeType, checkSymbolNodeType} from "../parseNode";
import {makeEm} from "../units";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -126,8 +127,9 @@ defineFunction({
}
node.setAttribute("stretchy", "true");
node.setAttribute("minsize", delimiter.sizeToMaxHeight[group.size] + "em");
node.setAttribute("maxsize", delimiter.sizeToMaxHeight[group.size] + "em");
const size = makeEm(delimiter.sizeToMaxHeight[group.size]);
node.setAttribute("minsize", size);
node.setAttribute("maxsize", size);
return node;
},

View File

@@ -6,7 +6,7 @@ import utils from "../utils";
import stretchy from "../stretchy";
import {phasePath} from "../svgGeometry";
import {PathNode, SvgNode} from "../domTree";
import {calculateSize} from "../units";
import {calculateSize, makeEm} from "../units";
import {assertNodeType} from "../parseNode";
import * as html from "../buildHTML";
@@ -48,20 +48,20 @@ const htmlBuilder = (group, options) => {
const angleHeight = inner.height + inner.depth + lineWeight + clearance;
// Reserve a left pad for the angle.
inner.style.paddingLeft = (angleHeight / 2 + lineWeight) + "em";
inner.style.paddingLeft = makeEm(angleHeight / 2 + lineWeight);
// Create an SVG
const viewBoxHeight = Math.floor(1000 * angleHeight * scale);
const path = phasePath(viewBoxHeight);
const svgNode = new SvgNode([new PathNode("phase", path)], {
"width": "400em",
"height": `${viewBoxHeight / 1000}em`,
"height": makeEm(viewBoxHeight / 1000),
"viewBox": `0 0 400000 ${viewBoxHeight}`,
"preserveAspectRatio": "xMinYMin slice",
});
// Wrap it in a span with overflow: hidden.
img = buildCommon.makeSvgSpan(["hide-tail"], [svgNode], options);
img.style.height = angleHeight + "em";
img.style.height = makeEm(angleHeight);
imgShift = inner.depth + lineWeight + clearance;
} else {
@@ -104,10 +104,10 @@ const htmlBuilder = (group, options) => {
img = stretchy.encloseSpan(inner, label, topPad, bottomPad, options);
if (/fbox|boxed|fcolorbox/.test(label)) {
img.style.borderStyle = "solid";
img.style.borderWidth = `${ruleThickness}em`;
img.style.borderWidth = makeEm(ruleThickness);
} else if (label === "angl" && ruleThickness !== 0.049) {
img.style.borderTopWidth = `${ruleThickness}em`;
img.style.borderRightWidth = `${ruleThickness}em`;
img.style.borderTopWidth = makeEm(ruleThickness);
img.style.borderRightWidth = makeEm(ruleThickness);
}
imgShift = inner.depth + bottomPad;

View File

@@ -9,7 +9,7 @@ import {assert} from "../utils";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
import {calculateSize} from "../units";
import {calculateSize, makeEm} from "../units";
const adjustStyle = (size, originalStyle) => {
// Figure out what style this fraction should be in based on the
@@ -196,7 +196,7 @@ const mathmlBuilder = (group, options) => {
node.setAttribute("linethickness", "0px");
} else if (group.barSize) {
const ruleWidth = calculateSize(group.barSize, options);
node.setAttribute("linethickness", ruleWidth + "em");
node.setAttribute("linethickness", makeEm(ruleWidth));
}
const style = adjustStyle(group.size, options.style);

View File

@@ -1,7 +1,7 @@
// @flow
import defineFunction from "../defineFunction";
import type {Measurement} from "../units";
import {calculateSize, validUnit} from "../units";
import {calculateSize, validUnit, makeEm} from "../units";
import ParseError from "../ParseError";
import {Img} from "../domTree";
import mathMLTree from "../mathMLTree";
@@ -108,7 +108,6 @@ defineFunction({
if (group.totalheight.number > 0) {
depth = calculateSize(group.totalheight, options) - height;
depth = Number(depth.toFixed(2));
}
let width = 0;
@@ -116,12 +115,12 @@ defineFunction({
width = calculateSize(group.width, options);
}
const style: CssStyle = {height: height + depth + "em"};
const style: CssStyle = {height: makeEm(height + depth)};
if (width > 0) {
style.width = width + "em";
style.width = makeEm(width);
}
if (depth > 0) {
style.verticalAlign = -depth + "em";
style.verticalAlign = makeEm(-depth);
}
const node = new Img(group.src, group.alt, style);
@@ -138,14 +137,13 @@ defineFunction({
let depth = 0;
if (group.totalheight.number > 0) {
depth = calculateSize(group.totalheight, options) - height;
depth = depth.toFixed(2);
node.setAttribute("valign", "-" + depth + "em");
node.setAttribute("valign", makeEm(-depth));
}
node.setAttribute("height", height + depth + "em");
node.setAttribute("height", makeEm(height + depth));
if (group.width.number > 0) {
const width = calculateSize(group.width, options);
node.setAttribute("width", width + "em");
node.setAttribute("width", makeEm(width));
}
node.setAttribute("src", group.src);
return node;

View File

@@ -3,6 +3,7 @@
import defineFunction from "../defineFunction";
import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import {makeEm} from "../units";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -46,9 +47,9 @@ defineFunction({
// Otherwise, a tall argument may be misplaced.
// This code resolved issue #1153
const strut = buildCommon.makeSpan(["strut"]);
strut.style.height = (node.height + node.depth) + "em";
strut.style.height = makeEm(node.height + node.depth);
if (node.depth) {
strut.style.verticalAlign = -node.depth + "em";
strut.style.verticalAlign = makeEm(-node.depth);
}
node.children.unshift(strut);

View File

@@ -8,6 +8,7 @@ import utils from "../utils";
import Style from "../Style";
import {assembleSupSub} from "./utils/assembleSupSub";
import {assertNodeType} from "../parseNode";
import {makeEm} from "../units";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -132,7 +133,7 @@ export const htmlBuilder: HtmlBuilderSupSub<"op"> = (grp, options) => {
} else {
if (baseShift) {
base.style.position = "relative";
base.style.top = baseShift + "em";
base.style.top = makeEm(baseShift);
}
return base;

View File

@@ -3,7 +3,7 @@ import buildCommon from "../buildCommon";
import defineFunction from "../defineFunction";
import mathMLTree from "../mathMLTree";
import {assertNodeType} from "../parseNode";
import {calculateSize} from "../units";
import {calculateSize, makeEm} from "../units";
defineFunction({
type: "rule",
@@ -35,9 +35,9 @@ defineFunction({
const shift = (group.shift) ? calculateSize(group.shift, options) : 0;
// Style the rule to the right size
rule.style.borderRightWidth = width + "em";
rule.style.borderTopWidth = height + "em";
rule.style.bottom = shift + "em";
rule.style.borderRightWidth = makeEm(width);
rule.style.borderTopWidth = makeEm(height);
rule.style.bottom = makeEm(shift);
// Record the height and width
rule.width = width;
@@ -58,17 +58,17 @@ defineFunction({
const rule = new mathMLTree.MathNode("mspace");
rule.setAttribute("mathbackground", color);
rule.setAttribute("width", width + "em");
rule.setAttribute("height", height + "em");
rule.setAttribute("width", makeEm(width));
rule.setAttribute("height", makeEm(height));
const wrapper = new mathMLTree.MathNode("mpadded", [rule]);
if (shift >= 0) {
wrapper.setAttribute("height", "+" + shift + "em");
wrapper.setAttribute("height", makeEm(shift));
} else {
wrapper.setAttribute("height", shift + "em");
wrapper.setAttribute("depth", "+" + (-shift) + "em");
wrapper.setAttribute("height", makeEm(shift));
wrapper.setAttribute("depth", makeEm(-shift));
}
wrapper.setAttribute("voffset", shift + "em");
wrapper.setAttribute("voffset", makeEm(shift));
return wrapper;
},

View File

@@ -2,6 +2,7 @@
import buildCommon from "../buildCommon";
import defineFunction from "../defineFunction";
import mathMLTree from "../mathMLTree";
import {makeEm} from "../units";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -83,7 +84,7 @@ defineFunction({
// in, so we can't reset the size to normal before changing it. Now
// that we're passing an options parameter we should be able to fix
// this.
node.setAttribute("mathsize", newOptions.sizeMultiplier + "em");
node.setAttribute("mathsize", makeEm(newOptions.sizeMultiplier));
return node;
},

View File

@@ -4,6 +4,7 @@ import buildCommon from "../buildCommon";
import mathMLTree from "../mathMLTree";
import delimiter from "../delimiter";
import Style from "../Style";
import {makeEm} from "../units";
import * as html from "../buildHTML";
import * as mml from "../buildMathML";
@@ -70,7 +71,7 @@ defineFunction({
// Shift the sqrt image
const imgShift = img.height - inner.height - lineClearance - ruleWidth;
inner.style.paddingLeft = advanceWidth + "em";
inner.style.paddingLeft = makeEm(advanceWidth);
// Overlay the image and the argument.
const body = buildCommon.makeVList({

View File

@@ -4,6 +4,7 @@ import buildCommon from "../buildCommon";
import {SymbolNode} from "../domTree";
import mathMLTree from "../mathMLTree";
import utils from "../utils";
import {makeEm} from "../units";
import Style from "../Style";
import * as html from "../buildHTML";
@@ -111,7 +112,7 @@ defineFunctionBuilders({
// scriptspace is a font-size-independent size, so scale it
// appropriately for use as the marginRight.
const multiplier = options.sizeMultiplier;
const marginRight = (0.5 / metrics.ptPerEm) / multiplier + "em";
const marginRight = makeEm((0.5 / metrics.ptPerEm) / multiplier);
let marginLeft = null;
if (subm) {
@@ -123,7 +124,7 @@ defineFunctionBuilders({
(group.base.name === "\\oiint" || group.base.name === "\\oiiint");
if (base instanceof SymbolNode || isOiint) {
// $FlowFixMe
marginLeft = -base.italic + "em";
marginLeft = makeEm(-base.italic);
}
}

View File

@@ -6,6 +6,7 @@ import type {StyleInterface} from "../../Style";
import type Options from "../../Options";
import type {DomSpan, SymbolNode} from "../../domTree";
import type {AnyParseNode} from "../../parseNode";
import {makeEm} from "../../units";
// For an operator with limits, assemble the base, sup, and sub into a span.
@@ -62,11 +63,11 @@ export const assembleSupSub = (
positionData: bottom,
children: [
{type: "kern", size: options.fontMetrics().bigOpSpacing5},
{type: "elem", elem: sub.elem, marginLeft: -slant + "em"},
{type: "elem", elem: sub.elem, marginLeft: makeEm(-slant)},
{type: "kern", size: sub.kern},
{type: "elem", elem: base},
{type: "kern", size: sup.kern},
{type: "elem", elem: sup.elem, marginLeft: slant + "em"},
{type: "elem", elem: sup.elem, marginLeft: makeEm(slant)},
{type: "kern", size: options.fontMetrics().bigOpSpacing5},
],
}, options);
@@ -82,7 +83,7 @@ export const assembleSupSub = (
positionData: top,
children: [
{type: "kern", size: options.fontMetrics().bigOpSpacing5},
{type: "elem", elem: sub.elem, marginLeft: -slant + "em"},
{type: "elem", elem: sub.elem, marginLeft: makeEm(-slant)},
{type: "kern", size: sub.kern},
{type: "elem", elem: base},
],
@@ -96,7 +97,7 @@ export const assembleSupSub = (
children: [
{type: "elem", elem: base},
{type: "kern", size: sup.kern},
{type: "elem", elem: sup.elem, marginLeft: slant + "em"},
{type: "elem", elem: sup.elem, marginLeft: makeEm(slant)},
{type: "kern", size: options.fontMetrics().bigOpSpacing5},
],
}, options);
@@ -112,7 +113,7 @@ export const assembleSupSub = (
// A negative margin-left was applied to the lower limit.
// Avoid an overlap by placing a spacer on the left on the group.
const spacer = buildCommon.makeSpan(["mspace"], [], options);
spacer.style.marginRight = `${slant}em`;
spacer.style.marginRight = makeEm(slant);
parts.unshift(spacer);
}
return buildCommon.makeSpan(["mop", "op-limits"], parts, options);

View File

@@ -13,6 +13,7 @@ import fontMetricsData from "./fontMetricsData";
import functions from "./functions";
import symbols from "./symbols";
import utils from "./utils";
import {makeEm} from "./units";
import ParseError from "./ParseError";
@@ -634,8 +635,8 @@ defineMacro("\\TeX", "\\textrm{\\html@mathml{" +
// boxes, though visually the A appears to extend above slightly).
// We compute the corresponding \raisebox when A is rendered in \normalsize
// \scriptstyle, which has a scale factor of 0.7 (see Options.js).
const latexRaiseA = fontMetricsData['Main-Regular']["T".charCodeAt(0)][1] -
0.7 * fontMetricsData['Main-Regular']["A".charCodeAt(0)][1] + "em";
const latexRaiseA = makeEm(fontMetricsData['Main-Regular']["T".charCodeAt(0)][1] -
0.7 * fontMetricsData['Main-Regular']["A".charCodeAt(0)][1]);
defineMacro("\\LaTeX", "\\textrm{\\html@mathml{" +
`L\\kern-.36em\\raisebox{${latexRaiseA}}{\\scriptstyle A}` +
"\\kern-.15em\\TeX}{LaTeX}}");

View File

@@ -12,6 +12,7 @@
import utils from "./utils";
import {DocumentFragment} from "./tree";
import {createClass} from "./domTree";
import {makeEm} from "./units";
import type {VirtualNode} from "./tree";
@@ -219,7 +220,7 @@ class SpaceNode implements MathDomNode {
} else {
const node = document.createElementNS(
"http://www.w3.org/1998/Math/MathML", "mspace");
node.setAttribute("width", this.width + "em");
node.setAttribute("width", makeEm(this.width));
return node;
}
}
@@ -231,7 +232,7 @@ class SpaceNode implements MathDomNode {
if (this.character) {
return `<mtext>${this.character}</mtext>`;
} else {
return `<mspace width="${this.width}em"/>`;
return `<mspace width="${makeEm(this.width)}"/>`;
}
}

View File

@@ -9,6 +9,7 @@ import {LineNode, PathNode, SvgNode} from "./domTree";
import buildCommon from "./buildCommon";
import mathMLTree from "./mathMLTree";
import utils from "./utils";
import {makeEm} from "./units";
import type Options from "./Options";
import type {ParseNode, AnyParseNode} from "./parseNode";
@@ -233,7 +234,7 @@ const svgSpan = function(
const path = new PathNode(pathName);
const svgNode = new SvgNode([path], {
"width": "100%",
"height": height + "em",
"height": makeEm(height),
"viewBox": `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
"preserveAspectRatio": "none",
});
@@ -274,7 +275,7 @@ const svgSpan = function(
const svgNode = new SvgNode([path], {
"width": "400em",
"height": height + "em",
"height": makeEm(height),
"viewBox": `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
"preserveAspectRatio": aligns[i] + " slice",
});
@@ -284,7 +285,7 @@ const svgSpan = function(
if (numSvgChildren === 1) {
return {span, minWidth, height};
} else {
span.style.height = height + "em";
span.style.height = makeEm(height);
spans.push(span);
}
}
@@ -301,9 +302,9 @@ const svgSpan = function(
// Note that we are returning span.depth = 0.
// Any adjustments relative to the baseline must be done in buildHTML.
span.height = height;
span.style.height = height + "em";
span.style.height = makeEm(height);
if (minWidth > 0) {
span.style.minWidth = minWidth + "em";
span.style.minWidth = makeEm(minWidth);
}
return span;
@@ -358,14 +359,14 @@ const encloseSpan = function(
const svgNode = new SvgNode(lines, {
"width": "100%",
"height": totalHeight + "em",
"height": makeEm(totalHeight),
});
img = buildCommon.makeSvgSpan([], [svgNode], options);
}
img.height = totalHeight;
img.style.height = totalHeight + "em";
img.style.height = makeEm(totalHeight);
return img;
};

View File

@@ -96,3 +96,11 @@ export const calculateSize = function(
}
return Math.min(sizeValue.number * scale, options.maxSize);
};
/**
* Round `n` to 4 decimal places, or to the nearest 1/10,000th em. See
* https://github.com/KaTeX/KaTeX/pull/2460.
*/
export const makeEm = function(n: number): string {
return +n.toFixed(4) + "em";
};

View File

@@ -214,7 +214,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
"height": 0,
"maxFontSize": 0,
"style": {
"marginRight": "0.2777777777777778em"
"marginRight": "0.2778em"
}
},
{
@@ -272,7 +272,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
"height": 0,
"maxFontSize": 0,
"style": {
"marginRight": "0.2777777777777778em"
"marginRight": "0.2778em"
}
},
{
@@ -302,7 +302,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
"height": 0,
"maxFontSize": 0,
"style": {
"marginRight": "0.2222222222222222em"
"marginRight": "0.2222em"
}
},
{
@@ -360,7 +360,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
"height": 0,
"maxFontSize": 0,
"style": {
"marginRight": "0.2222222222222222em"
"marginRight": "0.2222em"
}
},
{
@@ -390,7 +390,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
"height": 0,
"maxFontSize": 0,
"style": {
"marginRight": "0.2222222222222222em"
"marginRight": "0.2222em"
}
},
{
@@ -448,7 +448,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
"height": 0,
"maxFontSize": 0,
"style": {
"marginRight": "0.2222222222222222em"
"marginRight": "0.2222em"
}
},
{
@@ -657,7 +657,7 @@ exports[`An HTML extension builder should not affect spacing 1`] = `
"height": 0,
"maxFontSize": 0,
"style": {
"marginRight": "0.2222222222222222em"
"marginRight": "0.2222em"
}
},
{
@@ -686,7 +686,7 @@ exports[`An HTML extension builder should not affect spacing 1`] = `
"height": 0,
"maxFontSize": 0,
"style": {
"marginRight": "0.2222222222222222em"
"marginRight": "0.2222em"
}
}
],
@@ -1089,7 +1089,7 @@ exports[`Extending katex by new fonts and symbols Add new font class to new exte
>
<span class="base">
<span class="strut"
style="height:0.84425em;"
style="height:0.8442em;"
>
</span>
<span class="mord mockEasternArabicFont-Regular">
@@ -1103,7 +1103,7 @@ exports[`Extending katex by new fonts and symbols Add new font class to new exte
<span class="vlist-t">
<span class="vlist-r">
<span class="vlist"
style="height:0.84425em;"
style="height:0.8442em;"
>
<span style="top:-3.063em;margin-right:0.05em;">
<span class="pstrut"
@@ -1170,7 +1170,7 @@ exports[`Newlines via \\\\ and \\newline \\\\ causes newline, even after mrel an
>
<span class="base">
<span class="strut"
style="height:0.68333em;"
style="height:0.6833em;"
>
</span>
<span class="mord mathnormal"
@@ -1179,7 +1179,7 @@ exports[`Newlines via \\\\ and \\newline \\\\ causes newline, even after mrel an
M
</span>
<span class="mspace"
style="margin-right:0.2777777777777778em;"
style="margin-right:0.2778em;"
>
</span>
<span class="mrel">
@@ -1190,14 +1190,14 @@ exports[`Newlines via \\\\ and \\newline \\\\ causes newline, even after mrel an
</span>
<span class="base">
<span class="strut"
style="height:0.66666em;vertical-align:-0.08333em;"
style="height:0.6667em;vertical-align:-0.0833em;"
>
</span>
<span class="mord mathnormal">
a
</span>
<span class="mspace"
style="margin-right:0.2222222222222222em;"
style="margin-right:0.2222em;"
>
</span>
<span class="mbin">
@@ -1208,7 +1208,7 @@ exports[`Newlines via \\\\ and \\newline \\\\ causes newline, even after mrel an
</span>
<span class="base">
<span class="strut"
style="height:0.69444em;"
style="height:0.6944em;"
>
</span>
<span class="mord mathnormal">
@@ -1219,7 +1219,7 @@ exports[`Newlines via \\\\ and \\newline \\\\ causes newline, even after mrel an
</span>
<span class="base">
<span class="strut"
style="height:0.43056em;"
style="height:0.4306em;"
>
</span>
<span class="mord mathnormal">
@@ -1404,7 +1404,7 @@ exports[`href and url commands should not affect spacing around 1`] = `
"height": 0,
"maxFontSize": 0,
"style": {
"marginRight": "0.2222222222222222em"
"marginRight": "0.2222em"
}
},
{
@@ -1438,7 +1438,7 @@ exports[`href and url commands should not affect spacing around 1`] = `
"height": 0,
"maxFontSize": 0,
"style": {
"marginRight": "0.2222222222222222em"
"marginRight": "0.2222em"
}
},
{

View File

@@ -209,7 +209,7 @@ exports[`A MathML builder should build the CD environment properly 1`] = `
display="block"
>
<semantics>
<mtable rowspacing="0.2500em"
<mtable rowspacing="0.25em"
columnalign="center center center"
columnspacing="0.5em"
>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 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: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 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: 23 KiB

After

Width:  |  Height:  |  Size: 23 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: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 39 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: 11 KiB

After

Width:  |  Height:  |  Size: 11 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: 17 KiB

After

Width:  |  Height:  |  Size: 17 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: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 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: 21 KiB

After

Width:  |  Height:  |  Size: 21 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: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 7.9 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: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 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: 31 KiB

After

Width:  |  Height:  |  Size: 31 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: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 35 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: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 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: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 35 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: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 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: 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: 10 KiB

After

Width:  |  Height:  |  Size: 10 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: 11 KiB

After

Width:  |  Height:  |  Size: 11 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: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 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: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 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: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 9.0 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: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 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: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 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: 20 KiB

After

Width:  |  Height:  |  Size: 20 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: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Some files were not shown because too many files have changed in this diff Show More