Skip to content

Commit 3aeb542

Browse files
authored
Merge pull request #676 from mathjax/issue2595
Add support for all \mathXYZ and \symXYZ macros using multi-letter <mi>. (mathjax/MathJax#2595)
2 parents 21f873f + 2895baa commit 3aeb542

File tree

8 files changed

+116
-54
lines changed

8 files changed

+116
-54
lines changed

ts/core/MmlTree/MmlNodes/mi.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ export class MmlMi extends AbstractMmlTokenNode {
8383
public setTeXclass(prev: AbstractMmlNode) {
8484
this.getPrevClass(prev);
8585
let name = this.getText();
86-
if (name.length > 1 && name.match(MmlMi.operatorName) && this.getProperty('texClass') === undefined) {
86+
if (name.length > 1 && name.match(MmlMi.operatorName) &&
87+
this.attributes.get('mathvariant') === 'normal' &&
88+
this.getProperty('autoOP') === undefined &&
89+
this.getProperty('texClass') === undefined) {
8790
this.texClass = TEXCLASS.OP;
8891
this.setProperty('autoOP', true);
8992
}

ts/core/MmlTree/SerializedMmlVisitor.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ export class SerializedMmlVisitor extends MmlVisitor {
4646
*/
4747
public static variants: PropertyList = {
4848
'-tex-calligraphic': 'script',
49-
'-tex-calligraphic-bold': 'bold-script',
49+
'-tex-bold-calligraphic': 'bold-script',
5050
'-tex-oldstyle': 'normal',
51-
'-tex-oldstyle-bold': 'bold',
51+
'-tex-bold-oldstyle': 'bold',
5252
'-tex-mathit': 'italic'
5353
};
5454

@@ -202,6 +202,7 @@ export class SerializedMmlVisitor extends MmlVisitor {
202202
variant && variants.hasOwnProperty(variant) && this.setDataAttribute(data, 'variant', variant);
203203
node.getProperty('variantForm') && this.setDataAttribute(data, 'alternate', '1');
204204
node.getProperty('pseudoscript') && this.setDataAttribute(data, 'pseudoscript', 'true');
205+
node.getProperty('autoOP') === false && this.setDataAttribute(data, 'auto-op', 'false');
205206
const texclass = node.getProperty('texClass') as number;
206207
if (texclass !== undefined) {
207208
let setclass = true;

ts/input/mathml/MathMLCompile.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ export class MathMLCompile<N, T, D> {
166166
mml.setProperty('useHeight', false);
167167
} else if (name === 'data-mjx-accent') {
168168
mml.setProperty('mathaccent', value === 'true');
169+
} else if (name === 'data-mjx-auto-op') {
170+
mml.setProperty('autoOP', value === 'true');
169171
}
170172
} else if (name !== 'class') {
171173
let val = value.toLowerCase();

ts/input/tex/ParseMethods.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,20 @@ import ParseUtil from './ParseUtil.js';
3333
namespace ParseMethods {
3434

3535
/**
36-
* Handle a variable (a single letter).
36+
* Handle a variable (a single letter or multi-letter if allowed).
3737
* @param {TexParser} parser The current tex parser.
38-
* @param {string} c The single letter string to transform into an mi.
38+
* @param {string} c The letter to transform into an mi.
3939
*/
4040
export function variable(parser: TexParser, c: string) {
4141
// @test Identifier Font
4242
const def = ParseUtil.getFontDef(parser);
43+
if (parser.stack.env.multiLetterIdentifiers && parser.stack.env.font !== '') {
44+
c = parser.string.substr(parser.i - 1).match(/^[a-z]+/i)[0];
45+
parser.i += c.length - 1;
46+
if (def.mathvariant === TexConstant.Variant.NORMAL) {
47+
def.autoOP = false;
48+
}
49+
}
4350
// @test Identifier
4451
const node = parser.create('token', 'mi', def, c);
4552
parser.Push(node);

ts/input/tex/TexConstants.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ export namespace TexConstant {
4545
LOOPED: 'looped',
4646
STRETCHED: 'stretched',
4747
CALLIGRAPHIC: '-tex-calligraphic',
48-
OLDSTYLE: '-tex-oldstyle'
48+
BOLDCALLIGRAPHIC: '-tex-bold-calligraphic',
49+
OLDSTYLE: '-tex-oldstyle',
50+
BOLDOLDSTYLE: '-tex-bold-oldstyle',
51+
MATHITALIC: '-tex-mathit'
4952
};
5053

5154
export const Form = {

ts/input/tex/base/BaseMappings.ts

Lines changed: 77 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -400,15 +400,67 @@ new sm.CommandMap('macros', {
400400
mit: ['SetFont', TexConstant.Variant.ITALIC],
401401
oldstyle: ['SetFont', TexConstant.Variant.OLDSTYLE],
402402
cal: ['SetFont', TexConstant.Variant.CALLIGRAPHIC],
403-
it: ['SetFont', '-tex-mathit'], // needs special handling
403+
it: ['SetFont', TexConstant.Variant.MATHITALIC], // needs special handling
404404
bf: ['SetFont', TexConstant.Variant.BOLD],
405405
bbFont: ['SetFont', TexConstant.Variant.DOUBLESTRUCK],
406406
scr: ['SetFont', TexConstant.Variant.SCRIPT],
407407
frak: ['SetFont', TexConstant.Variant.FRAKTUR],
408408
sf: ['SetFont', TexConstant.Variant.SANSSERIF],
409409
tt: ['SetFont', TexConstant.Variant.MONOSPACE],
410410

411-
// font:
411+
mathrm: ['MathFont', TexConstant.Variant.NORMAL],
412+
mathup: ['MathFont', TexConstant.Variant.NORMAL],
413+
mathnormal: ['MathFont', ''],
414+
mathbf: ['MathFont', TexConstant.Variant.BOLD],
415+
mathbfup: ['MathFont', TexConstant.Variant.BOLD],
416+
mathit: ['MathFont', TexConstant.Variant.MATHITALIC],
417+
mathbfit: ['MathFont', TexConstant.Variant.BOLDITALIC],
418+
mathbb: ['MathFont', TexConstant.Variant.DOUBLESTRUCK],
419+
Bbb: ['MathFont', TexConstant.Variant.DOUBLESTRUCK],
420+
mathfrak: ['MathFont', TexConstant.Variant.FRAKTUR],
421+
mathbffrak: ['MathFont', TexConstant.Variant.BOLDFRAKTUR],
422+
mathscr: ['MathFont', TexConstant.Variant.SCRIPT],
423+
mathbfscr: ['MathFont', TexConstant.Variant.BOLDSCRIPT],
424+
mathsf: ['MathFont', TexConstant.Variant.SANSSERIF],
425+
mathsfup: ['MathFont', TexConstant.Variant.SANSSERIF],
426+
mathbfsf: ['MathFont', TexConstant.Variant.BOLDSANSSERIF],
427+
mathbfsfup: ['MathFont', TexConstant.Variant.BOLDSANSSERIF],
428+
mathsfit: ['MathFont', TexConstant.Variant.SANSSERIFITALIC],
429+
mathbfsfit: ['MathFont', TexConstant.Variant.SANSSERIFBOLDITALIC],
430+
mathtt: ['MathFont', TexConstant.Variant.MONOSPACE],
431+
mathcal: ['MathFont', TexConstant.Variant.CALLIGRAPHIC],
432+
mathbfcal: ['MathFont', TexConstant.Variant.BOLDCALLIGRAPHIC],
433+
434+
symrm: ['MathFont', TexConstant.Variant.NORMAL],
435+
symup: ['MathFont', TexConstant.Variant.NORMAL],
436+
symnormal: ['MathFont', ''],
437+
symbf: ['MathFont', TexConstant.Variant.BOLD],
438+
symbfup: ['MathFont', TexConstant.Variant.BOLD],
439+
symit: ['MathFont', TexConstant.Variant.ITALIC],
440+
symbfit: ['MathFont', TexConstant.Variant.BOLDITALIC],
441+
symbb: ['MathFont', TexConstant.Variant.DOUBLESTRUCK],
442+
symfrak: ['MathFont', TexConstant.Variant.FRAKTUR],
443+
symbffrak: ['MathFont', TexConstant.Variant.BOLDFRAKTUR],
444+
symscr: ['MathFont', TexConstant.Variant.SCRIPT],
445+
symbfscr: ['MathFont', TexConstant.Variant.BOLDSCRIPT],
446+
symsf: ['MathFont', TexConstant.Variant.SANSSERIF],
447+
symsfup: ['MathFont', TexConstant.Variant.SANSSERIF],
448+
symbfsf: ['MathFont', TexConstant.Variant.BOLDSANSSERIF],
449+
symbfsfup: ['MathFont', TexConstant.Variant.BOLDSANSSERIF],
450+
symsfit: ['MathFont', TexConstant.Variant.SANSSERIFITALIC],
451+
symbfsfit: ['MathFont', TexConstant.Variant.SANSSERIFBOLDITALIC],
452+
symtt: ['MathFont', TexConstant.Variant.MONOSPACE],
453+
symcal: ['MathFont', TexConstant.Variant.CALLIGRAPHIC],
454+
symbfcal: ['MathFont', TexConstant.Variant.BOLDCALLIGRAPHIC],
455+
456+
textrm: ['HBox', null, TexConstant.Variant.NORMAL],
457+
textup: ['HBox', null, TexConstant.Variant.NORMAL],
458+
textnormal: ['HBox'],
459+
textit: ['HBox', null, TexConstant.Variant.ITALIC],
460+
textbf: ['HBox', null, TexConstant.Variant.BOLD],
461+
textsf: ['HBox', null, TexConstant.Variant.SANSSERIF],
462+
texttt: ['HBox', null, TexConstant.Variant.MONOSPACE],
463+
412464
tiny: ['SetSize', 0.5],
413465
Tiny: ['SetSize', 0.6], // non-standard
414466
scriptsize: ['SetSize', 0.7],
@@ -420,38 +472,38 @@ new sm.CommandMap('macros', {
420472
huge: ['SetSize', 2.07],
421473
Huge: ['SetSize', 2.49],
422474

423-
arcsin: ['NamedFn'],
424-
arccos: ['NamedFn'],
425-
arctan: ['NamedFn'],
426-
arg: ['NamedFn'],
427-
cos: ['NamedFn'],
428-
cosh: ['NamedFn'],
429-
cot: ['NamedFn'],
430-
coth: ['NamedFn'],
431-
csc: ['NamedFn'],
432-
deg: ['NamedFn'],
475+
arcsin: 'NamedFn',
476+
arccos: 'NamedFn',
477+
arctan: 'NamedFn',
478+
arg: 'NamedFn',
479+
cos: 'NamedFn',
480+
cosh: 'NamedFn',
481+
cot: 'NamedFn',
482+
coth: 'NamedFn',
483+
csc: 'NamedFn',
484+
deg: 'NamedFn',
433485
det: 'NamedOp',
434-
dim: ['NamedFn'],
435-
exp: ['NamedFn'],
486+
dim: 'NamedFn',
487+
exp: 'NamedFn',
436488
gcd: 'NamedOp',
437-
hom: ['NamedFn'],
489+
hom: 'NamedFn',
438490
inf: 'NamedOp',
439-
ker: ['NamedFn'],
440-
lg: ['NamedFn'],
491+
ker: 'NamedFn',
492+
lg: 'NamedFn',
441493
lim: 'NamedOp',
442494
liminf: ['NamedOp', 'lim&thinsp;inf'],
443495
limsup: ['NamedOp', 'lim&thinsp;sup'],
444-
ln: ['NamedFn'],
445-
log: ['NamedFn'],
496+
ln: 'NamedFn',
497+
log: 'NamedFn',
446498
max: 'NamedOp',
447499
min: 'NamedOp',
448500
Pr: 'NamedOp',
449-
sec: ['NamedFn'],
450-
sin: ['NamedFn'],
451-
sinh: ['NamedFn'],
501+
sec: 'NamedFn',
502+
sin: 'NamedFn',
503+
sinh: 'NamedFn',
452504
sup: 'NamedOp',
453-
tan: ['NamedFn'],
454-
tanh: ['NamedFn'],
505+
tan: 'NamedFn',
506+
tanh: 'NamedFn',
455507

456508
limits: ['Limits', 1],
457509
nolimits: ['Limits', 0],
@@ -611,21 +663,7 @@ new sm.CommandMap('macros', {
611663
'{\\kern8mu}{\\kern8mu}(#1)', 1],
612664
iff: ['Macro', '\\;\\Longleftrightarrow\\;'],
613665
skew: ['Macro', '{{#2{#3\\mkern#1mu}\\mkern-#1mu}{}}', 3],
614-
mathcal: ['Macro', '{\\cal #1}', 1],
615-
mathscr: ['Macro', '{\\scr #1}', 1],
616-
mathrm: ['Macro', '{\\rm #1}', 1],
617-
mathbf: ['Macro', '{\\bf #1}', 1],
618-
mathbb: ['Macro', '{\\bbFont #1}', 1],
619-
Bbb: ['Macro', '{\\bbFont #1}', 1],
620-
mathit: ['Macro', '{\\it #1}', 1],
621-
mathfrak: ['Macro', '{\\frak #1}', 1],
622-
mathsf: ['Macro', '{\\sf #1}', 1],
623-
mathtt: ['Macro', '{\\tt #1}', 1],
624-
textrm: ['HBox', null, TexConstant.Variant.NORMAL],
625-
textit: ['HBox', null, TexConstant.Variant.ITALIC],
626-
textbf: ['HBox', null, TexConstant.Variant.BOLD],
627-
textsf: ['HBox', null, TexConstant.Variant.SANSSERIF],
628-
texttt: ['HBox', null, TexConstant.Variant.MONOSPACE],
666+
629667
pmb: ['Macro', '\\rlap{#1}\\kern1px{#1}', 1],
630668
TeX: ['Macro', 'T\\kern-.14em\\lower.5ex{E}\\kern-.115em X'],
631669
LaTeX: ['Macro', 'L\\kern-.325em\\raise.21em' +

ts/input/tex/base/BaseMethods.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,23 @@ BaseMethods.Hash = function(_parser: TexParser, _c: string) {
272272
*
273273
*/
274274

275+
276+
/**
277+
* Handle \mathrm, \mathbf, etc, allowing for multi-letter runs to be one <mi>.
278+
*/
279+
BaseMethods.MathFont = function(parser: TexParser, name: string, variant: string) {
280+
const text = parser.GetArgument(name);
281+
let mml = new TexParser(text, {
282+
...parser.stack.env,
283+
font: variant,
284+
multiLetterIdentifiers: true
285+
}, parser.configuration).mml();
286+
if (mml.isKind('inferredMrow')) {
287+
mml = parser.create('node', 'mrow', mml.childNodes);
288+
}
289+
parser.Push(mml);
290+
};
291+
275292
/**
276293
* Setting font, e.g., via \\rm, \\bf etc.
277294
* @param {TexParser} parser The calling parser.

ts/input/tex/textmacros/TextMacrosMappings.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,6 @@ new CommandMap('text-macros', {
101101
huge: ['SetSize', 2.07],
102102
Huge: ['SetSize', 2.49],
103103

104-
mathcal: 'MathModeOnly',
105-
mathscr: 'MathModeOnly',
106-
mathrm: 'MathModeOnly',
107-
mathbf: 'MathModeOnly',
108-
mathbb: 'MathModeOnly',
109-
mathit: 'MathModeOnly',
110-
mathfrak: 'MathModeOnly',
111-
mathsf: 'MathModeOnly',
112-
mathtt: 'MathModeOnly',
113104
Bbb: ['Macro', '{\\bbFont #1}', 1],
114105
textrm: ['Macro', '{\\rm #1}', 1],
115106
textit: ['Macro', '{\\it #1}', 1],

0 commit comments

Comments
 (0)