mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-05 19:28:39 +00:00
Stacking text commands (#1009)
* Adding support for SansSerif-Bold * Updating to include SansSerif Italic. * WIP * Working text stacking * More robust screenshot. * Don't want to break users :) * Updating per PR comments. * Fixing Unicode and updating snapshots. * Adding suggested tests. * Opting to use old method for unit testing. * Adding TODO
This commit is contained in:
committed by
Kevin Barabash
parent
cf23517499
commit
50765a0ccd
@@ -36,6 +36,8 @@ def main():
|
||||
'cmtt10.tfm',
|
||||
'rsfs10.tfm',
|
||||
'cmss10.tfm',
|
||||
'cmssbx10.tfm',
|
||||
'cmssi10.tfm',
|
||||
]
|
||||
|
||||
# Extracted by running `\font\a=<font>` and then `\showthe\skewchar\a` in
|
||||
@@ -57,6 +59,8 @@ def main():
|
||||
'cmtt10': None,
|
||||
'rsfs10': None,
|
||||
'cmss10': None,
|
||||
'cmssbx10': None,
|
||||
'cmssi10': None,
|
||||
}
|
||||
|
||||
font_name_to_tfm = {}
|
||||
|
@@ -1004,6 +1004,94 @@ $map{rsfs10} = {
|
||||
],
|
||||
};
|
||||
|
||||
$map{cmssbx10} = {
|
||||
"SansSerif-Bold" => [
|
||||
[0,1] => 0x393, # \Gamma, \Delta
|
||||
2 => 0x398, # \Theta
|
||||
3 => 0x39B, # \Lambda
|
||||
4 => 0x39E, # \Xi
|
||||
5 => 0x3A0, # \Pi
|
||||
6 => 0x3A3, # \Sigma
|
||||
[7,8] => 0x3A5, # \Upsilon, \Phi
|
||||
[9,0xA] => 0x3A8, # \Psi, \Omega
|
||||
|
||||
0x10 => 0x131, # \imath (roman)
|
||||
0x11 => 0x237, # \jmath (roman)
|
||||
0x12 => [0x300,-550,0], # \grave (combining)
|
||||
0x13 => [0x301,-550,0], # \acute (combining)
|
||||
0x14 => [0x30C,-550,0], # \check (combining)
|
||||
0x15 => [0x306,-550,0], # \breve (combining)
|
||||
0x16 => [0x304,-550,0], # \bar (combining)
|
||||
0x17 => [0x30A,-608,0], # ring above (combining)
|
||||
|
||||
[0x21,0x2F] => 0x21, # !, ", #, $, %, &, ', (, ), *, +, comma, -, ., /
|
||||
0x22 => 0x201D, # "
|
||||
0x27 => 0x2019, # '
|
||||
[0x30,0x39] => 0x30, # 0-9
|
||||
[0x3A,0x3B] => 0x3A, # :, ;
|
||||
0x3D => 0x3D, # =
|
||||
[0x3F,0x40] => 0x3F, # ?, @
|
||||
[0x41,0x5A] => 0x41, # A-Z
|
||||
0x5B => 0x5B, # [
|
||||
0x5C => 0x201C, # ``
|
||||
[0x5D,0x5E] => 0x5D, # ], ^
|
||||
0x5E => [0x302,-550,0], # \hat (combining)
|
||||
0x5F => [0x307,-428,0], # \dot (combining)
|
||||
0x60 => 0x2018, # `
|
||||
[0x61,0x7A] => 0x61, # a-z
|
||||
[0x7B,0x7C] => 0x2013, # \endash, \emdash
|
||||
0x7B => [0x5F,0,-350], # underline
|
||||
0x7D => [0x30B,-550,0], # double acute (combining)
|
||||
0x7E => [0x7E,0,-350], # ~
|
||||
0x7E => [0x303,-550,0], # \tilde (combining)
|
||||
0x7F => [0x308,-550,0], # \ddot (combining)
|
||||
],
|
||||
};
|
||||
|
||||
$map{cmssi10} = {
|
||||
"SansSerif-Italic" => [
|
||||
[0,1] => 0x393, # \Gamma, \Delta
|
||||
2 => 0x398, # \Theta
|
||||
3 => 0x39B, # \Lambda
|
||||
4 => 0x39E, # \Xi
|
||||
5 => 0x3A0, # \Pi
|
||||
6 => 0x3A3, # \Sigma
|
||||
[7,8] => 0x3A5, # \Upsilon, \Phi
|
||||
[9,0xA] => 0x3A8, # \Psi, \Omega
|
||||
|
||||
0x10 => 0x131, # \imath (roman)
|
||||
0x11 => 0x237, # \jmath (roman)
|
||||
0x12 => [0x300,-500,0], # \grave (combining)
|
||||
0x13 => [0x301,-500,0], # \acute (combining)
|
||||
0x14 => [0x30C,-500,0], # \check (combining)
|
||||
0x15 => [0x306,-500,0], # \breve (combining)
|
||||
0x16 => [0x304,-500,0], # \bar (combining)
|
||||
0x17 => [0x30A,-613,0], # ring above (combining)
|
||||
|
||||
[0x21,0x2F] => 0x21, # !, ", #, $, %, &, ', (, ), *, +, comma, -, ., /
|
||||
0x22 => 0x201D, # "
|
||||
0x27 => 0x2019, # '
|
||||
[0x30,0x39] => 0x30, # 0-9
|
||||
[0x3A,0x3B] => 0x3A, # :, ;
|
||||
0x3D => 0x3D, # =
|
||||
[0x3F,0x40] => 0x3F, # ?, @
|
||||
[0x41,0x5A] => 0x41, # A-Z
|
||||
0x5B => 0x5B, # [
|
||||
0x5C => 0x201C, # ``
|
||||
[0x5D,0x5E] => 0x5D, # ], ^
|
||||
0x5E => [0x302,-500,0], # \hat (combining)
|
||||
0x5F => [0x307,-389,0], # \dot (combining)
|
||||
0x60 => 0x2018, # `
|
||||
[0x61,0x7A] => 0x61, # a-z
|
||||
[0x7B,0x7C] => 0x2013, # \endash, \emdash
|
||||
0x7B => [0x5F,0,-350], # underline
|
||||
0x7D => [0x30B,-500,0], # double acute (combining)
|
||||
0x7E => [0x7E,0,-350], # ~
|
||||
0x7E => [0x303,-500,0], # \tilde (combining)
|
||||
0x7F => [0x308,-500,0], # \ddot (combining)
|
||||
],
|
||||
};
|
||||
|
||||
$map{cmss10} = {
|
||||
"SansSerif-Regular" => [
|
||||
[0,1] => 0x393, # \Gamma, \Delta
|
||||
|
@@ -45,6 +45,7 @@
|
||||
"object-assign": "^4.1.0",
|
||||
"pako": "1.0.4",
|
||||
"pre-commit": "^1.2.2",
|
||||
"rimraf": "^2.6.2",
|
||||
"selenium-webdriver": "^2.48.2",
|
||||
"sri-toolbox": "^0.2.0",
|
||||
"stylelint": "^8.2.0",
|
||||
@@ -58,13 +59,14 @@
|
||||
"lint": "eslint katex.js server.js cli.js webpack.config.js webpackDevServer.js src test contrib dockers && stylelint static/fonts.less static/katex.less",
|
||||
"flow": "flow",
|
||||
"jest": "jest",
|
||||
"jest-update": "jest --updateSnapshot",
|
||||
"coverage": "jest --coverage",
|
||||
"copy": "cp -a static/. build/ && cp -a contrib build/",
|
||||
"clean": "rm -rf build/* node_modules/",
|
||||
"clean-install": "npm run clean && npm i",
|
||||
"test": "check-dependencies && npm run lint && npm run flow && npm run jest",
|
||||
"build-css": "lessc --clean-css static/katex.less build/katex.css",
|
||||
"prestart": "npm run build-css && npm run copy",
|
||||
"prestart": "rimraf build && npm run build-css && npm run copy",
|
||||
"start": "check-dependencies && node webpackDevServer.js",
|
||||
"prepublishOnly": "make NIS= dist"
|
||||
},
|
||||
|
@@ -42,7 +42,11 @@ export type OptionsData = {
|
||||
size?: number;
|
||||
textSize?: number;
|
||||
phantom?: boolean;
|
||||
font?: string | void;
|
||||
// TODO(#1009): Keep consistent with fontFamily/fontWeight. Ensure this has a
|
||||
// string value.
|
||||
fontFamily?: string | void;
|
||||
fontWeight?: string;
|
||||
fontShape?: string;
|
||||
maxSize: number;
|
||||
};
|
||||
|
||||
@@ -59,7 +63,9 @@ class Options {
|
||||
size: number;
|
||||
textSize: number;
|
||||
phantom: boolean;
|
||||
font: string | void;
|
||||
fontFamily: string | void;
|
||||
fontWeight: string;
|
||||
fontShape: string;
|
||||
sizeMultiplier: number;
|
||||
maxSize: number;
|
||||
_fontMetrics: FontMetrics | void;
|
||||
@@ -75,7 +81,9 @@ class Options {
|
||||
this.size = data.size || Options.BASESIZE;
|
||||
this.textSize = data.textSize || this.size;
|
||||
this.phantom = !!data.phantom;
|
||||
this.font = data.font;
|
||||
this.fontFamily = data.fontFamily;
|
||||
this.fontWeight = data.fontWeight || '';
|
||||
this.fontShape = data.fontShape || '';
|
||||
this.sizeMultiplier = sizeMultipliers[this.size - 1];
|
||||
this.maxSize = data.maxSize;
|
||||
this._fontMetrics = undefined;
|
||||
@@ -92,7 +100,9 @@ class Options {
|
||||
textSize: this.textSize,
|
||||
color: this.color,
|
||||
phantom: this.phantom,
|
||||
font: this.font,
|
||||
fontFamily: this.fontFamily,
|
||||
fontWeight: this.fontWeight,
|
||||
fontShape: this.fontShape,
|
||||
maxSize: this.maxSize,
|
||||
};
|
||||
|
||||
@@ -183,9 +193,27 @@ class Options {
|
||||
/**
|
||||
* Create a new options objects with the give font.
|
||||
*/
|
||||
withFont(font: ?string): Options {
|
||||
withFontFamily(fontFamily: ?string): Options {
|
||||
return this.extend({
|
||||
font: font || this.font,
|
||||
fontFamily: fontFamily || this.fontFamily,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new options object with the given font weight
|
||||
*/
|
||||
withFontWeight(fontWeight: string): Options {
|
||||
return this.extend({
|
||||
fontWeight,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new options object with the given font weight
|
||||
*/
|
||||
withFontShape(fontShape: string): Options {
|
||||
return this.extend({
|
||||
fontShape,
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -115,7 +115,7 @@ const mathsym = function(
|
||||
// text ordinal and is therefore not present as a symbol in the symbols
|
||||
// table for text, as well as a special case for boldsymbol because it
|
||||
// can be used for bold + and -
|
||||
if ((options && options.font && options.font === "boldsymbol") &&
|
||||
if ((options && options.fontFamily && options.fontFamily === "boldsymbol") &&
|
||||
lookupSymbol(value, "Main-Bold", mode).metrics) {
|
||||
return makeSymbol(value, "Main-Bold", mode, options,
|
||||
classes.concat(["mathbf"]));
|
||||
@@ -144,12 +144,17 @@ const mathDefault = function(
|
||||
} else if (type === "textord") {
|
||||
const font = symbols[mode][value] && symbols[mode][value].font;
|
||||
if (font === "ams") {
|
||||
const fontName = retrieveTextFontName("amsrm", options.fontWeight,
|
||||
options.fontShape);
|
||||
return makeSymbol(
|
||||
value, "AMS-Regular", mode, options, classes.concat(["amsrm"]));
|
||||
value, fontName, mode, options,
|
||||
classes.concat("amsrm", options.fontWeight, options.fontShape));
|
||||
} else { // if (font === "main") {
|
||||
const fontName = retrieveTextFontName("textrm", options.fontWeight,
|
||||
options.fontShape);
|
||||
return makeSymbol(
|
||||
value, "Main-Regular", mode, options,
|
||||
classes.concat(["mathrm"]));
|
||||
value, fontName, mode, options,
|
||||
classes.concat(options.fontWeight, options.fontShape));
|
||||
}
|
||||
} else {
|
||||
throw new Error("unexpected type: " + type + " in mathDefault");
|
||||
@@ -224,19 +229,31 @@ const makeOrd = function(
|
||||
|
||||
const classes = ["mord"];
|
||||
|
||||
const font = options.font;
|
||||
if (font) {
|
||||
let fontLookup;
|
||||
if (font === "boldsymbol") {
|
||||
fontLookup = boldsymbol(value, mode, options, classes);
|
||||
} else if (font === "mathit" || utils.contains(mainitLetters, value)) {
|
||||
fontLookup = mathit(value, mode, options, classes);
|
||||
const fontFamily = options.fontFamily;
|
||||
if (fontFamily) {
|
||||
let fontName;
|
||||
let fontClasses;
|
||||
if (fontFamily === "boldsymbol") {
|
||||
const fontData = boldsymbol(value, mode, options, classes);
|
||||
fontName = fontData.fontName;
|
||||
fontClasses = [fontData.fontClass];
|
||||
} else if (fontFamily === "mathit" ||
|
||||
utils.contains(mainitLetters, value)) {
|
||||
const fontData = mathit(value, mode, options, classes);
|
||||
fontName = fontData.fontName;
|
||||
fontClasses = [fontData.fontClass];
|
||||
} else if (fontFamily.includes("math") || mode === "math") {
|
||||
// To support old font functions (i.e. \rm \sf etc.) or math mode.
|
||||
fontName = fontMap[fontFamily].fontName;
|
||||
fontClasses = [fontFamily];
|
||||
} else {
|
||||
fontLookup = fontMap[font];
|
||||
fontName = retrieveTextFontName(fontFamily, options.fontWeight,
|
||||
options.fontShape);
|
||||
fontClasses = [fontFamily, options.fontWeight, options.fontShape];
|
||||
}
|
||||
if (lookupSymbol(value, fontLookup.fontName, mode).metrics) {
|
||||
return makeSymbol(value, fontLookup.fontName, mode, options,
|
||||
classes.concat([fontLookup.fontClass || font]));
|
||||
if (lookupSymbol(value, fontName, mode).metrics) {
|
||||
return makeSymbol(value, fontName, mode, options,
|
||||
classes.concat(fontClasses));
|
||||
} else {
|
||||
return mathDefault(value, mode, options, classes, type);
|
||||
}
|
||||
@@ -570,6 +587,52 @@ const makeVerb = function(group: ParseNode, options: Options): string {
|
||||
return text;
|
||||
};
|
||||
|
||||
// Takes an Options object, and returns the appropriate fontLookup
|
||||
const retrieveTextFontName = function(
|
||||
fontFamily: string,
|
||||
fontWeight: string,
|
||||
fontShape: string,
|
||||
): string {
|
||||
const baseFontName = retrieveBaseFontName(fontFamily);
|
||||
const fontStylesName = retrieveFontStylesName(fontWeight, fontShape);
|
||||
return `${baseFontName}-${fontStylesName}`;
|
||||
};
|
||||
|
||||
const retrieveBaseFontName = function(font: string): string {
|
||||
let baseFontName = "";
|
||||
switch (font) {
|
||||
case "amsrm":
|
||||
baseFontName = "AMS";
|
||||
break;
|
||||
case "textrm":
|
||||
baseFontName = "Main";
|
||||
break;
|
||||
case "textsf":
|
||||
baseFontName = "SansSerif";
|
||||
break;
|
||||
case "texttt":
|
||||
baseFontName = "Typewriter";
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Invalid font provided: ${font}`);
|
||||
}
|
||||
return baseFontName;
|
||||
};
|
||||
|
||||
const retrieveFontStylesName = function(
|
||||
fontWeight?: string,
|
||||
fontShape?: string,
|
||||
): string {
|
||||
let fontStylesName = '';
|
||||
if (fontWeight === "textbf") {
|
||||
fontStylesName += "Bold";
|
||||
}
|
||||
if (fontShape === "textit") {
|
||||
fontStylesName += "Italic";
|
||||
}
|
||||
return fontStylesName || "Regular";
|
||||
};
|
||||
|
||||
// A map of spacing functions to their attributes, like size and corresponding
|
||||
// CSS class
|
||||
const spacingFunctions: {[string]: {| size: string, className: string |}} = {
|
||||
|
@@ -591,7 +591,7 @@ groupTypes.styling = function(group, options) {
|
||||
|
||||
groupTypes.font = function(group, options) {
|
||||
const font = group.value.font;
|
||||
return buildGroup(group.value.body, options.withFont(font));
|
||||
return buildGroup(group.value.body, options.withFontFamily(font));
|
||||
};
|
||||
|
||||
groupTypes.verb = function(group, options) {
|
||||
|
@@ -31,7 +31,7 @@ export const makeText = function(text, mode) {
|
||||
* Returns the math variant as a string or null if none is required.
|
||||
*/
|
||||
const getVariant = function(group, options) {
|
||||
const font = options.font;
|
||||
const font = options.fontFamily;
|
||||
if (!font) {
|
||||
return null;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ const getVariant = function(group, options) {
|
||||
|
||||
const fontName = buildCommon.fontMap[font].fontName;
|
||||
if (fontMetrics.getCharacterMetrics(value, fontName)) {
|
||||
return buildCommon.fontMap[options.font].variant;
|
||||
return buildCommon.fontMap[font].variant;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -268,7 +268,7 @@ groupTypes.spacing = function(group) {
|
||||
|
||||
groupTypes.font = function(group, options) {
|
||||
const font = group.value.font;
|
||||
return buildGroup(group.value.body, options.withFont(font));
|
||||
return buildGroup(group.value.body, options.withFontFamily(font));
|
||||
};
|
||||
|
||||
groupTypes.styling = function(group, options) {
|
||||
|
@@ -246,6 +246,9 @@ const getCharacterMetrics = function(
|
||||
character: string,
|
||||
font: string,
|
||||
): ?CharacterMetrics {
|
||||
if (!metricMap[font]) {
|
||||
throw new Error(`Font metrics not found for font: ${font}.`);
|
||||
}
|
||||
let ch = character.charCodeAt(0);
|
||||
if (character[0] in extraCharacterMap) {
|
||||
ch = extraCharacterMap[character[0]].charCodeAt(0);
|
||||
|
@@ -1,5 +1,4 @@
|
||||
// @flow
|
||||
const fontMetricsData = {
|
||||
module.exports = {
|
||||
"AMS-Regular": {
|
||||
"65": [0, 0.68889, 0, 0],
|
||||
"66": [0, 0.68889, 0, 0],
|
||||
@@ -1331,6 +1330,244 @@ const fontMetricsData = {
|
||||
"1009": [0.19444, 0.43056, 0, 0.08334],
|
||||
"1013": [0, 0.43056, 0, 0.05556],
|
||||
},
|
||||
"SansSerif-Bold": {
|
||||
"33": [0, 0.69444, 0, 0],
|
||||
"34": [0, 0.69444, 0, 0],
|
||||
"35": [0.19444, 0.69444, 0, 0],
|
||||
"36": [0.05556, 0.75, 0, 0],
|
||||
"37": [0.05556, 0.75, 0, 0],
|
||||
"38": [0, 0.69444, 0, 0],
|
||||
"39": [0, 0.69444, 0, 0],
|
||||
"40": [0.25, 0.75, 0, 0],
|
||||
"41": [0.25, 0.75, 0, 0],
|
||||
"42": [0, 0.75, 0, 0],
|
||||
"43": [0.11667, 0.61667, 0, 0],
|
||||
"44": [0.10556, 0.13056, 0, 0],
|
||||
"45": [0, 0.45833, 0, 0],
|
||||
"46": [0, 0.13056, 0, 0],
|
||||
"47": [0.25, 0.75, 0, 0],
|
||||
"48": [0, 0.69444, 0, 0],
|
||||
"49": [0, 0.69444, 0, 0],
|
||||
"50": [0, 0.69444, 0, 0],
|
||||
"51": [0, 0.69444, 0, 0],
|
||||
"52": [0, 0.69444, 0, 0],
|
||||
"53": [0, 0.69444, 0, 0],
|
||||
"54": [0, 0.69444, 0, 0],
|
||||
"55": [0, 0.69444, 0, 0],
|
||||
"56": [0, 0.69444, 0, 0],
|
||||
"57": [0, 0.69444, 0, 0],
|
||||
"58": [0, 0.45833, 0, 0],
|
||||
"59": [0.10556, 0.45833, 0, 0],
|
||||
"61": [-0.09375, 0.40625, 0, 0],
|
||||
"63": [0, 0.69444, 0, 0],
|
||||
"64": [0, 0.69444, 0, 0],
|
||||
"65": [0, 0.69444, 0, 0],
|
||||
"66": [0, 0.69444, 0, 0],
|
||||
"67": [0, 0.69444, 0, 0],
|
||||
"68": [0, 0.69444, 0, 0],
|
||||
"69": [0, 0.69444, 0, 0],
|
||||
"70": [0, 0.69444, 0, 0],
|
||||
"71": [0, 0.69444, 0, 0],
|
||||
"72": [0, 0.69444, 0, 0],
|
||||
"73": [0, 0.69444, 0, 0],
|
||||
"74": [0, 0.69444, 0, 0],
|
||||
"75": [0, 0.69444, 0, 0],
|
||||
"76": [0, 0.69444, 0, 0],
|
||||
"77": [0, 0.69444, 0, 0],
|
||||
"78": [0, 0.69444, 0, 0],
|
||||
"79": [0, 0.69444, 0, 0],
|
||||
"80": [0, 0.69444, 0, 0],
|
||||
"81": [0.10556, 0.69444, 0, 0],
|
||||
"82": [0, 0.69444, 0, 0],
|
||||
"83": [0, 0.69444, 0, 0],
|
||||
"84": [0, 0.69444, 0, 0],
|
||||
"85": [0, 0.69444, 0, 0],
|
||||
"86": [0, 0.69444, 0.01528, 0],
|
||||
"87": [0, 0.69444, 0.01528, 0],
|
||||
"88": [0, 0.69444, 0, 0],
|
||||
"89": [0, 0.69444, 0.0275, 0],
|
||||
"90": [0, 0.69444, 0, 0],
|
||||
"91": [0.25, 0.75, 0, 0],
|
||||
"93": [0.25, 0.75, 0, 0],
|
||||
"94": [0, 0.69444, 0, 0],
|
||||
"95": [0.35, 0.10833, 0.03056, 0],
|
||||
"97": [0, 0.45833, 0, 0],
|
||||
"98": [0, 0.69444, 0, 0],
|
||||
"99": [0, 0.45833, 0, 0],
|
||||
"100": [0, 0.69444, 0, 0],
|
||||
"101": [0, 0.45833, 0, 0],
|
||||
"102": [0, 0.69444, 0.07639, 0],
|
||||
"103": [0.19444, 0.45833, 0.01528, 0],
|
||||
"104": [0, 0.69444, 0, 0],
|
||||
"105": [0, 0.69444, 0, 0],
|
||||
"106": [0.19444, 0.69444, 0, 0],
|
||||
"107": [0, 0.69444, 0, 0],
|
||||
"108": [0, 0.69444, 0, 0],
|
||||
"109": [0, 0.45833, 0, 0],
|
||||
"110": [0, 0.45833, 0, 0],
|
||||
"111": [0, 0.45833, 0, 0],
|
||||
"112": [0.19444, 0.45833, 0, 0],
|
||||
"113": [0.19444, 0.45833, 0, 0],
|
||||
"114": [0, 0.45833, 0.01528, 0],
|
||||
"115": [0, 0.45833, 0, 0],
|
||||
"116": [0, 0.58929, 0, 0],
|
||||
"117": [0, 0.45833, 0, 0],
|
||||
"118": [0, 0.45833, 0.01528, 0],
|
||||
"119": [0, 0.45833, 0.01528, 0],
|
||||
"120": [0, 0.45833, 0, 0],
|
||||
"121": [0.19444, 0.45833, 0.01528, 0],
|
||||
"122": [0, 0.45833, 0, 0],
|
||||
"126": [0.35, 0.34444, 0, 0],
|
||||
"305": [0, 0.45833, 0, 0],
|
||||
"567": [0.19444, 0.45833, 0, 0],
|
||||
"768": [0, 0.69444, 0, 0],
|
||||
"769": [0, 0.69444, 0, 0],
|
||||
"770": [0, 0.69444, 0, 0],
|
||||
"771": [0, 0.69444, 0, 0],
|
||||
"772": [0, 0.63778, 0, 0],
|
||||
"774": [0, 0.69444, 0, 0],
|
||||
"775": [0, 0.69444, 0, 0],
|
||||
"776": [0, 0.69444, 0, 0],
|
||||
"778": [0, 0.69444, 0, 0],
|
||||
"779": [0, 0.69444, 0, 0],
|
||||
"780": [0, 0.63542, 0, 0],
|
||||
"915": [0, 0.69444, 0, 0],
|
||||
"916": [0, 0.69444, 0, 0],
|
||||
"920": [0, 0.69444, 0, 0],
|
||||
"923": [0, 0.69444, 0, 0],
|
||||
"926": [0, 0.69444, 0, 0],
|
||||
"928": [0, 0.69444, 0, 0],
|
||||
"931": [0, 0.69444, 0, 0],
|
||||
"933": [0, 0.69444, 0, 0],
|
||||
"934": [0, 0.69444, 0, 0],
|
||||
"936": [0, 0.69444, 0, 0],
|
||||
"937": [0, 0.69444, 0, 0],
|
||||
"8211": [0, 0.45833, 0.03056, 0],
|
||||
"8212": [0, 0.45833, 0.03056, 0],
|
||||
"8216": [0, 0.69444, 0, 0],
|
||||
"8217": [0, 0.69444, 0, 0],
|
||||
"8220": [0, 0.69444, 0, 0],
|
||||
"8221": [0, 0.69444, 0, 0],
|
||||
},
|
||||
"SansSerif-Italic": {
|
||||
"33": [0, 0.69444, 0.05733, 0],
|
||||
"34": [0, 0.69444, 0.00316, 0],
|
||||
"35": [0.19444, 0.69444, 0.05087, 0],
|
||||
"36": [0.05556, 0.75, 0.11156, 0],
|
||||
"37": [0.05556, 0.75, 0.03126, 0],
|
||||
"38": [0, 0.69444, 0.03058, 0],
|
||||
"39": [0, 0.69444, 0.07816, 0],
|
||||
"40": [0.25, 0.75, 0.13164, 0],
|
||||
"41": [0.25, 0.75, 0.02536, 0],
|
||||
"42": [0, 0.75, 0.11775, 0],
|
||||
"43": [0.08333, 0.58333, 0.02536, 0],
|
||||
"44": [0.125, 0.08333, 0, 0],
|
||||
"45": [0, 0.44444, 0.01946, 0],
|
||||
"46": [0, 0.08333, 0, 0],
|
||||
"47": [0.25, 0.75, 0.13164, 0],
|
||||
"48": [0, 0.65556, 0.11156, 0],
|
||||
"49": [0, 0.65556, 0.11156, 0],
|
||||
"50": [0, 0.65556, 0.11156, 0],
|
||||
"51": [0, 0.65556, 0.11156, 0],
|
||||
"52": [0, 0.65556, 0.11156, 0],
|
||||
"53": [0, 0.65556, 0.11156, 0],
|
||||
"54": [0, 0.65556, 0.11156, 0],
|
||||
"55": [0, 0.65556, 0.11156, 0],
|
||||
"56": [0, 0.65556, 0.11156, 0],
|
||||
"57": [0, 0.65556, 0.11156, 0],
|
||||
"58": [0, 0.44444, 0.02502, 0],
|
||||
"59": [0.125, 0.44444, 0.02502, 0],
|
||||
"61": [-0.13, 0.37, 0.05087, 0],
|
||||
"63": [0, 0.69444, 0.11809, 0],
|
||||
"64": [0, 0.69444, 0.07555, 0],
|
||||
"65": [0, 0.69444, 0, 0],
|
||||
"66": [0, 0.69444, 0.08293, 0],
|
||||
"67": [0, 0.69444, 0.11983, 0],
|
||||
"68": [0, 0.69444, 0.07555, 0],
|
||||
"69": [0, 0.69444, 0.11983, 0],
|
||||
"70": [0, 0.69444, 0.13372, 0],
|
||||
"71": [0, 0.69444, 0.11983, 0],
|
||||
"72": [0, 0.69444, 0.08094, 0],
|
||||
"73": [0, 0.69444, 0.13372, 0],
|
||||
"74": [0, 0.69444, 0.08094, 0],
|
||||
"75": [0, 0.69444, 0.11983, 0],
|
||||
"76": [0, 0.69444, 0, 0],
|
||||
"77": [0, 0.69444, 0.08094, 0],
|
||||
"78": [0, 0.69444, 0.08094, 0],
|
||||
"79": [0, 0.69444, 0.07555, 0],
|
||||
"80": [0, 0.69444, 0.08293, 0],
|
||||
"81": [0.125, 0.69444, 0.07555, 0],
|
||||
"82": [0, 0.69444, 0.08293, 0],
|
||||
"83": [0, 0.69444, 0.09205, 0],
|
||||
"84": [0, 0.69444, 0.13372, 0],
|
||||
"85": [0, 0.69444, 0.08094, 0],
|
||||
"86": [0, 0.69444, 0.1615, 0],
|
||||
"87": [0, 0.69444, 0.1615, 0],
|
||||
"88": [0, 0.69444, 0.13372, 0],
|
||||
"89": [0, 0.69444, 0.17261, 0],
|
||||
"90": [0, 0.69444, 0.11983, 0],
|
||||
"91": [0.25, 0.75, 0.15942, 0],
|
||||
"93": [0.25, 0.75, 0.08719, 0],
|
||||
"94": [0, 0.69444, 0.0799, 0],
|
||||
"95": [0.35, 0.09444, 0.08616, 0],
|
||||
"97": [0, 0.44444, 0.00981, 0],
|
||||
"98": [0, 0.69444, 0.03057, 0],
|
||||
"99": [0, 0.44444, 0.08336, 0],
|
||||
"100": [0, 0.69444, 0.09483, 0],
|
||||
"101": [0, 0.44444, 0.06778, 0],
|
||||
"102": [0, 0.69444, 0.21705, 0],
|
||||
"103": [0.19444, 0.44444, 0.10836, 0],
|
||||
"104": [0, 0.69444, 0.01778, 0],
|
||||
"105": [0, 0.67937, 0.09718, 0],
|
||||
"106": [0.19444, 0.67937, 0.09162, 0],
|
||||
"107": [0, 0.69444, 0.08336, 0],
|
||||
"108": [0, 0.69444, 0.09483, 0],
|
||||
"109": [0, 0.44444, 0.01778, 0],
|
||||
"110": [0, 0.44444, 0.01778, 0],
|
||||
"111": [0, 0.44444, 0.06613, 0],
|
||||
"112": [0.19444, 0.44444, 0.0389, 0],
|
||||
"113": [0.19444, 0.44444, 0.04169, 0],
|
||||
"114": [0, 0.44444, 0.10836, 0],
|
||||
"115": [0, 0.44444, 0.0778, 0],
|
||||
"116": [0, 0.57143, 0.07225, 0],
|
||||
"117": [0, 0.44444, 0.04169, 0],
|
||||
"118": [0, 0.44444, 0.10836, 0],
|
||||
"119": [0, 0.44444, 0.10836, 0],
|
||||
"120": [0, 0.44444, 0.09169, 0],
|
||||
"121": [0.19444, 0.44444, 0.10836, 0],
|
||||
"122": [0, 0.44444, 0.08752, 0],
|
||||
"126": [0.35, 0.32659, 0.08826, 0],
|
||||
"305": [0, 0.44444, 0.04169, 0],
|
||||
"567": [0.19444, 0.44444, 0.04169, 0],
|
||||
"768": [0, 0.69444, 0, 0],
|
||||
"769": [0, 0.69444, 0.09205, 0],
|
||||
"770": [0, 0.69444, 0.0799, 0],
|
||||
"771": [0, 0.67659, 0.08826, 0],
|
||||
"772": [0, 0.60889, 0.08776, 0],
|
||||
"774": [0, 0.69444, 0.09483, 0],
|
||||
"775": [0, 0.67937, 0.07774, 0],
|
||||
"776": [0, 0.67937, 0.06385, 0],
|
||||
"778": [0, 0.69444, 0, 0],
|
||||
"779": [0, 0.69444, 0.09205, 0],
|
||||
"780": [0, 0.63194, 0.08432, 0],
|
||||
"915": [0, 0.69444, 0.13372, 0],
|
||||
"916": [0, 0.69444, 0, 0],
|
||||
"920": [0, 0.69444, 0.07555, 0],
|
||||
"923": [0, 0.69444, 0, 0],
|
||||
"926": [0, 0.69444, 0.12816, 0],
|
||||
"928": [0, 0.69444, 0.08094, 0],
|
||||
"931": [0, 0.69444, 0.11983, 0],
|
||||
"933": [0, 0.69444, 0.09031, 0],
|
||||
"934": [0, 0.69444, 0.04603, 0],
|
||||
"936": [0, 0.69444, 0.09031, 0],
|
||||
"937": [0, 0.69444, 0.08293, 0],
|
||||
"8211": [0, 0.44444, 0.08616, 0],
|
||||
"8212": [0, 0.44444, 0.08616, 0],
|
||||
"8216": [0, 0.69444, 0.07816, 0],
|
||||
"8217": [0, 0.69444, 0.07816, 0],
|
||||
"8220": [0, 0.69444, 0.14205, 0],
|
||||
"8221": [0, 0.69444, 0.00316, 0],
|
||||
},
|
||||
"SansSerif-Regular": {
|
||||
"33": [0, 0.69444, 0, 0],
|
||||
"34": [0, 0.69444, 0, 0],
|
||||
@@ -1746,13 +1983,9 @@ const fontMetricsData = {
|
||||
"934": [0, 0.61111, 0, 0],
|
||||
"936": [0, 0.61111, 0, 0],
|
||||
"937": [0, 0.61111, 0, 0],
|
||||
"2018": [0, 0.61111, 0, 0],
|
||||
"2019": [0, 0.61111, 0, 0],
|
||||
"8216": [0, 0.61111, 0, 0],
|
||||
"8217": [0, 0.61111, 0, 0],
|
||||
"8242": [0, 0.61111, 0, 0],
|
||||
"9251": [0.11111, 0.21944, 0, 0],
|
||||
},
|
||||
};
|
||||
|
||||
export default fontMetricsData;
|
||||
|
@@ -7,17 +7,28 @@ import * as html from "../buildHTML";
|
||||
import * as mml from "../buildMathML";
|
||||
|
||||
// Non-mathy text, possibly in a font
|
||||
const textFunctionFonts = {
|
||||
"\\text": undefined, "\\textrm": "mathrm", "\\textsf": "mathsf",
|
||||
"\\texttt": "mathtt", "\\textnormal": "mathrm", "\\textbf": "mathbf",
|
||||
const textFontFamilies = {
|
||||
"\\text": undefined, "\\textrm": "textrm", "\\textsf": "textsf",
|
||||
"\\texttt": "texttt", "\\textnormal": "textrm",
|
||||
};
|
||||
|
||||
const textFontWeights = {
|
||||
"\\textbf": "textbf",
|
||||
};
|
||||
|
||||
const textFontShapes = {
|
||||
"\\textit": "textit",
|
||||
};
|
||||
|
||||
defineFunction({
|
||||
type: "text",
|
||||
names: [
|
||||
// Font families
|
||||
"\\text", "\\textrm", "\\textsf", "\\texttt", "\\textnormal",
|
||||
"\\textbf", "\\textit",
|
||||
// Font weights
|
||||
"\\textbf",
|
||||
// Font Shapes
|
||||
"\\textit",
|
||||
],
|
||||
props: {
|
||||
numArgs: 1,
|
||||
@@ -30,11 +41,20 @@ defineFunction({
|
||||
return {
|
||||
type: "text",
|
||||
body: ordargument(body),
|
||||
font: textFunctionFonts[context.funcName],
|
||||
font: context.funcName,
|
||||
};
|
||||
},
|
||||
htmlBuilder(group, options) {
|
||||
const newOptions = options.withFont(group.value.font);
|
||||
const font = group.value.font;
|
||||
// Checks if the argument is a font family or a font style.
|
||||
let newOptions;
|
||||
if (textFontFamilies[font]) {
|
||||
newOptions = options.withFontFamily(textFontFamilies[font]);
|
||||
} else if (textFontWeights[font]) {
|
||||
newOptions = options.withFontWeight(textFontWeights[font]);
|
||||
} else {
|
||||
newOptions = options.withFontShape(textFontShapes[font]);
|
||||
}
|
||||
const inner = html.buildExpression(group.value.body, newOptions, true);
|
||||
buildCommon.tryCombineChars(inner);
|
||||
return buildCommon.makeSpan(["mord", "text"],
|
||||
|
@@ -56,19 +56,39 @@
|
||||
.strut {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mathrm {
|
||||
font-style: normal;
|
||||
|
||||
// Text font weights
|
||||
.textbf {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
// Text font shapes.
|
||||
.textit {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
// Text font families.
|
||||
.textrm {
|
||||
font-family: KaTeX_Main;
|
||||
}
|
||||
|
||||
.textsf {
|
||||
font-family: KaTeX_SansSerif;
|
||||
}
|
||||
|
||||
.texttt {
|
||||
font-family: KaTeX_Typewriter;
|
||||
}
|
||||
|
||||
// Math fonts.
|
||||
.mathit {
|
||||
font-family: KaTeX_Math;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.mathrm {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.mathbf {
|
||||
font-family: KaTeX_Main;
|
||||
|
@@ -1585,7 +1585,7 @@ describe("An HTML font tree-builder", function() {
|
||||
|
||||
it("should render \\text{R} with the correct font", function() {
|
||||
const markup = katex.renderToString("\\text{R}");
|
||||
expect(markup).toContain("<span class=\"mord mathrm\">R</span>");
|
||||
expect(markup).toContain("<span class=\"mord\">R</span>");
|
||||
});
|
||||
|
||||
it("should render \\textit{R} with the correct font", function() {
|
||||
@@ -1600,24 +1600,41 @@ describe("An HTML font tree-builder", function() {
|
||||
|
||||
it("should render \\text{R\\textit{S}T} with the correct fonts", function() {
|
||||
const markup = katex.renderToString("\\text{R\\textit{S}T}");
|
||||
expect(markup).toContain("<span class=\"mord mathrm\">R</span>");
|
||||
expect(markup).toContain("<span class=\"mord\">R</span>");
|
||||
expect(markup).toContain("<span class=\"mord textit\">S</span>");
|
||||
expect(markup).toContain("<span class=\"mord mathrm\">T</span>");
|
||||
expect(markup).toContain("<span class=\"mord\">T</span>");
|
||||
});
|
||||
|
||||
it("should render \\textbf{R} with the correct font", function() {
|
||||
const markup = katex.renderToString("\\textbf{R}");
|
||||
expect(markup).toContain("<span class=\"mord mathbf\">R</span>");
|
||||
expect(markup).toContain("<span class=\"mord textbf\">R</span>");
|
||||
});
|
||||
|
||||
it("should render \\textsf{R} with the correct font", function() {
|
||||
const markup = katex.renderToString("\\textsf{R}");
|
||||
expect(markup).toContain("<span class=\"mord mathsf\">R</span>");
|
||||
expect(markup).toContain("<span class=\"mord textsf\">R</span>");
|
||||
});
|
||||
|
||||
it("should render \\textsf{\\textit{R}G\\textbf{B}} with the correct font", function() {
|
||||
const markup = katex.renderToString("\\textsf{\\textit{R}G\\textbf{B}}");
|
||||
expect(markup).toContain("<span class=\"mord textsf textit\">R</span>");
|
||||
expect(markup).toContain("<span class=\"mord textsf\">G</span>");
|
||||
expect(markup).toContain("<span class=\"mord textsf textbf\">B</span>");
|
||||
});
|
||||
|
||||
it("should render \\textsf{\\textbf{$\\mathrm{A}$}} with the correct font", function() {
|
||||
const markup = katex.renderToString("\\textsf{\\textbf{$\\mathrm{A}$}}");
|
||||
expect(markup).toContain("<span class=\"mord mathrm\">A</span>");
|
||||
});
|
||||
|
||||
it("should render \\textsf{\\textbf{$\\mathrm{\\textsf{A}}$}} with the correct font", function() {
|
||||
const markup = katex.renderToString("\\textsf{\\textbf{$\\mathrm{\\textsf{A}}$}}");
|
||||
expect(markup).toContain("<span class=\"mord textsf textbf\">A</span>");
|
||||
});
|
||||
|
||||
it("should render \\texttt{R} with the correct font", function() {
|
||||
const markup = katex.renderToString("\\texttt{R}");
|
||||
expect(markup).toContain("<span class=\"mord mathtt\">R</span>");
|
||||
expect(markup).toContain("<span class=\"mord texttt\">R</span>");
|
||||
});
|
||||
|
||||
it("should render a combination of font and color changes", function() {
|
||||
|
BIN
test/screenshotter/images/TextStacked-chrome.png
Normal file
BIN
test/screenshotter/images/TextStacked-chrome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
test/screenshotter/images/TextStacked-firefox.png
Normal file
BIN
test/screenshotter/images/TextStacked-firefox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
@@ -268,6 +268,13 @@ Symbols1: |
|
||||
\maltese\degree\pounds\$
|
||||
\text{\maltese\degree\pounds\textdollar}
|
||||
Text: \frac{a}{b}\text{c~ {ab} \ e}+fg
|
||||
TextStacked:
|
||||
\begin{matrix}
|
||||
\textsf{abc123 \textbf{abc123} \textit{abc123}}\\
|
||||
\text{abc123 \textbf{abc123} \textit{abc123}}\\
|
||||
\textrm{abc123 \textbf{abc123} \textit{abc123}}\\
|
||||
\textsf{\textrm{\textbf{abc123}} \textbf{abc123} \textit{abc123}}\\
|
||||
\end{matrix}
|
||||
TextWithMath: \text{for $a < b$ and $ c < d $}.
|
||||
Unicode: \begin{matrix}\text{ÀàÇçÉéÏïÖöÛû} \\ \text{БГДЖЗЙЛФЦШЫЮЯ} \\ \text{여보세요} \\ \text{私はバナナです} \end{matrix}
|
||||
Units: |
|
||||
|
Reference in New Issue
Block a user