Skip to content
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"=============================================================================== copy": "",
"copy:assets": "pnpm -s log:comp 'Copying assets'; copy() { pnpm -s copy:locales $1 && pnpm -s copy:mj2 $1 && pnpm -s copy:mml3 $1 && pnpm -s copy:html $1; }; copy",
"copy:html": "copy() { pnpm -s log:single 'Copying sre auxiliary files'; pnpm copyfiles -u 1 'ts/a11y/sre/*.html' 'ts/a11y/sre/require.*' $1; }; copy",
"copy:locales": "pnpm -s log:single 'Copying TeX extension locales'; copy() { pnpm copyfiles -u 3 'ts/input/tex/*/locales/*.json' $1/input/tex/extensions; }; copy",
"copy:locales": "pnpm -s log:single 'Copying TeX extension locales'; copy() { pnpm copyfiles -u 3 'ts/input/tex/locales/*.json' 'ts/input/tex/*/locales/*.json' $1/input/tex/extensions; }; copy",
"copy:mj2": "copy() { pnpm -s log:single 'Copying legacy code AsciiMath'; pnpm copyfiles -u 1 'ts/input/asciimath/legacy/**/*' $1; }; copy",
"copy:mml3": "copy() { pnpm -s log:single 'Copying MathML3 extension json'; pnpm copyfiles -u 1 ts/input/mathml/mml3/mml3.sef.json $1; }; copy",
"copy:pkg": "copy() { pnpm -s log:single \"Copying package.json to $1\"; pnpm copyfiles -u 2 components/bin/package.json $1; }; copy",
Expand Down
4 changes: 2 additions & 2 deletions testsuite/tests/input/tex/Mathtools.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,7 @@ describe('Mathtools More Environments', () => {

test('ArrowBetweenLines error', () => {
expectTexError('\\ArrowBetweenLines').toBe(
'\\ArrowBetweenLines can only be used in aligment environments'
'\\ArrowBetweenLines can only be used in alignment environments'
);
});

Expand Down Expand Up @@ -1040,7 +1040,7 @@ describe('Mathtools Boxed Equations', () => {

test('Aboxed error', () => {
expectTexError('\\Aboxed{ a & = b}').toBe(
'\\Aboxed can only be used in aligment environments'
'\\Aboxed can only be used in alignment environments'
);
});

Expand Down
2 changes: 1 addition & 1 deletion testsuite/tests/input/tex/Newcommand.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ describe('NewcommandError', () => {

it('Recursive Macro', () => {
expectTexError('\\def\\x{\\x} \\x').toBe(
'MathJax maximum macro substitution count exceeded; is here a recursive macro call?'
'MathJax maximum macro substitution count exceeded; is there a recursive macro call?'
);
});

Expand Down
10 changes: 5 additions & 5 deletions testsuite/tests/input/tex/Tex.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,22 +138,22 @@ describe('Tags', () => {

describe('TexError', () => {
test('Number argument', () => {
const err = new TexError('test', 'Number: %1', 1 as any);
const err = new TexError(null, 'test', 'Number: %1', 1 as any);
expect(err.message).toBe('Number: 1');
});

test('Braced insertion', () => {
const err = new TexError('test', 'Msg: %{1}, Number: %{2}', 'OK', 2 as any);
const err = new TexError(null, 'test', 'Msg: %{1}, Number: %{2}', 'OK', 2 as any);
expect(err.message).toBe('Msg: OK, Number: 2');
});

test('Plural', () => {
const err = new TexError('test', '%{plural:%1|abc}', 'apple');
test.skip('Plural', () => {
const err = new TexError(null, 'test', '%{plural:%1|abc}', 'apple');
expect(err.message).toBe('%{plural:%1|abc}');
});

test('Percent', () => {
const err = new TexError('test', '10%%');
const err = new TexError(null, 'test', '10%%');
expect(err.message).toBe('10%');
});
});
Expand Down
2 changes: 1 addition & 1 deletion testsuite/tests/input/tex/Verb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { afterAll, beforeEach, describe, expect, it } from '@jest/globals';
import { getTokens, setupTex, tex2mml, expectTexError } from '#helpers';
import '#js/input/tex/verb/VerbConfiguration';

beforeEach(() => setupTex(['base', 'verb']));
beforeEach(async () => setupTex(['base', 'verb']));

/**********************************************************************************/

Expand Down
29 changes: 8 additions & 21 deletions ts/input/tex/ColumnParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { lookup } from '../../util/Options.js';
import { ParseUtil } from './ParseUtil.js';
import { UnitUtil } from './UnitUtil.js';

const COMPONENT = '[tex]';

/***********************************************************************/

/**
Expand Down Expand Up @@ -133,16 +135,13 @@ export class ColumnParser {
let n = 0;
while (state.i < state.template.length) {
if (n++ > this.MAXCOLUMNS) {
throw new TexError(
'MaxColumns',
'Too many column specifiers (perhaps looping column definitions?)'
);
throw new TexError(COMPONENT, 'MaxColumns');
}
const code = state.template.codePointAt(state.i);
const c = (state.c = String.fromCodePoint(code));
state.i += c.length;
if (!Object.hasOwn(this.columnHandler, c)) {
throw new TexError('BadPreamToken', 'Illegal pream-token (%1)', c);
throw new TexError(COMPONENT, 'BadPreamToken', c);
}
this.columnHandler[c](state);
}
Expand Down Expand Up @@ -264,11 +263,7 @@ export class ColumnParser {
public getDimen(state: ColumnState): string {
const dim = this.getBraces(state);
if (!UnitUtil.matchDimen(dim)[0]) {
throw new TexError(
'MissingColumnDimOrUnits',
'Missing dimension or its units for %1 column declaration',
state.c
);
throw new TexError(COMPONENT, 'MissingColumnDimOrUnits', state.c);
}
return dim;
}
Expand Down Expand Up @@ -299,11 +294,7 @@ export class ColumnParser {
public getBraces(state: ColumnState): string {
while (state.template[state.i] === ' ') state.i++;
if (state.i >= state.template.length) {
throw new TexError(
'MissingArgForColumn',
'Missing argument for %1 column declaration',
state.c
);
throw new TexError(COMPONENT, 'MissingArgForColumn', state.c);
}
if (state.template[state.i] !== '{') {
return state.template[state.i++];
Expand All @@ -325,7 +316,7 @@ export class ColumnParser {
break;
}
}
throw new TexError('MissingCloseBrace', 'Missing close brace');
throw new TexError(COMPONENT, 'MissingCloseBrace');
}

/**
Expand Down Expand Up @@ -410,11 +401,7 @@ export class ColumnParser {
const cols = this.getBraces(state);
const n = parseInt(num);
if (String(n) !== num) {
throw new TexError(
'ColArgNotNum',
'First argument to %1 column specifier must be a number',
'*'
);
throw new TexError(COMPONENT, 'ColArgNotNum', '*');
}
state.template =
new Array(n).fill(cols).join('') + state.template.substring(state.i);
Expand Down
4 changes: 4 additions & 0 deletions ts/input/tex/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ import { FunctionList } from '../../util/FunctionList.js';
import { TeX } from '../tex.js';
import { PrioritizedList } from '../../util/PrioritizedList.js';
import { TagsFactory } from './Tags.js';
import { Locale } from '../../util/Locale.js';

export const COMPONENT = '[tex]';
Locale.registerLocaleFiles(COMPONENT, '../ts/input/tex');

export type StackItemConfig = { [kind: string]: StackItemClass };
export type TagsConfig = { [kind: string]: TagsClass };
Expand Down
60 changes: 14 additions & 46 deletions ts/input/tex/ParseUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import { entities } from '../../util/Entities.js';
import { MmlMunderover } from '../../core/MmlTree/MmlNodes/munderover.js';
import { UnitUtil } from './UnitUtil.js';

const COMPONENT = '[tex]';

/**
* The data needed for checking the value of a key-value pair.
*/
Expand Down Expand Up @@ -185,10 +187,8 @@ function readValue(
// Closing braces.
case '}':
if (!braces) {
throw new TexError(
'ExtraCloseMissingOpen',
'Extra close brace or missing open brace'
);
// Closing braces.
throw new TexError(COMPONENT, 'ExtraCloseMissingOpen');
}
braces--;
countBraces = false; // Stop counting start left braces.
Expand All @@ -211,10 +211,7 @@ function readValue(
value += c;
}
if (braces) {
throw new TexError(
'ExtraOpenMissingClose',
'Extra open brace or missing close brace'
);
throw new TexError(COMPONENT, 'ExtraOpenMissingClose');
}
return dropBrace && start
? ['', '', removeBraces(value, 1)]
Expand Down Expand Up @@ -546,11 +543,7 @@ export const ParseUtil = {
.substring(i)
.match(/^\s*(?:([0-9A-F])|\{\s*([0-9A-F]+)\s*\})/);
if (!arg) {
throw new TexError(
'BadRawUnicode',
'Argument to %1 must a hexadecimal number with 1 to 6 digits',
'\\U'
);
throw new TexError(COMPONENT, 'BadRawUnicode', '\\U');
}
// Replace \U{...} with specified character
const c = String.fromCodePoint(parseInt(arg[1] || arg[2], 16));
Expand All @@ -565,10 +558,7 @@ export const ParseUtil = {
}
if (match !== '') {
// @test Internal Math Error
throw new TexError(
'MathNotTerminated',
'Math mode is not properly terminated'
);
throw new TexError(COMPONENT, 'MathNotTerminated');
}
}
if (k < text.length) {
Expand Down Expand Up @@ -733,10 +723,7 @@ export const ParseUtil = {
text += c;
} else {
if (!c.match(/[1-9]/) || parseInt(c, 10) > args.length) {
throw new TexError(
'IllegalMacroParam',
'Illegal macro parameter reference'
);
throw new TexError(COMPONENT, 'IllegalMacroParam');
}
newstring = ParseUtil.addArgs(
parser,
Expand Down Expand Up @@ -767,11 +754,7 @@ export const ParseUtil = {
s1 += ' ';
}
if (s1.length + s2.length > parser.configuration.options['maxBuffer']) {
throw new TexError(
'MaxBufferSize',
'MathJax internal buffer size exceeded; is there a' +
' recursive macro call?'
);
throw new TexError(COMPONENT, 'MaxBufferSize');
}
return s1 + s2;
},
Expand All @@ -787,17 +770,9 @@ export const ParseUtil = {
return;
}
if (isMacro) {
throw new TexError(
'MaxMacroSub1',
'MathJax maximum macro substitution count exceeded; ' +
'is here a recursive macro call?'
);
throw new TexError(COMPONENT, 'MaxMacroSub1');
} else {
throw new TexError(
'MaxMacroSub2',
'MathJax maximum substitution count exceeded; ' +
'is there a recursive latex environment?'
);
throw new TexError(COMPONENT, 'MaxMacroSub2');
}
},

Expand All @@ -820,10 +795,7 @@ export const ParseUtil = {
return;
}
if (!top.isKind('start') || first) {
throw new TexError(
'ErroneousNestingEq',
'Erroneous nesting of equation structures'
);
throw new TexError(COMPONENT, 'ErroneousNestingEq');
}
},

Expand Down Expand Up @@ -902,17 +874,13 @@ export const ParseUtil = {
const type = allowed[key] as KeyValueDef<any>;
const value = String(def[key]);
if (!type.verify(value)) {
throw new TexError(
'InvalidValue',
"Value for key '%1' is not of the expected type",
key
);
throw new TexError(COMPONENT, 'InvalidValue', key);
}
def[key] = type.convert(value);
}
} else {
if (error) {
throw new TexError('InvalidOption', 'Invalid option: %1', key);
throw new TexError(COMPONENT, 'InvalidOption', key);
}
delete def[key];
}
Expand Down
28 changes: 14 additions & 14 deletions ts/input/tex/StackItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import TexError from './TexError.js';
import StackItemFactory from './StackItemFactory.js';
import { TexConstant } from './TexConstants.js';

const COMPONENT = '[tex]/base';

// Union types for abbreviation.
export type EnvProp = string | number | boolean;

Expand Down Expand Up @@ -387,17 +389,16 @@ export abstract class BaseItem extends MmlStack implements StackItem {

/**
* A list of basic errors.
*
* @type {{[key: string]: string[]}}
* @type {{[key: string]: string}}
*/
protected static errors: { [key: string]: string[] } = {
protected static errors: { [key: string]: string } = {
// @test ExtraOpenMissingClose
end: ['MissingBeginExtraEnd', 'Missing \\begin{%1} or extra \\end{%1}'],
end: 'MissingBeginExtraEnd',
// @test ExtraCloseMissingOpen
close: ['ExtraCloseMissingOpen', 'Extra close brace or missing open brace'],
close: 'ExtraCloseMissingOpen',
// @test MissingLeftExtraRight
right: ['MissingLeftExtraRight', 'Missing \\left or extra \\right'],
middle: ['ExtraMiddle', 'Extra \\middle'],
right: 'MissingLeftExtraRight',
middle: 'ExtraMiddle',
};

/**
Expand Down Expand Up @@ -514,13 +515,12 @@ export abstract class BaseItem extends MmlStack implements StackItem {
return BaseItem.fail;
}
// @test Ampersand-error
throw new TexError('Misplaced', 'Misplaced %1', item.getName());
throw new TexError(COMPONENT, 'Misplaced', item.getName());
}
if (item.isClose && this.getErrors(item.kind)) {
if (item.isClose && this.getError(item.kind)) {
// @test ExtraOpenMissingClose, ExtraCloseMissingOpen,
// MissingLeftExtraRight, MissingBeginExtraEnd
const [id, message] = this.getErrors(item.kind);
throw new TexError(id, message, item.getName());
throw new TexError(COMPONENT, this.getError(item.kind), item.getName());
}
if (!item.isFinal) {
return BaseItem.success;
Expand Down Expand Up @@ -566,11 +566,11 @@ export abstract class BaseItem extends MmlStack implements StackItem {
* subclasses.
*
* @param {string} kind The stack item type.
* @returns {string[]} The list of arguments for the TeXError.
* @returns {string} The id of the error message.
*/
public getErrors(kind: string): string[] {
public getError(kind: string): string {
const CLASS = this.constructor as typeof BaseItem;
return CLASS.errors[kind] || BaseItem.errors[kind];
return CLASS.errors?.[kind] ?? BaseItem.errors[kind];
}

/**
Expand Down
Loading