Skip to content

Commit 1b990e6

Browse files
committed
Merge remote-tracking branch 'origin/newcommand' into beta
2 parents af33057 + 066962a commit 1b990e6

File tree

3 files changed

+129
-77
lines changed

3 files changed

+129
-77
lines changed

mathjax3-ts/input/tex/MapHandler.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,11 @@ new sm.CommandMap('new-Command', {}, {});
9696
new sm.EnvironmentMap('new-Environment', ParseMethods.environment, {}, {});
9797
const emptyConf = Configuration.create(
9898
'empty',
99-
{handler: {character: ['new-Macro'],
100-
delimiter: ['new-Delimiter'],
101-
macro: ['new-Command'],
102-
environment: ['new-Environment']
103-
}});
99+
{handler: {character: [],
100+
delimiter: ['new-Delimiter'],
101+
macro: ['new-Delimiter', 'new-Command', 'new-Macro'],
102+
environment: ['new-Environment']
103+
}});
104104

105105

106106
/**
@@ -192,7 +192,7 @@ export class SubHandler {
192192
* @param {string} symbol The symbol to parse.
193193
* @return {SymbolMap} A map that can parse the symbol.
194194
*/
195-
private applicable(symbol: string): SymbolMap {
195+
public applicable(symbol: string): SymbolMap {
196196
for (let map of this._configuration) {
197197
if (map.contains(symbol)) {
198198
return map;

mathjax3-ts/input/tex/newcommand/NewcommandMethods.ts

Lines changed: 87 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
*/
2424

2525

26-
import {ParseMethod} from '../Types.js';
26+
import {Args, Attributes, ParseMethod} from '../Types.js';
2727
import TexError from '../TexError.js';
2828
import TexParser from '../TexParser.js';
29-
import {MacroMap, EnvironmentMap, CommandMap} from '../SymbolMap.js';
29+
import * as sm from '../SymbolMap.js';
3030
import {MapHandler} from '../MapHandler.js';
3131
import {Symbol, Macro} from '../Symbol.js';
3232
import BaseMethods from '../base/BaseMethods.js';
@@ -59,7 +59,7 @@ NewcommandMethods.NewCommand = function(parser: TexParser, name: string) {
5959
'Illegal number of parameters specified in %1', name]);
6060
}
6161
}
62-
let newMacros = MapHandler.getInstance().getMap('new-Command') as CommandMap;
62+
let newMacros = MapHandler.getInstance().getMap('new-Command') as sm.CommandMap;
6363
newMacros.add(cs,
6464
new Macro('Macro', NewcommandMethods.Macro, [def, n, opt]));
6565
// this.setDef(cs, ['Macro', def, n, opt]);
@@ -81,7 +81,7 @@ NewcommandMethods.NewEnvironment = function(parser: TexParser, name: string) {
8181
'Illegal number of parameters specified in %1', name]);
8282
}
8383
}
84-
let newEnv = MapHandler.getInstance().getMap('new-Environment') as EnvironmentMap;
84+
let newEnv = MapHandler.getInstance().getMap('new-Environment') as sm.EnvironmentMap;
8585
newEnv.add(env, new Macro(env, NewcommandMethods.BeginEnv, [true, bdef, edef, n, opt]));
8686
};
8787

@@ -92,16 +92,14 @@ NewcommandMethods.MacroDef = function(parser: TexParser, name: string) {
9292
let cs = GetCSname(parser, name);
9393
let params = GetTemplate(parser, name, '\\' + cs);
9494
let def = parser.GetArgument(name);
95-
let newMacros = MapHandler.getInstance().getMap('new-Command') as CommandMap;
95+
let newMacros = MapHandler.getInstance().getMap('new-Command') as sm.CommandMap;
9696
if (!(params instanceof Array)) {
9797
newMacros.add(cs,
9898
new Macro('Macro', NewcommandMethods.Macro, [def, params]));
99-
// this.setDef(cs,['Macro', def, params]);
10099
}
101100
else {
102101
newMacros.add(cs, new Macro('MacroWithTemplate', NewcommandMethods.MacroWithTemplate,
103102
[def].concat(params)));
104-
// this.setDef(cs, ['MacroWithTemplate', def].concat(params));
105103
}
106104
};
107105

@@ -116,69 +114,87 @@ let cloneMacro = function(macro: Macro | Symbol): Macro | Symbol {
116114
/**
117115
* Implements the \let command
118116
*/
119-
// NewcommandMethods.Let = function(parser: TexParser, name: string) {
120-
// let cs = GetCSname(parser, name), macro;
121-
// let c = parser.GetNext();
122-
// if (c === '=') {
123-
// parser.i++;
124-
// c = parser.GetNext();
125-
// }
126-
// //
127-
// // All \let commands create entries in the macros array, but we
128-
// // have to look in the various mathchar and delimiter arrays if
129-
// // the source isn't a macro already, and attach the data to a
130-
// // macro with the proper routine to process it.
131-
// //
132-
// // A command of the form \let\cs=char produces a macro equivalent
133-
// // to \def\cs{char}, which is as close as MathJax can get for this.
134-
// // So \let\bgroup={ is possible, but doesn't work as it does in TeX.
135-
// //
136-
// if (c === '\\') {
137-
// name = GetCSname(parser, name);
138-
// // macro = parser.configuration.handlers.lookup(name);
139-
// // csFindMacro(name);
140-
// const handlers = parser.configuration.handlers;
141-
// let macro: Symbol | Macro = handlers.get('macro').lookup(name) as Macro;
142-
// if (macro) {
143-
// (MapHandler.getInstance().getMap('new-Command') as CommandMap).
144-
// add(name, new Macro(macro.symbol, macro.func, macro.args));
145-
// return;
146-
// }
147-
// macro = handlers.get('character').lookup(name) as Macro;
148-
// if (macro) {
149-
// (MapHandler.getInstance().getMap('new-Character') as MacroMap).
150-
// add(name, new Macro(macro.symbol, macro.func, macro.args));
151-
// return;
152-
// }
153-
// macro = handlers.get('delimiter').lookup(name) as Macro;
154-
// if (macro) {
155-
// (MapHandler.getInstance().getMap('new-Character') as MacroMap).
156-
// add(name, new Macro(macro.symbol, macro.func, macro.args));
157-
// return;
158-
// }
159-
160-
// || handlers.get('delimiter').lookup(name);
161-
// if (!macro) {
162-
// return;
163-
// }
164-
// if (macro instanceof Macro) {
165-
166-
// } else {
167-
168-
// }
169-
// if (!macro) {
170-
// if (TEXDEF.mathchar0mi[name]) {macro = ['csMathchar0mi',TEXDEF.mathchar0mi[name]]} else
171-
// if (TEXDEF.mathchar0mo[name]) {macro = ['csMathchar0mo',TEXDEF.mathchar0mo[name]]} else
172-
// if (TEXDEF.mathchar7[name]) {macro = ['csMathchar7',TEXDEF.mathchar7[name]]} else
173-
// if (TEXDEF.delimiter['\\'+name] != null) {macro = ['csDelimiter',TEXDEF.delimiter['\\'+name]]} else
174-
// return;
175-
// }
176-
// } else {
177-
// macro = ['Macro', c];
178-
// parser.i++;
179-
// }
180-
// // parser.setDef(cs, macro);
181-
// };
117+
NewcommandMethods.Let = function(parser: TexParser, name: string) {
118+
let cs = GetCSname(parser, name), macro;
119+
let c = parser.GetNext();
120+
if (c === '=') {
121+
parser.i++;
122+
c = parser.GetNext();
123+
}
124+
//
125+
// All \let commands create entries in the macros array, but we
126+
// have to look in the various mathchar and delimiter arrays if
127+
// the source isn't a macro already, and attach the data to a
128+
// macro with the proper routine to process it.
129+
//
130+
// A command of the form \let\cs=char produces a macro equivalent
131+
// to \def\cs{char}, which is as close as MathJax can get for this.
132+
// So \let\bgroup={ is possible, but doesn't work as it does in TeX.
133+
//
134+
const handlers = parser.configuration.handlers;
135+
if (c === '\\') {
136+
name = GetCSname(parser, name);
137+
macro = handlers.get('delimiter').lookup('\\' + name) as Symbol;
138+
if (macro) {
139+
(MapHandler.getInstance().getMap('new-Delimiter') as sm.DelimiterMap).
140+
add('\\' + cs, new Symbol('\\' + cs, macro.char, macro.attributes));
141+
return;
142+
}
143+
let map = handlers.get('macro').applicable(name);
144+
if (map instanceof sm.CommandMap) {
145+
macro = (map as sm.CommandMap).lookup(name) as Macro;
146+
let newArgs: Args[] = [name as Args].concat(macro.args);
147+
(MapHandler.getInstance().getMap('new-Command') as sm.CommandMap).
148+
add(cs, new Macro(macro.symbol, macro.func, newArgs));
149+
return;
150+
}
151+
if (map instanceof sm.CharacterMap) {
152+
macro = (map as sm.CharacterMap).lookup(name) as Symbol;
153+
let newArgs = disassembleSymbol(cs, macro);
154+
let method = (p: TexParser, cs: string, ...rest: any[]) => {
155+
let symb = assembleSymbol(rest);
156+
return map.parser(p, symb);
157+
};
158+
let newMacro = new Macro(cs, method as any, newArgs);
159+
(MapHandler.getInstance().getMap('new-Command') as sm.CommandMap).
160+
add(cs, newMacro);
161+
return;
162+
}
163+
} else {
164+
// TODO: Add the delimiter case for elements like [],()
165+
parser.i++;
166+
macro = handlers.get('delimiter').lookup(c) as Symbol;
167+
if (macro) {
168+
(MapHandler.getInstance().getMap('new-Delimiter') as sm.DelimiterMap).
169+
add('\\' + cs, new Symbol('\\' + cs, macro.char, macro.attributes));
170+
return;
171+
}
172+
let newMacros = MapHandler.getInstance().getMap('new-Command') as sm.CommandMap;
173+
newMacros.add(cs,
174+
new Macro('Macro', NewcommandMethods.Macro, [c]));
175+
}
176+
};
177+
178+
let disassembleSymbol = function(name: string, symbol: Symbol): Args[] {
179+
let newArgs = [name, symbol.char] as Args[];
180+
if (symbol.attributes) {
181+
for (let key in symbol.attributes) {
182+
newArgs.push(key);
183+
newArgs.push(symbol.attributes[key] as Args);
184+
}
185+
}
186+
return newArgs;
187+
};
188+
189+
let assembleSymbol = function(args: Args[]): Symbol {
190+
let name = args[0] as string;
191+
let char = args[1] as string;
192+
let attrs: Attributes = {};
193+
for (let i = 2; i < args.length; i = i + 2) {
194+
attrs[args[i] as string] = args[i + 1];
195+
}
196+
return new Symbol(name, char, attrs);
197+
};
182198

183199

184200
/**
@@ -278,7 +294,7 @@ NewcommandMethods.BeginEnv = function(parser: TexParser, begin: StackItem,
278294
return parser.itemFactory.create('endEnv').setProperties({name: begin.getName()});
279295
}
280296
if (n) {
281-
let args = [];
297+
let args: string[] = [];
282298
if (def != null) {
283299
let optional = parser.GetBrackets('\\begin{' + begin.getName() + '}');
284300
args.push(optional == null ? def : optional);

mathjax3-ts/input/tex/newcommand/tests

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,39 @@
5555

5656
\renewenvironment{argument}[2][a]{\textbf{Argument #1(#2):}}{aa}
5757
\begin{argument}[c]{3}b\end{argument}
58+
59+
60+
\let\b\lvert
61+
\let\lvert\langle
62+
\vert
63+
\b
64+
\lvert
65+
\left\b q \right\lvert
66+
67+
68+
\let\be={
69+
70+
\be a}
71+
72+
\let\be={
73+
74+
\be a}
75+
76+
\let\car^
77+
78+
a\car b
79+
80+
\let\lb=\{
81+
\lb \frac{1}{2} \}
82+
\left\lb \frac{1}{2} \right\}
83+
84+
85+
\let\al\alpha
86+
\al\alpha
87+
\let\al\aleph
88+
\al\alpha
89+
90+
\let\al\alpha
91+
\al\alpha
92+
\let\alpha\beta
93+
\al\alpha

0 commit comments

Comments
 (0)