mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-09 21:18:40 +00:00
Fix frac-line (#1025)
* Fix frac lline For frac-line, use an SVG line in an extra tall span. I still need to think of a way to adust `vertical-separator`. * Fix spaces in katex.less * regenerate screenshots * update HorizontalBraces and StrikeThrough screenshots
This commit is contained in:
@@ -330,11 +330,13 @@ const makeLineSpan = function(
|
||||
className: string,
|
||||
options: Options,
|
||||
) {
|
||||
// Fill the entire span instead of just a border. That way, the min-height
|
||||
// value in katex.less will ensure that at least one screen pixel displays.
|
||||
const line = stretchy.ruleSpan(className, options);
|
||||
line.height = options.fontMetrics().defaultRuleThickness;
|
||||
line.style.height = line.height + "em";
|
||||
// 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";
|
||||
line.maxFontSize = 1.0;
|
||||
return line;
|
||||
};
|
||||
|
@@ -199,7 +199,7 @@ const htmlBuilder = function(group, options) {
|
||||
}
|
||||
|
||||
if (colDescr.separator === "|") {
|
||||
const separator = stretchy.ruleSpan("vertical-separator",
|
||||
const separator = stretchy.ruleSpan("vertical-separator", 0.05,
|
||||
options);
|
||||
separator.style.height = totalHeight + "em";
|
||||
separator.style.verticalAlign =
|
||||
|
@@ -126,7 +126,7 @@ defineFunction({
|
||||
}
|
||||
|
||||
let frac;
|
||||
if (ruleWidth === 0) {
|
||||
if (!rule) {
|
||||
// Rule 15c
|
||||
const candidateClearance =
|
||||
(numShift - numerm.depth) - (denomm.height - denomShift);
|
||||
@@ -166,8 +166,12 @@ defineFunction({
|
||||
positionType: "individualShift",
|
||||
children: [
|
||||
{type: "elem", elem: denomm, shift: denomShift},
|
||||
// $FlowFixMe `rule` cannot be `null` here.
|
||||
{type: "elem", elem: rule, shift: midShift},
|
||||
// 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 gap in the SVG = 2 * ruleWidth.
|
||||
{type: "elem", elem: rule, shift: midShift + 2 * ruleWidth},
|
||||
{type: "elem", elem: numerm, shift: -numShift},
|
||||
],
|
||||
}, options);
|
||||
|
@@ -34,9 +34,13 @@ defineFunction({
|
||||
positionType: "firstBaseline",
|
||||
children: [
|
||||
{type: "elem", elem: innerGroup},
|
||||
{type: "kern", size: 3 * line.height},
|
||||
{type: "elem", elem: line},
|
||||
// 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: "elem", elem: line},
|
||||
],
|
||||
}, options);
|
||||
|
||||
|
@@ -24,7 +24,7 @@ defineFunction({
|
||||
// Build the inner group.
|
||||
const innerGroup = html.buildGroup(group.value.body, options);
|
||||
|
||||
// Create the line above the body
|
||||
// Create the line to go below the body
|
||||
const line = buildCommon.makeLineSpan("underline-line", options);
|
||||
|
||||
// Generate the vlist, with the appropriate kerns
|
||||
@@ -32,9 +32,11 @@ defineFunction({
|
||||
positionType: "top",
|
||||
positionData: innerGroup.height,
|
||||
children: [
|
||||
{type: "kern", size: line.height},
|
||||
// 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: "elem", elem: line},
|
||||
{type: "kern", size: 3 * line.height},
|
||||
{type: "kern", size: 5 * line.height},
|
||||
{type: "elem", elem: innerGroup},
|
||||
],
|
||||
}, options);
|
||||
|
@@ -326,16 +326,53 @@ const encloseSpan = function(
|
||||
return img;
|
||||
};
|
||||
|
||||
const ruleSpan = function(className: string, options: Options): domTree.span {
|
||||
// Get a big square image. The parent span will hide the overflow.
|
||||
const pathNode = new domTree.pathNode('bigRule');
|
||||
const svg = new domTree.svgNode([pathNode], {
|
||||
"width": "400em",
|
||||
"height": "400em",
|
||||
"viewBox": "0 0 400000 400000",
|
||||
"preserveAspectRatio": "xMinYMin slice",
|
||||
});
|
||||
return buildCommon.makeSpan([className, "hide-tail"], [svg], options);
|
||||
const ruleSpan = function(className: string, lineThickness: number,
|
||||
options: Options): domTree.span {
|
||||
|
||||
// Get a span with an SVG line that fills the middle fifth of the span.
|
||||
// We're using an extra wide span so Chrome won't round it down to zero.
|
||||
|
||||
const lines = [];
|
||||
let svgNode;
|
||||
if (className === "vertical-separator") {
|
||||
// Apply 2 brush strokes for sharper edges on low-res screens.
|
||||
for (let i = 0; i < 2; i++) {
|
||||
lines.push(new domTree.lineNode({
|
||||
"x1": "5",
|
||||
"y1": "0",
|
||||
"x2": "5",
|
||||
"y2": "10",
|
||||
"stroke-width": "2",
|
||||
}));
|
||||
}
|
||||
|
||||
svgNode = new domTree.svgNode(lines, {
|
||||
"width": "0.25em",
|
||||
"height": "100%",
|
||||
"viewBox": "0 0 10 10",
|
||||
"preserveAspectRatio": "none",
|
||||
});
|
||||
|
||||
} else {
|
||||
for (let i = 0; i < 2; i++) {
|
||||
lines.push(new domTree.lineNode({
|
||||
"x1": "0",
|
||||
"y1": "5",
|
||||
"x2": "10",
|
||||
"y2": "5",
|
||||
"stroke-width": "2",
|
||||
}));
|
||||
}
|
||||
|
||||
svgNode = new domTree.svgNode(lines, {
|
||||
"width": "100%",
|
||||
"height": 5 * lineThickness + "em",
|
||||
"viewBox": "0 0 10 10",
|
||||
"preserveAspectRatio": "none",
|
||||
});
|
||||
}
|
||||
|
||||
return buildCommon.makeSpan([className], [svgNode], options);
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@@ -5,10 +5,6 @@
|
||||
*/
|
||||
|
||||
const path: {[string]: string} = {
|
||||
// bigRule provides a big square image for frac-lines, etc.
|
||||
// The actual rendered rule is smaller, controlled by overflow:hidden.
|
||||
bigRule: 'M0 0 h400000 v400000 h-400000z M0 0 h400000 v400000 h-400000z',
|
||||
|
||||
// sqrtMain path geometry is from glyph U221A in the font KaTeX Main
|
||||
sqrtMain: `M95 622c-2.667 0-7.167-2.667-13.5
|
||||
-8S72 604 72 600c0-2 .333-3.333 1-4 1.333-2.667 23.833-20.667 67.5-54s
|
||||
|
Reference in New Issue
Block a user