Added support for bold italic symbols (#1011)

* added support for \boldsymbol

* added \boldsymbol tests

* added \boldsymbol screenshots

* added \bm, snapshot, updated screenshots

* updated snapshot for \boldsymbol

* properly display \imath and 2 in boldsymbol

* implemented \boldsymbol for +

* fix typo, remove boldsymbolLetters hardcode

* make comment about using Main-Bold more general

* fixed trailing space CI error
This commit is contained in:
Alexander Terenin
2017-12-12 20:09:52 -08:00
committed by Kevin Barabash
parent 36ca9beaa7
commit cf23517499
9 changed files with 104 additions and 9 deletions

View File

@@ -113,8 +113,13 @@ const mathsym = function(
// Have a special case for when the value = \ because the \ is used as a // Have a special case for when the value = \ because the \ is used as a
// textord in unsupported command errors but cannot be parsed as a regular // textord in unsupported command errors but cannot be parsed as a regular
// text ordinal and is therefore not present as a symbol in the symbols // text ordinal and is therefore not present as a symbol in the symbols
// table for text // table for text, as well as a special case for boldsymbol because it
if (value === "\\" || symbols[mode][value].font === "main") { // can be used for bold + and -
if ((options && options.font && options.font === "boldsymbol") &&
lookupSymbol(value, "Main-Bold", mode).metrics) {
return makeSymbol(value, "Main-Bold", mode, options,
classes.concat(["mathbf"]));
} else if (value === "\\" || symbols[mode][value].font === "main") {
return makeSymbol(value, "Main-Regular", mode, options, classes); return makeSymbol(value, "Main-Regular", mode, options, classes);
} else { } else {
return makeSymbol( return makeSymbol(
@@ -179,6 +184,33 @@ const mathit = function(
} }
}; };
/**
* Determines which of the two font names (Main-Bold and Math-BoldItalic) and
* corresponding style tags (mathbf or boldsymbol) to use for font "boldsymbol",
* depending on the symbol. Use this function instead of fontMap for font
* "boldsymbol".
*/
const boldsymbol = function(
value: string,
mode: Mode,
options: Options,
classes: string[],
): {| fontName: string, fontClass: string |} {
if (lookupSymbol(value, "Math-BoldItalic", mode).metrics) {
return {
fontName: "Math-BoldItalic",
fontClass: "boldsymbol",
};
} else {
// Some glyphs do not exist in Math-BoldItalic so we need to use
// Main-Bold instead.
return {
fontName: "Main-Bold",
fontClass: "mathbf",
};
}
};
/** /**
* Makes either a mathord or textord in the correct font and color. * Makes either a mathord or textord in the correct font and color.
*/ */
@@ -195,7 +227,9 @@ const makeOrd = function(
const font = options.font; const font = options.font;
if (font) { if (font) {
let fontLookup; let fontLookup;
if (font === "mathit" || utils.contains(mainitLetters, value)) { if (font === "boldsymbol") {
fontLookup = boldsymbol(value, mode, options, classes);
} else if (font === "mathit" || utils.contains(mainitLetters, value)) {
fontLookup = mathit(value, mode, options, classes); fontLookup = mathit(value, mode, options, classes);
} else { } else {
fontLookup = fontMap[font]; fontLookup = fontMap[font];
@@ -590,9 +624,10 @@ const fontMap: {[string]: {| variant: string, fontName: string |}} = {
fontName: "Main-Italic", fontName: "Main-Italic",
}, },
// "mathit" is missing because it requires the use of two fonts: Main-Italic // "mathit" and "boldsymbol" are missing because they require the use of two
// and Math-Italic. This is handled by a special case in makeOrd which ends // fonts: Main-Italic and Math-Italic for "mathit", and Math-BoldItalic and
// up calling mathit. // Main-Bold for "boldsymbol". This is handled by a special case in makeOrd
// which ends up calling mathit and boldsymbol.
// families // families
"mathbb": { "mathbb": {

View File

@@ -39,6 +39,8 @@ const getVariant = function(group, options) {
const mode = group.mode; const mode = group.mode;
if (font === "mathit") { if (font === "mathit") {
return "italic"; return "italic";
} else if (font === "boldsymbol") {
return "bold-italic";
} }
let value = group.value; let value = group.value;
@@ -106,10 +108,15 @@ groupTypes.textord = function(group, options) {
return node; return node;
}; };
groupTypes.bin = function(group) { groupTypes.bin = function(group, options) {
const node = new mathMLTree.MathNode( const node = new mathMLTree.MathNode(
"mo", [makeText(group.value, group.mode)]); "mo", [makeText(group.value, group.mode)]);
const variant = getVariant(group, options);
if (variant === "bold-italic") {
node.setAttribute("mathvariant", variant);
}
return node; return node;
}; };

View File

@@ -147,6 +147,7 @@ const fontAliases = {
"\\Bbb": "\\mathbb", "\\Bbb": "\\mathbb",
"\\bold": "\\mathbf", "\\bold": "\\mathbf",
"\\frak": "\\mathfrak", "\\frak": "\\mathfrak",
"\\bm": "\\boldsymbol",
}; };
const singleCharIntegrals: {[string]: string} = { const singleCharIntegrals: {[string]: string} = {
@@ -244,14 +245,14 @@ defineFunction([
defineFunction([ defineFunction([
// styles // styles
"\\mathrm", "\\mathit", "\\mathbf", "\\mathrm", "\\mathit", "\\mathbf", "\\boldsymbol",
// families // families
"\\mathbb", "\\mathcal", "\\mathfrak", "\\mathscr", "\\mathsf", "\\mathbb", "\\mathcal", "\\mathfrak", "\\mathscr", "\\mathsf",
"\\mathtt", "\\mathtt",
// aliases // aliases
"\\Bbb", "\\bold", "\\frak", "\\Bbb", "\\bold", "\\frak", "\\bm",
], { ], {
numArgs: 1, numArgs: 1,
greediness: 2, greediness: 2,

View File

@@ -75,6 +75,12 @@
font-weight: bold; font-weight: bold;
} }
.boldsymbol {
font-family: KaTeX_Math;
font-weight: bold;
font-style: italic;
}
.amsrm { .amsrm {
font-family: KaTeX_AMS; font-family: KaTeX_AMS;
} }

View File

@@ -77,6 +77,46 @@ exports[`A MathML builder should make prime operators into <mo> nodes 1`] = `
`; `;
exports[`A MathML builder should render boldsymbol with the correct mathvariants 1`] = `
<math>
<semantics>
<mrow>
<mrow>
<mi mathvariant="bold-italic">
A
</mi>
<mi mathvariant="bold-italic">
x
</mi>
<mn mathvariant="bold-italic">
2
</mn>
<mi mathvariant="bold-italic">
k
</mi>
<mi mathvariant="bold-italic">
ω
</mi>
<mi mathvariant="bold-italic">
Ω
</mi>
<mi mathvariant="bold-italic">
ı
</mi>
<mo mathvariant="bold-italic">
+
</mo>
</mrow>
</mrow>
<annotation encoding="application/x-tex">
\\boldsymbol{Ax2k\\omega\\Omega\\imath+}
</annotation>
</semantics>
</math>
`;
exports[`A MathML builder should render mathchoice as if there was nothing 1`] = ` exports[`A MathML builder should render mathchoice as if there was nothing 1`] = `
<math> <math>

View File

@@ -75,4 +75,9 @@ describe("A MathML builder", function() {
expect(getMathML(`x_{y_{\\mathchoice{D}{T}{S}{${cmd}}}}`)) expect(getMathML(`x_{y_{\\mathchoice{D}{T}{S}{${cmd}}}}`))
.toMatchSnapshot(); .toMatchSnapshot();
}); });
it("should render boldsymbol with the correct mathvariants", () => {
expect(getMathML(`\\boldsymbol{Ax2k\\omega\\Omega\\imath+}`))
.toMatchSnapshot();
});
}); });

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -57,6 +57,7 @@ BinCancellation: |
\end{array} \end{array}
BinomTest: \dbinom{a}{b}\tbinom{a}{b}^{\binom{a}{b}+17} BinomTest: \dbinom{a}{b}\tbinom{a}{b}^{\binom{a}{b}+17}
BoldSpacing: \mathbf{A}^2+\mathbf{B}_3*\mathscr{C}' BoldSpacing: \mathbf{A}^2+\mathbf{B}_3*\mathscr{C}'
BoldSymbol: \sum_{\boldsymbol{\alpha}}^{\boldsymbol{\beta}} \boldsymbol{\omega}+ \int_{\boldsymbol{\alpha}}^{\boldsymbol{\beta}} \boldsymbol{\Omega}+\boldsymbol{Ax2k\omega\Omega\imath+}
Boxed: \boxed{F=ma} \quad \boxed{ac}\color{magenta}{\boxed{F}}\boxed{F=mg} Boxed: \boxed{F=ma} \quad \boxed{ac}\color{magenta}{\boxed{F}}\boxed{F=mg}
Cases: | Cases: |
f(a,b)=\begin{cases} f(a,b)=\begin{cases}