Skip to content

Commit dad5b94

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 by moving the functions in ParseUtil that TexParser used into 2 new namespaces. + DimensionUtil -> matchDimen + StringUtil -> trimSpaces I'm trying to be consistent with how the modules are laid out.
1 parent 41565a9 commit dad5b94

File tree

4 files changed

+141
-81
lines changed

4 files changed

+141
-81
lines changed

ts/input/tex/DimensionUtil.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*************************************************************
2+
*
3+
* Copyright (c) 2009-2021 The MathJax Consortium
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
namespace DimensionUtil {
18+
// TODO (VS): Combine some of this with lengths in util.
19+
const emPerInch = 7.2;
20+
const pxPerInch = 72;
21+
// Note, the following are TeX CM font values.
22+
const UNIT_CASES: { [key: string]: (m: number) => number } = {
23+
em: (m) => m,
24+
ex: (m) => m * 0.43,
25+
pt: (m) => m / 10, // 10 pt to an em
26+
pc: (m) => m * 1.2, // 12 pt to a pc
27+
px: (m) => (m * emPerInch) / pxPerInch,
28+
in: (m) => m * emPerInch,
29+
cm: (m) => (m * emPerInch) / 2.54, // 2.54 cm to an inch
30+
mm: (m) => (m * emPerInch) / 25.4, // 10 mm to a cm
31+
mu: (m) => m / 18,
32+
};
33+
const num = '([-+]?([.,]\\d+|\\d+([.,]\\d*)?))';
34+
const unit = '(pt|em|ex|mu|px|mm|cm|in|pc)';
35+
const dimenEnd = RegExp('^\\s*' + num + '\\s*' + unit + '\\s*$');
36+
const dimenRest = RegExp('^\\s*' + num + '\\s*' + unit + ' ?');
37+
/**
38+
* Matches for a dimension argument.
39+
* @param {string} dim The argument.
40+
* @param {boolean} rest Allow for trailing garbage in the dimension string.
41+
* @return {[string, string, number]} The match result as (Anglosaxon) value,
42+
* unit name, length of matched string. The latter is interesting in the
43+
* case of trailing garbage.
44+
*/
45+
export function matchDimen(
46+
dim: string,
47+
rest: boolean = false
48+
): [string, string, number] {
49+
let match = dim.match(rest ? dimenRest : dimenEnd);
50+
return match
51+
? muReplace([match[1].replace(/,/, '.'), match[4], match[0].length])
52+
: [null, null, 0];
53+
}
54+
55+
/**
56+
* Convert a dimension string into standard em dimension.
57+
* @param {string} dim The attribute string.
58+
* @return {number} The numerical value.
59+
*/
60+
export function dimen2em(dim: string): number {
61+
let [value, unit] = matchDimen(dim);
62+
let m = parseFloat(value || '1');
63+
let func = UNIT_CASES[unit];
64+
return func ? func(m) : 0;
65+
}
66+
67+
/**
68+
* Transforms mu dimension to em if necessary.
69+
* @param {[string, string, number]} [value, unit, length] The dimension triple.
70+
* @return {[string, string, number]} [value, unit, length] The transformed triple.
71+
*/
72+
function muReplace([value, unit, length]: [string, string, number]): [
73+
string,
74+
string,
75+
number
76+
] {
77+
if (unit !== 'mu') {
78+
return [value, unit, length];
79+
}
80+
let em = Em(UNIT_CASES[unit](parseFloat(value || '1')));
81+
return [em.slice(0, -2), 'em', length];
82+
}
83+
84+
/**
85+
* Turns a number into an em value.
86+
* @param {number} m The number.
87+
* @return {string} The em dimension string.
88+
*/
89+
export function Em(m: number): string {
90+
if (Math.abs(m) < 0.0006) {
91+
return '0em';
92+
}
93+
return m.toFixed(3).replace(/\.?0+$/, '') + 'em';
94+
}
95+
}
96+
97+
export default DimensionUtil;

ts/input/tex/ParseUtil.ts

Lines changed: 5 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -31,87 +31,15 @@ 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-
34+
import DimensionUtil from './DimensionUtil';
3535

3636
namespace ParseUtil {
3737

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-
}
38+
export const matchDimen = DimensionUtil.matchDimen;
11439

40+
export const dimen2em = DimensionUtil.dimen2em;
41+
42+
export const Em = DimensionUtil.Em;
11543

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

ts/input/tex/StringUtil.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*************************************************************
2+
*
3+
* Copyright (c) 2009-2021 The MathJax Consortium
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
namespace StringUtil {
18+
/**
19+
* Trim spaces from a string.
20+
* @param {string} text The string to clean.
21+
* @return {string} The string with leading and trailing whitespace removed.
22+
*/
23+
export function trimSpaces(text: string): string {
24+
if (typeof text !== 'string') {
25+
return text;
26+
}
27+
let TEXT = text.trim();
28+
if (TEXT.match(/\\$/) && text.match(/ $/)) {
29+
TEXT += ' ';
30+
}
31+
return TEXT;
32+
}
33+
}
34+
export default StringUtil;

ts/input/tex/TexParser.ts

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

26-
import ParseUtil from './ParseUtil.js';
26+
import DimensionUtil from './DimensionUtil';
27+
import StringUtil from './StringUtil';
2728
import {HandlerType} from './MapHandler.js';
2829
import Stack from './Stack.js';
2930
import StackItemFactory from './StackItemFactory.js';
@@ -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] = DimensionUtil.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] = DimensionUtil.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 = StringUtil.trimSpaces(this.GetArgument(name));
479480
if (c === '') {
480481
return null;
481482
}

0 commit comments

Comments
 (0)