diff --git a/CHANGELOG.md b/CHANGELOG.md index e27672ead..746ce56f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ i.e. `(f(x))` would be parsed as `(f(x)`. - **#2116** Pressing the "/" key after an expression ending with a superscript would not recognize the left argument as a numerator. +- **#2124** In text mode, some characters were incorrectly interpreted as a math command, for example `(` was interpreted as \lparen`. This could cause some interoperability issues. ### Improvements diff --git a/src/addons/debug.ts b/src/addons/debug.ts index 964840e3f..8452222e5 100644 --- a/src/addons/debug.ts +++ b/src/addons/debug.ts @@ -7,7 +7,6 @@ import { LATEX_COMMANDS, MATH_SYMBOLS, - TEXT_SYMBOLS, ENVIRONMENTS, } from '../core-definitions/definitions'; import { DEFAULT_KEYBINDINGS } from '../editor/keybindings-definitions'; @@ -16,7 +15,6 @@ import { getKeybindingMarkup } from '../editor/keybindings'; const MathliveDebug = { FUNCTIONS: LATEX_COMMANDS, MATH_SYMBOLS, - TEXT_SYMBOLS, ENVIRONMENTS, DEFAULT_KEYBINDINGS, diff --git a/src/core-definitions/definitions-utils.ts b/src/core-definitions/definitions-utils.ts index d0df5a0fc..41f51460c 100644 --- a/src/core-definitions/definitions-utils.ts +++ b/src/core-definitions/definitions-utils.ts @@ -557,7 +557,7 @@ const DEFAULT_MACROS: MacroDictionary = { // Body-text symbols // See http://ctan.mirrors.hoobly.com/info/symbols/comprehensive/symbols-a4.pdf, p14 -export const TEXT_SYMBOLS: Record = { +const TEXT_SYMBOLS: Record = { ' ': 0x0020, // want that in Text mode. '\\!': 0x0021, @@ -566,11 +566,13 @@ export const TEXT_SYMBOLS: Record = { '\\%': 0x0025, '\\&': 0x0026, '-': 0x002d, // In Math mode, '-' is substituted to U+2212, but we don't - '\\_': 0x005f, + '\\textunderscore': 0x005f, // '_' '\\euro': 0x20ac, '\\maltese': 0x2720, '\\{': 0x007b, '\\}': 0x007d, + '\\textbraceleft': 0x007b, + '\\textbraceright': 0x007d, '\\nobreakspace': 0x00a0, '\\ldots': 0x2026, '\\textellipsis': 0x2026, @@ -583,9 +585,7 @@ export const TEXT_SYMBOLS: Record = { '\\textasciicircum': 0x005e, '\\textasciitilde': 0x007e, '\\textasteriskcentered': 0x002a, - '\\textbackslash': 0x005c, - '\\textbraceleft': 0x007b, - '\\textbraceright': 0x007d, + '\\textbackslash': 0x005c, // '\' '\\textbullet': 0x2022, '\\textdollar': 0x0024, '\\textsterling': 0x00a3, @@ -634,22 +634,19 @@ if (supportRegexPropertyEscape()) { */ function newSymbol( symbol: string, - value: number | undefined, + codepoint: number | undefined, type: AtomType = 'mord', variant?: Variant ): void { - if (value === undefined) return; + if (codepoint === undefined) return; MATH_SYMBOLS[symbol] = { definitionType: 'symbol', type, variant, - codepoint: value, + codepoint, }; - if (!REVERSE_MATH_SYMBOLS[value]) REVERSE_MATH_SYMBOLS[value] = symbol; - - // We accept all math symbols in text mode as well - // which is a bit more permissive than TeX - if (!TEXT_SYMBOLS[symbol]) TEXT_SYMBOLS[symbol] = value; + if (!REVERSE_MATH_SYMBOLS[codepoint]) + REVERSE_MATH_SYMBOLS[codepoint] = symbol; } /** @@ -1081,7 +1078,7 @@ export function unicodeCharToLatex( * If there is a matching command (e.g. `\alpha`) it is returned. */ export function charToLatex( - parseMode: ArgumentType, + parseMode: ParseMode, codepoint: number | undefined ): string { if (codepoint === undefined) return ''; @@ -1089,16 +1086,14 @@ export function charToLatex( return REVERSE_MATH_SYMBOLS[codepoint]; if (parseMode === 'text') { - let textSymbol = Object.keys(TEXT_SYMBOLS).find( + const textSymbol = Object.keys(TEXT_SYMBOLS).find( (x) => TEXT_SYMBOLS[x] === codepoint ); - if (!textSymbol) { - const hex = codepoint.toString(16); - textSymbol = '^'.repeat(hex.length) + hex; - } - - return textSymbol; + if (textSymbol) return textSymbol; + return String.fromCodePoint(codepoint); } + // const hex = codepoint.toString(16).toLowerCase(); + // return '^'.repeat(hex.length) + hex; return String.fromCodePoint(codepoint); } diff --git a/src/core-definitions/symbols.ts b/src/core-definitions/symbols.ts index 08de88c3e..57157810e 100644 --- a/src/core-definitions/symbols.ts +++ b/src/core-definitions/symbols.ts @@ -122,8 +122,8 @@ newSymbols([ ['\\lbrace', 0x007b, 'mopen'], ['\\rbrace', 0x007d, 'mclose'], - ['\\lparen', 0x0028, 'mopen'], - ['\\rparen', 0x0029, 'mclose'], + ['\\lparen', 0x0028, 'mopen'], // mathtools.sty + ['\\rparen', 0x0029, 'mclose'], // mathtools.sty ['\\langle', 0x27e8, 'mopen'], ['\\rangle', 0x27e9, 'mclose'], ['\\lfloor', 0x230a, 'mopen'], diff --git a/src/editor-mathfield/keyboard-input.ts b/src/editor-mathfield/keyboard-input.ts index 6a9011fa6..4ef9b6f99 100644 --- a/src/editor-mathfield/keyboard-input.ts +++ b/src/editor-mathfield/keyboard-input.ts @@ -1021,9 +1021,9 @@ function isValidClose(open: string | undefined, close: string): boolean { if (!open) return true; if ( - ['(', '{', '[', '\\lbrace', '\\lparen', '\\{', '\\lbrack'].includes(open) + ['(', '\\lparen', '{', '\\{', '\\lbrace', '[', '\\lbrack'].includes(open) ) { - return [')', '}', ']', '\\rbrace', '\\rparen', '\\}', '\\rbrack'].includes( + return [')', '\\rparen', '}', '\\}', '\\rbrace', ']', '\\rbrack'].includes( close ); } @@ -1034,9 +1034,9 @@ function isValidOpen(open: string, close: string | undefined): boolean { if (!close) return true; if ( - [')', '}', ']', '\\rbrace', '\\rparen', '\\}', '\\rbrack'].includes(close) + [')', '\\rparen', '}', '\\}', '\\rbrace', ']', '\\rbrack'].includes(close) ) { - return ['(', '{', '[', '\\lbrace', '\\lparen', '\\{', '\\lbrack'].includes( + return ['(', '\\lparen', '{', '\\{', '\\lbrace', '[', '\\lbrack'].includes( open ); } diff --git a/src/mathlive.ts b/src/mathlive.ts index 8c1dfe7f7..8dc6f813d 100644 --- a/src/mathlive.ts +++ b/src/mathlive.ts @@ -153,7 +153,6 @@ export const version = { // export const debug = { // FUNCTIONS: MathLiveDebug.FUNCTIONS, // MATH_SYMBOLS: MathLiveDebug.MATH_SYMBOLS, -// TEXT_SYMBOLS: MathLiveDebug.TEXT_SYMBOLS, // ENVIRONMENTS: MathLiveDebug.ENVIRONMENTS, // DEFAULT_KEYBINDINGS: MathLiveDebug.DEFAULT_KEYBINDINGS, // getKeybindingMarkup: MathLiveDebug.getKeybindingMarkup,