Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix handling of _ and ^ followed by command that doesn't push content (mathjax/MathJax#3184) #1060

Merged
merged 1 commit into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion ts/input/tex/Stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ export default class Stack {
this.Push(...top);
continue;
}
this.stack.push(item);
if (!item.isKind('null')) {
this.stack.push(item);
}
if (item.env) {
if (item.copyEnv) {
Object.assign(item.env, this.env);
Expand Down
2 changes: 1 addition & 1 deletion ts/input/tex/StackItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ export abstract class BaseItem extends MmlStack implements StackItem {
/**
* @return {string} The type of the stack item.
*/
public get kind(): string {
public get kind(): string {
return 'base';
}

Expand Down
25 changes: 15 additions & 10 deletions ts/input/tex/TexParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,11 +570,13 @@ export default class TexParser {
}
// These are the cases to handle sub and superscripts.
if (node.attributes.get(TexConstant.Attr.LATEX) === '^' &&
str !== '^' && str !== '\\^') {
if (str === '}') {
this.composeBraces(node.childNodes[2]);
} else {
node.childNodes[2].attributes.set(TexConstant.Attr.LATEX, str);
str !== '^' && str !== '\\^') {
if (node.childNodes[2]) {
if (str === '}') {
this.composeBraces(node.childNodes[2]);
} else {
node.childNodes[2].attributes.set(TexConstant.Attr.LATEX, str);
}
}
if (node.childNodes[1]) {
const sub = node.childNodes[1].attributes.get(TexConstant.Attr.LATEX);
Expand All @@ -585,11 +587,13 @@ export default class TexParser {
return;
}
if (node.attributes.get(TexConstant.Attr.LATEX) === '_' &&
str !== '_' && str !== '\\_') {
if (str === '}') {
this.composeBraces(node.childNodes[1]);
} else {
node.childNodes[1].attributes.set(TexConstant.Attr.LATEX, str);
str !== '_' && str !== '\\_') {
if (node.childNodes[1]) {
if (str === '}') {
this.composeBraces(node.childNodes[1]);
} else {
node.childNodes[1].attributes.set(TexConstant.Attr.LATEX, str);
}
}
if (node.childNodes[2]) {
const sub = node.childNodes[2].attributes.get(TexConstant.Attr.LATEX);
Expand All @@ -616,6 +620,7 @@ export default class TexParser {
*/
private composeLatex(
node: MmlNode, comp: string, pos1: number, pos2: number) {
if (!node.childNodes[pos1] || !node.childNodes[pos2]) return;
const expr = node.childNodes[pos1].attributes.get(TexConstant.Attr.LATEX) + comp +
node.childNodes[pos2].attributes.get(TexConstant.Attr.LATEX);
node.attributes.set(TexConstant.Attr.LATEX, expr);
Expand Down
2 changes: 2 additions & 0 deletions ts/input/tex/ams/AmsMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ AmsMethods.HandleDeclareOp = function (parser: TexParser, name: string) {
let op = parser.GetArgument(name);
(parser.configuration.handlers.retrieve(NEW_OPS) as CommandMap).
add(cs, new Macro(cs, AmsMethods.Macro, [`\\operatorname${star}{${op}}`]));
parser.Push(parser.itemFactory.create('null'));
};


Expand Down Expand Up @@ -586,6 +587,7 @@ AmsMethods.HandleTag = function(parser: TexParser, name: string) {
let star = parser.GetStar();
let tagId = ParseUtil.trimSpaces(parser.GetArgument(name));
parser.tags.tag(tagId, star);
parser.Push(parser.itemFactory.create('null'));
};


Expand Down
1 change: 1 addition & 0 deletions ts/input/tex/base/BaseConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export const BaseConfiguration: Configuration = Configuration.create(
[bitem.StopItem.prototype.kind]: bitem.StopItem,
[bitem.OpenItem.prototype.kind]: bitem.OpenItem,
[bitem.CloseItem.prototype.kind]: bitem.CloseItem,
[bitem.NullItem.prototype.kind]: bitem.NullItem,
[bitem.PrimeItem.prototype.kind]: bitem.PrimeItem,
[bitem.SubsupItem.prototype.kind]: bitem.SubsupItem,
[bitem.OverItem.prototype.kind]: bitem.OverItem,
Expand Down
12 changes: 12 additions & 0 deletions ts/input/tex/base/BaseItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,18 @@ export class CloseItem extends BaseItem {

}

/**
* Item pushed when a macro doesn't produce any output.
*/
export class NullItem extends BaseItem {
/**
* @override
*/
public get kind() {
return 'null';
}
}


/**
* Item indicating an we are currently dealing with a prime mark.
Expand Down
8 changes: 5 additions & 3 deletions ts/input/tex/base/BaseMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,7 @@ BaseMethods.Prime = function(parser: TexParser, c: string) {
} while (c === '\'' || c === entities.rsquo);
sup = ['', '\u2032', '\u2033', '\u2034', '\u2057'][sup.length] || sup;
const node = parser.create('token', 'mo', {variantForm: true}, sup);
parser.Push(
parser.itemFactory.create('prime', base, node) );
parser.Push(parser.itemFactory.create('prime', base, node));
};


Expand Down Expand Up @@ -327,6 +326,7 @@ BaseMethods.MathFont = function(parser: TexParser, name: string, variant: string
*/
BaseMethods.SetFont = function(parser: TexParser, _name: string, font: string) {
parser.stack.env['font'] = font;
parser.Push(parser.itemFactory.create('null'));
};

/**
Expand Down Expand Up @@ -811,6 +811,7 @@ BaseMethods.VBox = function(parser: TexParser, name: string, align: string) {
BaseMethods.Hsize = function (parser: TexParser, name: string) {
parser.GetNext() === '=' && parser.i++;
parser.stack.env.hsize = parser.GetDimen(name);
parser.Push(parser.itemFactory.create('null'));
};

/**
Expand Down Expand Up @@ -1538,10 +1539,11 @@ BaseMethods.NewColumnType = function (parser: TexParser, name: string) {
throw new TexError('BadColumnName', 'Column specifier must be exactly one character: %1', c);
}
if (!n.match(/^\d+$/)) {
throw new TexError('PositiveIntegerArg', 'Argument to %1 must me a positive integer', n);
throw new TexError('PositiveIntegerArg', 'Argument to %1 must be a positive integer', n);
}
const cparser = parser.configuration.columnParser;
cparser.columnHandler[c] = (state: ColumnState) => cparser.macroColumn(state, macro, parseInt(n));
parser.Push(parser.itemFactory.create('null'));
}


Expand Down
1 change: 1 addition & 0 deletions ts/input/tex/color/ColorMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ ColorMethods.DefineColor = function (parser: TexParser, name: string) {

const colorModel: ColorModel = parser.configuration.packageData.get('color').model;
colorModel.defineColor(model, cname, def);
parser.Push(parser.itemFactory.create('null'));
};

/**
Expand Down
1 change: 1 addition & 0 deletions ts/input/tex/extpfeil/ExtpfeilConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ ExtpfeilMethods.NewExtArrow = function(parser: TexParser, name: string) {
let spaces = space.split(',');
NewcommandUtil.addMacro(parser, cs, ExtpfeilMethods.xArrow,
[parseInt(chr), parseInt(spaces[0]), parseInt(spaces[1])]);
parser.Push(parser.itemFactory.create('null'));
};


Expand Down
7 changes: 7 additions & 0 deletions ts/input/tex/mathtools/MathtoolsMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ export const MathtoolsMethods: Record<string, ParseMethod> = {
const open = parser.GetArgument(name);
const close = parser.GetArgument(name);
MathtoolsUtil.addPairedDelims(parser.configuration, cs, [open, close]);
parser.Push(parser.itemFactory.create('null'));
},

/**
Expand All @@ -530,6 +531,7 @@ export const MathtoolsMethods: Record<string, ParseMethod> = {
const close = parser.GetArgument(name);
const body = parser.GetArgument(name);
MathtoolsUtil.addPairedDelims(parser.configuration, cs, [open, close, body, n]);
parser.Push(parser.itemFactory.create('null'));
},

/**
Expand All @@ -547,6 +549,7 @@ export const MathtoolsMethods: Record<string, ParseMethod> = {
const post = parser.GetArgument(name);
const body = parser.GetArgument(name);
MathtoolsUtil.addPairedDelims(parser.configuration, cs, [open, close, body, n, pre, post]);
parser.Push(parser.itemFactory.create('null'));
},

/**
Expand Down Expand Up @@ -710,6 +713,7 @@ export const MathtoolsMethods: Record<string, ParseMethod> = {
throw new TexError('DuplicateTagForm', 'Duplicate tag form: %1', id);
}
tags.mtFormats.set(id, [left, right, format]);
parser.Push(parser.itemFactory.create('null'));
},

/**
Expand All @@ -726,12 +730,14 @@ export const MathtoolsMethods: Record<string, ParseMethod> = {
const id = parser.GetArgument(name).trim();
if (!id) {
tags.mtCurrent = null;
parser.Push(parser.itemFactory.create('null'));
return;
}
if (!tags.mtFormats.has(id)) {
throw new TexError('UndefinedTagForm', 'Undefined tag form: %1', id);
}
tags.mtCurrent = tags.mtFormats.get(id);
parser.Push(parser.itemFactory.create('null'));
},

/**
Expand All @@ -756,6 +762,7 @@ export const MathtoolsMethods: Record<string, ParseMethod> = {
for (const id of Object.keys(keys)) {
options[id] = keys[id];
}
parser.Push(parser.itemFactory.create('null'));
},

/**
Expand Down
4 changes: 4 additions & 0 deletions ts/input/tex/newcommand/NewcommandMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ NewcommandMethods.NewCommand = function(parser: TexParser, name: string) {
let opt = parser.GetBrackets(name);
let def = parser.GetArgument(name);
NewcommandUtil.addMacro(parser, cs, NewcommandMethods.Macro, [def, n, opt]);
parser.Push(parser.itemFactory.create('null'));
};


Expand All @@ -65,6 +66,7 @@ NewcommandMethods.NewEnvironment = function(parser: TexParser, name: string) {
let bdef = parser.GetArgument(name);
let edef = parser.GetArgument(name);
NewcommandUtil.addEnvironment(parser, env, NewcommandMethods.BeginEnv, [true, bdef, edef, n, opt]);
parser.Push(parser.itemFactory.create('null'));
};


Expand All @@ -83,6 +85,7 @@ NewcommandMethods.MacroDef = function(parser: TexParser, name: string) {
NewcommandUtil.addMacro(parser, cs, NewcommandMethods.Macro, [def, params]) :
// @test Def Let
NewcommandUtil.addMacro(parser, cs, NewcommandMethods.MacroWithTemplate, [def].concat(params));
parser.Push(parser.itemFactory.create('null'));
};


Expand Down Expand Up @@ -112,6 +115,7 @@ NewcommandMethods.Let = function(parser: TexParser, name: string) {
c = parser.GetNext();
}
const handlers = parser.configuration.handlers;
parser.Push(parser.itemFactory.create('null'));
if (c === '\\') {
// @test Let Bar, Let Brace Equal Stretchy
name = NewcommandUtil.GetCSname(parser, name);
Expand Down
1 change: 1 addition & 0 deletions ts/input/tex/require/RequireConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ export const RequireMethods: Record<string, ParseMethod> = {
throw new TexError('BadPackageName', 'Argument for %1 is not a valid package name', name);
}
RequireLoad(parser, required);
parser.Push(parser.itemFactory.create('null'));
}

};
Expand Down
1 change: 1 addition & 0 deletions ts/input/tex/setoptions/SetOptionsConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ const setOptionsMap = new CommandMap('setoptions', {
config.filterValue(parser, extension, key, options[key]);
}
}
parser.Push(parser.itemFactory.create('null'));
}
});

Expand Down