diff --git a/ts/input/tex/ColumnParser.ts b/ts/input/tex/ColumnParser.ts index 82287d2e1..f35751363 100644 --- a/ts/input/tex/ColumnParser.ts +++ b/ts/input/tex/ColumnParser.ts @@ -25,7 +25,7 @@ import {ArrayItem} from './base/BaseItems.js'; import TexParser from './TexParser.js'; import TexError from './TexError.js'; import {lookup} from '../../util/Options.js'; -import ParseUtil from './ParseUtil.js'; +import * as ParseUtil from './ParseUtil.js'; /***********************************************************************/ diff --git a/ts/input/tex/ParseMethods.ts b/ts/input/tex/ParseMethods.ts index ea7e906d4..950cda900 100644 --- a/ts/input/tex/ParseMethods.ts +++ b/ts/input/tex/ParseMethods.ts @@ -27,7 +27,7 @@ import TexParser from './TexParser.js'; import NodeUtil from './NodeUtil.js'; import {TexConstant} from './TexConstants.js'; import {MmlNode} from '../../core/MmlTree/MmlNode.js'; -import ParseUtil from './ParseUtil.js'; +import * as ParseUtil from './ParseUtil.js'; const MATHVARIANT = TexConstant.Variant; diff --git a/ts/input/tex/ParseUtil.ts b/ts/input/tex/ParseUtil.ts index 8eb04b0c2..ef54d9a7b 100644 --- a/ts/input/tex/ParseUtil.ts +++ b/ts/input/tex/ParseUtil.ts @@ -33,669 +33,667 @@ import {entities} from '../../util/Entities.js'; import {MmlMunderover} from '../../core/MmlTree/MmlNodes/munderover.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. - export const UNIT_CASES: Map = new Map([ - ['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], - ]); - - const num = '([-+]?([.,]\\d+|\\d+([.,]\\d*)?))'; - const unit = () => `(${Array.from(UNIT_CASES.keys()).join('|')})`; - 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.get(unit) * (parseFloat(value || '1'))); - return [em.slice(0, -2), 'em', length]; +// 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. +export const UNIT_CASES: Map = new Map([ + ['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], +]); + +const num = '([-+]?([.,]\\d+|\\d+([.,]\\d*)?))'; +const unit = () => `(${Array.from(UNIT_CASES.keys()).join('|')})`; +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.get(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.get(unit); + return func ? func * (m) : 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.get(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'; +} - /** - * 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. - * @param {number[]} W The widths to be turned into em values - * @return {string} The numbers with em units, separated by spaces. - */ - export function cols(...W: number[]): string { - return W.map(n => Em(n)).join(' '); - } - - - /** - * Create an mrow that has stretchy delimiters at either end, as needed - * @param {ParseOptions} configuration Current parse options. - * @param {string} open The opening fence. - * @param {MmlNode} mml The enclosed node. - * @param {string} close The closing fence. - * @param {string=} big Bigg command. - */ - export function fenced(configuration: ParseOptions, open: string, mml: MmlNode, - close: string, big: string = '', color: string = '') { - // @test Fenced, Fenced3 - let nf = configuration.nodeFactory; - let mrow = nf.create('node', 'mrow', [], - {open: open, close: close, texClass: TEXCLASS.INNER}); - let mo; - if (big) { - mo = new TexParser('\\' + big + 'l' + open, configuration.parser.stack.env, configuration).mml(); - } else { - let openNode = nf.create('text', open); - mo = nf.create('node', 'mo', [], - {fence: true, stretchy: true, symmetric: true, texClass: TEXCLASS.OPEN}, - openNode); - } - NodeUtil.appendChildren(mrow, [mo, mml]); - if (big) { - mo = new TexParser('\\' + big + 'r' + close, configuration.parser.stack.env, configuration).mml(); - } else { - let closeNode = nf.create('text', close); - mo = nf.create('node', 'mo', [], - {fence: true, stretchy: true, symmetric: true, texClass: TEXCLASS.CLOSE}, - closeNode); - } - color && mo.attributes.set('mathcolor', color); - NodeUtil.appendChildren(mrow, [mo]); - return mrow; - } - - - /** - * Create an mrow that has \\mathchoice using \\bigg and \\big for the delimiters. - * @param {ParseOptions} configuration The current parse options. - * @param {string} open The opening fence. - * @param {MmlNode} mml The enclosed node. - * @param {string} close The closing fence. - * @return {MmlNode} The mrow node. - */ - export function fixedFence(configuration: ParseOptions, open: string, - mml: MmlNode, close: string): MmlNode { - // @test Choose, Over With Delims, Above with Delims - let mrow = configuration.nodeFactory.create('node', - 'mrow', [], {open: open, close: close, texClass: TEXCLASS.ORD}); - if (open) { - NodeUtil.appendChildren(mrow, [mathPalette(configuration, open, 'l')]); - } - if (NodeUtil.isType(mml, 'mrow')) { - NodeUtil.appendChildren(mrow, NodeUtil.getChildren(mml)); - } else { - NodeUtil.appendChildren(mrow, [mml]); - } - if (close) { - NodeUtil.appendChildren(mrow, [mathPalette(configuration, close, 'r')]); - } - return mrow; - } - - - /** - * Generates a mathchoice element for fences. These will be resolved later, - * once the position, and therefore size, of the of the fenced expression is - * known. - * @param {ParseOptions} configuration The current parse otpions. - * @param {string} fence The fence. - * @param {string} side The side of the fence (l or r). - * @return {MmlNode} The mathchoice node. - */ - export function mathPalette(configuration: ParseOptions, fence: string, - side: string): MmlNode { - if (fence === '{' || fence === '}') { - fence = '\\' + fence; - } - let D = '{\\bigg' + side + ' ' + fence + '}'; - let T = '{\\big' + side + ' ' + fence + '}'; - return new TexParser('\\mathchoice' + D + T + T + T, {}, configuration).mml(); - } - - - /** - * If the initial child, skipping any initial space or - * empty braces (TeXAtom with child being an empty inferred row), - * is an , precede it by an empty to force the to - * be infix. - * @param {ParseOptions} configuration The current parse options. - * @param {MmlNode[]} nodes The row of nodes to scan for an initial - */ - export function fixInitialMO(configuration: ParseOptions, nodes: MmlNode[]) { - for (let i = 0, m = nodes.length; i < m; i++) { - let child = nodes[i]; - if (child && (!NodeUtil.isType(child, 'mspace') && - (!NodeUtil.isType(child, 'TeXAtom') || - (NodeUtil.getChildren(child)[0] && - NodeUtil.getChildren(NodeUtil.getChildren(child)[0]).length)))) { - if (NodeUtil.isEmbellished(child) || - (NodeUtil.isType(child, 'TeXAtom') && NodeUtil.getTexClass(child) === TEXCLASS.REL)) { - let mi = configuration.nodeFactory.create('node', 'mi'); - nodes.unshift(mi); - } - break; +/** + * Takes an array of numbers and returns a space-separated string of em values. + * @param {number[]} W The widths to be turned into em values + * @return {string} The numbers with em units, separated by spaces. + */ +export function cols(...W: number[]): string { + return W.map(n => Em(n)).join(' '); +} + + +/** + * Create an mrow that has stretchy delimiters at either end, as needed + * @param {ParseOptions} configuration Current parse options. + * @param {string} open The opening fence. + * @param {MmlNode} mml The enclosed node. + * @param {string} close The closing fence. + * @param {string=} big Bigg command. + */ +export function fenced(configuration: ParseOptions, open: string, mml: MmlNode, + close: string, big: string = '', color: string = '') { + // @test Fenced, Fenced3 + let nf = configuration.nodeFactory; + let mrow = nf.create('node', 'mrow', [], + {open: open, close: close, texClass: TEXCLASS.INNER}); + let mo; + if (big) { + mo = new TexParser('\\' + big + 'l' + open, configuration.parser.stack.env, configuration).mml(); + } else { + let openNode = nf.create('text', open); + mo = nf.create('node', 'mo', [], + {fence: true, stretchy: true, symmetric: true, texClass: TEXCLASS.OPEN}, + openNode); + } + NodeUtil.appendChildren(mrow, [mo, mml]); + if (big) { + mo = new TexParser('\\' + big + 'r' + close, configuration.parser.stack.env, configuration).mml(); + } else { + let closeNode = nf.create('text', close); + mo = nf.create('node', 'mo', [], + {fence: true, stretchy: true, symmetric: true, texClass: TEXCLASS.CLOSE}, + closeNode); + } + color && mo.attributes.set('mathcolor', color); + NodeUtil.appendChildren(mrow, [mo]); + return mrow; +} + + +/** + * Create an mrow that has \\mathchoice using \\bigg and \\big for the delimiters. + * @param {ParseOptions} configuration The current parse options. + * @param {string} open The opening fence. + * @param {MmlNode} mml The enclosed node. + * @param {string} close The closing fence. + * @return {MmlNode} The mrow node. + */ +export function fixedFence(configuration: ParseOptions, open: string, + mml: MmlNode, close: string): MmlNode { + // @test Choose, Over With Delims, Above with Delims + let mrow = configuration.nodeFactory.create('node', + 'mrow', [], {open: open, close: close, texClass: TEXCLASS.ORD}); + if (open) { + NodeUtil.appendChildren(mrow, [mathPalette(configuration, open, 'l')]); + } + if (NodeUtil.isType(mml, 'mrow')) { + NodeUtil.appendChildren(mrow, NodeUtil.getChildren(mml)); + } else { + NodeUtil.appendChildren(mrow, [mml]); + } + if (close) { + NodeUtil.appendChildren(mrow, [mathPalette(configuration, close, 'r')]); + } + return mrow; +} + + +/** + * Generates a mathchoice element for fences. These will be resolved later, + * once the position, and therefore size, of the of the fenced expression is + * known. + * @param {ParseOptions} configuration The current parse otpions. + * @param {string} fence The fence. + * @param {string} side The side of the fence (l or r). + * @return {MmlNode} The mathchoice node. + */ +export function mathPalette(configuration: ParseOptions, fence: string, + side: string): MmlNode { + if (fence === '{' || fence === '}') { + fence = '\\' + fence; + } + let D = '{\\bigg' + side + ' ' + fence + '}'; + let T = '{\\big' + side + ' ' + fence + '}'; + return new TexParser('\\mathchoice' + D + T + T + T, {}, configuration).mml(); +} + + +/** + * If the initial child, skipping any initial space or + * empty braces (TeXAtom with child being an empty inferred row), + * is an , precede it by an empty to force the to + * be infix. + * @param {ParseOptions} configuration The current parse options. + * @param {MmlNode[]} nodes The row of nodes to scan for an initial + */ +export function fixInitialMO(configuration: ParseOptions, nodes: MmlNode[]) { + for (let i = 0, m = nodes.length; i < m; i++) { + let child = nodes[i]; + if (child && (!NodeUtil.isType(child, 'mspace') && + (!NodeUtil.isType(child, 'TeXAtom') || + (NodeUtil.getChildren(child)[0] && + NodeUtil.getChildren(NodeUtil.getChildren(child)[0]).length)))) { + if (NodeUtil.isEmbellished(child) || + (NodeUtil.isType(child, 'TeXAtom') && NodeUtil.getTexClass(child) === TEXCLASS.REL)) { + let mi = configuration.nodeFactory.create('node', 'mi'); + nodes.unshift(mi); } + break; } } +} - /** - * Break up a string into text and math blocks. - * @param {TexParser} parser The calling parser. - * @param {string} text The text in the math expression to parse. - * @param {number|string=} level The scriptlevel. - * @param {string} font The mathvariant to use - * @return {MmlNode[]} The nodes corresponding to the internal math expression. - */ - export function internalMath( - parser: TexParser, - text: string, - level?: number | string, - font?: string - ): MmlNode[] { - text = text.replace(/ +/g, ' '); - if (parser.configuration.options.internalMath) { - return parser.configuration.options.internalMath(parser, text, level, font); - } - let mathvariant = font || parser.stack.env.font; - let def = (mathvariant ? {mathvariant} : {}); - let mml: MmlNode[] = [], i = 0, k = 0, c, node, match = '', braces = 0; - if (text.match(/\\?[${}\\]|\\\(|\\(?:eq)?ref\s*\{|\\U/)) { - while (i < text.length) { - c = text.charAt(i++); - if (c === '$') { - if (match === '$' && braces === 0) { - // @test Interspersed Text - node = parser.create( - 'node', 'TeXAtom', - [(new TexParser(text.slice(k, i - 1), {}, parser.configuration)).mml()]); - mml.push(node); - match = ''; - k = i; - } else if (match === '') { +/** + * Break up a string into text and math blocks. + * @param {TexParser} parser The calling parser. + * @param {string} text The text in the math expression to parse. + * @param {number|string=} level The scriptlevel. + * @param {string} font The mathvariant to use + * @return {MmlNode[]} The nodes corresponding to the internal math expression. + */ +export function internalMath( + parser: TexParser, + text: string, + level?: number | string, + font?: string +): MmlNode[] { + text = text.replace(/ +/g, ' '); + if (parser.configuration.options.internalMath) { + return parser.configuration.options.internalMath(parser, text, level, font); + } + let mathvariant = font || parser.stack.env.font; + let def = (mathvariant ? {mathvariant} : {}); + let mml: MmlNode[] = [], i = 0, k = 0, c, node, match = '', braces = 0; + if (text.match(/\\?[${}\\]|\\\(|\\(?:eq)?ref\s*\{|\\U/)) { + while (i < text.length) { + c = text.charAt(i++); + if (c === '$') { + if (match === '$' && braces === 0) { + // @test Interspersed Text + node = parser.create( + 'node', 'TeXAtom', + [(new TexParser(text.slice(k, i - 1), {}, parser.configuration)).mml()]); + mml.push(node); + match = ''; + k = i; + } else if (match === '') { + // @test Interspersed Text + if (k < i - 1) { // @test Interspersed Text - if (k < i - 1) { - // @test Interspersed Text - mml.push(internalText(parser, text.slice(k, i - 1), def)); - } - match = '$'; - k = i; + mml.push(internalText(parser, text.slice(k, i - 1), def)); } - } else if (c === '{' && match !== '') { - // @test Mbox Mbox, Mbox Math - braces++; - } else if (c === '}') { - // @test Mbox Mbox, Mbox Math - if (match === '}' && braces === 0) { - // @test Mbox Eqref, Mbox Math - let atom = (new TexParser(text.slice(k, i), {}, parser.configuration)).mml(); - node = parser.create('node', 'TeXAtom', [atom], def); - mml.push(node); - match = ''; - k = i; - } else if (match !== '') { + match = '$'; + k = i; + } + } else if (c === '{' && match !== '') { + // @test Mbox Mbox, Mbox Math + braces++; + } else if (c === '}') { + // @test Mbox Mbox, Mbox Math + if (match === '}' && braces === 0) { + // @test Mbox Eqref, Mbox Math + let atom = (new TexParser(text.slice(k, i), {}, parser.configuration)).mml(); + node = parser.create('node', 'TeXAtom', [atom], def); + mml.push(node); + match = ''; + k = i; + } else if (match !== '') { + // @test Mbox Math, Mbox Mbox + if (braces) { // @test Mbox Math, Mbox Mbox - if (braces) { - // @test Mbox Math, Mbox Mbox - braces--; - } + braces--; } - } else if (c === '\\') { - // @test Mbox Eqref, Mbox CR - if (match === '' && text.substring(i).match(/^(eq)?ref\s*\{/)) { + } + } else if (c === '\\') { + // @test Mbox Eqref, Mbox CR + if (match === '' && text.substring(i).match(/^(eq)?ref\s*\{/)) { + // @test Mbox Eqref + let len = ((RegExp as any)['$&'] as string).length; + if (k < i - 1) { // @test Mbox Eqref - let len = ((RegExp as any)['$&'] as string).length; - if (k < i - 1) { - // @test Mbox Eqref - mml.push(internalText(parser, text.slice(k, i - 1), def)); - } - match = '}'; - k = i - 1; - i += len; - } else { - // @test Mbox CR, Mbox Mbox - c = text.charAt(i++); - if (c === '(' && match === '') { - // @test Mbox Internal Display - if (k < i - 2) { - // @test Mbox Internal Display - mml.push(internalText(parser, text.slice(k, i - 2), def)); - } - match = ')'; k = i; - } else if (c === ')' && match === ')' && braces === 0) { + mml.push(internalText(parser, text.slice(k, i - 1), def)); + } + match = '}'; + k = i - 1; + i += len; + } else { + // @test Mbox CR, Mbox Mbox + c = text.charAt(i++); + if (c === '(' && match === '') { + // @test Mbox Internal Display + if (k < i - 2) { // @test Mbox Internal Display - node = parser.create( - 'node', 'TeXAtom', - [(new TexParser(text.slice(k, i - 2), {}, parser.configuration)).mml()]); - mml.push(node); - match = ''; - k = i; - } else if (c.match(/[${}\\]/) && match === '') { - // @test Mbox CR - i--; - text = text.substring(0, i - 1) + text.substring(i); // remove \ from \$, \{, \}, or \\ - } else if (c === 'U') { - const arg = text.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'); - } - // Replace \U{...} with specified character - const c = String.fromCodePoint(parseInt(arg[1] || arg[2], 16)); - text = text.substring(0, i - 2) + c + text.substring(i + arg[0].length); + mml.push(internalText(parser, text.slice(k, i - 2), def)); } + match = ')'; k = i; + } else if (c === ')' && match === ')' && braces === 0) { + // @test Mbox Internal Display + node = parser.create( + 'node', 'TeXAtom', + [(new TexParser(text.slice(k, i - 2), {}, parser.configuration)).mml()]); + mml.push(node); + match = ''; + k = i; + } else if (c.match(/[${}\\]/) && match === '') { + // @test Mbox CR + i--; + text = text.substring(0, i - 1) + text.substring(i); // remove \ from \$, \{, \}, or \\ + } else if (c === 'U') { + const arg = text.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'); + } + // Replace \U{...} with specified character + const c = String.fromCodePoint(parseInt(arg[1] || arg[2], 16)); + text = text.substring(0, i - 2) + c + text.substring(i + arg[0].length); } } } - if (match !== '') { - // @test Internal Math Error - throw new TexError('MathNotTerminated', 'Math not terminated in text box'); - } } - if (k < text.length) { - // @test Interspersed Text, Mbox Mbox - mml.push(internalText(parser, text.slice(k), def)); + if (match !== '') { + // @test Internal Math Error + throw new TexError('MathNotTerminated', 'Math not terminated in text box'); } - if (level != null) { - // @test Label, Fbox, Hbox - mml = [parser.create('node', 'mstyle', mml, {displaystyle: false, scriptlevel: level})]; - } else if (mml.length > 1) { - // @test Interspersed Text - mml = [parser.create('node', 'mrow', mml)]; - } - return mml; } + if (k < text.length) { + // @test Interspersed Text, Mbox Mbox + mml.push(internalText(parser, text.slice(k), def)); + } + if (level != null) { + // @test Label, Fbox, Hbox + mml = [parser.create('node', 'mstyle', mml, {displaystyle: false, scriptlevel: level})]; + } else if (mml.length > 1) { + // @test Interspersed Text + mml = [parser.create('node', 'mrow', mml)]; + } + return mml; +} - /** - * Parses text internal to boxes or labels. - * @param {TexParser} parser The current tex parser. - * @param {string} text The text to parse. - * @param {EnvList} def The attributes of the text node. - * @return {MmlNode} The text node. - */ - export function internalText(parser: TexParser, text: string, def: EnvList): MmlNode { - // @test Label, Fbox, Hbox - text = text.replace(/\n+/g, ' ').replace(/^\s+/, entities.nbsp).replace(/\s+$/, entities.nbsp); - let textNode = parser.create('text', text); - return parser.create('node', 'mtext', [], def, textNode); - } - - /** - * Create an munderover node with the given script position. - * @param {TexParser} parser The current TeX parser. - * @param {MmlNode} base The base node. - * @param {MmlNode} script The under- or over-script. - * @param {string} pos Either 'over' or 'under'. - * @param {boolean} stack True if super- or sub-scripts should stack. - * @return {MmlNode} The generated node (MmlMunderover or TeXAtom) - */ - export function underOver(parser: TexParser, base: MmlNode, script: MmlNode, pos: string, stack: boolean): MmlNode { - // @test Overline - ParseUtil.checkMovableLimits(base); - if (NodeUtil.isType(base, 'munderover') && NodeUtil.isEmbellished(base)) { - // @test Overline Limits - NodeUtil.setProperties(NodeUtil.getCoreMO(base), {lspace: 0, rspace: 0}); - const mo = parser.create('node', 'mo', [], {rspace: 0}); - base = parser.create('node', 'mrow', [mo, base]); - // TODO? add an empty so it's not embellished any more - } - const mml = parser.create('node', 'munderover', [base]) as MmlMunderover; - NodeUtil.setChild(mml, pos === 'over' ? mml.over : mml.under, script); - let node: MmlNode = mml; - if (stack) { - // @test Overbrace 1 2 3, Underbrace, Overbrace Op 1 2 - node = parser.create('node', 'TeXAtom', [mml], {texClass: TEXCLASS.OP, movesupsub: true}); - } - NodeUtil.setProperty(node, 'subsupOK', true); - return node; - } - - /** - * Set movablelimits to false if necessary. - * @param {MmlNode} base The base node being tested. - */ - export function checkMovableLimits(base: MmlNode) { - const symbol = (NodeUtil.isType(base, 'mo') ? NodeUtil.getForm(base) : null); - if (NodeUtil.getProperty(base, 'movablelimits') || (symbol && symbol[3] && symbol[3].movablelimits)) { - // @test Overline Sum - NodeUtil.setProperties(base, {movablelimits: false}); - } +/** + * Parses text internal to boxes or labels. + * @param {TexParser} parser The current tex parser. + * @param {string} text The text to parse. + * @param {EnvList} def The attributes of the text node. + * @return {MmlNode} The text node. + */ +export function internalText(parser: TexParser, text: string, def: EnvList): MmlNode { + // @test Label, Fbox, Hbox + text = text.replace(/\n+/g, ' ').replace(/^\s+/, entities.nbsp).replace(/\s+$/, entities.nbsp); + let textNode = parser.create('text', text); + return parser.create('node', 'mtext', [], def, textNode); +} + +/** + * Create an munderover node with the given script position. + * @param {TexParser} parser The current TeX parser. + * @param {MmlNode} base The base node. + * @param {MmlNode} script The under- or over-script. + * @param {string} pos Either 'over' or 'under'. + * @param {boolean} stack True if super- or sub-scripts should stack. + * @return {MmlNode} The generated node (MmlMunderover or TeXAtom) + */ +export function underOver(parser: TexParser, base: MmlNode, script: MmlNode, pos: string, stack: boolean): MmlNode { + // @test Overline + checkMovableLimits(base); + if (NodeUtil.isType(base, 'munderover') && NodeUtil.isEmbellished(base)) { + // @test Overline Limits + NodeUtil.setProperties(NodeUtil.getCoreMO(base), {lspace: 0, rspace: 0}); + const mo = parser.create('node', 'mo', [], {rspace: 0}); + base = parser.create('node', 'mrow', [mo, base]); + // TODO? add an empty so it's not embellished any more + } + const mml = parser.create('node', 'munderover', [base]) as MmlMunderover; + NodeUtil.setChild(mml, pos === 'over' ? mml.over : mml.under, script); + let node: MmlNode = mml; + if (stack) { + // @test Overbrace 1 2 3, Underbrace, Overbrace Op 1 2 + node = parser.create('node', 'TeXAtom', [mml], {texClass: TEXCLASS.OP, movesupsub: true}); } + NodeUtil.setProperty(node, 'subsupOK', true); + return node; +} - /** - * 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; +/** + * Set movablelimits to false if necessary. + * @param {MmlNode} base The base node being tested. + */ +export function checkMovableLimits(base: MmlNode) { + const symbol = (NodeUtil.isType(base, 'mo') ? NodeUtil.getForm(base) : null); + if (NodeUtil.getProperty(base, 'movablelimits') || (symbol && symbol[3] && symbol[3].movablelimits)) { + // @test Overline Sum + NodeUtil.setProperties(base, {movablelimits: false}); + } +} + +/** + * 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; +} - /** - * Sets alignment in array definitions. - * @param {ArrayItem} array The array item. - * @param {string} align The alignment string. - * @param {TexParser?} parser The current tex parser. - * @return {ArrayItem} The altered array item. - */ - export function setArrayAlign(array: ArrayItem, align: string, parser?: TexParser): ArrayItem { - // @test Array1, Array2, Array Test - if (!parser) { - align = ParseUtil.trimSpaces(align || ''); +/** + * Sets alignment in array definitions. + * @param {ArrayItem} array The array item. + * @param {string} align The alignment string. + * @param {TexParser?} parser The current tex parser. + * @return {ArrayItem} The altered array item. + */ +export function setArrayAlign(array: ArrayItem, align: string, parser?: TexParser): ArrayItem { + // @test Array1, Array2, Array Test + if (!parser) { + align = trimSpaces(align || ''); + } + if (align === 't') { + array.arraydef.align = 'baseline 1'; + } else if (align === 'b') { + array.arraydef.align = 'baseline -1'; + } else if (align === 'c') { + array.arraydef.align = 'axis'; + } else if (align) { + if (parser) { + parser.string = `[${align}]` + parser.string.slice(parser.i); + parser.i = 0; + } else { + array.arraydef.align = align; } - if (align === 't') { - array.arraydef.align = 'baseline 1'; - } else if (align === 'b') { - array.arraydef.align = 'baseline -1'; - } else if (align === 'c') { - array.arraydef.align = 'axis'; - } else if (align) { - if (parser) { - parser.string = `[${align}]` + parser.string.slice(parser.i); - parser.i = 0; + } + return array; +} + + +/** + * Replace macro parameters with their values. + * @param {TexParser} parser The current TeX parser. + * @param {string[]} args A list of arguments for macro parameters. + * @param {string} str The macro parameter string. + * @return {string} The string with all parameters replaced by arguments. + */ +export function substituteArgs(parser: TexParser, args: string[], + str: string): string { + let text = ''; + let newstring = ''; + let i = 0; + while (i < str.length) { + let c = str.charAt(i++); + if (c === '\\') { + text += c + str.charAt(i++); + } + else if (c === '#') { + c = str.charAt(i++); + if (c === '#') { + text += c; } else { - array.arraydef.align = align; - } - } - return array; - } - - - /** - * Replace macro parameters with their values. - * @param {TexParser} parser The current TeX parser. - * @param {string[]} args A list of arguments for macro parameters. - * @param {string} str The macro parameter string. - * @return {string} The string with all parameters replaced by arguments. - */ - export function substituteArgs(parser: TexParser, args: string[], - str: string): string { - let text = ''; - let newstring = ''; - let i = 0; - while (i < str.length) { - let c = str.charAt(i++); - if (c === '\\') { - text += c + str.charAt(i++); - } - else if (c === '#') { - c = str.charAt(i++); - if (c === '#') { - text += c; - } else { - if (!c.match(/[1-9]/) || parseInt(c, 10) > args.length) { - throw new TexError('IllegalMacroParam', - 'Illegal macro parameter reference'); - } - newstring = addArgs(parser, addArgs(parser, newstring, text), - args[parseInt(c, 10) - 1]); - text = ''; + if (!c.match(/[1-9]/) || parseInt(c, 10) > args.length) { + throw new TexError('IllegalMacroParam', + 'Illegal macro parameter reference'); } - } else { - text += c; + newstring = addArgs(parser, addArgs(parser, newstring, text), + args[parseInt(c, 10) - 1]); + text = ''; } + } else { + text += c; } - return addArgs(parser, newstring, text); - } - - - /** - * Adds a new expanded argument to an already macro parameter string. Makes - * sure that macros are followed by a space if their names could accidentally - * be continued into the following text. - * @param {TexParser} parser The current TeX parser. - * @param {string} s1 The already expanded string. - * @param {string} s2 The string to add. - * @return {string} The combined string. - */ - export function addArgs(parser: TexParser, s1: string, s2: string): string { - if (s2.match(/^[a-z]/i) && s1.match(/(^|[^\\])(\\\\)*\\[a-z]+$/i)) { - 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?'); - } - return s1 + s2; } + return addArgs(parser, newstring, text); +} - /** - * Report an error if there are too many macro substitutions. - * @param {TexParser} parser The current TeX parser. - * @param {boolean} isMacro True if we are substituting a macro, false for environment. - */ - export function checkMaxMacros(parser: TexParser, isMacro: boolean = true) { - if (++parser.macroCount <= parser.configuration.options['maxMacros']) { - return; - } - if (isMacro) { - throw new TexError('MaxMacroSub1', - 'MathJax maximum macro substitution count exceeded; ' + - 'is here a recursive macro call?'); - } else { - throw new TexError('MaxMacroSub2', - 'MathJax maximum substitution count exceeded; ' + - 'is there a recursive latex environment?'); - } + +/** + * Adds a new expanded argument to an already macro parameter string. Makes + * sure that macros are followed by a space if their names could accidentally + * be continued into the following text. + * @param {TexParser} parser The current TeX parser. + * @param {string} s1 The already expanded string. + * @param {string} s2 The string to add. + * @return {string} The combined string. + */ +export function addArgs(parser: TexParser, s1: string, s2: string): string { + if (s2.match(/^[a-z]/i) && s1.match(/(^|[^\\])(\\\\)*\\[a-z]+$/i)) { + 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?'); } + return s1 + s2; +} +/** + * Report an error if there are too many macro substitutions. + * @param {TexParser} parser The current TeX parser. + * @param {boolean} isMacro True if we are substituting a macro, false for environment. + */ +export function checkMaxMacros(parser: TexParser, isMacro: boolean = true) { + if (++parser.macroCount <= parser.configuration.options['maxMacros']) { + return; + } + if (isMacro) { + throw new TexError('MaxMacroSub1', + 'MathJax maximum macro substitution count exceeded; ' + + 'is here a recursive macro call?'); + } else { + throw new TexError('MaxMacroSub2', + 'MathJax maximum substitution count exceeded; ' + + 'is there a recursive latex environment?'); + } +} - /** - * Check for bad nesting of equation environments - */ - export function checkEqnEnv(parser: TexParser, nestable: boolean = true) { - const top = parser.stack.Top(); - const first = top.First; - // - // The gather environment can include align and others, but only one level deep. - // - if (top.getProperty('nestable') && nestable && !first) { - return; - } - if (!top.isKind('start') || first) { - throw new TexError('ErroneousNestingEq', 'Erroneous nesting of equation structures'); - } + +/** + * Check for bad nesting of equation environments + */ +export function checkEqnEnv(parser: TexParser, nestable: boolean = true) { + const top = parser.stack.Top(); + const first = top.First; + // + // The gather environment can include align and others, but only one level deep. + // + if (top.getProperty('nestable') && nestable && !first) { + return; + } + if (!top.isKind('start') || first) { + throw new TexError('ErroneousNestingEq', 'Erroneous nesting of equation structures'); } +} - /** - * Copy an MmlNode and add it (and its children) to the proper lists. - * - * @param {MmlNode} node The MmlNode to copy - * @param {TexParser} parser The active tex parser - * @return {MmlNode} The duplicate tree - */ - export function copyNode(node: MmlNode, parser: TexParser): MmlNode { - const tree = node.copy(); - const options = parser.configuration; - tree.walkTree((n: MmlNode) => { - options.addNode(n.kind, n); - const lists = (n.getProperty('in-lists') as string || '').split(/,/); - for (const list of lists) { - list && options.addNode(list, n); - } - }); - return tree; - } - - /** - * This is a placeholder for future security filtering of attributes. - * @param {TexParser} parser The current parser. - * @param {string} name The attribute name. - * @param {string} value The attribute value to filter. - * @return {string} The filtered value. - */ - export function MmlFilterAttribute(_parser: TexParser, _name: string, value: string): string { - // TODO: Implement in security package. - return value; - } - - - /** - * Initialises an stack environment with current font definition in the parser. - * @param {TexParser} parser The current tex parser. - * @return {EnvList} The initialised environment list. - */ - export function getFontDef(parser: TexParser): EnvList { - const font = parser.stack.env['font']; - return (font ? {mathvariant: font} : {}); - } - - - /** - * Splits a package option list of the form [x=y,z=1] into an attribute list - * of the form {x: y, z: 1}. - * @param {string} attrib The attributes of the package. - * @param {{[key: string]: number}?} allowed A list of allowed options. If - * given only allowed arguments are returned. - * @param {boolean?} error If true, raises an exception if not allowed options - * are found. - * @return {EnvList} The attribute list. - */ - export function keyvalOptions(attrib: string, - allowed: {[key: string]: number} = null, - error: boolean = false): EnvList { - let def: EnvList = readKeyval(attrib); - if (allowed) { - for (let key of Object.keys(def)) { - if (!allowed.hasOwnProperty(key)) { - if (error) { - throw new TexError('InvalidOption', 'Invalid option: %1', key); - } - delete def[key]; +/** + * Copy an MmlNode and add it (and its children) to the proper lists. + * + * @param {MmlNode} node The MmlNode to copy + * @param {TexParser} parser The active tex parser + * @return {MmlNode} The duplicate tree + */ +export function copyNode(node: MmlNode, parser: TexParser): MmlNode { + const tree = node.copy(); + const options = parser.configuration; + tree.walkTree((n: MmlNode) => { + options.addNode(n.kind, n); + const lists = (n.getProperty('in-lists') as string || '').split(/,/); + for (const list of lists) { + list && options.addNode(list, n); + } + }); + return tree; +} + +/** + * This is a placeholder for future security filtering of attributes. + * @param {TexParser} parser The current parser. + * @param {string} name The attribute name. + * @param {string} value The attribute value to filter. + * @return {string} The filtered value. + */ +export function MmlFilterAttribute(_parser: TexParser, _name: string, value: string): string { + // TODO: Implement in security package. + return value; +} + + +/** + * Initialises an stack environment with current font definition in the parser. + * @param {TexParser} parser The current tex parser. + * @return {EnvList} The initialised environment list. + */ +export function getFontDef(parser: TexParser): EnvList { + const font = parser.stack.env['font']; + return (font ? {mathvariant: font} : {}); +} + + +/** + * Splits a package option list of the form [x=y,z=1] into an attribute list + * of the form {x: y, z: 1}. + * @param {string} attrib The attributes of the package. + * @param {{[key: string]: number}?} allowed A list of allowed options. If + * given only allowed arguments are returned. + * @param {boolean?} error If true, raises an exception if not allowed options + * are found. + * @return {EnvList} The attribute list. + */ +export function keyvalOptions(attrib: string, + allowed: {[key: string]: number} = null, + error: boolean = false): EnvList { + let def: EnvList = readKeyval(attrib); + if (allowed) { + for (let key of Object.keys(def)) { + if (!allowed.hasOwnProperty(key)) { + if (error) { + throw new TexError('InvalidOption', 'Invalid option: %1', key); } + delete def[key]; } } - return def; - } - - - /** - * Implementation of the keyval function from https://www.ctan.org/pkg/keyval - * @param {string} text The optional parameter string for a package or - * command. - * @return {EnvList} Set of options as key/value pairs. - */ - function readKeyval(text: string): EnvList { - let options: EnvList = {}; - let rest = text; - let end, key, val; - while (rest) { - [key, end, rest] = readValue(rest, ['=', ',']); - if (end === '=') { - [val, end, rest] = readValue(rest, [',']); - val = (val === 'false' || val === 'true') ? - JSON.parse(val) : val; - options[key] = val; - } else if (key) { - options[key] = true; - } - } - return options; } + return def; +} - /** - * Removes pairs of outer braces. - * @param {string} text The string to clean. - * @param {number} count The number of outer braces to slice off. - * @return {string} The cleaned string. - */ - function removeBraces(text: string, count: number): string { - while (count > 0) { - text = text.trim().slice(1, -1); - count--; +/** + * Implementation of the keyval function from https://www.ctan.org/pkg/keyval + * @param {string} text The optional parameter string for a package or + * command. + * @return {EnvList} Set of options as key/value pairs. + */ +function readKeyval(text: string): EnvList { + let options: EnvList = {}; + let rest = text; + let end, key, val; + while (rest) { + [key, end, rest] = readValue(rest, ['=', ',']); + if (end === '=') { + [val, end, rest] = readValue(rest, [',']); + val = (val === 'false' || val === 'true') ? + JSON.parse(val) : val; + options[key] = val; + } else if (key) { + options[key] = true; } - return text.trim(); - } - - - /** - * Read a value from the given string until an end parameter is reached or - * string is exhausted. - * @param {string} text The string to process. - * @param {string[]} end List of possible end characters. - * @return {[string, string, string]} The collected value, the actual end - * character, and the rest of the string still to parse. - */ - function readValue(text: string, end: string[]): [string, string, string] { - let length = text.length; - let braces = 0; - let value = ''; - let index = 0; - let start = 0; // Counter for the starting left braces. - let startCount = true; // Flag for counting starting left braces. - let stopCount = false; // If true right braces are found directly - // after starting braces, but no other char yet. - while (index < length) { - let c = text[index++]; - switch (c) { + } + return options; +} + + +/** + * Removes pairs of outer braces. + * @param {string} text The string to clean. + * @param {number} count The number of outer braces to slice off. + * @return {string} The cleaned string. + */ +function removeBraces(text: string, count: number): string { + while (count > 0) { + text = text.trim().slice(1, -1); + count--; + } + return text.trim(); +} + + +/** + * Read a value from the given string until an end parameter is reached or + * string is exhausted. + * @param {string} text The string to process. + * @param {string[]} end List of possible end characters. + * @return {[string, string, string]} The collected value, the actual end + * character, and the rest of the string still to parse. + */ +function readValue(text: string, end: string[]): [string, string, string] { + let length = text.length; + let braces = 0; + let value = ''; + let index = 0; + let start = 0; // Counter for the starting left braces. + let startCount = true; // Flag for counting starting left braces. + let stopCount = false; // If true right braces are found directly + // after starting braces, but no other char yet. + while (index < length) { + let c = text[index++]; + switch (c) { case ' ': // Ignore spaces. break; case '{': @@ -722,29 +720,25 @@ namespace ParseUtil { default: if (!braces && end.indexOf(c) !== -1) { // End character reached. return [stopCount ? 'true' : // If Stop count is true we - // have balanced braces, only. - removeBraces(value, start), c, text.slice(index)]; + // have balanced braces, only. + removeBraces(value, start), c, text.slice(index)]; } startCount = false; stopCount = false; - } - value += c; } - if (braces) { - throw new TexError('ExtraOpenMissingClose', - 'Extra open brace or missing close brace'); - } - return [stopCount ? 'true' : removeBraces(value, start), '', text.slice(index)]; + value += c; } - - /** - * @param {string} c The character to test. - * @return {boolean} True if the character is Latin or Greek - */ - export function isLatinOrGreekChar(c: string): boolean { - return !!c.normalize('NFD').match(/[a-zA-Z\u0370-\u03F0]/); + if (braces) { + throw new TexError('ExtraOpenMissingClose', + 'Extra open brace or missing close brace'); } - + return [stopCount ? 'true' : removeBraces(value, start), '', text.slice(index)]; } -export default ParseUtil; +/** + * @param {string} c The character to test. + * @return {boolean} True if the character is Latin or Greek + */ +export function isLatinOrGreekChar(c: string): boolean { + return !!c.normalize('NFD').match(/[a-zA-Z\u0370-\u03F0]/); +} diff --git a/ts/input/tex/TexParser.ts b/ts/input/tex/TexParser.ts index f5d518ead..708139227 100644 --- a/ts/input/tex/TexParser.ts +++ b/ts/input/tex/TexParser.ts @@ -23,7 +23,7 @@ * @author v.sorge@mathjax.org (Volker Sorge) */ -import ParseUtil from './ParseUtil.js'; +import * as ParseUtil from './ParseUtil.js'; import {HandlerType} from './MapHandler.js'; import Stack from './Stack.js'; import StackItemFactory from './StackItemFactory.js'; diff --git a/ts/input/tex/ams/AmsItems.ts b/ts/input/tex/ams/AmsItems.ts index a13d26b88..289c969cb 100644 --- a/ts/input/tex/ams/AmsItems.ts +++ b/ts/input/tex/ams/AmsItems.ts @@ -24,7 +24,7 @@ import {ArrayItem, EqnArrayItem} from '../base/BaseItems.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import NodeUtil from '../NodeUtil.js'; import TexError from '../TexError.js'; import {TexConstant} from '../TexConstants.js'; diff --git a/ts/input/tex/ams/AmsMappings.ts b/ts/input/tex/ams/AmsMappings.ts index 96e051ac7..0303da94a 100644 --- a/ts/input/tex/ams/AmsMappings.ts +++ b/ts/input/tex/ams/AmsMappings.ts @@ -27,7 +27,7 @@ import {AmsMethods} from './AmsMethods.js'; import * as sm from '../TokenMap.js'; import {TexConstant} from '../TexConstants.js'; import ParseMethods from '../ParseMethods.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js'; import {MATHSPACE} from '../../../util/lengths.js'; diff --git a/ts/input/tex/ams/AmsMethods.ts b/ts/input/tex/ams/AmsMethods.ts index d019c5977..13ef10822 100644 --- a/ts/input/tex/ams/AmsMethods.ts +++ b/ts/input/tex/ams/AmsMethods.ts @@ -25,7 +25,7 @@ import {StackItem} from '../StackItem.js'; import {ParseMethod} from '../Types.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import ParseMethods from '../ParseMethods.js'; import NodeUtil from '../NodeUtil.js'; import {TexConstant} from '../TexConstants.js'; diff --git a/ts/input/tex/base/BaseConfiguration.ts b/ts/input/tex/base/BaseConfiguration.ts index 20f38f719..10e03d518 100644 --- a/ts/input/tex/base/BaseConfiguration.ts +++ b/ts/input/tex/base/BaseConfiguration.ts @@ -33,7 +33,7 @@ import {AbstractTags} from '../Tags.js'; import './BaseMappings.js'; import {getRange} from '../../../core/MmlTree/OperatorDictionary.js'; import ParseOptions from '../ParseOptions.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; /** * Remapping some ASCII characters to their Unicode operator equivalent. diff --git a/ts/input/tex/base/BaseItems.ts b/ts/input/tex/base/BaseItems.ts index 45c759196..ce6243d3c 100644 --- a/ts/input/tex/base/BaseItems.ts +++ b/ts/input/tex/base/BaseItems.ts @@ -31,7 +31,7 @@ import {MmlMo} from '../../../core/MmlTree/MmlNodes/mo.js'; import {MmlMsubsup} from '../../../core/MmlTree/MmlNodes/msubsup.js'; import TexParser from '../TexParser.js'; import TexError from '../TexError.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import NodeUtil from '../NodeUtil.js'; import {Property, PropertyList} from '../../../core/Tree/Node.js'; import StackItemFactory from '../StackItemFactory.js'; diff --git a/ts/input/tex/base/BaseMappings.ts b/ts/input/tex/base/BaseMappings.ts index 758fc1745..22406d401 100644 --- a/ts/input/tex/base/BaseMappings.ts +++ b/ts/input/tex/base/BaseMappings.ts @@ -26,7 +26,7 @@ import * as sm from '../TokenMap.js'; import {TexConstant} from '../TexConstants.js'; import BaseMethods from './BaseMethods.js'; import ParseMethods from '../ParseMethods.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js'; import {MATHSPACE, em} from '../../../util/lengths.js'; diff --git a/ts/input/tex/base/BaseMethods.ts b/ts/input/tex/base/BaseMethods.ts index 5a8f169e5..e727aeef7 100644 --- a/ts/input/tex/base/BaseMethods.ts +++ b/ts/input/tex/base/BaseMethods.ts @@ -30,7 +30,7 @@ import NodeUtil from '../NodeUtil.js'; import TexError from '../TexError.js'; import TexParser from '../TexParser.js'; import {TexConstant} from '../TexConstants.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {PropertyList} from '../../../core/Tree/Node.js'; import {MmlNode, TEXCLASS} from '../../../core/MmlTree/MmlNode.js'; import {MmlMo} from '../../../core/MmlTree/MmlNodes/mo.js'; diff --git a/ts/input/tex/braket/BraketItems.ts b/ts/input/tex/braket/BraketItems.ts index daba2a199..04863a263 100644 --- a/ts/input/tex/braket/BraketItems.ts +++ b/ts/input/tex/braket/BraketItems.ts @@ -25,7 +25,7 @@ import {CheckType, BaseItem, StackItem} from '../StackItem.js'; import {TEXCLASS, MmlNode} from '../../../core/MmlTree/MmlNode.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {MATHSPACE, em} from '../../../util/lengths.js'; const THINSPACE = em(MATHSPACE.thinmathspace); diff --git a/ts/input/tex/bussproofs/BussproofsMethods.ts b/ts/input/tex/bussproofs/BussproofsMethods.ts index 7af362053..6f051bf74 100644 --- a/ts/input/tex/bussproofs/BussproofsMethods.ts +++ b/ts/input/tex/bussproofs/BussproofsMethods.ts @@ -26,7 +26,7 @@ import {ParseMethod} from '../Types.js'; import TexError from '../TexError.js'; import TexParser from '../TexParser.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {StackItem} from '../StackItem.js'; import {MmlNode} from '../../../core/MmlTree/MmlNode.js'; import * as BussproofsUtil from './BussproofsUtil.js'; diff --git a/ts/input/tex/bussproofs/BussproofsUtil.ts b/ts/input/tex/bussproofs/BussproofsUtil.ts index f5bbb679f..c1aba1b89 100644 --- a/ts/input/tex/bussproofs/BussproofsUtil.ts +++ b/ts/input/tex/bussproofs/BussproofsUtil.ts @@ -25,7 +25,7 @@ import ParseOptions from '../ParseOptions.js'; import NodeUtil from '../NodeUtil.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {MmlNode} from '../../../core/MmlTree/MmlNode.js'; import {Property} from '../../../core/Tree/Node.js'; diff --git a/ts/input/tex/cancel/CancelConfiguration.ts b/ts/input/tex/cancel/CancelConfiguration.ts index 8d7239f48..d73611774 100644 --- a/ts/input/tex/cancel/CancelConfiguration.ts +++ b/ts/input/tex/cancel/CancelConfiguration.ts @@ -27,7 +27,7 @@ import TexParser from '../TexParser.js'; import {TexConstant} from '../TexConstants.js'; import {CommandMap} from '../TokenMap.js'; import {ParseMethod} from '../Types.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {ENCLOSE_OPTIONS} from '../enclose/EncloseConfiguration.js'; diff --git a/ts/input/tex/cases/CasesConfiguration.ts b/ts/input/tex/cases/CasesConfiguration.ts index c260cf7c5..8e3956286 100644 --- a/ts/input/tex/cases/CasesConfiguration.ts +++ b/ts/input/tex/cases/CasesConfiguration.ts @@ -1,6 +1,6 @@ import {Configuration} from '../Configuration.js'; import {EnvironmentMap, MacroMap} from '../TokenMap.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import BaseMethods from '../base/BaseMethods.js'; import TexParser from '../TexParser.js'; import TexError from '../TexError.js'; diff --git a/ts/input/tex/color/ColorMethods.ts b/ts/input/tex/color/ColorMethods.ts index 9a681d2ae..535a129c9 100644 --- a/ts/input/tex/color/ColorMethods.ts +++ b/ts/input/tex/color/ColorMethods.ts @@ -25,7 +25,7 @@ import NodeUtil from '../NodeUtil.js'; import {ParseMethod} from '../Types.js'; import {PropertyList} from '../../../core/Tree/Node.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import TexParser from '../TexParser.js'; import {ColorModel} from './ColorUtil.js'; diff --git a/ts/input/tex/empheq/EmpheqConfiguration.ts b/ts/input/tex/empheq/EmpheqConfiguration.ts index c815f2a9d..8e3a6fde2 100644 --- a/ts/input/tex/empheq/EmpheqConfiguration.ts +++ b/ts/input/tex/empheq/EmpheqConfiguration.ts @@ -25,7 +25,7 @@ import {Configuration} from '../Configuration.js'; import {CommandMap, EnvironmentMap} from '../TokenMap.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import TexParser from '../TexParser.js'; import TexError from '../TexError.js'; import {BeginItem} from '../base/BaseItems.js'; diff --git a/ts/input/tex/empheq/EmpheqUtil.ts b/ts/input/tex/empheq/EmpheqUtil.ts index 2fe99d37d..a54eb26be 100644 --- a/ts/input/tex/empheq/EmpheqUtil.ts +++ b/ts/input/tex/empheq/EmpheqUtil.ts @@ -23,7 +23,7 @@ */ -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import TexParser from '../TexParser.js'; import {EnvList} from '../StackItem.js'; import {AbstractTags} from '../Tags.js'; diff --git a/ts/input/tex/enclose/EncloseConfiguration.ts b/ts/input/tex/enclose/EncloseConfiguration.ts index b3c4f8a22..1f4d60092 100644 --- a/ts/input/tex/enclose/EncloseConfiguration.ts +++ b/ts/input/tex/enclose/EncloseConfiguration.ts @@ -26,7 +26,7 @@ import {Configuration} from '../Configuration.js'; import TexParser from '../TexParser.js'; import {CommandMap} from '../TokenMap.js'; import {ParseMethod} from '../Types.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; /** diff --git a/ts/input/tex/html/HtmlMethods.ts b/ts/input/tex/html/HtmlMethods.ts index 79f436aaf..bfd1e4339 100644 --- a/ts/input/tex/html/HtmlMethods.ts +++ b/ts/input/tex/html/HtmlMethods.ts @@ -26,7 +26,7 @@ import TexParser from '../TexParser.js'; import {ParseMethod} from '../Types.js'; import NodeUtil from '../NodeUtil.js'; -import ParseUtil from "../ParseUtil.js"; +import * as ParseUtil from "../ParseUtil.js"; import {MmlNode} from '../../../core/MmlTree/MmlNode.js'; import TexError from '../TexError.js'; diff --git a/ts/input/tex/mathtools/MathtoolsMethods.ts b/ts/input/tex/mathtools/MathtoolsMethods.ts index 125d8d5f1..25d01bcb4 100644 --- a/ts/input/tex/mathtools/MathtoolsMethods.ts +++ b/ts/input/tex/mathtools/MathtoolsMethods.ts @@ -24,7 +24,7 @@ import {ArrayItem, EqnArrayItem} from '../base/BaseItems.js'; import {StackItem} from '../StackItem.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {ParseMethod, ParseResult} from '../Types.js'; import {AmsMethods} from '../ams/AmsMethods.js'; import BaseMethods from '../base/BaseMethods.js'; diff --git a/ts/input/tex/mathtools/MathtoolsUtil.ts b/ts/input/tex/mathtools/MathtoolsUtil.ts index 3ddde9b72..56765fd04 100644 --- a/ts/input/tex/mathtools/MathtoolsUtil.ts +++ b/ts/input/tex/mathtools/MathtoolsUtil.ts @@ -21,7 +21,7 @@ */ import {EqnArrayItem} from '../base/BaseItems.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import TexParser from '../TexParser.js'; import TexError from '../TexError.js'; import {CommandMap} from '../TokenMap.js'; diff --git a/ts/input/tex/newcommand/NewcommandMethods.ts b/ts/input/tex/newcommand/NewcommandMethods.ts index abf3670e4..a86916090 100644 --- a/ts/input/tex/newcommand/NewcommandMethods.ts +++ b/ts/input/tex/newcommand/NewcommandMethods.ts @@ -29,7 +29,7 @@ import TexParser from '../TexParser.js'; import * as sm from '../TokenMap.js'; import {Token, Macro} from '../Token.js'; import BaseMethods from '../base/BaseMethods.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {StackItem} from '../StackItem.js'; import NewcommandUtil from './NewcommandUtil.js'; diff --git a/ts/input/tex/newcommand/NewcommandUtil.ts b/ts/input/tex/newcommand/NewcommandUtil.ts index 299e122c8..85754609f 100644 --- a/ts/input/tex/newcommand/NewcommandUtil.ts +++ b/ts/input/tex/newcommand/NewcommandUtil.ts @@ -23,7 +23,7 @@ */ -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import TexError from '../TexError.js'; import TexParser from '../TexParser.js'; import {Macro, Token} from '../Token.js'; diff --git a/ts/input/tex/physics/PhysicsItems.ts b/ts/input/tex/physics/PhysicsItems.ts index 3357d9ddb..d02b6b8a8 100644 --- a/ts/input/tex/physics/PhysicsItems.ts +++ b/ts/input/tex/physics/PhysicsItems.ts @@ -24,7 +24,7 @@ import {CheckType, BaseItem, StackItem} from '../StackItem.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import NodeUtil from '../NodeUtil.js'; import TexParser from '../TexParser.js'; import {AbstractMmlTokenNode} from '../../../core/MmlTree/MmlNode.js'; diff --git a/ts/input/tex/physics/PhysicsMethods.ts b/ts/input/tex/physics/PhysicsMethods.ts index b348eae9c..272eabf39 100644 --- a/ts/input/tex/physics/PhysicsMethods.ts +++ b/ts/input/tex/physics/PhysicsMethods.ts @@ -27,7 +27,7 @@ import BaseMethods from '../base/BaseMethods.js'; import TexParser from '../TexParser.js'; import TexError from '../TexError.js'; import {TEXCLASS, MmlNode} from '../../../core/MmlTree/MmlNode.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import NodeUtil from '../NodeUtil.js'; import {NodeFactory} from '../NodeFactory.js'; import {Macro} from '../Token.js'; diff --git a/ts/input/tex/setoptions/SetOptionsConfiguration.ts b/ts/input/tex/setoptions/SetOptionsConfiguration.ts index a5dd47df7..d66babb85 100644 --- a/ts/input/tex/setoptions/SetOptionsConfiguration.ts +++ b/ts/input/tex/setoptions/SetOptionsConfiguration.ts @@ -27,7 +27,7 @@ import {TeX} from '../../tex.js'; import TexParser from '../TexParser.js'; import {CommandMap} from '../TokenMap.js'; import TexError from '../TexError.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {Macro} from '../Token.js'; import BaseMethods from '../base/BaseMethods.js'; import {expandable, isObject} from '../../../util/Options.js'; diff --git a/ts/input/tex/textcomp/TextcompMappings.ts b/ts/input/tex/textcomp/TextcompMappings.ts index 3afc41d3a..6e2531278 100644 --- a/ts/input/tex/textcomp/TextcompMappings.ts +++ b/ts/input/tex/textcomp/TextcompMappings.ts @@ -27,7 +27,7 @@ import {CommandMap} from '../TokenMap.js'; import {TexConstant} from '../TexConstants.js'; import {TextMacrosMethods} from '../textmacros/TextMacrosMethods.js'; import TexParser from '../TexParser.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {TextParser} from '../textmacros/TextParser.js'; diff --git a/ts/input/tex/textmacros/TextParser.ts b/ts/input/tex/textmacros/TextParser.ts index b9b7ea0a4..d35e5a543 100644 --- a/ts/input/tex/textmacros/TextParser.ts +++ b/ts/input/tex/textmacros/TextParser.ts @@ -25,7 +25,7 @@ import TexParser from '../TexParser.js'; import TexError from '../TexError.js'; import ParseOptions from '../ParseOptions.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import {StackItem} from '../StackItem.js'; import {MmlNode, AbstractMmlNode} from '../../../core/MmlTree/MmlNode.js'; import {EnvList} from '../StackItem.js'; diff --git a/ts/input/tex/unicode/UnicodeConfiguration.ts b/ts/input/tex/unicode/UnicodeConfiguration.ts index 62a034a54..6982eb2c8 100644 --- a/ts/input/tex/unicode/UnicodeConfiguration.ts +++ b/ts/input/tex/unicode/UnicodeConfiguration.ts @@ -28,7 +28,7 @@ import TexParser from '../TexParser.js'; import TexError from '../TexError.js'; import {CommandMap} from '../TokenMap.js'; import {ParseMethod} from '../Types.js'; -import ParseUtil from '../ParseUtil.js'; +import * as ParseUtil from '../ParseUtil.js'; import NodeUtil from '../NodeUtil.js'; import {numeric} from '../../../util/Entities.js'; import {Other} from '../base/BaseConfiguration.js';