Skip to content

Commit

Permalink
fix: Remove circular dependency
Browse files Browse the repository at this point in the history
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

```
  • Loading branch information
edeustace committed Sep 9, 2021
1 parent b34d1c9 commit dbc3b42
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 98 deletions.
80 changes: 1 addition & 79 deletions ts/input/tex/ParseUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,87 +31,9 @@ import TexParser from './TexParser.js';
import TexError from './TexError.js';
import {entities} from '../../util/Entities.js';
import {MmlMunderover} from '../../core/MmlTree/MmlNodes/munderover.js';


import {Em} from '../../util/lengths.js';
namespace ParseUtil {

// TODO (VS): Combine some of this with lengths in util.
const emPerInch = 7.2;
const pxPerInch = 72;
// Note, the following are TeX CM font values.
const UNIT_CASES: {[key: string]: ((m: number) => number)} = {
'em': m => m,
'ex': m => m * .43,
'pt': m => m / 10, // 10 pt to an em
'pc': m => m * 1.2, // 12 pt to a pc
'px': m => m * emPerInch / pxPerInch,
'in': m => m * emPerInch,
'cm': m => m * emPerInch / 2.54, // 2.54 cm to an inch
'mm': m => m * emPerInch / 25.4, // 10 mm to a cm
'mu': m => m / 18,
};
const num = '([-+]?([.,]\\d+|\\d+([.,]\\d*)?))';
const unit = '(pt|em|ex|mu|px|mm|cm|in|pc)';
const dimenEnd = RegExp('^\\s*' + num + '\\s*' + unit + '\\s*$');
const dimenRest = RegExp('^\\s*' + num + '\\s*' + unit + ' ?');


/**
* Matches for a dimension argument.
* @param {string} dim The argument.
* @param {boolean} rest Allow for trailing garbage in the dimension string.
* @return {[string, string, number]} The match result as (Anglosaxon) value,
* unit name, length of matched string. The latter is interesting in the
* case of trailing garbage.
*/
export function matchDimen(
dim: string, rest: boolean = false): [string, string, number] {
let match = dim.match(rest ? dimenRest : dimenEnd);
return match ?
muReplace([match[1].replace(/,/, '.'), match[4], match[0].length]) :
[null, null, 0];
}


/**
* Transforms mu dimension to em if necessary.
* @param {[string, string, number]} [value, unit, length] The dimension triple.
* @return {[string, string, number]} [value, unit, length] The transformed triple.
*/
function muReplace([value, unit, length]: [string, string, number]): [string, string, number] {
if (unit !== 'mu') {
return [value, unit, length];
}
let em = Em(UNIT_CASES[unit](parseFloat(value || '1')));
return [em.slice(0, -2), 'em', length];
}


/**
* Convert a dimension string into standard em dimension.
* @param {string} dim The attribute string.
* @return {number} The numerical value.
*/
export function dimen2em(dim: string): number {
let [value, unit] = matchDimen(dim);
let m = parseFloat(value || '1');
let func = UNIT_CASES[unit];
return func ? func(m) : 0;
}


/**
* Turns a number into an em value.
* @param {number} m The number.
* @return {string} The em dimension string.
*/
export function Em(m: number): string {
if (Math.abs(m) < .0006) {
return '0em';
}
return m.toFixed(3).replace(/\.?0+$/, '') + 'em';
}


/**
* Takes an array of numbers and returns a space-separated string of em values.
Expand Down
9 changes: 5 additions & 4 deletions ts/input/tex/TexParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
* @author [email protected] (Volker Sorge)
*/

import ParseUtil from './ParseUtil.js';
import {HandlerType} from './MapHandler.js';
import Stack from './Stack.js';
import StackItemFactory from './StackItemFactory.js';
Expand All @@ -35,6 +34,8 @@ import ParseOptions from './ParseOptions.js';
import {StackItem, EnvList} from './StackItem.js';
import {Symbol} from './Symbol.js';
import {OptionList} from '../../util/Options.js';
import {matchDimen} from '../../util/lengths.js';
import {trimSpaces} from '../../util/string.js';


/**
Expand Down Expand Up @@ -392,15 +393,15 @@ export default class TexParser {
public GetDimen(name: string): string {
if (this.GetNext() === '{') {
let dimen = this.GetArgument(name);
let [value, unit] = ParseUtil.matchDimen(dimen);
let [value, unit] = matchDimen(dimen);
if (value) {
// @test Raise In Line, Lower 2, (Raise|Lower) Negative
return value + unit;
}
} else {
// @test Above, Raise, Lower, Modulo, Above With Delims
let dimen = this.string.slice(this.i);
let [value, unit, length] = ParseUtil.matchDimen(dimen, true);
let [value, unit, length] = matchDimen(dimen, true);
if (value) {
this.i += length;
return value + unit;
Expand Down Expand Up @@ -475,7 +476,7 @@ export default class TexParser {
* @return {string} The delimiter.
*/
public GetDelimiterArg(name: string): string {
let c = ParseUtil.trimSpaces(this.GetArgument(name));
let c = trimSpaces(this.GetArgument(name));
if (c === '') {
return null;
}
Expand Down
3 changes: 2 additions & 1 deletion ts/input/tex/ams/AmsMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {FlalignItem} from './AmsItems.js';
import BaseMethods from '../base/BaseMethods.js';
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
import {MmlMunderover} from '../../../core/MmlTree/MmlNodes/munderover.js';
import {Em} from '../../../util/lengths.js';


// Namespace
Expand Down Expand Up @@ -289,7 +290,7 @@ AmsMethods.MultiIntegral = function(parser: TexParser, name: string,
*/
AmsMethods.xArrow = function(parser: TexParser, name: string,
chr: number, l: number, r: number) {
let def = {width: '+' + ParseUtil.Em((l + r) / 18), lspace: ParseUtil.Em(l / 18)};
let def = {width: '+' + Em((l + r) / 18), lspace: Em(l / 18)};
let bot = parser.GetBrackets(name);
let first = parser.ParseArg(name);
let dstrut = parser.create('node', 'mspace', [], {depth: '.25em'});
Expand Down
9 changes: 5 additions & 4 deletions ts/input/tex/base/BaseItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import NodeUtil from '../NodeUtil.js';
import {Property} from '../../../core/Tree/Node.js';
import StackItemFactory from '../StackItemFactory.js';
import {CheckType, BaseItem, StackItem, EnvList} from '../StackItem.js';
import { dimen2em, Em } from '../../../util/lengths.js';


/**
Expand Down Expand Up @@ -1082,15 +1083,15 @@ export class ArrayItem extends BaseItem {
const rows = (this.arraydef['rowspacing'] as string).split(/ /);
if (!this.getProperty('rowspacing')) {
// @test Array Custom Linebreak
let dimem = ParseUtil.dimen2em(rows[0]);
let dimem = dimen2em(rows[0]);
this.setProperty('rowspacing', dimem);
}
const rowspacing = this.getProperty('rowspacing') as number;
while (rows.length < this.table.length) {
rows.push(ParseUtil.Em(rowspacing));
rows.push(Em(rowspacing));
}
rows[this.table.length - 1] = ParseUtil.Em(
Math.max(0, rowspacing + ParseUtil.dimen2em(spacing)));
rows[this.table.length - 1] = Em(
Math.max(0, rowspacing + dimen2em(spacing)));
this.arraydef['rowspacing'] = rows.join(' ');
}
}
Expand Down
4 changes: 2 additions & 2 deletions ts/input/tex/base/BaseMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {MmlNode, TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
import {MmlMsubsup} from '../../../core/MmlTree/MmlNodes/msubsup.js';
import {MmlMunderover} from '../../../core/MmlTree/MmlNodes/munderover.js';
import {Label} from '../Tags.js';
import {em} from '../../../util/lengths.js';
import {em, matchDimen} from '../../../util/lengths.js';
import {entities} from '../../../util/Entities.js';
import {lookup} from '../../../util/Options.js';

Expand Down Expand Up @@ -1239,7 +1239,7 @@ BaseMethods.CrLaTeX = function(parser: TexParser, name: string, nobrackets: bool
}
if (parser.string.charAt(parser.i) === '[') {
let dim = parser.GetBrackets(name, '');
let [value, unit, ] = ParseUtil.matchDimen(dim);
let [value, unit, ] = matchDimen(dim);
// @test Custom Linebreak
if (dim && !value) {
// @test Dimension Error
Expand Down
8 changes: 4 additions & 4 deletions ts/input/tex/bussproofs/BussproofsUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@

import ParseOptions from '../ParseOptions.js';
import NodeUtil from '../NodeUtil.js';
import ParseUtil from '../ParseUtil.js';

import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
import {Property} from '../../../core/Tree/Node.js';
import {MathItem} from '../../../core/MathItem.js';
import {MathDocument} from '../../../core/MathDocument.js';
import {dimen2em, Em} from '../../../util/lengths.js';


type MATHITEM = MathItem<any, any, any>;
Expand Down Expand Up @@ -270,12 +270,12 @@ let addSpace = function(config: ParseOptions, inf: MmlNode,
if (NodeUtil.isType(mspace, 'mspace')) {
NodeUtil.setAttribute(
mspace, 'width',
ParseUtil.Em(ParseUtil.dimen2em(
Em(dimen2em(
NodeUtil.getAttribute(mspace, 'width') as string) + space));
return;
}
mspace = config.nodeFactory.create('node', 'mspace', [],
{width: ParseUtil.Em(space)});
{width: Em(space)});
if (right) {
inf.appendChild(mspace);
return;
Expand Down Expand Up @@ -362,7 +362,7 @@ let adjustSequents = function(config: ParseOptions) {
const addSequentSpace = function(config: ParseOptions, sequent: MmlNode,
position: number, direction: string, width: number) {
let mspace = config.nodeFactory.create('node', 'mspace', [],
{width: ParseUtil.Em(width)});
{width: Em(width)});
if (direction === 'left') {
let row = sequent.childNodes[position].childNodes[0] as MmlNode;
mspace.parent = row;
Expand Down
4 changes: 2 additions & 2 deletions ts/input/tex/mathtools/MathtoolsMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import TexParser from '../TexParser.js';
import TexError from '../TexError.js';
import NodeUtil from '../NodeUtil.js';
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
import {length2em, em} from '../../../util/lengths.js';
import {length2em, em, Em} from '../../../util/lengths.js';
import {lookup} from '../../../util/Options.js';
import NewcommandUtil from '../newcommand/NewcommandUtil.js';
import NewcommandMethods from '../newcommand/NewcommandMethods.js';
Expand Down Expand Up @@ -74,7 +74,7 @@ export const MathtoolsMethods: Record<string, ParseMethod> = {
align = parser.GetBrackets(`\\begin{${begin.getName()}}`, parser.options.mathtools['smallmatrix-align']);
}
return MathtoolsMethods.Array(
parser, begin, open, close, align, ParseUtil.Em(1 / 3), '.2em', 'S', 1
parser, begin, open, close, align, Em(1 / 3), '.2em', 'S', 1
);
},

Expand Down
5 changes: 3 additions & 2 deletions ts/input/tex/mathtools/MathtoolsUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {MmlNode} from '../../../core/MmlTree/MmlNode.js';

import {MathtoolsMethods} from './MathtoolsMethods.js';
import {PAIREDDELIMS} from './MathtoolsConfiguration.js';
import { dimen2em, Em } from '../../../util/lengths.js';

/**
* Utility functions for the Mathtools package.
Expand Down Expand Up @@ -98,10 +99,10 @@ export const MathtoolsUtil = {
if (!mtable.isKind('mtable')) return;
let rowspacing = mtable.attributes.get('rowspacing') as string;
if (rowspacing) {
const add = ParseUtil.dimen2em(spread);
const add = dimen2em(spread);
rowspacing = rowspacing
.split(/ /)
.map(s => ParseUtil.Em(Math.max(0, ParseUtil.dimen2em(s) + add)))
.map(s => Em(Math.max(0, dimen2em(s) + add)))
.join(' ');
} else {
rowspacing = spread;
Expand Down
75 changes: 75 additions & 0 deletions ts/util/lengths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,78 @@ export function px(m: number, M: number = -BIGDIMEN, em: number = 16): string {
if (Math.abs(m) < .1) return '0';
return m.toFixed(1).replace(/\.0$/, '') + 'px';
}

// TODO (VS): Combine some of this with lengths in util.
const emPerInch = 7.2;
const pxPerInch = 72;
// Note, the following are TeX CM font values.
const UNIT_CASES: { [key: string]: (m: number) => number } = {
em: (m) => m,
ex: (m) => m * 0.43,
pt: (m) => m / 10, // 10 pt to an em
pc: (m) => m * 1.2, // 12 pt to a pc
px: (m) => (m * emPerInch) / pxPerInch,
in: (m) => m * emPerInch,
cm: (m) => (m * emPerInch) / 2.54, // 2.54 cm to an inch
mm: (m) => (m * emPerInch) / 25.4, // 10 mm to a cm
mu: (m) => m / 18,
};
const num = '([-+]?([.,]\\d+|\\d+([.,]\\d*)?))';
const unit = '(pt|em|ex|mu|px|mm|cm|in|pc)';
const dimenEnd = RegExp('^\\s*' + num + '\\s*' + unit + '\\s*$');
const dimenRest = RegExp('^\\s*' + num + '\\s*' + unit + ' ?');
/**
* Matches for a dimension argument.
* @param {string} dim The argument.
* @param {boolean} rest Allow for trailing garbage in the dimension string.
* @return {[string, string, number]} The match result as (Anglosaxon) value,
* unit name, length of matched string. The latter is interesting in the
* case of trailing garbage.
*/
export function matchDimen(
dim: string,
rest: boolean = false
): [string, string, number] {
let match = dim.match(rest ? dimenRest : dimenEnd);
return match
? muReplace([match[1].replace(/,/, '.'), match[4], match[0].length])
: [null, null, 0];
}
/**
* Convert a dimension string into standard em dimension.
* @param {string} dim The attribute string.
* @return {number} The numerical value.
*/
export function dimen2em(dim: string): number {
let [value, unit] = matchDimen(dim);
let m = parseFloat(value || '1');
let func = UNIT_CASES[unit];
return func ? func(m) : 0;
}
/**
* Transforms mu dimension to em if necessary.
* @param {[string, string, number]} [value, unit, length] The dimension triple.
* @return {[string, string, number]} [value, unit, length] The transformed triple.
*/
function muReplace([value, unit, length]: [string, string, number]): [
string,
string,
number
] {
if (unit !== 'mu') {
return [value, unit, length];
}
let em = Em(UNIT_CASES[unit](parseFloat(value || '1')));
return [em.slice(0, -2), 'em', length];
}
/**
* Turns a number into an em value.
* @param {number} m The number.
* @return {string} The em dimension string.
*/
export function Em(m: number): string {
if (Math.abs(m) < 0.0006) {
return '0em';
}
return m.toFixed(3).replace(/\.?0+$/, '') + 'em';
}
16 changes: 16 additions & 0 deletions ts/util/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,19 @@ export function isPercent(x: string): boolean {
export function split(x: string): string[] {
return x.trim().split(/\s+/);
}

/**
* Trim spaces from a string.
* @param {string} text The string to clean.
* @return {string} The string with leading and trailing whitespace removed.
*/
export function trimSpaces(text: string): string {
if (typeof text !== 'string') {
return text;
}
let TEXT = text.trim();
if (TEXT.match(/\\$/) && text.match(/ $/)) {
TEXT += ' ';
}
return TEXT;
}

0 comments on commit dbc3b42

Please sign in to comment.