[plugin system] Add a utility function (setFontMetrics) to extend builtin fontMetrics (#1269)

* Add and expose addFontMetrics function

* fix typo

* recreate package.json-lock

* Add setFontMetrics function to change the defualt metricMap - change getFontMetrics to getGlobalMetrics

* use new setFontMetrics on main KaTeX object

* fix package-lock.json error by rebuilding it

* Add appropriate tests

* update the snapshot
This commit is contained in:
Hossein Saniei
2018-06-10 05:12:35 +04:30
committed by Kevin Barabash
parent 251283ffc1
commit 8b1e1b4886
10 changed files with 453 additions and 264 deletions

View File

@@ -6,7 +6,7 @@
* `.reset` functions.
*/
import fontMetrics from "./fontMetrics";
import {getGlobalMetrics} from "./fontMetrics";
import type {FontMetrics} from "./fontMetrics";
import type {StyleInterface} from "./Style";
@@ -27,7 +27,7 @@ const sizeStyleMap = [
];
const sizeMultipliers = [
// fontMetrics.js:getFontMetrics also uses size indexes, so if
// fontMetrics.js:getGlobalMetrics also uses size indexes, so if
// you change size indexes, change that function.
0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.44, 1.728, 2.074, 2.488,
];
@@ -266,7 +266,7 @@ class Options {
*/
fontMetrics(): FontMetrics {
if (!this._fontMetrics) {
this._fontMetrics = fontMetrics.getFontMetrics(this.size);
this._fontMetrics = getGlobalMetrics(this.size);
}
return this._fontMetrics;
}

View File

@@ -6,7 +6,7 @@
*/
import domTree from "./domTree";
import fontMetrics from "./fontMetrics";
import {getCharacterMetrics} from "./fontMetrics";
import symbols, {ligatures} from "./symbols";
import utils from "./utils";
import {wideCharacterFont} from "./wide-character";
@@ -43,7 +43,7 @@ const lookupSymbol = function(
}
return {
value: value,
metrics: fontMetrics.getCharacterMetrics(value, fontName, mode),
metrics: getCharacterMetrics(value, fontName, mode),
};
};
@@ -152,12 +152,19 @@ const mathDefault = function(
return makeSymbol(
value, fontName, mode, options,
classes.concat("amsrm", options.fontWeight, options.fontShape));
} else { // if (font === "main") {
} else if (font === "main" || !font) {
const fontName = retrieveTextFontName("textrm", options.fontWeight,
options.fontShape);
return makeSymbol(
value, fontName, mode, options,
classes.concat(options.fontWeight, options.fontShape));
} else { // fonts added by plugins
const fontName = retrieveTextFontName(font, options.fontWeight,
options.fontShape);
// We add font name as a css class
return makeSymbol(
value, fontName, mode, options,
classes.concat(fontName, options.fontWeight, options.fontShape));
}
} else {
throw new Error("unexpected type: " + type + " in mathDefault");
@@ -611,7 +618,7 @@ const makeVerb = function(group: ParseNode<"verb">, options: Options): string {
};
// Glue is a concept from TeX which is a flexible space between elements in
// either a vertical or horizontal list. In KaTeX, at least for now, it's
// either a vertical or horizontal list. In KaTeX, at least for now, it's
// static space between elements in a horizontal layout.
const makeGlue = (measurement: Measurement, options: Options): DomSpan => {
// Make an empty span for the space
@@ -621,7 +628,7 @@ const makeGlue = (measurement: Measurement, options: Options): DomSpan => {
return rule;
};
// Takes an Options object, and returns the appropriate fontLookup
// Takes font options, and returns the appropriate fontLookup name
const retrieveTextFontName = function(
fontFamily: string,
fontWeight: string,
@@ -642,7 +649,7 @@ const retrieveTextFontName = function(
baseFontName = "Typewriter";
break;
default:
throw new Error(`Invalid font provided: ${fontFamily}`);
baseFontName = fontFamily; // use fonts added by a plugin
}
let fontStylesName;

View File

@@ -5,7 +5,7 @@
*/
import buildCommon from "./buildCommon";
import fontMetrics from "./fontMetrics";
import {getCharacterMetrics} from "./fontMetrics";
import mathMLTree from "./mathMLTree";
import ParseError from "./ParseError";
import symbols, {ligatures} from "./symbols";
@@ -91,7 +91,7 @@ export const getVariant = function(group, options) {
}
const fontName = buildCommon.fontMap[font].fontName;
if (fontMetrics.getCharacterMetrics(value, fontName, mode)) {
if (getCharacterMetrics(value, fontName, mode)) {
return buildCommon.fontMap[font].variant;
}

View File

@@ -26,7 +26,7 @@ import Style from "./Style";
import domTree from "./domTree";
import buildCommon from "./buildCommon";
import fontMetrics from "./fontMetrics";
import {getCharacterMetrics} from "./fontMetrics";
import symbols from "./symbols";
import utils from "./utils";
@@ -48,7 +48,7 @@ const getMetrics = function(
): CharacterMetrics {
const replace = symbols.math[symbol] && symbols.math[symbol].replace;
const metrics =
fontMetrics.getCharacterMetrics(replace || symbol, font, mode);
getCharacterMetrics(replace || symbol, font, mode);
if (!metrics) {
throw new Error(`Unsupported symbol ${symbol} and font size ${font}.`);
}

View File

@@ -183,6 +183,18 @@ export type CharacterMetrics = {
width: number;
};
export type MetricMap = {
[string]: number[]
}
/**
* This function adds new font metrics to default metricMap
* It can also override existing metrics
*/
export function setFontMetrics(fontName: string, metrics: MetricMap) {
metricMap[fontName] = metrics;
}
/**
* This function is a convenience function for looking up information in the
* metricMap table. It takes a character as a string, and a font.
@@ -190,7 +202,7 @@ export type CharacterMetrics = {
* Note: the `width` property may be undefined if fontMetricsData.js wasn't
* built using `Make extended_metrics`.
*/
const getCharacterMetrics = function(
export function getCharacterMetrics(
character: string,
font: string,
mode: Mode,
@@ -227,7 +239,7 @@ const getCharacterMetrics = function(
width: metrics[4],
};
}
};
}
type FontSizeIndex = 0 | 1 | 2;
export type FontMetrics = {
@@ -240,7 +252,7 @@ const fontMetricsBySizeIndex: {[FontSizeIndex]: FontMetrics} = {};
/**
* Get the font metrics for a given size.
*/
const getFontMetrics = function(size: number): FontMetrics {
export function getGlobalMetrics(size: number): FontMetrics {
let sizeIndex: FontSizeIndex;
if (size >= 5) {
sizeIndex = 0;
@@ -260,9 +272,4 @@ const getFontMetrics = function(size: number): FontMetrics {
}
}
return fontMetricsBySizeIndex[sizeIndex];
};
export default {
getFontMetrics: getFontMetrics,
getCharacterMetrics: getCharacterMetrics,
};
}

View File

@@ -19,7 +19,7 @@
import type {Mode} from "./types";
type Font = "main" | "ams"
type Font = "main" | "ams";
// Some of these have a "-token" suffix since these are also used as `ParseNode`
// types for raw text tokens, and we want to avoid conflicts with higher-level
// `ParseNode` types. These `ParseNode`s are constructed within `Parser` by