Make accents zero width (#1033)
* Make accents zero width Make the width of an accented character equal to the width of the character, by making accents zero width. In particular, fixes #1028 (`\ddot\imath`). This involved reworking all of the accent offset machinery, in particular skew and accent-hungarian. A bit cleaner now. Also added support for the new width character metrics in symbolNode. * Update AccentsText test * Fix comment
@@ -73,13 +73,13 @@ const makeSymbol = function(
|
|||||||
}
|
}
|
||||||
symbolNode = new domTree.symbolNode(
|
symbolNode = new domTree.symbolNode(
|
||||||
value, metrics.height, metrics.depth, italic, metrics.skew,
|
value, metrics.height, metrics.depth, italic, metrics.skew,
|
||||||
classes);
|
metrics.width, classes);
|
||||||
} else {
|
} else {
|
||||||
// TODO(emily): Figure out a good way to only print this in development
|
// TODO(emily): Figure out a good way to only print this in development
|
||||||
typeof console !== "undefined" && console.warn(
|
typeof console !== "undefined" && console.warn(
|
||||||
"No character metrics for '" + value + "' in style '" +
|
"No character metrics for '" + value + "' in style '" +
|
||||||
fontFamily + "'");
|
fontFamily + "'");
|
||||||
symbolNode = new domTree.symbolNode(value, 0, 0, 0, 0, classes);
|
symbolNode = new domTree.symbolNode(value, 0, 0, 0, 0, 0, classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options) {
|
if (options) {
|
||||||
@@ -733,6 +733,8 @@ const staticSvg = function(value: string, options: Options): domTree.span {
|
|||||||
const svgNode = new domTree.svgNode([path], {
|
const svgNode = new domTree.svgNode([path], {
|
||||||
"width": width + "em",
|
"width": width + "em",
|
||||||
"height": height + "em",
|
"height": height + "em",
|
||||||
|
// Override CSS rule `.katex svg { width: 100% }`
|
||||||
|
"style": "width:" + width + "em",
|
||||||
"viewBox": "0 0 " + 1000 * width + " " + 1000 * height,
|
"viewBox": "0 0 " + 1000 * width + " " + 1000 * height,
|
||||||
"preserveAspectRatio": "xMinYMin",
|
"preserveAspectRatio": "xMinYMin",
|
||||||
});
|
});
|
||||||
|
@@ -688,6 +688,7 @@ groupTypes.accent = function(group, options) {
|
|||||||
// So now we use an SVG.
|
// So now we use an SVG.
|
||||||
// If Safari reforms, we should consider reverting to the glyph.
|
// If Safari reforms, we should consider reverting to the glyph.
|
||||||
accent = buildCommon.staticSvg("vec", options);
|
accent = buildCommon.staticSvg("vec", options);
|
||||||
|
accent.width = parseFloat(accent.style.width);
|
||||||
} else {
|
} else {
|
||||||
accent = buildCommon.makeSymbol(
|
accent = buildCommon.makeSymbol(
|
||||||
group.value.label, "Main-Regular", group.mode, options);
|
group.value.label, "Main-Regular", group.mode, options);
|
||||||
@@ -696,22 +697,26 @@ groupTypes.accent = function(group, options) {
|
|||||||
// shift the accent over to a place we don't want.
|
// shift the accent over to a place we don't want.
|
||||||
accent.italic = 0;
|
accent.italic = 0;
|
||||||
|
|
||||||
|
accentBody = makeSpan(["accent-body"], [accent]);
|
||||||
|
|
||||||
|
// CSS defines `.katex .accent .accent-body { width: 0 }`
|
||||||
|
// so that the accent doesn't contribute to the bounding box.
|
||||||
|
// We need to shift the character by its width (effectively half
|
||||||
|
// its width) to compensate.
|
||||||
|
let left = -accent.width / 2;
|
||||||
|
|
||||||
|
// Shift the accent over by the skew.
|
||||||
|
left += skew;
|
||||||
|
|
||||||
// The \H character that the fonts use is a combining character, and
|
// The \H character that the fonts use is a combining character, and
|
||||||
// thus shows up much too far to the left. To account for this, we add a
|
// thus shows up much too far to the left. To account for this, we add
|
||||||
// specific class which shifts the accent over to where we want it.
|
// a manual shift of the width of one space.
|
||||||
// TODO(emily): Fix this in a better way, like by changing the font
|
// TODO(emily): Fix this in a better way, like by changing the font
|
||||||
let accentClass = null;
|
|
||||||
if (group.value.label === '\\H') {
|
if (group.value.label === '\\H') {
|
||||||
accentClass = "accent-hungarian";
|
left += 0.5; // twice width of space, or width of accent
|
||||||
}
|
}
|
||||||
|
|
||||||
accentBody = makeSpan([], [accent]);
|
accentBody.style.left = left + "em";
|
||||||
accentBody = makeSpan(["accent-body", accentClass], [accentBody]);
|
|
||||||
|
|
||||||
// Shift the accent over by the skew. Note we shift by twice the skew
|
|
||||||
// because we are centering the accent, so by adding 2*skew to the left,
|
|
||||||
// we shift it to the right by 1*skew.
|
|
||||||
accentBody.style.marginLeft = 2 * skew + "em";
|
|
||||||
|
|
||||||
accentBody = buildCommon.makeVList({
|
accentBody = buildCommon.makeVList({
|
||||||
positionType: "firstBaseline",
|
positionType: "firstBaseline",
|
||||||
|
@@ -383,6 +383,7 @@ class symbolNode implements CombinableDomNode {
|
|||||||
depth: number;
|
depth: number;
|
||||||
italic: number;
|
italic: number;
|
||||||
skew: number;
|
skew: number;
|
||||||
|
width: number;
|
||||||
maxFontSize: number;
|
maxFontSize: number;
|
||||||
classes: string[];
|
classes: string[];
|
||||||
style: {[string]: string};
|
style: {[string]: string};
|
||||||
@@ -393,6 +394,7 @@ class symbolNode implements CombinableDomNode {
|
|||||||
depth?: number,
|
depth?: number,
|
||||||
italic?: number,
|
italic?: number,
|
||||||
skew?: number,
|
skew?: number,
|
||||||
|
width?: number,
|
||||||
classes?: string[],
|
classes?: string[],
|
||||||
style?: {[string]: string},
|
style?: {[string]: string},
|
||||||
) {
|
) {
|
||||||
@@ -401,6 +403,7 @@ class symbolNode implements CombinableDomNode {
|
|||||||
this.depth = depth || 0;
|
this.depth = depth || 0;
|
||||||
this.italic = italic || 0;
|
this.italic = italic || 0;
|
||||||
this.skew = skew || 0;
|
this.skew = skew || 0;
|
||||||
|
this.width = width || 0;
|
||||||
this.classes = classes || [];
|
this.classes = classes || [];
|
||||||
this.style = style || {};
|
this.style = style || {};
|
||||||
this.maxFontSize = 0;
|
this.maxFontSize = 0;
|
||||||
|
@@ -554,13 +554,9 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accent-body > span {
|
.accent-body {
|
||||||
width: 0;
|
width: 0;
|
||||||
}
|
position: relative; // so that 'left' can shift the accent
|
||||||
|
|
||||||
.accent-body.accent-hungarian > span {
|
|
||||||
position: relative;
|
|
||||||
left: 0.250em; // width of space
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
@@ -14,8 +14,8 @@
|
|||||||
Accents: \vec{A}\vec{x}\vec x^2\vec{x}_2^2\vec{A}^2\vec{xA}^2
|
Accents: \vec{A}\vec{x}\vec x^2\vec{x}_2^2\vec{A}^2\vec{xA}^2
|
||||||
AccentsText: |
|
AccentsText: |
|
||||||
\begin{array}{l}
|
\begin{array}{l}
|
||||||
\text{\H{e}}\\
|
\text{\H{e}} & \text{\'\i} \\
|
||||||
\text{\H{X}}\\
|
\text{\H{X}} & \text{\"\i} \\
|
||||||
\end{array}
|
\end{array}
|
||||||
Aligned: |
|
Aligned: |
|
||||||
\begin{aligned}
|
\begin{aligned}
|
||||||
|