Fix \mathit
font and italic correction and add \mathnormal
(#1700)
* Fix \mathit font (Math-Italic -> Main-Italic) and italic correction * Rename mathit to mathdefault and mainit to mathit * Add \mathnormal
@@ -617,6 +617,7 @@ table td {
|
||||
|\mathinner|$ab\mathinner{\text{inside}}cd$|`ab\mathinner{\text{inside}}cd`|
|
||||
|\mathit|$\mathit{AaBb}$|`\mathit{AaBb}`<br>KaTeX supports A-Za-z|
|
||||
|\mathllap|${=}\mathllap{/\,}$|`{=}\mathllap{/\,}`|
|
||||
|\mathnormal|$\mathnormal{AaBb}$|`\mathnormal{AaBb}`<br>KaTeX supports A-Za-z|
|
||||
|\mathop|$\mathop{\star}_a^b$|`\mathop{\star}_a^b`|
|
||||
|\mathopen|$a + \mathopen\lt b) + c$|`a + \mathopen\lt b) + c`|
|
||||
|\mathord|$1\mathord{,}234{,}567$|`1\mathord{,}234{,}567`|
|
||||
|
@@ -515,14 +515,14 @@ For color definition, KaTeX color functions will accept the standard HTML [pred
|
||||
||||
|
||||
|:------------------------------|:------------------------------|:-----
|
||||
|$\mathrm{Ab0}$ `\mathrm{Ab0}` |$\mathbf{Ab0}$ `\mathbf{Ab0}` |$\mathit{Ab}$ `\mathit{Ab}`
|
||||
|$\textrm{Ab0}$ `\textrm{Ab0}` |$\textbf{Ab0}$ `\textbf{Ab0}` |$\textit{Ab}$ `\textit{Ab}`
|
||||
|$\rm Ab0$ `\rm Ab0` |$\bf Ab0$ `\bf Ab0` |$\it Ab$ `\it Ab`
|
||||
|$\textnormal{Ab0}$ `\textnormal{Ab0}`|$\bold{Ab0}$ `\bold{Ab0}`|$\Bbb{AB}$ `\Bbb{AB}`
|
||||
|$\text{Ab0}$ `\text{Ab0}` |$\boldsymbol{Ab}$ `\boldsymbol{Ab}`|$\mathbb{AB}$ `\mathbb{AB}`
|
||||
|$\mathsf{Ab0}$ `\mathsf{Ab0}` |$\bm{Ab}$ `\bm{Ab}` |$\frak{Ab0}$ `\frak{Ab0}`
|
||||
|$\textsf{Ab0}$ `\textsf{Ab0}` |$\mathtt{Ab0}$ `\mathtt{Ab0}` |$\mathfrak{Ab0}$ `\mathfrak{Ab0}`
|
||||
|$\sf Ab0$ `\sf Ab0` |$\texttt{Ab0}$ `\texttt{Ab0}` |$\mathcal{AB0}$ `\mathcal{AB0}`
|
||||
| |$\tt Ab0$ `\tt Ab0` |$\mathscr{AB}$ `\mathscr{AB}`
|
||||
|$\mathnormal{Ab0}$ `\mathnormal{Ab0}`|$\textbf{Ab0}$ `\textbf{Ab0}` |$\textit{Ab}$ `\textit{Ab}`
|
||||
|$\textrm{Ab0}$ `\textrm{Ab0}` |$\bf Ab0$ `\bf Ab0` |$\it Ab$ `\it Ab`
|
||||
|$\rm Ab0$ `\rm Ab0` |$\bold{Ab0}$ `\bold{Ab0}`|$\Bbb{AB}$ `\Bbb{AB}`
|
||||
|$\textnormal{Ab0}$ `\textnormal{Ab0}`|$\boldsymbol{Ab}$ `\boldsymbol{Ab}`|$\mathbb{AB}$ `\mathbb{AB}`
|
||||
|$\text{Ab0}$ `\text{Ab0}` |$\bm{Ab}$ `\bm{Ab}` |$\frak{Ab0}$ `\frak{Ab0}`
|
||||
|$\mathsf{Ab0}$ `\mathsf{Ab0}` |$\mathtt{Ab0}$ `\mathtt{Ab0}` |$\mathfrak{Ab0}$ `\mathfrak{Ab0}`
|
||||
|$\textsf{Ab0}$ `\textsf{Ab0}` |$\texttt{Ab0}$ `\texttt{Ab0}` |$\mathcal{AB0}$ `\mathcal{AB0}`
|
||||
|$\sf Ab0$ `\sf Ab0` |$\tt Ab0$ `\tt Ab0` |$\mathscr{AB}$ `\mathscr{AB}`
|
||||
|
||||
One can stack font family, font weight, and font shape by using the `\textXX` versions of the font functions. So `\textsf{\textbf{H}}` will produce $\textsf{\textbf{H}}$. The other versions do not stack, e.g., `\mathsf{\mathbf{H}}` will produce $\mathsf{\mathbf{H}}$.
|
||||
|
||||
|
@@ -21,8 +21,8 @@ import type {documentFragment as HtmlDocumentFragment} from "./domTree";
|
||||
import type {HtmlDomNode, DomSpan, SvgSpan, CssStyle} from "./domTree";
|
||||
import type {Measurement} from "./units";
|
||||
|
||||
// The following have to be loaded from Main-Italic font, using class mainit
|
||||
const mainitLetters = [
|
||||
// The following have to be loaded from Main-Italic font, using class mathit
|
||||
const mathitLetters = [
|
||||
"\\imath", "ı", // dotless i
|
||||
"\\jmath", "ȷ", // dotless j
|
||||
"\\pounds", "\\mathsterling", "\\textsterling", "£", // pounds symbol
|
||||
@@ -72,7 +72,7 @@ const makeSymbol = function(
|
||||
let symbolNode;
|
||||
if (metrics) {
|
||||
let italic = metrics.italic;
|
||||
if (mode === "text") {
|
||||
if (mode === "text" || (options && options.font === "mathit")) {
|
||||
italic = 0;
|
||||
}
|
||||
symbolNode = new SymbolNode(
|
||||
@@ -133,11 +133,10 @@ const mathsym = function(
|
||||
|
||||
/**
|
||||
* Determines which of the two font names (Main-Italic and Math-Italic) and
|
||||
* corresponding style tags (mainit or mathit) to use for font "mathit",
|
||||
* depending on the symbol. Use this function instead of fontMap for font
|
||||
* "mathit".
|
||||
* corresponding style tags (maindefault or mathit) to use for default math font,
|
||||
* depending on the symbol.
|
||||
*/
|
||||
const mathit = function(
|
||||
const mathdefault = function(
|
||||
value: string,
|
||||
mode: Mode,
|
||||
options: Options,
|
||||
@@ -146,16 +145,46 @@ const mathit = function(
|
||||
if (/[0-9]/.test(value.charAt(0)) ||
|
||||
// glyphs for \imath and \jmath do not exist in Math-Italic so we
|
||||
// need to use Main-Italic instead
|
||||
utils.contains(mainitLetters, value)) {
|
||||
utils.contains(mathitLetters, value)) {
|
||||
return {
|
||||
fontName: "Main-Italic",
|
||||
fontClass: "mainit",
|
||||
fontClass: "mathit",
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
fontName: "Math-Italic",
|
||||
fontClass: "mathdefault",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines which of the font names (Main-Italic, Math-Italic, and Caligraphic)
|
||||
* and corresponding style tags (mathit, mathdefault, or mathcal) to use for font
|
||||
* "mathnormal", depending on the symbol. Use this function instead of fontMap for
|
||||
* font "mathnormal".
|
||||
*/
|
||||
const mathnormal = function(
|
||||
value: string,
|
||||
mode: Mode,
|
||||
options: Options,
|
||||
classes: string[],
|
||||
): {| fontName: string, fontClass: string |} {
|
||||
if (utils.contains(mathitLetters, value)) {
|
||||
return {
|
||||
fontName: "Main-Italic",
|
||||
fontClass: "mathit",
|
||||
};
|
||||
} else if (/[0-9]/.test(value.charAt(0))) {
|
||||
return {
|
||||
fontName: "Caligraphic-Regular",
|
||||
fontClass: "mathcal",
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
fontName: "Math-Italic",
|
||||
fontClass: "mathdefault",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -210,15 +239,15 @@ const makeOrd = function<NODETYPE: "spacing" | "mathord" | "textord">(
|
||||
} else if (fontOrFamily) {
|
||||
let fontName;
|
||||
let fontClasses;
|
||||
if (fontOrFamily === "boldsymbol") {
|
||||
const fontData = boldsymbol(text, mode, options, classes);
|
||||
fontName = fontData.fontName;
|
||||
fontClasses = [fontData.fontClass];
|
||||
} else if (fontOrFamily === "mathit" ||
|
||||
utils.contains(mainitLetters, text)) {
|
||||
const fontData = mathit(text, mode, options, classes);
|
||||
if (fontOrFamily === "boldsymbol" || fontOrFamily === "mathnormal") {
|
||||
const fontData = fontOrFamily === "boldsymbol"
|
||||
? boldsymbol(text, mode, options, classes)
|
||||
: mathnormal(text, mode, options, classes);
|
||||
fontName = fontData.fontName;
|
||||
fontClasses = [fontData.fontClass];
|
||||
} else if (utils.contains(mathitLetters, text)) {
|
||||
fontName = "Main-Italic";
|
||||
fontClasses = ["mathit"];
|
||||
} else if (isFont) {
|
||||
fontName = fontMap[fontOrFamily].fontName;
|
||||
fontClasses = [fontOrFamily];
|
||||
@@ -245,7 +274,7 @@ const makeOrd = function<NODETYPE: "spacing" | "mathord" | "textord">(
|
||||
|
||||
// Makes a symbol in the default font for mathords and textords.
|
||||
if (type === "mathord") {
|
||||
const fontLookup = mathit(text, mode, options, classes);
|
||||
const fontLookup = mathdefault(text, mode, options, classes);
|
||||
return makeSymbol(text, fontLookup.fontName, mode, options,
|
||||
classes.concat([fontLookup.fontClass]));
|
||||
} else if (type === "textord") {
|
||||
@@ -705,11 +734,17 @@ const fontMap: {[string]: {| variant: FontVariant, fontName: string |}} = {
|
||||
variant: "italic",
|
||||
fontName: "Main-Italic",
|
||||
},
|
||||
"mathit": {
|
||||
variant: "italic",
|
||||
fontName: "Main-Italic",
|
||||
},
|
||||
|
||||
// "mathit" and "boldsymbol" are missing because they require the use of two
|
||||
// fonts: Main-Italic and Math-Italic for "mathit", and Math-BoldItalic and
|
||||
// Main-Bold for "boldsymbol". This is handled by a special case in makeOrd
|
||||
// which ends up calling mathit and boldsymbol.
|
||||
// Default math font, "mathnormal" and "boldsymbol" are missing because they
|
||||
// require the use of several fonts: Main-Italic and Math-Italic for default
|
||||
// math font, Main-Italic, Math-Italic, Caligraphic for "mathnormal", and
|
||||
// Math-BoldItalic and Main-Bold for "boldsymbol". This is handled by a
|
||||
// special case in makeOrd which ends up calling mathdefault, mathnormal,
|
||||
// and boldsymbol.
|
||||
|
||||
// families
|
||||
"mathbb": {
|
||||
|
@@ -85,7 +85,7 @@ export const getVariant = function(
|
||||
}
|
||||
|
||||
const font = options.font;
|
||||
if (!font) {
|
||||
if (!font || font === "mathnormal") {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@@ -32,7 +32,7 @@ defineFunction({
|
||||
type: "font",
|
||||
names: [
|
||||
// styles, except \boldsymbol defined below
|
||||
"\\mathrm", "\\mathit", "\\mathbf",
|
||||
"\\mathrm", "\\mathit", "\\mathbf", "\\mathnormal",
|
||||
|
||||
// families
|
||||
"\\mathbb", "\\mathcal", "\\mathfrak", "\\mathscr", "\\mathsf",
|
||||
|
@@ -74,11 +74,16 @@
|
||||
}
|
||||
|
||||
// Math fonts.
|
||||
.mathit {
|
||||
.mathdefault {
|
||||
font-family: KaTeX_Math;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.mathit {
|
||||
font-family: KaTeX_Main;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.mathrm {
|
||||
font-style: normal;
|
||||
}
|
||||
@@ -138,11 +143,6 @@
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.mainit {
|
||||
font-family: KaTeX_Main;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.mainrm {
|
||||
font-family: KaTeX_Main;
|
||||
font-style: normal;
|
||||
|
@@ -25,8 +25,8 @@ const wideLatinLetterData: Array<[string, string, string]> = [
|
||||
["mathbf", "textbf", "Main-Bold"], // A-Z bold upright
|
||||
["mathbf", "textbf", "Main-Bold"], // a-z bold upright
|
||||
|
||||
["mathit", "textit", "Math-Italic"], // A-Z italic
|
||||
["mathit", "textit", "Math-Italic"], // a-z italic
|
||||
["mathdefault", "textit", "Math-Italic"], // A-Z italic
|
||||
["mathdefault", "textit", "Math-Italic"], // a-z italic
|
||||
|
||||
["boldsymbol", "boldsymbol", "Main-BoldItalic"], // A-Z bold italic
|
||||
["boldsymbol", "boldsymbol", "Main-BoldItalic"], // a-z bold italic
|
||||
|
@@ -137,7 +137,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
|
||||
{
|
||||
"classes": [
|
||||
"mord",
|
||||
"mathit"
|
||||
"mathdefault"
|
||||
],
|
||||
"depth": 0,
|
||||
"height": 0.43056,
|
||||
@@ -180,7 +180,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
|
||||
{
|
||||
"classes": [
|
||||
"mord",
|
||||
"mathit"
|
||||
"mathdefault"
|
||||
],
|
||||
"depth": 0,
|
||||
"height": 0.69444,
|
||||
@@ -268,7 +268,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
|
||||
{
|
||||
"classes": [
|
||||
"mord",
|
||||
"mathit"
|
||||
"mathdefault"
|
||||
],
|
||||
"depth": 0,
|
||||
"height": 0.43056,
|
||||
@@ -356,7 +356,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
|
||||
{
|
||||
"classes": [
|
||||
"mord",
|
||||
"mathit"
|
||||
"mathdefault"
|
||||
],
|
||||
"depth": 0,
|
||||
"height": 0.69444,
|
||||
@@ -459,7 +459,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
|
||||
{
|
||||
"classes": [
|
||||
"mord",
|
||||
"mathit"
|
||||
"mathdefault"
|
||||
],
|
||||
"depth": 0,
|
||||
"height": 0.43056,
|
||||
@@ -547,7 +547,7 @@ exports[`A font parser \\boldsymbol should inherit mbin/mrel from argument 1`] =
|
||||
{
|
||||
"classes": [
|
||||
"mord",
|
||||
"mathit"
|
||||
"mathdefault"
|
||||
],
|
||||
"depth": 0.19444,
|
||||
"height": 0.69444,
|
||||
|
@@ -1483,13 +1483,15 @@ describe("A style change parser", function() {
|
||||
});
|
||||
|
||||
describe("A font parser", function() {
|
||||
it("should parse \\mathrm, \\mathbb, and \\mathit", function() {
|
||||
it("should parse \\mathrm, \\mathbb, \\mathit, and \\mathnormal", function() {
|
||||
expect`\mathrm x`.toParse();
|
||||
expect`\mathbb x`.toParse();
|
||||
expect`\mathit x`.toParse();
|
||||
expect`\mathnormal x`.toParse();
|
||||
expect`\mathrm {x + 1}`.toParse();
|
||||
expect`\mathbb {x + 1}`.toParse();
|
||||
expect`\mathit {x + 1}`.toParse();
|
||||
expect`\mathnormal {x + 1}`.toParse();
|
||||
});
|
||||
|
||||
it("should parse \\mathcal and \\mathfrak", function() {
|
||||
@@ -1510,6 +1512,10 @@ describe("A font parser", function() {
|
||||
expect(mathitParse.font).toEqual("mathit");
|
||||
expect(mathitParse.type).toEqual("font");
|
||||
|
||||
const mathnormalParse = getParsed`\mathnormal x`[0];
|
||||
expect(mathnormalParse.font).toEqual("mathnormal");
|
||||
expect(mathnormalParse.type).toEqual("font");
|
||||
|
||||
const mathcalParse = getParsed`\mathcal C`[0];
|
||||
expect(mathcalParse.font).toEqual("mathcal");
|
||||
expect(mathcalParse.type).toEqual("font");
|
||||
@@ -1783,6 +1789,19 @@ describe("A MathML font tree-builder", function() {
|
||||
expect(markup).toContain("<mo>+</mo>");
|
||||
});
|
||||
|
||||
it("should render \\mathnormal{" + contents + "} with the correct mathvariants", function() {
|
||||
const tex = `\\mathnormal{${contents}}`;
|
||||
const tree = getParsed(tex);
|
||||
const markup = buildMathML(tree, tex, defaultOptions).toMarkup();
|
||||
expect(markup).toContain("<mi>A</mi>");
|
||||
expect(markup).toContain("<mi>x</mi>");
|
||||
expect(markup).toContain("<mn>2</mn>");
|
||||
expect(markup).toContain("<mi>\u03c9</mi>"); // \omega
|
||||
expect(markup).toContain("<mi mathvariant=\"normal\">\u03A9</mi>"); // \Omega
|
||||
expect(markup).toContain("<mi>\u0131</mi>"); // \imath
|
||||
expect(markup).toContain("<mo>+</mo>");
|
||||
});
|
||||
|
||||
it("should render \\mathbf{" + contents + "} with the correct mathvariants", function() {
|
||||
const tex = `\\mathbf{${contents}}`;
|
||||
const tree = getParsed(tex);
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 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 |
BIN
test/screenshotter/images/MathNormal-chrome.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
test/screenshotter/images/MathNormal-firefox.png
Normal file
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
@@ -200,6 +200,7 @@ MathBf: \mathbf{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
||||
MathCal: \mathcal{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
||||
MathFrak: \mathfrak{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
||||
MathIt: \mathit{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
||||
MathNormal: \mathnormal{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
||||
MathOp: a\mathop+b\mathop:c\mathop{\delta}e\mathop{\textrm{and}}f\mathrel{\mathop{:}}=g\sin h
|
||||
MathRm: \mathrm{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
||||
MathSf: \mathsf{Ax2k\breve{a}\omega\Omega\imath+\KaTeX}
|
||||
|