From f01f504cfea99136c6c6f6592f45d38d0a9c6ded Mon Sep 17 00:00:00 2001 From: Ron Kok Date: Mon, 7 May 2018 17:06:16 -0700 Subject: [PATCH] Support some Unicode Mathematical Alphanumeric Symbols (#1232) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Support some Unicode Mathematical Alphanumeric Symbols This PR adds support for some of the characters in Unicode range U+1D400 to U+1D7FF, [Mathematical Alphanumeric Symbols](https://www.unicode.org/charts/PDF/U1D400.pdf). Specifically, it adds support for: * A-Z a-z bold * A-Z a-z bold italic * A-Z a-z Fractur * A-Z a-z sans-serif * A-Z double struck • A-Z script Addresses issue #1215 and parts of #260. * Fix lint error * Fix MathML, and pick up review comments * Fix lint error * Add text mode. Remove sans-serif. * Fix lint error * Fixed \mathrm, added screenshotter test * Change screenshotter test to an array * Add screenshots * Picked up review comments. Add characters --- src/buildCommon.js | 7 +- src/buildMathML.js | 4 +- src/katex.less | 8 +- src/symbols.js | 87 +++++++++++++- src/wide-character.js | 110 ++++++++++++++++++ test/katex-spec.js | 37 +++++- .../images/SurrogatePairs-chrome.png | Bin 0 -> 21406 bytes .../images/SurrogatePairs-firefox.png | Bin 0 -> 21376 bytes test/screenshotter/ss_data.yaml | 6 + 9 files changed, 250 insertions(+), 9 deletions(-) create mode 100644 src/wide-character.js create mode 100644 test/screenshotter/images/SurrogatePairs-chrome.png create mode 100644 test/screenshotter/images/SurrogatePairs-firefox.png diff --git a/src/buildCommon.js b/src/buildCommon.js index c3d94b6d..05bd97de 100644 --- a/src/buildCommon.js +++ b/src/buildCommon.js @@ -10,6 +10,7 @@ import fontMetrics from "./fontMetrics"; import symbols from "./symbols"; import utils from "./utils"; import stretchy from "./stretchy"; +import {wideCharacterFont} from "./wide-character"; import {calculateSize} from "./units"; import type Options from "./Options"; @@ -234,7 +235,11 @@ const makeOrd = function( // Math mode or Old font (i.e. \rm) const isFont = mode === "math" || (mode === "text" && options.font); const fontOrFamily = isFont ? options.font : options.fontFamily; - if (fontOrFamily) { + if (value.charCodeAt(0) === 0xD835) { + // surrogate pairs get special treatment + const [wideFontName, wideFontClass] = wideCharacterFont(value, mode); + return makeSymbol(value, wideFontName, mode, options, [wideFontClass]); + } else if (fontOrFamily) { let fontName; let fontClasses; if (fontOrFamily === "boldsymbol") { diff --git a/src/buildMathML.js b/src/buildMathML.js index 420a8008..a828e4f7 100644 --- a/src/buildMathML.js +++ b/src/buildMathML.js @@ -21,7 +21,9 @@ import stretchy from "./stretchy"; */ export const makeText = function(text, mode) { if (symbols[mode][text] && symbols[mode][text].replace) { - text = symbols[mode][text].replace; + if (text.charCodeAt(0) !== 0xD835) { + text = symbols[mode][text].replace; + } } return new mathMLTree.TextNode(text); diff --git a/src/katex.less b/src/katex.less index b9b990e4..07a066a9 100644 --- a/src/katex.less +++ b/src/katex.less @@ -108,7 +108,7 @@ font-family: KaTeX_AMS; } - .mathbb { + .mathbb, .textbb { font-family: KaTeX_AMS; } @@ -116,7 +116,7 @@ font-family: KaTeX_Caligraphic; } - .mathfrak { + .mathfrak, .textfrak { font-family: KaTeX_Fraktur; } @@ -124,11 +124,11 @@ font-family: KaTeX_Typewriter; } - .mathscr { + .mathscr, .textscr { font-family: KaTeX_Script; } - .mathsf { + .mathsf, .textsf { font-family: KaTeX_SansSerif; } diff --git a/src/symbols.js b/src/symbols.js index 6bf0682b..58160414 100644 --- a/src/symbols.js +++ b/src/symbols.js @@ -729,7 +729,6 @@ defineSymbol(text, main, spacing, "\u00a0", " "); defineSymbol(text, main, spacing, "\u00a0", "~"); // There are lots of symbols which are the same, so we add them in afterwards. - // All of these are textords in math mode const mathTextSymbols = "0123456789/@.\""; for (let i = 0; i < mathTextSymbols.length; i++) { @@ -745,13 +744,97 @@ for (let i = 0; i < textSymbols.length; i++) { } // All of these are textords in text mode, and mathords in math mode -const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; for (let i = 0; i < letters.length; i++) { const ch = letters.charAt(i); defineSymbol(math, main, mathord, ch, ch); defineSymbol(text, main, textord, ch, ch); } +// The next loop loads wide (surrogate pair) characters. +// We support some letters in the Unicode range U+1D400 to U+1D7FF, +// Mathematical Alphanumeric Symbols. +// Some editors do not deal well with wide characters. So don't write the +// string into this file. Instead, create the string from the surrogate pair. +let wideChar = ""; +for (let i = 0; i < letters.length; i++) { + const ch = letters.charAt(i); + + // The hex numbers in the next line are a surrogate pair. + // 0xD835 is the high surrogate for all letters in the range we support. + // 0xDC00 is the low surrogate for bold A. + wideChar = String.fromCharCode(0xD835, 0xDC00 + i); // A-Z a-z bold + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDC34 + i); // A-Z a-z italic + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDC68 + i); // A-Z a-z bold italic + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDD04 + i); // A-Z a-z Fractur + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDDA0 + i); // A-Z a-z sans-serif + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDDD4 + i); // A-Z a-z sans bold + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDE08 + i); // A-Z a-z sans italic + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDE70 + i); // A-Z a-z monospace + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + if (i < 26) { + // KaTeX fonts have only capital letters for blackboard bold and script. + // See exception for k below. + wideChar = String.fromCharCode(0xD835, 0xDD38 + i); // A-Z double struck + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDC9C + i); // A-Z script + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + } + + // TODO: Add bold script when it is supported by a KaTeX font. +} +// "k" is the only double struck lower case letter in the KaTeX fonts. +wideChar = String.fromCharCode(0xD835, 0xDD5C); // k double struck +defineSymbol(math, main, mathord, "k", wideChar); +defineSymbol(text, main, textord, "k", wideChar); + +// Next, some wide character numerals +for (let i = 0; i < 10; i++) { + const ch = letters.charAt(i); + + wideChar = String.fromCharCode(0xD835, 0xDFCE + i); // 0-9 bold + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDFE2 + i); // 0-9 sans serif + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDFEC + i); // 0-9 bold sans + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); + + wideChar = String.fromCharCode(0xD835, 0xDFF6 + i); // 0-9 monospace + defineSymbol(math, main, mathord, ch, wideChar); + defineSymbol(text, main, textord, ch, wideChar); +} + // We add these Latin-1 letters as symbols for backwards-compatibility, // but they are not actually in the font, nor are they supported by the // Unicode accent mechanism, so they fall back to Times font and look ugly. diff --git a/src/wide-character.js b/src/wide-character.js new file mode 100644 index 00000000..c10cc1c9 --- /dev/null +++ b/src/wide-character.js @@ -0,0 +1,110 @@ +// @flow + +/** + * This file provides support for Unicode range U+1D400 to U+1D7FF, + * Mathematical Alphanumeric Symbols. + * + * Function wideCharacterFont takes a wide character as input and returns + * the font information necessary to render it properly. + */ + +import type {Mode} from "./types"; +import ParseError from "./ParseError"; + +/** + * Data below is from https://www.unicode.org/charts/PDF/U1D400.pdf + * That document sorts characters into groups by font type, say bold or italic. + * + * In the arrays below, each subarray consists three elements: + * * The CSS class of that group when in math mode. + * * The CSS class of that group when in text mode. + * * The font name, so that KaTeX can get font metrics. + */ + +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 + + ["boldsymbol", "boldsymbol", "Main-BoldItalic"], // A-Z bold italic + ["boldsymbol", "boldsymbol", "Main-BoldItalic"], // a-z bold italic + + // Map fancy A-Z letters to script, not calligraphic. + // This aligns with unicode-math and math fonts (except Cambria Math). + ["mathscr", "textscr", "Script-Regular"], // A-Z script + ["", "", ""], // a-z script. No font + + ["", "", ""], // A-Z bold script. No font + ["", "", ""], // a-z bold script. No font + + ["mathfrak", "textfrak", "Fraktur-Regular"], // A-Z Fraktur + ["mathfrak", "textfrak", "Fraktur-Regular"], // a-z Fraktur + + ["mathbb", "textbb", "AMS-Regular"], // A-Z double-struck + ["mathbb", "textbb", "AMS-Regular"], // k double-struck + + ["", "", ""], // A-Z bold Fraktur No font metrics + ["", "", ""], // a-z bold Fraktur. No font. + + ["mathsf", "textsf", "SansSerif-Regular"], // A-Z sans-serif + ["mathsf", "textsf", "SansSerif-Regular"], // a-z sans-serif + + ["mathboldsf", "textboldsf", "SansSerif-Bold"], // A-Z bold sans-serif + ["mathboldsf", "textboldsf", "SansSerif-Bold"], // a-z bold sans-serif + + ["mathitsf", "textitsf", "SansSerif-Italic"], // A-Z italic sans-serif + ["mathitsf", "textitsf", "SansSerif-Italic"], // a-z italic sans-serif + + ["", "", ""], // A-Z bold italic sans. No font + ["", "", ""], // a-z bold italic sans. No font + + ["mathtt", "texttt", "Typewriter-Regular"], // A-Z monospace + ["mathtt", "texttt", "Typewriter-Regular"], // a-z monospace +]; + +const wideNumeralData: Array<[string, string, string]> = [ + ["mathbf", "textbf", "Main-Bold"], // 0-9 bold + ["", "", ""], // 0-9 double-struck. No KaTeX font. + ["mathsf", "textsf", "SansSerif-Regular"], // 0-9 sans-serif + ["mathboldsf", "textboldsf", "SansSerif-Bold"], // 0-9 bold sans-serif + ["mathtt", "texttt", "Typewriter-Regular"], // 0-9 monospace +]; + +export const wideCharacterFont = function( + wideChar: string, + mode: Mode, +): [string, string] { + + // IE doesn't support codePointAt(). So work with the surrogate pair. + const H = wideChar.charCodeAt(0); // high surrogate + const L = wideChar.charCodeAt(1); // low surrogate + const codePoint = ((H - 0xD800) * 0x400) + (L - 0xDC00) + 0x10000; + + const j = mode === "math" ? 0 : 1; // column index for CSS class. + + if (0x1D400 <= codePoint && codePoint < 0x1D6A4) { + // wideLatinLetterData contains exactly 26 chars on each row. + // So we can calculate the relevant row. No traverse necessary. + const i = Math.floor((codePoint - 0x1D400) / 26); + return [wideLatinLetterData[i][2], wideLatinLetterData[i][j]]; + + } else if (0x1D7CE <= codePoint && codePoint <= 0x1D7FF) { + // Numerals, ten per row. + const i = Math.floor((codePoint - 0x1D7CE) / 10); + return [wideNumeralData[i][2], wideNumeralData[i][j]]; + + } else if (codePoint === 0x1D6A5 || codePoint === 0x1D6A6) { + // dotless i or j + return [wideLatinLetterData[0][2], wideLatinLetterData[0][j]]; + + } else if (0x1D6A6 < codePoint && codePoint < 0x1D7CE) { + // Greek letters. Not supported, yet. + return ["", ""]; + + } else { + // We don't support any wide characters outside 1D400–1D7FF. + throw new ParseError("Unsupported character: " + wideChar); + } +}; diff --git a/test/katex-spec.js b/test/katex-spec.js index 2d2cb613..cae86e94 100644 --- a/test/katex-spec.js +++ b/test/katex-spec.js @@ -3006,7 +3006,7 @@ describe("Unicode", function() { expect("±×÷∓∔∧∨∩∪≀⊎⊓⊔⊕⊖⊗⊘⊙⊚⊛⊝⊞⊟⊠⊡⊺⊻⊼⋇⋉⋊⋋⋌⋎⋏⋒⋓⩞\u22C5").toParse(); }); - it("should parse delimeters", function() { + it("should build delimiters", function() { expect("\\left\u230A\\frac{a}{b}\\right\u230B").toBuild(); expect("\\left\u2308\\frac{a}{b}\\right\u2308").toBuild(); expect("\\left\u27ee\\frac{a}{b}\\right\u27ef").toBuild(); @@ -3014,6 +3014,41 @@ describe("Unicode", function() { expect("\\left\u23b0\\frac{a}{b}\\right\u23b1").toBuild(); expect("┌x┐ └x┘").toBuild(); }); + + it("should build some surrogate pairs", function() { + let wideCharStr = ""; + wideCharStr += String.fromCharCode(0xD835, 0xDC00); // bold A + wideCharStr += String.fromCharCode(0xD835, 0xDC68); // bold italic A + wideCharStr += String.fromCharCode(0xD835, 0xDD04); // Fraktur A + wideCharStr += String.fromCharCode(0xD835, 0xDD38); // double-struck + wideCharStr += String.fromCharCode(0xD835, 0xDC9C); // script A + wideCharStr += String.fromCharCode(0xD835, 0xDDA0); // sans serif A + wideCharStr += String.fromCharCode(0xD835, 0xDDD4); // bold sans A + wideCharStr += String.fromCharCode(0xD835, 0xDE08); // italic sans A + wideCharStr += String.fromCharCode(0xD835, 0xDE70); // monospace A + wideCharStr += String.fromCharCode(0xD835, 0xDFCE); // bold zero + wideCharStr += String.fromCharCode(0xD835, 0xDFE2); // sans serif zero + wideCharStr += String.fromCharCode(0xD835, 0xDFEC); // bold sans zero + wideCharStr += String.fromCharCode(0xD835, 0xDFF6); // monospace zero + expect(wideCharStr).toBuild(); + + let wideCharText = "\text{"; + wideCharText += String.fromCharCode(0xD835, 0xDC00); // bold A + wideCharText += String.fromCharCode(0xD835, 0xDC68); // bold italic A + wideCharText += String.fromCharCode(0xD835, 0xDD04); // Fraktur A + wideCharText += String.fromCharCode(0xD835, 0xDD38); // double-struck + wideCharText += String.fromCharCode(0xD835, 0xDC9C); // script A + wideCharText += String.fromCharCode(0xD835, 0xDDA0); // sans serif A + wideCharText += String.fromCharCode(0xD835, 0xDDD4); // bold sans A + wideCharText += String.fromCharCode(0xD835, 0xDE08); // italic sans A + wideCharText += String.fromCharCode(0xD835, 0xDE70); // monospace A + wideCharText += String.fromCharCode(0xD835, 0xDFCE); // bold zero + wideCharText += String.fromCharCode(0xD835, 0xDFE2); // sans serif zero + wideCharText += String.fromCharCode(0xD835, 0xDFEC); // bold sans zero + wideCharText += String.fromCharCode(0xD835, 0xDFF6); // monospace zero + wideCharText += "}"; + expect(wideCharText).toBuild(); + }); }); describe("The maxSize setting", function() { diff --git a/test/screenshotter/images/SurrogatePairs-chrome.png b/test/screenshotter/images/SurrogatePairs-chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..770b13b4511134d8cf3557c1af6a3a610cab62fb GIT binary patch literal 21406 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 a_+!se^}0>|@3wf*(VCvFelF{r5}E)gSO$9l literal 0 HcmV?d00001 diff --git a/test/screenshotter/ss_data.yaml b/test/screenshotter/ss_data.yaml index 93f1cfff..1016651b 100644 --- a/test/screenshotter/ss_data.yaml +++ b/test/screenshotter/ss_data.yaml @@ -292,6 +292,12 @@ SupSubHorizSpacing: | SupSubLeftAlignReset: | \omega^8_{888} \quad \frac{1}{\hat{\omega}^{8}_{888}} \quad \displaystyle\sum_{\omega^{8}_{888}} SupSubOffsets: \displaystyle \int_{2+3}x f^{2+3}+3\lim_{2+3+4+5}f +SurrogatePairs: | + \begin{array}{l} + 𝐀𝐚𝑨𝒂𝔅𝔞𝔸𝒜 \\ + \text{𝐀𝐚𝑨𝒂𝔅𝔞𝔸𝒜} \\ + \mathrm{𝐀𝐚𝑨𝒂𝔅𝔞𝔸𝒜} + \end{array} SvgReset: # This math uses a lot of SVG glyphs tex: '\underbrace{\sqrt{\vec{x}} + \sqrt{\vec{\color{#f00}y}}}'