Skip to content

Commit dbc3b42

Browse files
committed
fix: Remove circular dependency
When bundling mathjax - you are warned that there is a circular dependency: ```shell code: CIRCULAR_DEPENDENCY, message: Circular dependency: node_modules/mathjax-full/js/input/tex/TexParser.js -> node_modules/mathjax-full/js/input/tex/ParseUtil.js -> node_modules/mathjax-full/js/input/tex/TexParser.js ``` This can lead to runtime errors as the bundler has to guess which module to define first. This commit removes this circular dependency. > Note: there are still other circular dependencies in place that should also be fixed: ```shell 1) components/loader.js > components/package.js 2) input/tex/mathtools/MathtoolsConfiguration.js > input/tex/mathtools/MathtoolsMappings.js > input/tex/mathtools/MathtoolsMethods.js > input/tex/mathtools/MathtoolsUtil.js 3) input/tex/mathtools/MathtoolsMethods.js > input/tex/mathtools/MathtoolsUtil.js 4) output/svg.js > output/svg/WrapperFactory.js > output/svg/Wrappers.js > output/svg/Wrapper.js ```
1 parent b34d1c9 commit dbc3b42

File tree

10 files changed

+115
-98
lines changed

10 files changed

+115
-98
lines changed

ts/input/tex/ParseUtil.ts

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -31,87 +31,9 @@ import TexParser from './TexParser.js';
3131
import TexError from './TexError.js';
3232
import {entities} from '../../util/Entities.js';
3333
import {MmlMunderover} from '../../core/MmlTree/MmlNodes/munderover.js';
34-
35-
34+
import {Em} from '../../util/lengths.js';
3635
namespace ParseUtil {
3736

38-
// TODO (VS): Combine some of this with lengths in util.
39-
const emPerInch = 7.2;
40-
const pxPerInch = 72;
41-
// Note, the following are TeX CM font values.
42-
const UNIT_CASES: {[key: string]: ((m: number) => number)} = {
43-
'em': m => m,
44-
'ex': m => m * .43,
45-
'pt': m => m / 10, // 10 pt to an em
46-
'pc': m => m * 1.2, // 12 pt to a pc
47-
'px': m => m * emPerInch / pxPerInch,
48-
'in': m => m * emPerInch,
49-
'cm': m => m * emPerInch / 2.54, // 2.54 cm to an inch
50-
'mm': m => m * emPerInch / 25.4, // 10 mm to a cm
51-
'mu': m => m / 18,
52-
};
53-
const num = '([-+]?([.,]\\d+|\\d+([.,]\\d*)?))';
54-
const unit = '(pt|em|ex|mu|px|mm|cm|in|pc)';
55-
const dimenEnd = RegExp('^\\s*' + num + '\\s*' + unit + '\\s*$');
56-
const dimenRest = RegExp('^\\s*' + num + '\\s*' + unit + ' ?');
57-
58-
59-
/**
60-
* Matches for a dimension argument.
61-
* @param {string} dim The argument.
62-
* @param {boolean} rest Allow for trailing garbage in the dimension string.
63-
* @return {[string, string, number]} The match result as (Anglosaxon) value,
64-
* unit name, length of matched string. The latter is interesting in the
65-
* case of trailing garbage.
66-
*/
67-
export function matchDimen(
68-
dim: string, rest: boolean = false): [string, string, number] {
69-
let match = dim.match(rest ? dimenRest : dimenEnd);
70-
return match ?
71-
muReplace([match[1].replace(/,/, '.'), match[4], match[0].length]) :
72-
[null, null, 0];
73-
}
74-
75-
76-
/**
77-
* Transforms mu dimension to em if necessary.
78-
* @param {[string, string, number]} [value, unit, length] The dimension triple.
79-
* @return {[string, string, number]} [value, unit, length] The transformed triple.
80-
*/
81-
function muReplace([value, unit, length]: [string, string, number]): [string, string, number] {
82-
if (unit !== 'mu') {
83-
return [value, unit, length];
84-
}
85-
let em = Em(UNIT_CASES[unit](parseFloat(value || '1')));
86-
return [em.slice(0, -2), 'em', length];
87-
}
88-
89-
90-
/**
91-
* Convert a dimension string into standard em dimension.
92-
* @param {string} dim The attribute string.
93-
* @return {number} The numerical value.
94-
*/
95-
export function dimen2em(dim: string): number {
96-
let [value, unit] = matchDimen(dim);
97-
let m = parseFloat(value || '1');
98-
let func = UNIT_CASES[unit];
99-
return func ? func(m) : 0;
100-
}
101-
102-
103-
/**
104-
* Turns a number into an em value.
105-
* @param {number} m The number.
106-
* @return {string} The em dimension string.
107-
*/
108-
export function Em(m: number): string {
109-
if (Math.abs(m) < .0006) {
110-
return '0em';
111-
}
112-
return m.toFixed(3).replace(/\.?0+$/, '') + 'em';
113-
}
114-
11537

11638
/**
11739
* Takes an array of numbers and returns a space-separated string of em values.

ts/input/tex/TexParser.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
* @author [email protected] (Volker Sorge)
2424
*/
2525

26-
import ParseUtil from './ParseUtil.js';
2726
import {HandlerType} from './MapHandler.js';
2827
import Stack from './Stack.js';
2928
import StackItemFactory from './StackItemFactory.js';
@@ -35,6 +34,8 @@ import ParseOptions from './ParseOptions.js';
3534
import {StackItem, EnvList} from './StackItem.js';
3635
import {Symbol} from './Symbol.js';
3736
import {OptionList} from '../../util/Options.js';
37+
import {matchDimen} from '../../util/lengths.js';
38+
import {trimSpaces} from '../../util/string.js';
3839

3940

4041
/**
@@ -392,15 +393,15 @@ export default class TexParser {
392393
public GetDimen(name: string): string {
393394
if (this.GetNext() === '{') {
394395
let dimen = this.GetArgument(name);
395-
let [value, unit] = ParseUtil.matchDimen(dimen);
396+
let [value, unit] = matchDimen(dimen);
396397
if (value) {
397398
// @test Raise In Line, Lower 2, (Raise|Lower) Negative
398399
return value + unit;
399400
}
400401
} else {
401402
// @test Above, Raise, Lower, Modulo, Above With Delims
402403
let dimen = this.string.slice(this.i);
403-
let [value, unit, length] = ParseUtil.matchDimen(dimen, true);
404+
let [value, unit, length] = matchDimen(dimen, true);
404405
if (value) {
405406
this.i += length;
406407
return value + unit;
@@ -475,7 +476,7 @@ export default class TexParser {
475476
* @return {string} The delimiter.
476477
*/
477478
public GetDelimiterArg(name: string): string {
478-
let c = ParseUtil.trimSpaces(this.GetArgument(name));
479+
let c = trimSpaces(this.GetArgument(name));
479480
if (c === '') {
480481
return null;
481482
}

ts/input/tex/ams/AmsMethods.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {FlalignItem} from './AmsItems.js';
3737
import BaseMethods from '../base/BaseMethods.js';
3838
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
3939
import {MmlMunderover} from '../../../core/MmlTree/MmlNodes/munderover.js';
40+
import {Em} from '../../../util/lengths.js';
4041

4142

4243
// Namespace
@@ -289,7 +290,7 @@ AmsMethods.MultiIntegral = function(parser: TexParser, name: string,
289290
*/
290291
AmsMethods.xArrow = function(parser: TexParser, name: string,
291292
chr: number, l: number, r: number) {
292-
let def = {width: '+' + ParseUtil.Em((l + r) / 18), lspace: ParseUtil.Em(l / 18)};
293+
let def = {width: '+' + Em((l + r) / 18), lspace: Em(l / 18)};
293294
let bot = parser.GetBrackets(name);
294295
let first = parser.ParseArg(name);
295296
let dstrut = parser.create('node', 'mspace', [], {depth: '.25em'});

ts/input/tex/base/BaseItems.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import NodeUtil from '../NodeUtil.js';
3434
import {Property} from '../../../core/Tree/Node.js';
3535
import StackItemFactory from '../StackItemFactory.js';
3636
import {CheckType, BaseItem, StackItem, EnvList} from '../StackItem.js';
37+
import { dimen2em, Em } from '../../../util/lengths.js';
3738

3839

3940
/**
@@ -1082,15 +1083,15 @@ export class ArrayItem extends BaseItem {
10821083
const rows = (this.arraydef['rowspacing'] as string).split(/ /);
10831084
if (!this.getProperty('rowspacing')) {
10841085
// @test Array Custom Linebreak
1085-
let dimem = ParseUtil.dimen2em(rows[0]);
1086+
let dimem = dimen2em(rows[0]);
10861087
this.setProperty('rowspacing', dimem);
10871088
}
10881089
const rowspacing = this.getProperty('rowspacing') as number;
10891090
while (rows.length < this.table.length) {
1090-
rows.push(ParseUtil.Em(rowspacing));
1091+
rows.push(Em(rowspacing));
10911092
}
1092-
rows[this.table.length - 1] = ParseUtil.Em(
1093-
Math.max(0, rowspacing + ParseUtil.dimen2em(spacing)));
1093+
rows[this.table.length - 1] = Em(
1094+
Math.max(0, rowspacing + dimen2em(spacing)));
10941095
this.arraydef['rowspacing'] = rows.join(' ');
10951096
}
10961097
}

ts/input/tex/base/BaseMethods.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {MmlNode, TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
3535
import {MmlMsubsup} from '../../../core/MmlTree/MmlNodes/msubsup.js';
3636
import {MmlMunderover} from '../../../core/MmlTree/MmlNodes/munderover.js';
3737
import {Label} from '../Tags.js';
38-
import {em} from '../../../util/lengths.js';
38+
import {em, matchDimen} from '../../../util/lengths.js';
3939
import {entities} from '../../../util/Entities.js';
4040
import {lookup} from '../../../util/Options.js';
4141

@@ -1239,7 +1239,7 @@ BaseMethods.CrLaTeX = function(parser: TexParser, name: string, nobrackets: bool
12391239
}
12401240
if (parser.string.charAt(parser.i) === '[') {
12411241
let dim = parser.GetBrackets(name, '');
1242-
let [value, unit, ] = ParseUtil.matchDimen(dim);
1242+
let [value, unit, ] = matchDimen(dim);
12431243
// @test Custom Linebreak
12441244
if (dim && !value) {
12451245
// @test Dimension Error

ts/input/tex/bussproofs/BussproofsUtil.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525

2626
import ParseOptions from '../ParseOptions.js';
2727
import NodeUtil from '../NodeUtil.js';
28-
import ParseUtil from '../ParseUtil.js';
2928

3029
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
3130
import {Property} from '../../../core/Tree/Node.js';
3231
import {MathItem} from '../../../core/MathItem.js';
3332
import {MathDocument} from '../../../core/MathDocument.js';
33+
import {dimen2em, Em} from '../../../util/lengths.js';
3434

3535

3636
type MATHITEM = MathItem<any, any, any>;
@@ -270,12 +270,12 @@ let addSpace = function(config: ParseOptions, inf: MmlNode,
270270
if (NodeUtil.isType(mspace, 'mspace')) {
271271
NodeUtil.setAttribute(
272272
mspace, 'width',
273-
ParseUtil.Em(ParseUtil.dimen2em(
273+
Em(dimen2em(
274274
NodeUtil.getAttribute(mspace, 'width') as string) + space));
275275
return;
276276
}
277277
mspace = config.nodeFactory.create('node', 'mspace', [],
278-
{width: ParseUtil.Em(space)});
278+
{width: Em(space)});
279279
if (right) {
280280
inf.appendChild(mspace);
281281
return;
@@ -362,7 +362,7 @@ let adjustSequents = function(config: ParseOptions) {
362362
const addSequentSpace = function(config: ParseOptions, sequent: MmlNode,
363363
position: number, direction: string, width: number) {
364364
let mspace = config.nodeFactory.create('node', 'mspace', [],
365-
{width: ParseUtil.Em(width)});
365+
{width: Em(width)});
366366
if (direction === 'left') {
367367
let row = sequent.childNodes[position].childNodes[0] as MmlNode;
368368
mspace.parent = row;

ts/input/tex/mathtools/MathtoolsMethods.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import TexParser from '../TexParser.js';
3232
import TexError from '../TexError.js';
3333
import NodeUtil from '../NodeUtil.js';
3434
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
35-
import {length2em, em} from '../../../util/lengths.js';
35+
import {length2em, em, Em} from '../../../util/lengths.js';
3636
import {lookup} from '../../../util/Options.js';
3737
import NewcommandUtil from '../newcommand/NewcommandUtil.js';
3838
import NewcommandMethods from '../newcommand/NewcommandMethods.js';
@@ -74,7 +74,7 @@ export const MathtoolsMethods: Record<string, ParseMethod> = {
7474
align = parser.GetBrackets(`\\begin{${begin.getName()}}`, parser.options.mathtools['smallmatrix-align']);
7575
}
7676
return MathtoolsMethods.Array(
77-
parser, begin, open, close, align, ParseUtil.Em(1 / 3), '.2em', 'S', 1
77+
parser, begin, open, close, align, Em(1 / 3), '.2em', 'S', 1
7878
);
7979
},
8080

ts/input/tex/mathtools/MathtoolsUtil.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
3232

3333
import {MathtoolsMethods} from './MathtoolsMethods.js';
3434
import {PAIREDDELIMS} from './MathtoolsConfiguration.js';
35+
import { dimen2em, Em } from '../../../util/lengths.js';
3536

3637
/**
3738
* Utility functions for the Mathtools package.
@@ -98,10 +99,10 @@ export const MathtoolsUtil = {
9899
if (!mtable.isKind('mtable')) return;
99100
let rowspacing = mtable.attributes.get('rowspacing') as string;
100101
if (rowspacing) {
101-
const add = ParseUtil.dimen2em(spread);
102+
const add = dimen2em(spread);
102103
rowspacing = rowspacing
103104
.split(/ /)
104-
.map(s => ParseUtil.Em(Math.max(0, ParseUtil.dimen2em(s) + add)))
105+
.map(s => Em(Math.max(0, dimen2em(s) + add)))
105106
.join(' ');
106107
} else {
107108
rowspacing = spread;

ts/util/lengths.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,78 @@ export function px(m: number, M: number = -BIGDIMEN, em: number = 16): string {
155155
if (Math.abs(m) < .1) return '0';
156156
return m.toFixed(1).replace(/\.0$/, '') + 'px';
157157
}
158+
159+
// TODO (VS): Combine some of this with lengths in util.
160+
const emPerInch = 7.2;
161+
const pxPerInch = 72;
162+
// Note, the following are TeX CM font values.
163+
const UNIT_CASES: { [key: string]: (m: number) => number } = {
164+
em: (m) => m,
165+
ex: (m) => m * 0.43,
166+
pt: (m) => m / 10, // 10 pt to an em
167+
pc: (m) => m * 1.2, // 12 pt to a pc
168+
px: (m) => (m * emPerInch) / pxPerInch,
169+
in: (m) => m * emPerInch,
170+
cm: (m) => (m * emPerInch) / 2.54, // 2.54 cm to an inch
171+
mm: (m) => (m * emPerInch) / 25.4, // 10 mm to a cm
172+
mu: (m) => m / 18,
173+
};
174+
const num = '([-+]?([.,]\\d+|\\d+([.,]\\d*)?))';
175+
const unit = '(pt|em|ex|mu|px|mm|cm|in|pc)';
176+
const dimenEnd = RegExp('^\\s*' + num + '\\s*' + unit + '\\s*$');
177+
const dimenRest = RegExp('^\\s*' + num + '\\s*' + unit + ' ?');
178+
/**
179+
* Matches for a dimension argument.
180+
* @param {string} dim The argument.
181+
* @param {boolean} rest Allow for trailing garbage in the dimension string.
182+
* @return {[string, string, number]} The match result as (Anglosaxon) value,
183+
* unit name, length of matched string. The latter is interesting in the
184+
* case of trailing garbage.
185+
*/
186+
export function matchDimen(
187+
dim: string,
188+
rest: boolean = false
189+
): [string, string, number] {
190+
let match = dim.match(rest ? dimenRest : dimenEnd);
191+
return match
192+
? muReplace([match[1].replace(/,/, '.'), match[4], match[0].length])
193+
: [null, null, 0];
194+
}
195+
/**
196+
* Convert a dimension string into standard em dimension.
197+
* @param {string} dim The attribute string.
198+
* @return {number} The numerical value.
199+
*/
200+
export function dimen2em(dim: string): number {
201+
let [value, unit] = matchDimen(dim);
202+
let m = parseFloat(value || '1');
203+
let func = UNIT_CASES[unit];
204+
return func ? func(m) : 0;
205+
}
206+
/**
207+
* Transforms mu dimension to em if necessary.
208+
* @param {[string, string, number]} [value, unit, length] The dimension triple.
209+
* @return {[string, string, number]} [value, unit, length] The transformed triple.
210+
*/
211+
function muReplace([value, unit, length]: [string, string, number]): [
212+
string,
213+
string,
214+
number
215+
] {
216+
if (unit !== 'mu') {
217+
return [value, unit, length];
218+
}
219+
let em = Em(UNIT_CASES[unit](parseFloat(value || '1')));
220+
return [em.slice(0, -2), 'em', length];
221+
}
222+
/**
223+
* Turns a number into an em value.
224+
* @param {number} m The number.
225+
* @return {string} The em dimension string.
226+
*/
227+
export function Em(m: number): string {
228+
if (Math.abs(m) < 0.0006) {
229+
return '0em';
230+
}
231+
return m.toFixed(3).replace(/\.?0+$/, '') + 'em';
232+
}

ts/util/string.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,19 @@ export function isPercent(x: string): boolean {
8282
export function split(x: string): string[] {
8383
return x.trim().split(/\s+/);
8484
}
85+
86+
/**
87+
* Trim spaces from a string.
88+
* @param {string} text The string to clean.
89+
* @return {string} The string with leading and trailing whitespace removed.
90+
*/
91+
export function trimSpaces(text: string): string {
92+
if (typeof text !== 'string') {
93+
return text;
94+
}
95+
let TEXT = text.trim();
96+
if (TEXT.match(/\\$/) && text.match(/ $/)) {
97+
TEXT += ' ';
98+
}
99+
return TEXT;
100+
}

0 commit comments

Comments
 (0)