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
25 changes: 12 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions tests/length.test.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import {jest} from '@jest/globals';
import {ParseUtil} from '../mjs/input/tex/ParseUtil.js';
import {UnitUtil} from '../mjs/input/tex/UnitUtil.js';
import * as Length from '../mjs/util/lengths.js';

// These methods will be rewritten into non-ParseUtil ones.
function convertLength(unit, num) {
return ParseUtil.UNIT_CASES.get(unit) * (num);
return UnitUtil.UNIT_CASES.get(unit) * (num);
}

function matchDimension(str) {
return ParseUtil.matchDimen(str);
return UnitUtil.matchDimen(str);
}

function convertDimension(str) {
return ParseUtil.dimen2em(str);
return UnitUtil.dimen2em(str);
}

function convertLengthDim(str) {
return Length.length2em(str);
}

function convertEm(num) {
return ParseUtil.em(num);
return UnitUtil.em(num);
}

describe('Length conversion', () => {
Expand Down Expand Up @@ -125,7 +125,7 @@ describe.skip('Dimension conversion comparison', () => {

// Useful for the IEEE case.
describe('Adds pi unit', () => {
beforeAll(() => ParseUtil.UNIT_CASES.set('pi', 1 / 10));
beforeAll(() => UnitUtil.UNIT_CASES.set('pi', 1 / 10));
it('pi', () => expect(convertLength('pi', 9)).toBe(0.9));
it('9pi', () => expect(matchDimension('9pi')).toEqual(['9', 'pi', 3]));
it('10pi', () => expect(matchDimension('10pi')).toEqual(['10', 'pi', 4]));
Expand Down
3 changes: 2 additions & 1 deletion ts/input/tex/ColumnParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import TexParser from './TexParser.js';
import TexError from './TexError.js';
import {lookup} from '../../util/Options.js';
import {ParseUtil} from './ParseUtil.js';
import { UnitUtil } from './UnitUtil.js';

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

Expand Down Expand Up @@ -233,7 +234,7 @@ export class ColumnParser {
*/
public getDimen(state: ColumnState) {
const dim = this.getBraces(state) || '';
if (!ParseUtil.matchDimen(dim)[0]) {
if (!UnitUtil.matchDimen(dim)[0]) {
throw new TexError('MissingColumnDimOrUnits',
'Missing dimension or its units for %1 column declaration', state.c);
}
Expand Down
153 changes: 4 additions & 149 deletions ts/input/tex/ParseUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,79 +31,7 @@ import TexParser from './TexParser.js';
import TexError from './TexError.js';
import {entities} from '../../util/Entities.js';
import {MmlMunderover} from '../../core/MmlTree/MmlNodes/munderover.js';


class UnitMap extends Map<string, number> {

public num = '([-+]?([.,]\\d+|\\d+([.,]\\d*)?))';
public unit = '';
public dimenEnd = /./;
public dimenRest = /./;

/**
* @override
*/
constructor(map: [string, number][]) {
super(map);
this.updateDimen();
}

/**
* Updates the regular expressions for the unit.
*/
private updateDimen() {
this.unit = `(${Array.from(this.keys()).join('|')})`;
this.dimenEnd = RegExp('^\\s*' + this.num + '\\s*' + this.unit + '\\s*$');
this.dimenRest = RegExp('^\\s*' + this.num + '\\s*' + this.unit + ' ?');
}

/**
* @override
*/
public set(name: string, ems: number) {
super.set(name, ems);
this.updateDimen();
return this;
}

/**
* Retrieves conversion value for an existing dimension. If the dimension does
* not exist, `pt` is used, similar to TeX behaviour. However, no error is thrown.
*
* @override
*/
public get(name: string) {
return super.get(name) || super.get('pt');
}

/**
* @override
*/
public delete(name: string) {
if (super.delete(name)) {
this.updateDimen();
return true;
}
return false;
}

}

const emPerInch = 7.2;
const pxPerInch = 72;

/**
* 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 = ParseUtil.em(ParseUtil.UNIT_CASES.get(unit) * (parseFloat(value || '1')));
return [em.slice(0, -2), 'em', length];
}
import { UnitUtil } from './UnitUtil.js';


/**
Expand Down Expand Up @@ -157,7 +85,7 @@ export const KeyValueTypes: {[name: string]: KeyValueType<any> | ((data: any) =>
),
dimen: new KeyValueType<string>(
'dimen',
(value) => ParseUtil.matchDimen(value)[0] !== null,
(value) => UnitUtil.matchDimen(value)[0] !== null,
(value) => value
)
};
Expand Down Expand Up @@ -271,62 +199,6 @@ function readValue(text: string, end: string[],

export const ParseUtil = {

// Note, the following are TeX CM font values.
UNIT_CASES: new UnitMap([
['em', 1],
['ex', .43],
['pt', 1 / 10], // 10 pt to an em
['pc', 1.2], // 12 pt to a pc
['px', emPerInch / pxPerInch],
['in', emPerInch],
['cm', emPerInch / 2.54], // 2.54 cm to an inch
['mm', emPerInch / 25.4], // 10 mm to a cm
['mu', 1 / 18],
]),


/**
* 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.
*/
matchDimen(
dim: string, rest: boolean = false): [string, string, number] {
let match = dim.match(rest ? ParseUtil.UNIT_CASES.dimenRest : ParseUtil.UNIT_CASES.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.
*/
dimen2em(dim: string): number {
let [value, unit] = ParseUtil.matchDimen(dim);
let m = parseFloat(value || '1');
let factor = ParseUtil.UNIT_CASES.get(unit);
return factor ? factor * (m) : 0;
},


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

// Above will move into lenghts
//
// Remainder: Parse Utililities
Expand All @@ -337,7 +209,7 @@ export const ParseUtil = {
* @return {string} The numbers with em units, separated by spaces.
*/
cols(...W: number[]): string {
return W.map(n => ParseUtil.em(n)).join(' ');
return W.map(n => UnitUtil.em(n)).join(' ');
},


Expand Down Expand Up @@ -638,23 +510,6 @@ export const ParseUtil = {
}
},

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


/**
* Sets alignment in array definitions.
* @param {ArrayItem} array The array item.
Expand All @@ -665,7 +520,7 @@ export const ParseUtil = {
setArrayAlign(array: ArrayItem, align: string, parser?: TexParser): ArrayItem {
// @test Array1, Array2, Array Test
if (!parser) {
align = ParseUtil.trimSpaces(align || '');
align = UnitUtil.trimSpaces(align || '');
}
if (align === 't') {
array.arraydef.align = 'baseline 1';
Expand Down
8 changes: 4 additions & 4 deletions ts/input/tex/TexParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* @author v.sorge@mathjax.org (Volker Sorge)
*/

import {ParseUtil} from './ParseUtil.js';
import {UnitUtil} from './UnitUtil.js';
import {HandlerType} from './MapHandler.js';
import Stack from './Stack.js';
import StackItemFactory from './StackItemFactory.js';
Expand Down Expand Up @@ -415,15 +415,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] = UnitUtil.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] = UnitUtil.matchDimen(dimen, true);
if (value) {
this.i += length;
return value + unit;
Expand Down Expand Up @@ -498,7 +498,7 @@ export default class TexParser {
* @return {string} The delimiter.
*/
public GetDelimiterArg(name: string): string {
let c = ParseUtil.trimSpaces(this.GetArgument(name));
let c = UnitUtil.trimSpaces(this.GetArgument(name));
if (c === '') {
return null;
}
Expand Down
Loading