add initial marp implementation with sample content and build configuration
This commit is contained in:
127
node_modules/mathjax-full/ts/input/tex/AllPackages.ts
generated
vendored
Normal file
127
node_modules/mathjax-full/ts/input/tex/AllPackages.ts
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Loads all the TeX extensions
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
import './base/BaseConfiguration.js';
|
||||
import './action/ActionConfiguration.js';
|
||||
import './ams/AmsConfiguration.js';
|
||||
import './amscd/AmsCdConfiguration.js';
|
||||
import './bbox/BboxConfiguration.js';
|
||||
import './boldsymbol/BoldsymbolConfiguration.js';
|
||||
import './braket/BraketConfiguration.js';
|
||||
import './bussproofs/BussproofsConfiguration.js';
|
||||
import './cancel/CancelConfiguration.js';
|
||||
import './cases/CasesConfiguration.js';
|
||||
import './centernot/CenternotConfiguration.js';
|
||||
import './color/ColorConfiguration.js';
|
||||
import './colorv2/ColorV2Configuration.js';
|
||||
import './colortbl/ColortblConfiguration.js';
|
||||
import './configmacros/ConfigMacrosConfiguration.js';
|
||||
import './empheq/EmpheqConfiguration.js';
|
||||
import './enclose/EncloseConfiguration.js';
|
||||
import './extpfeil/ExtpfeilConfiguration.js';
|
||||
import './gensymb/GensymbConfiguration.js';
|
||||
import './html/HtmlConfiguration.js';
|
||||
import './mathtools/MathtoolsConfiguration.js';
|
||||
import './mhchem/MhchemConfiguration.js';
|
||||
import './newcommand/NewcommandConfiguration.js';
|
||||
import './noerrors/NoErrorsConfiguration.js';
|
||||
import './noundefined/NoUndefinedConfiguration.js';
|
||||
import './physics/PhysicsConfiguration.js';
|
||||
import './setoptions/SetOptionsConfiguration.js';
|
||||
import './tagformat/TagFormatConfiguration.js';
|
||||
import './textcomp/TextcompConfiguration.js';
|
||||
import './textmacros/TextMacrosConfiguration.js';
|
||||
import './upgreek/UpgreekConfiguration.js';
|
||||
import './unicode/UnicodeConfiguration.js';
|
||||
import './verb/VerbConfiguration.js';
|
||||
|
||||
declare const MathJax: any;
|
||||
if (typeof MathJax !== 'undefined' && MathJax.loader) {
|
||||
MathJax.loader.preLoad(
|
||||
'[tex]/action',
|
||||
'[tex]/ams',
|
||||
'[tex]/amscd',
|
||||
'[tex]/bbox',
|
||||
'[tex]/boldsymbol',
|
||||
'[tex]/braket',
|
||||
'[tex]/bussproofs',
|
||||
'[tex]/cancel',
|
||||
'[tex]/cases',
|
||||
'[tex]/centernot',
|
||||
'[tex]/color',
|
||||
'[tex]/colorv2',
|
||||
'[tex]/colortbl',
|
||||
'[tex]/empheq',
|
||||
'[tex]/enclose',
|
||||
'[tex]/extpfeil',
|
||||
'[tex]/gensymb',
|
||||
'[tex]/html',
|
||||
'[tex]/mathtools',
|
||||
'[tex]/mhchem',
|
||||
'[tex]/newcommand',
|
||||
'[tex]/noerrors',
|
||||
'[tex]/noundefined',
|
||||
'[tex]/physics',
|
||||
'[tex]/upgreek',
|
||||
'[tex]/unicode',
|
||||
'[tex]/verb',
|
||||
'[tex]/configmacros',
|
||||
'[tex]/tagformat',
|
||||
'[tex]/textcomp',
|
||||
'[tex]/textmacros',
|
||||
'[tex]/setoptions',
|
||||
);
|
||||
}
|
||||
|
||||
export const AllPackages: string[] = [
|
||||
'base',
|
||||
'action',
|
||||
'ams',
|
||||
'amscd',
|
||||
'bbox',
|
||||
'boldsymbol',
|
||||
'braket',
|
||||
'bussproofs',
|
||||
'cancel',
|
||||
'cases',
|
||||
'centernot',
|
||||
'color',
|
||||
'colortbl',
|
||||
'empheq',
|
||||
'enclose',
|
||||
'extpfeil',
|
||||
'gensymb',
|
||||
'html',
|
||||
'mathtools',
|
||||
'mhchem',
|
||||
'newcommand',
|
||||
'noerrors',
|
||||
'noundefined',
|
||||
'upgreek',
|
||||
'unicode',
|
||||
'verb',
|
||||
'configmacros',
|
||||
'tagformat',
|
||||
'textcomp',
|
||||
'textmacros'
|
||||
];
|
||||
418
node_modules/mathjax-full/ts/input/tex/Configuration.ts
generated
vendored
Normal file
418
node_modules/mathjax-full/ts/input/tex/Configuration.ts
generated
vendored
Normal file
@@ -0,0 +1,418 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration options for the TexParser.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {HandlerConfig, FallbackConfig} from './MapHandler.js';
|
||||
import {StackItemClass} from './StackItem.js';
|
||||
import {TagsClass} from './Tags.js';
|
||||
import {userOptions, defaultOptions, OptionList} from '../../util/Options.js';
|
||||
import {SubHandlers} from './MapHandler.js';
|
||||
import {FunctionList} from '../../util/FunctionList.js';
|
||||
import {TeX} from '../tex.js';
|
||||
import {PrioritizedList} from '../../util/PrioritizedList.js';
|
||||
import {TagsFactory} from './Tags.js';
|
||||
|
||||
|
||||
export type StackItemConfig = {[kind: string]: StackItemClass};
|
||||
export type TagsConfig = {[kind: string]: TagsClass};
|
||||
export type Processor<T> = [T, number];
|
||||
export type ProtoProcessor<T> = Processor<T> | T;
|
||||
export type ProcessorList = Processor<Function>[];
|
||||
export type ConfigMethod = (c: ParserConfiguration, j: TeX<any, any, any>) => void;
|
||||
export type InitMethod = (c: ParserConfiguration) => void;
|
||||
|
||||
|
||||
|
||||
export class Configuration {
|
||||
|
||||
/**
|
||||
* Creates a function priority pair.
|
||||
* @param {ProtoProcessor<T>} func The function or processor.
|
||||
* @param {number} priority The default priority.
|
||||
* @return {Processor} The processor pair.
|
||||
* @template T
|
||||
*/
|
||||
private static makeProcessor<T>(func: ProtoProcessor<T>, priority: number): Processor<T> {
|
||||
return Array.isArray(func) ? func : [func, priority];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a configuration for a package.
|
||||
* @param {string} name The package name or empty string.
|
||||
* @param {Object} config See `create` method.
|
||||
* @return {Configuration} The newly generated configuration.
|
||||
*/
|
||||
private static _create(name: string,
|
||||
config: {handler?: HandlerConfig,
|
||||
fallback?: FallbackConfig,
|
||||
items?: StackItemConfig,
|
||||
tags?: TagsConfig,
|
||||
options?: OptionList,
|
||||
nodes?: {[key: string]: any},
|
||||
preprocessors?: ProtoProcessor<Function>[],
|
||||
postprocessors?: ProtoProcessor<Function>[],
|
||||
init?: ProtoProcessor<InitMethod>,
|
||||
config?: ProtoProcessor<ConfigMethod>,
|
||||
priority?: number,
|
||||
parser?: string,
|
||||
} = {}): Configuration {
|
||||
let priority = config.priority || PrioritizedList.DEFAULTPRIORITY;
|
||||
let init = config.init ? this.makeProcessor(config.init, priority) : null;
|
||||
let conf = config.config ? this.makeProcessor(config.config, priority) : null;
|
||||
let preprocessors = (config.preprocessors || []).map(
|
||||
pre => this.makeProcessor(pre, priority));
|
||||
let postprocessors = (config.postprocessors || []).map(
|
||||
post => this.makeProcessor(post, priority));
|
||||
let parser = config.parser || 'tex';
|
||||
return new Configuration(
|
||||
name,
|
||||
config.handler || {},
|
||||
config.fallback || {},
|
||||
config.items || {},
|
||||
config.tags || {},
|
||||
config.options || {},
|
||||
config.nodes || {},
|
||||
preprocessors, postprocessors, init, conf, priority,
|
||||
parser
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creator pattern for creating a named package configuration. This will be
|
||||
* administered in the configuration handler and can be retrieved again.
|
||||
* @param {string} name The package name.
|
||||
* @param {Object} config The configuration parameters:
|
||||
* Configuration for the TexParser consist of the following:
|
||||
* * _handler_ configuration mapping handler types to lists of symbol mappings.
|
||||
* * _fallback_ configuration mapping handler types to fallback methods.
|
||||
* * _items_ for the StackItem factory.
|
||||
* * _tags_ mapping tagging configurations to tagging objects.
|
||||
* * _options_ parse options for the packages.
|
||||
* * _nodes_ for the Node factory.
|
||||
* * _preprocessors_ list of functions for preprocessing the LaTeX
|
||||
* string wrt. to given parse options. Can contain a priority.
|
||||
* * _postprocessors_ list of functions for postprocessing the MmlNode
|
||||
* wrt. to given parse options. Can contain a priority.
|
||||
* * _init_ init method and optionally its priority.
|
||||
* * _config_ config method and optionally its priority.
|
||||
* * _priority_ default priority of the configuration.
|
||||
* * _parser_ the name of the parser that this configuration targets.
|
||||
* @return {Configuration} The newly generated configuration.
|
||||
*/
|
||||
public static create(name: string,
|
||||
config: {handler?: HandlerConfig,
|
||||
fallback?: FallbackConfig,
|
||||
items?: StackItemConfig,
|
||||
tags?: TagsConfig,
|
||||
options?: OptionList,
|
||||
nodes?: {[key: string]: any},
|
||||
preprocessors?: ProtoProcessor<Function>[],
|
||||
postprocessors?: ProtoProcessor<Function>[],
|
||||
init?: ProtoProcessor<InitMethod>,
|
||||
config?: ProtoProcessor<ConfigMethod>,
|
||||
priority?: number,
|
||||
parser?: string,
|
||||
} = {}): Configuration {
|
||||
let configuration = Configuration._create(name, config);
|
||||
ConfigurationHandler.set(name, configuration);
|
||||
return configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an unnamed, ephemeral package configuration. It will not added to
|
||||
* the configuration handler.
|
||||
* @param {Object} config See `create` method.
|
||||
* @return {Configuration} The ephemeral package configuration.
|
||||
*/
|
||||
public static local(config: {handler?: HandlerConfig,
|
||||
fallback?: FallbackConfig,
|
||||
items?: StackItemConfig,
|
||||
tags?: TagsConfig,
|
||||
options?: OptionList,
|
||||
nodes?: {[key: string]: any},
|
||||
preprocessors?: ProtoProcessor<Function>[],
|
||||
postprocessors?: ProtoProcessor<Function>[],
|
||||
init?: ProtoProcessor<InitMethod>,
|
||||
config?: ProtoProcessor<ConfigMethod>,
|
||||
priority?: number,
|
||||
parser?: string,
|
||||
} = {}): Configuration {
|
||||
return Configuration._create('', config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
private constructor(readonly name: string,
|
||||
readonly handler: HandlerConfig = {},
|
||||
readonly fallback: FallbackConfig = {},
|
||||
readonly items: StackItemConfig = {},
|
||||
readonly tags: TagsConfig = {},
|
||||
readonly options: OptionList = {},
|
||||
readonly nodes: {[key: string]: any} = {},
|
||||
readonly preprocessors: ProcessorList = [],
|
||||
readonly postprocessors: ProcessorList = [],
|
||||
readonly initMethod: Processor<InitMethod> = null,
|
||||
readonly configMethod: Processor<ConfigMethod> = null,
|
||||
public priority: number,
|
||||
readonly parser: string
|
||||
) {
|
||||
this.handler = Object.assign(
|
||||
{character: [], delimiter: [], macro: [], environment: []}, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* The init method.
|
||||
* @type {Function}
|
||||
*/
|
||||
public get init(): InitMethod {
|
||||
return this.initMethod ? this.initMethod[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The config method to call once jax is ready.
|
||||
* @type {FunctionList}
|
||||
*/
|
||||
public get config(): ConfigMethod {
|
||||
return this.configMethod ? this.configMethod[0] : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export namespace ConfigurationHandler {
|
||||
|
||||
let maps: Map<string, Configuration> = new Map();
|
||||
|
||||
/**
|
||||
* Adds a new configuration to the handler overwriting old ones.
|
||||
*
|
||||
* @param {string} name The name of the configuration.
|
||||
* @param {Configuration} map The configuration mapping.
|
||||
*/
|
||||
export let set = function(name: string, map: Configuration): void {
|
||||
maps.set(name, map);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Looks up a configuration.
|
||||
*
|
||||
* @param {string} name The name of the configuration.
|
||||
* @return {Configuration} The configuration with the given name or null.
|
||||
*/
|
||||
export let get = function(name: string): Configuration {
|
||||
return maps.get(name);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string[]} All configurations in the handler.
|
||||
*/
|
||||
export let keys = function(): IterableIterator<string> {
|
||||
return maps.keys();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parser configuration combines the configurations of the currently selected
|
||||
* packages.
|
||||
* @constructor
|
||||
*/
|
||||
export class ParserConfiguration {
|
||||
|
||||
/**
|
||||
* Priority list of init methods.
|
||||
* @type {FunctionList}
|
||||
*/
|
||||
protected initMethod: FunctionList = new FunctionList();
|
||||
|
||||
/**
|
||||
* Priority list of init methods to call once jax is ready.
|
||||
* @type {FunctionList}
|
||||
*/
|
||||
protected configMethod: FunctionList = new FunctionList();
|
||||
|
||||
/**
|
||||
* An ordered list of cofigurations.
|
||||
* @type {PrioritizedList<Configuration>}
|
||||
*/
|
||||
protected configurations: PrioritizedList<Configuration> = new PrioritizedList();
|
||||
|
||||
/**
|
||||
* The list of parsers this configuration targets
|
||||
*/
|
||||
protected parsers: string[] = [];
|
||||
|
||||
/**
|
||||
* The subhandlers for this configuration.
|
||||
* @type {SubHandlers}
|
||||
*/
|
||||
public handlers: SubHandlers = new SubHandlers();
|
||||
|
||||
/**
|
||||
* The collated stack items.
|
||||
* @type {StackItemConfig}
|
||||
*/
|
||||
public items: StackItemConfig = {};
|
||||
|
||||
/**
|
||||
* The collated tag configurations.
|
||||
* @type {TagsConfig}
|
||||
*/
|
||||
public tags: TagsConfig = {};
|
||||
|
||||
/**
|
||||
* The collated options.
|
||||
* @type {OptionList}
|
||||
*/
|
||||
public options: OptionList = {};
|
||||
|
||||
/**
|
||||
* The collated node creators.
|
||||
* @type {{[key: string]: any}}
|
||||
*/
|
||||
public nodes: {[key: string]: any} = {};
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {(string|[string,number])[]} packages A list of packages with
|
||||
* optional priorities.
|
||||
* @parm {string[]} parsers The names of the parsers this package targets
|
||||
*/
|
||||
constructor(packages: (string | [string, number])[], parsers: string[] = ['tex']) {
|
||||
this.parsers = parsers;
|
||||
for (const pkg of packages.slice().reverse()) {
|
||||
this.addPackage(pkg);
|
||||
}
|
||||
for (let {item: config, priority: priority} of this.configurations) {
|
||||
this.append(config, priority);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init method for the configuration;
|
||||
*/
|
||||
public init() {
|
||||
this.initMethod.execute(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init method for when the jax is ready
|
||||
* @param {TeX} jax The TeX jax for this configuration
|
||||
*/
|
||||
public config(jax: TeX<any, any, any>) {
|
||||
this.configMethod.execute(this, jax);
|
||||
for (const config of this.configurations) {
|
||||
this.addFilters(jax, config.item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves and adds configuration for a package with priority.
|
||||
* @param {(string | [string, number]} pkg Package with priority.
|
||||
*/
|
||||
public addPackage(pkg: (string | [string, number])) {
|
||||
const name = typeof pkg === 'string' ? pkg : pkg[0];
|
||||
const conf = this.getPackage(name);
|
||||
conf && this.configurations.add(conf, typeof pkg === 'string' ? conf.priority : pkg[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a configuration after the input jax is created. (Used by \require.)
|
||||
* Sets items, nodes and runs configuration method explicitly.
|
||||
*
|
||||
* @param {string} name The name of the package to add
|
||||
* @param {TeX} jax The TeX jax where it is being registered
|
||||
* @param {OptionList=} options The options for the configuration.
|
||||
*/
|
||||
public add(name: string, jax: TeX<any, any, any>, options: OptionList = {}) {
|
||||
const config = this.getPackage(name);
|
||||
this.append(config);
|
||||
this.configurations.add(config, config.priority);
|
||||
this.init();
|
||||
const parser = jax.parseOptions;
|
||||
parser.nodeFactory.setCreators(config.nodes);
|
||||
for (const kind of Object.keys(config.items)) {
|
||||
parser.itemFactory.setNodeClass(kind, config.items[kind]);
|
||||
}
|
||||
TagsFactory.addTags(config.tags);
|
||||
defaultOptions(parser.options, config.options);
|
||||
userOptions(parser.options, options);
|
||||
this.addFilters(jax, config);
|
||||
if (config.config) {
|
||||
config.config(this, jax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a package and check that it is for the targeted parser
|
||||
*
|
||||
* @param {string} name The name of the package to check
|
||||
* @return {Configuration} The configuration for the package
|
||||
*/
|
||||
protected getPackage(name: string): Configuration {
|
||||
const config = ConfigurationHandler.get(name);
|
||||
if (config && this.parsers.indexOf(config.parser) < 0) {
|
||||
throw Error(`Package ${name} doesn't target the proper parser`);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a configuration to the overall configuration object.
|
||||
* @param {Configuration} config A configuration.
|
||||
* @param {number} priority The configurations optional priority.
|
||||
*/
|
||||
public append(config: Configuration, priority?: number) {
|
||||
priority = priority || config.priority;
|
||||
if (config.initMethod) {
|
||||
this.initMethod.add(config.initMethod[0], config.initMethod[1]);
|
||||
}
|
||||
if (config.configMethod) {
|
||||
this.configMethod.add(config.configMethod[0], config.configMethod[1]);
|
||||
}
|
||||
this.handlers.add(config.handler, config.fallback, priority);
|
||||
Object.assign(this.items, config.items);
|
||||
Object.assign(this.tags, config.tags);
|
||||
defaultOptions(this.options, config.options);
|
||||
Object.assign(this.nodes, config.nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds pre- and postprocessor as filters to the jax.
|
||||
* @param {TeX<any} jax The TeX Jax.
|
||||
* @param {Configuration} config The configuration whose processors are added.
|
||||
*/
|
||||
private addFilters(jax: TeX<any, any, any>, config: Configuration) {
|
||||
for (const [pre, priority] of config.preprocessors) {
|
||||
jax.preFilters.add(pre, priority);
|
||||
}
|
||||
for (const [post, priority] of config.postprocessors) {
|
||||
jax.postFilters.add(post, priority);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
295
node_modules/mathjax-full/ts/input/tex/FilterUtil.ts
generated
vendored
Normal file
295
node_modules/mathjax-full/ts/input/tex/FilterUtil.ts
generated
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Utility functions for standard pre and post filters.
|
||||
*
|
||||
* @author sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import {TEXCLASS, MMLNODE, MmlNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import NodeUtil from './NodeUtil.js';
|
||||
import ParseOptions from './ParseOptions.js';
|
||||
import {MmlMo} from '../../core/MmlTree/MmlNodes/mo.js';
|
||||
import {Attributes} from '../../core/MmlTree/Attributes.js';
|
||||
|
||||
|
||||
namespace FilterUtil {
|
||||
|
||||
/**
|
||||
* Visitor to set stretchy attributes to false on <mo> elements, if they are
|
||||
* not used as delimiters. Also wraps non-stretchy infix delimiters into a
|
||||
* TeXAtom.
|
||||
* @param {MmlNode} math The node to rewrite.
|
||||
* @param {ParseOptions} data The parse options.
|
||||
*/
|
||||
export let cleanStretchy = function(arg: {math: any, data: ParseOptions}) {
|
||||
let options = arg.data;
|
||||
for (let mo of options.getList('fixStretchy')) {
|
||||
if (NodeUtil.getProperty(mo, 'fixStretchy')) {
|
||||
let symbol = NodeUtil.getForm(mo);
|
||||
if (symbol && symbol[3] && symbol[3]['stretchy']) {
|
||||
NodeUtil.setAttribute(mo, 'stretchy', false);
|
||||
}
|
||||
const parent = mo.parent;
|
||||
if (!NodeUtil.getTexClass(mo) && (!symbol || !symbol[2])) {
|
||||
const texAtom = options.nodeFactory.create('node', 'TeXAtom', [mo]);
|
||||
parent.replaceChild(texAtom, mo);
|
||||
texAtom.inheritAttributesFrom(mo);
|
||||
}
|
||||
NodeUtil.removeProperties(mo, 'fixStretchy');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Visitor that removes superfluous attributes from nodes. I.e., if a node has
|
||||
* an attribute, which is also an inherited attribute it will be removed. This
|
||||
* is necessary as attributes are set bottom up in the parser.
|
||||
* @param {ParseOptions} data The parse options.
|
||||
*/
|
||||
export let cleanAttributes = function(arg: {data: ParseOptions}) {
|
||||
let node = arg.data.root as MmlNode;
|
||||
node.walkTree((mml: MmlNode, _d: any) => {
|
||||
let attribs = mml.attributes as any;
|
||||
if (!attribs) {
|
||||
return;
|
||||
}
|
||||
const keep = new Set((attribs.get('mjx-keep-attrs') || '').split(/ /));
|
||||
delete (attribs.getAllAttributes())['mjx-keep-attrs'];
|
||||
for (const key of attribs.getExplicitNames()) {
|
||||
if (!keep.has(key) && attribs.attributes[key] === mml.attributes.getInherited(key)) {
|
||||
delete attribs.attributes[key];
|
||||
}
|
||||
}
|
||||
}, {});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Combine adjacent <mo> elements that are relations (since MathML treats the
|
||||
* spacing very differently)
|
||||
* @param {ParseOptions} data The parse options.
|
||||
*/
|
||||
export let combineRelations = function(arg: {data: ParseOptions}) {
|
||||
const remove: MmlNode[] = [];
|
||||
for (let mo of arg.data.getList('mo')) {
|
||||
if (mo.getProperty('relationsCombined') || !mo.parent ||
|
||||
(mo.parent && !NodeUtil.isType(mo.parent, 'mrow')) ||
|
||||
NodeUtil.getTexClass(mo) !== TEXCLASS.REL) {
|
||||
// @test Prime, PrimeSup, Named Function
|
||||
continue;
|
||||
}
|
||||
let mml = mo.parent;
|
||||
let m2: MmlNode;
|
||||
let children = mml.childNodes as MMLNODE[];
|
||||
let next = children.indexOf(mo) + 1;
|
||||
let variantForm = NodeUtil.getProperty(mo, 'variantForm');
|
||||
while (next < children.length && (m2 = children[next]) &&
|
||||
NodeUtil.isType(m2, 'mo') &&
|
||||
NodeUtil.getTexClass(m2) === TEXCLASS.REL) {
|
||||
if (variantForm === NodeUtil.getProperty(m2, 'variantForm') &&
|
||||
_compareExplicit(mo, m2)) {
|
||||
// @test Shift Left, Less Equal,
|
||||
// Multirel Font X, Multirel Mathvariant X
|
||||
NodeUtil.appendChildren(mo, NodeUtil.getChildren(m2));
|
||||
// This treatment means we might loose some inheritance structure, but
|
||||
// no properties.
|
||||
_copyExplicit(['stretchy', 'rspace'], mo, m2);
|
||||
for (const name of m2.getPropertyNames()) {
|
||||
mo.setProperty(name, m2.getProperty(name));
|
||||
}
|
||||
children.splice(next, 1);
|
||||
remove.push(m2);
|
||||
m2.parent = null;
|
||||
m2.setProperty('relationsCombined', true);
|
||||
} else {
|
||||
// @test Preset Rspace Lspace
|
||||
if (mo.attributes.getExplicit('rspace') == null) {
|
||||
// @test Mulitrel Mathvariant 3, Mulitrel Mathvariant 4
|
||||
NodeUtil.setAttribute(mo, 'rspace', '0pt');
|
||||
}
|
||||
if (m2.attributes.getExplicit('lspace') == null) {
|
||||
// @test Mulitrel Mathvariant 3, Mulitrel Mathvariant 4
|
||||
NodeUtil.setAttribute(m2, 'lspace', '0pt');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
mo.attributes.setInherited('form', (mo as MmlMo).getForms()[0]);
|
||||
}
|
||||
arg.data.removeFromList('mo', remove);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Copies the specified explicit attributes from node2 to node1.
|
||||
* @param {string[]} attrs List of explicit attribute names.
|
||||
* @param {MmlNode} node1 The goal node.
|
||||
* @param {MmlNode} node2 The source node.
|
||||
*/
|
||||
let _copyExplicit = function(attrs: string[],
|
||||
node1: MmlNode, node2: MmlNode) {
|
||||
let attr1 = node1.attributes;
|
||||
let attr2 = node2.attributes;
|
||||
attrs.forEach(x => {
|
||||
let attr = attr2.getExplicit(x);
|
||||
if (attr != null) {
|
||||
// @test Infix Stretchy Right, Preset Lspace Rspace
|
||||
attr1.set(x, attr);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares the explicit attributes of two nodes. Returns true if they
|
||||
* coincide, with the following exceptions:
|
||||
* - lspace attribute of node1 is ignored.
|
||||
* - rspace attribute of node2 is ignored.
|
||||
* - stretchy=false attributes are ignored.
|
||||
* @param {MmlNode} node1 The first node.
|
||||
* @param {MmlNode} node2 Its next sibling.
|
||||
*/
|
||||
let _compareExplicit = function(node1: MmlNode, node2: MmlNode) {
|
||||
let filter = (attr: Attributes, space: string): string[] => {
|
||||
let exp = attr.getExplicitNames();
|
||||
return exp.filter(x => {
|
||||
return x !== space &&
|
||||
(x !== 'stretchy' ||
|
||||
attr.getExplicit('stretchy'));
|
||||
});
|
||||
};
|
||||
let attr1 = node1.attributes;
|
||||
let attr2 = node2.attributes;
|
||||
let exp1 = filter(attr1, 'lspace');
|
||||
let exp2 = filter(attr2, 'rspace');
|
||||
if (exp1.length !== exp2.length) {
|
||||
return false;
|
||||
}
|
||||
for (let name of exp1) {
|
||||
if (attr1.getExplicit(name) !== attr2.getExplicit(name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cleans msubsup and munderover elements.
|
||||
* @param {ParseOptions} options The parse options.
|
||||
* @param {string} low String representing the lower part of the expression.
|
||||
* @param {string} up String representing the upper part.
|
||||
*/
|
||||
let _cleanSubSup = function(options: ParseOptions, low: string, up: string) {
|
||||
const remove: MmlNode[] = [];
|
||||
for (let mml of options.getList('m' + low + up) as any[]) {
|
||||
const children = mml.childNodes;
|
||||
if (children[mml[low]] && children[mml[up]]) {
|
||||
continue;
|
||||
}
|
||||
const parent = mml.parent;
|
||||
let newNode = (children[mml[low]] ?
|
||||
options.nodeFactory.create('node', 'm' + low, [children[mml.base], children[mml[low]]]) :
|
||||
options.nodeFactory.create('node', 'm' + up, [children[mml.base], children[mml[up]]]));
|
||||
NodeUtil.copyAttributes(mml, newNode);
|
||||
if (parent) {
|
||||
parent.replaceChild(newNode, mml);
|
||||
} else {
|
||||
options.root = newNode;
|
||||
}
|
||||
remove.push(mml);
|
||||
}
|
||||
options.removeFromList('m' + low + up, remove);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Visitor that rewrites incomplete msubsup/munderover elements in the given
|
||||
* node into corresponding msub/sup/under/over nodes.
|
||||
* @param {MmlNode} math The node to rewrite.
|
||||
* @param {ParseOptions} data The parse options.
|
||||
*/
|
||||
export let cleanSubSup = function(arg: {math: any, data: ParseOptions}) {
|
||||
let options = arg.data;
|
||||
if (options.error) {
|
||||
return;
|
||||
}
|
||||
_cleanSubSup(options, 'sub', 'sup');
|
||||
_cleanSubSup(options, 'under', 'over');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Looks through the list of munderover elements for ones that have
|
||||
* movablelimits and bases that are not mo's, and creates new msubsup
|
||||
* elements to replace them if they aren't in displaystyle.
|
||||
*
|
||||
* @param {MmlNode} ath The node to rewrite.
|
||||
* @param {ParseOptions} data The parse options.
|
||||
*/
|
||||
let _moveLimits = function (options: ParseOptions, underover: string, subsup: string) {
|
||||
const remove: MmlNode[] = [];
|
||||
for (const mml of options.getList(underover)) {
|
||||
if (mml.attributes.get('displaystyle')) {
|
||||
continue;
|
||||
}
|
||||
const base = mml.childNodes[(mml as any).base] as MmlNode;
|
||||
const mo = base.coreMO();
|
||||
if (base.getProperty('movablelimits') && !mo.attributes.getExplicit('movablelimits')) {
|
||||
let node = options.nodeFactory.create('node', subsup, mml.childNodes);
|
||||
NodeUtil.copyAttributes(mml, node);
|
||||
if (mml.parent) {
|
||||
mml.parent.replaceChild(node, mml);
|
||||
} else {
|
||||
options.root = node;
|
||||
}
|
||||
remove.push(mml);
|
||||
}
|
||||
}
|
||||
options.removeFromList(underover, remove);
|
||||
};
|
||||
|
||||
/**
|
||||
* Visitor that rewrites in-line munderover elements with movablelimits but bases
|
||||
* that are not mo's into explicit msubsup elements.
|
||||
*
|
||||
* @param {ParseOptions} data The parse options to use
|
||||
*/
|
||||
export let moveLimits = function (arg: {data: ParseOptions}) {
|
||||
const options = arg.data;
|
||||
_moveLimits(options, 'munderover', 'msubsup');
|
||||
_moveLimits(options, 'munder', 'msub');
|
||||
_moveLimits(options, 'mover', 'msup');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Recursively sets the inherited attributes on the math tree.
|
||||
* @param {MmlNode} math The node to rewrite.
|
||||
* @param {ParseOptions} data The parse options.
|
||||
*/
|
||||
export let setInherited = function(arg: {math: any, data: ParseOptions}) {
|
||||
arg.data.root.setInheritedAttributes({}, arg.math['display'], 0, false);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default FilterUtil;
|
||||
241
node_modules/mathjax-full/ts/input/tex/FindTeX.ts
generated
vendored
Normal file
241
node_modules/mathjax-full/ts/input/tex/FindTeX.ts
generated
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Implements the TeX version of the FindMath object
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
import {AbstractFindMath} from '../../core/FindMath.js';
|
||||
import {OptionList} from '../../util/Options.js';
|
||||
import {sortLength, quotePattern} from '../../util/string.js';
|
||||
import {ProtoItem, protoItem} from '../../core/MathItem.js';
|
||||
|
||||
/**
|
||||
* Shorthand types for data about end delimiters and delimiter pairs
|
||||
*/
|
||||
export type EndItem = [string, boolean, RegExp];
|
||||
export type Delims = [string, string];
|
||||
|
||||
/*****************************************************************/
|
||||
/*
|
||||
* Implements the FindTeX class (extends AbstractFindMath)
|
||||
*
|
||||
* Locates TeX expressions within strings
|
||||
*/
|
||||
|
||||
/*
|
||||
* @template N The HTMLElement node class
|
||||
* @template T The Text node class
|
||||
* @template D The Document class
|
||||
*/
|
||||
export class FindTeX<N, T, D> extends AbstractFindMath<N, T, D> {
|
||||
|
||||
/**
|
||||
* @type {OptionList}
|
||||
*/
|
||||
public static OPTIONS: OptionList = {
|
||||
inlineMath: [ // The start/end delimiter pairs for in-line math
|
||||
// ['$', '$'], // (comment out any you don't want, or add your own, but
|
||||
['\\(', '\\)'] // be sure that you don't have an extra comma at the end)
|
||||
],
|
||||
|
||||
displayMath: [ // The start/end delimiter pairs for display math
|
||||
['$$', '$$'], // (comment out any you don't want, or add your own, but
|
||||
['\\[', '\\]'] // be sure that you don't have an extra comma at the end)
|
||||
],
|
||||
|
||||
processEscapes: true, // set to true to allow \$ to produce a dollar without
|
||||
// starting in-line math mode
|
||||
processEnvironments: true, // set to true to process \begin{xxx}...\end{xxx} outside
|
||||
// of math mode, false to prevent that
|
||||
processRefs: true, // set to true to process \ref{...} outside of math mode
|
||||
};
|
||||
|
||||
/**
|
||||
* The regular expression for any starting delimiter
|
||||
*/
|
||||
protected start: RegExp;
|
||||
|
||||
/**
|
||||
* The end-delimiter data keyed to the opening delimiter string
|
||||
*/
|
||||
protected end: {[name: string]: EndItem};
|
||||
|
||||
/**
|
||||
* False if the configuration has no delimiters (so search can be skipped), true otherwise
|
||||
*/
|
||||
protected hasPatterns: boolean;
|
||||
|
||||
/**
|
||||
* The index of the \begin...\end pattern in the regex match array
|
||||
*/
|
||||
protected env: number;
|
||||
|
||||
/**
|
||||
* The index of the \ref and escaped character patters in the regex match array
|
||||
*/
|
||||
protected sub: number;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
constructor(options: OptionList) {
|
||||
super(options);
|
||||
this.getPatterns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the patterns needed for searching the strings for TeX
|
||||
* based on the configuration options
|
||||
*/
|
||||
protected getPatterns() {
|
||||
let options = this.options;
|
||||
let starts: string[] = [], parts: string[] = [], subparts: string[] = [];
|
||||
this.end = {};
|
||||
this.env = this.sub = 0;
|
||||
let i = 1;
|
||||
options['inlineMath'].forEach((delims: Delims) => this.addPattern(starts, delims, false));
|
||||
options['displayMath'].forEach((delims: Delims) => this.addPattern(starts, delims, true));
|
||||
if (starts.length) {
|
||||
parts.push(starts.sort(sortLength).join('|'));
|
||||
}
|
||||
if (options['processEnvironments']) {
|
||||
parts.push('\\\\begin\\s*\\{([^}]*)\\}');
|
||||
this.env = i;
|
||||
i++;
|
||||
}
|
||||
if (options['processEscapes']) {
|
||||
subparts.push('\\\\([\\\\$])');
|
||||
}
|
||||
if (options['processRefs']) {
|
||||
subparts.push('(\\\\(?:eq)?ref\\s*\\{[^}]*\\})');
|
||||
}
|
||||
if (subparts.length) {
|
||||
parts.push('(' + subparts.join('|') + ')');
|
||||
this.sub = i;
|
||||
}
|
||||
this.start = new RegExp(parts.join('|'), 'g');
|
||||
this.hasPatterns = (parts.length > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the needed patterns for a pair of delimiters
|
||||
*
|
||||
* @param {string[]} starts Array of starting delimiter strings
|
||||
* @param {Delims} delims Array of delimiter strings, as [start, end]
|
||||
* @param {boolean} display True if the delimiters are for display mode
|
||||
*/
|
||||
protected addPattern(starts: string[], delims: Delims, display: boolean) {
|
||||
let [open, close] = delims;
|
||||
starts.push(quotePattern(open));
|
||||
this.end[open] = [close, display, this.endPattern(close)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the pattern for a close delimiter
|
||||
*
|
||||
* @param {string} end The end delimiter text
|
||||
* @param {string} endp The end delimiter pattern (overrides the literal end pattern)
|
||||
* @return {RegExp} The regular expression for the end delimiter
|
||||
*/
|
||||
protected endPattern(end: string, endp?: string): RegExp {
|
||||
return new RegExp((endp || quotePattern(end)) + '|\\\\(?:[a-zA-Z]|.)|[{}]', 'g');
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the end delimiter given the start delimiter,
|
||||
* skipping braced groups, and control sequences that aren't
|
||||
* the close delimiter.
|
||||
*
|
||||
* @param {string} text The string being searched for the end delimiter
|
||||
* @param {number} n The index of the string being searched
|
||||
* @param {RegExpExecArray} start The result array from the start-delimiter search
|
||||
* @param {EndItem} end The end-delimiter data corresponding to the start delimiter
|
||||
* @return {ProtoItem<N,T>} The proto math item for the math, if found
|
||||
*/
|
||||
protected findEnd(text: string, n: number, start: RegExpExecArray, end: EndItem): ProtoItem<N, T> {
|
||||
let [close, display, pattern] = end;
|
||||
let i = pattern.lastIndex = start.index + start[0].length;
|
||||
let match: RegExpExecArray, braces: number = 0;
|
||||
while ((match = pattern.exec(text))) {
|
||||
if ((match[1] || match[0]) === close && braces === 0) {
|
||||
return protoItem<N, T>(start[0], text.substr(i, match.index - i), match[0],
|
||||
n, start.index, match.index + match[0].length, display);
|
||||
} else if (match[0] === '{') {
|
||||
braces++;
|
||||
} else if (match[0] === '}' && braces) {
|
||||
braces--;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a string for math delimited by one of the delimiter pairs,
|
||||
* or by \begin{env}...\end{env}, or \eqref{...}, \ref{...}, \\, or \$.
|
||||
*
|
||||
* @param {ProtoItem[]} math The array of proto math items located so far
|
||||
* @param {number} n The index of the string being searched
|
||||
* @param {string} text The string being searched
|
||||
*/
|
||||
protected findMathInString(math: ProtoItem<N, T>[], n: number, text: string) {
|
||||
let start, match;
|
||||
this.start.lastIndex = 0;
|
||||
while ((start = this.start.exec(text))) {
|
||||
if (start[this.env] !== undefined && this.env) {
|
||||
let end = '\\\\end\\s*(\\{' + quotePattern(start[this.env]) + '\\})';
|
||||
match = this.findEnd(text, n, start, ['{' + start[this.env] + '}', true, this.endPattern(null, end)]);
|
||||
if (match) {
|
||||
match.math = match.open + match.math + match.close;
|
||||
match.open = match.close = '';
|
||||
}
|
||||
} else if (start[this.sub] !== undefined && this.sub) {
|
||||
let math = start[this.sub];
|
||||
let end = start.index + start[this.sub].length;
|
||||
if (math.length === 2) {
|
||||
match = protoItem<N, T>('', math.substr(1), '', n, start.index, end);
|
||||
} else {
|
||||
match = protoItem<N, T>('', math, '', n, start.index, end, false);
|
||||
}
|
||||
} else {
|
||||
match = this.findEnd(text, n, start, this.end[start[0]]);
|
||||
}
|
||||
if (match) {
|
||||
math.push(match);
|
||||
this.start.lastIndex = match.end.n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for math in an array of strings and return an array of matches.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public findMath(strings: string[]) {
|
||||
let math: ProtoItem<N, T>[] = [];
|
||||
if (this.hasPatterns) {
|
||||
for (let i = 0, m = strings.length; i < m; i++) {
|
||||
this.findMathInString(math, i, strings[i]);
|
||||
}
|
||||
}
|
||||
return math;
|
||||
}
|
||||
|
||||
}
|
||||
255
node_modules/mathjax-full/ts/input/tex/MapHandler.ts
generated
vendored
Normal file
255
node_modules/mathjax-full/ts/input/tex/MapHandler.ts
generated
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Singleton class for handling symbol maps.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {AbstractSymbolMap, SymbolMap} from './SymbolMap.js';
|
||||
import {ParseInput, ParseResult, ParseMethod} from './Types.js';
|
||||
// import {ParserConfiguration} from './Configuration.js';
|
||||
import {PrioritizedList} from '../../util/PrioritizedList.js';
|
||||
import {FunctionList} from '../../util/FunctionList.js';
|
||||
|
||||
|
||||
export type HandlerType = 'delimiter' | 'macro' | 'character' | 'environment';
|
||||
|
||||
export type HandlerConfig = {[P in HandlerType]?: string[]};
|
||||
export type FallbackConfig = {[P in HandlerType]?: ParseMethod};
|
||||
|
||||
|
||||
export namespace MapHandler {
|
||||
|
||||
let maps: Map<string, SymbolMap> = new Map();
|
||||
|
||||
/**
|
||||
* Adds a new symbol map to the map handler. Might overwrite an existing
|
||||
* symbol map of the same name.
|
||||
*
|
||||
* @param {SymbolMap} map Registers a new symbol map.
|
||||
*/
|
||||
export let register = function(map: SymbolMap): void {
|
||||
maps.set(map.name, map);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Looks up a symbol map if it exists.
|
||||
*
|
||||
* @param {string} name The name of the symbol map.
|
||||
* @return {SymbolMap} The symbol map with the given name or null.
|
||||
*/
|
||||
export let getMap = function(name: string): SymbolMap {
|
||||
return maps.get(name);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class of symbol mappings that are active in a configuration.
|
||||
*/
|
||||
export class SubHandler {
|
||||
|
||||
private _configuration: PrioritizedList<SymbolMap> = new PrioritizedList<SymbolMap>();
|
||||
private _fallback: FunctionList = new FunctionList();
|
||||
|
||||
/**
|
||||
* Adds a list of symbol maps to the handler.
|
||||
* @param {string[]} maps The names of the symbol maps to add.
|
||||
* @param {ParseMethod} fallback A fallback method.
|
||||
* @param {number} priority Optionally a priority.
|
||||
*/
|
||||
public add(maps: string[], fallback: ParseMethod,
|
||||
priority: number = PrioritizedList.DEFAULTPRIORITY) {
|
||||
for (const name of maps.slice().reverse()) {
|
||||
let map = MapHandler.getMap(name);
|
||||
if (!map) {
|
||||
this.warn('Configuration ' + name + ' not found! Omitted.');
|
||||
return;
|
||||
}
|
||||
this._configuration.add(map, priority);
|
||||
}
|
||||
if (fallback) {
|
||||
this._fallback.add(fallback, priority);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given input with the first applicable symbol map.
|
||||
* @param {ParseInput} input The input for the parser.
|
||||
* @return {ParseResult} The output of the parsing function.
|
||||
*/
|
||||
public parse(input: ParseInput): ParseResult {
|
||||
for (let {item: map} of this._configuration) {
|
||||
const result = map.parse(input);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
let [env, symbol] = input;
|
||||
Array.from(this._fallback)[0].item(env, symbol);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps a symbol to its "parse value" if it exists.
|
||||
*
|
||||
* @param {string} symbol The symbol to parse.
|
||||
* @return {T} A boolean, Character, or Macro.
|
||||
*/
|
||||
public lookup<T>(symbol: string): T {
|
||||
let map = this.applicable(symbol) as AbstractSymbolMap<T>;
|
||||
return map ? map.lookup(symbol) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a symbol is contained in one of the symbol mappings of this
|
||||
* configuration.
|
||||
*
|
||||
* @param {string} symbol The symbol to parse.
|
||||
* @return {boolean} True if the symbol is contained in the mapping.
|
||||
*/
|
||||
public contains(symbol: string): boolean {
|
||||
return this.applicable(symbol) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public toString(): string {
|
||||
let names = [];
|
||||
for (let {item: map} of this._configuration) {
|
||||
names.push(map.name);
|
||||
}
|
||||
return names.join(', ');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the first applicable symbol map in the configuration.
|
||||
* @param {string} symbol The symbol to parse.
|
||||
* @return {SymbolMap} A map that can parse the symbol.
|
||||
*/
|
||||
public applicable(symbol: string): SymbolMap {
|
||||
for (let {item: map} of this._configuration) {
|
||||
if (map.contains(symbol)) {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the map of the given name.
|
||||
* @param {string} name Name of the symbol map.
|
||||
* @return {SymbolMap} The map if it exists.
|
||||
*/
|
||||
public retrieve(name: string): SymbolMap {
|
||||
for (let {item: map} of this._configuration) {
|
||||
if (map.name === name) {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prints a warning message.
|
||||
* @param {string} message The warning.
|
||||
*/
|
||||
private warn(message: string) {
|
||||
console.log('TexParser Warning: ' + message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export class SubHandlers {
|
||||
|
||||
private map = new Map<HandlerType, SubHandler>();
|
||||
|
||||
/**
|
||||
* Adds a symbol map to the configuration if it exists.
|
||||
* @param {string} name of the symbol map.
|
||||
*/
|
||||
public add(handlers: HandlerConfig, fallbacks: FallbackConfig,
|
||||
priority: number = PrioritizedList.DEFAULTPRIORITY): void {
|
||||
for (const key of Object.keys(handlers)) {
|
||||
let name = key as HandlerType;
|
||||
let subHandler = this.get(name);
|
||||
if (!subHandler) {
|
||||
subHandler = new SubHandler();
|
||||
this.set(name, subHandler);
|
||||
}
|
||||
subHandler.add(handlers[name], fallbacks[name], priority);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for subhandlers.
|
||||
* @param {HandlerType} name The name of the subhandler.
|
||||
* @param {SubHandler} subHandler The subhandler.
|
||||
*/
|
||||
public set(name: HandlerType, subHandler: SubHandler) {
|
||||
this.map.set(name, subHandler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for subhandler.
|
||||
* @param {HandlerType} name Name of the subhandler.
|
||||
* @return {SubHandler} The subhandler by that name if it exists.
|
||||
*/
|
||||
public get(name: HandlerType): SubHandler {
|
||||
return this.map.get(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a symbol map of the given name.
|
||||
* @param {string} name Name of the symbol map.
|
||||
* @return {SymbolMap} The map if it exists. O/w null.
|
||||
*/
|
||||
public retrieve(name: string): SymbolMap {
|
||||
for (const handler of this.map.values()) {
|
||||
let map = handler.retrieve(name);
|
||||
if (map) {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* All names of registered subhandlers.
|
||||
* @return {IterableIterator<string>} Iterable list of keys.
|
||||
*/
|
||||
public keys(): IterableIterator<string> {
|
||||
return this.map.keys();
|
||||
}
|
||||
|
||||
}
|
||||
176
node_modules/mathjax-full/ts/input/tex/NodeFactory.ts
generated
vendored
Normal file
176
node_modules/mathjax-full/ts/input/tex/NodeFactory.ts
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Node factory for creating MmlNodes. This allows extension
|
||||
* packages to add node constructors or overwrite existing ones.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {TextNode, MmlNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import {MmlFactory} from '../../core/MmlTree/MmlFactory.js';
|
||||
import ParseOptions from './ParseOptions.js';
|
||||
import NodeUtil from './NodeUtil.js';
|
||||
|
||||
|
||||
export type NodeFactoryMethod = (factory: NodeFactory, kind: string, ...rest: any[]) => MmlNode;
|
||||
|
||||
export class NodeFactory {
|
||||
|
||||
/**
|
||||
* Parser configuration that can be used to pass information between node methods.
|
||||
* @type {ParseOption}
|
||||
*/
|
||||
public configuration: ParseOptions;
|
||||
|
||||
|
||||
/**
|
||||
* The external node factory.
|
||||
* @type {MmlFactory}
|
||||
*/
|
||||
protected mmlFactory: MmlFactory = null;
|
||||
|
||||
|
||||
/**
|
||||
* The factory table populated with some default methods.
|
||||
*/
|
||||
private factory: {[kind: string]: NodeFactoryMethod} =
|
||||
{'node': NodeFactory.createNode,
|
||||
'token': NodeFactory.createToken,
|
||||
'text': NodeFactory.createText,
|
||||
'error': NodeFactory.createError
|
||||
};
|
||||
|
||||
/**
|
||||
* Default node generation function.
|
||||
* @param {NodeFactory} factory The current node factory.
|
||||
* @param {string} kind The type of node to create.
|
||||
* @param {MmlNode[]} children Its children.
|
||||
* @param {any=} def Its properties.
|
||||
* @param {TextNode=} text An optional text node if this is a token.
|
||||
* @return {MmlNode} The newly created Mml node.
|
||||
*/
|
||||
public static createNode(factory: NodeFactory, kind: string,
|
||||
children: MmlNode[] = [], def: any = {},
|
||||
text?: TextNode): MmlNode {
|
||||
const node = factory.mmlFactory.create(kind);
|
||||
node.setChildren(children);
|
||||
if (text) {
|
||||
node.appendChild(text);
|
||||
}
|
||||
NodeUtil.setProperties(node, def);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default token generation function.
|
||||
* @param {NodeFactory} factory The current node factory.
|
||||
* @param {string} kind The type of node to create.
|
||||
* @param {any} def Its properties.
|
||||
* @param {string} text Text of the token.
|
||||
* @return {MmlNode} The newly created token node.
|
||||
*/
|
||||
public static createToken(factory: NodeFactory, kind: string,
|
||||
def: any = {}, text: string = ''): MmlNode {
|
||||
const textNode = factory.create('text', text);
|
||||
return factory.create('node', kind, [], def, textNode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default text node generation function.
|
||||
* @param {NodeFactory} factory The current node factory.
|
||||
* @param {string} text The text for the new node.
|
||||
* @return {TextNode} The newly created text node.
|
||||
*/
|
||||
public static createText(factory: NodeFactory, text: string): TextNode {
|
||||
if (text == null) {
|
||||
return null;
|
||||
}
|
||||
return (factory.mmlFactory.create('text') as TextNode).setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default error node generation function.
|
||||
* @param {NodeFactory} factory The current node factory.
|
||||
* @param {string} message The error message.
|
||||
* @return {MmlNode} The newly created error node.
|
||||
*/
|
||||
public static createError(factory: NodeFactory, message: string): MmlNode {
|
||||
let text = factory.create('text', message);
|
||||
let mtext = factory.create('node', 'mtext', [], {}, text);
|
||||
let error = factory.create('node', 'merror', [mtext], {'data-mjx-error': message});
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {MmlFactory} mmlFactory The MmlFactory for the TeX jax to use
|
||||
*/
|
||||
public setMmlFactory(mmlFactory: MmlFactory) {
|
||||
this.mmlFactory = mmlFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a method to the factory.
|
||||
* @param {string} kind The type of node the method creates.
|
||||
* @param {NodeFactoryMethod} func The node creator.
|
||||
*/
|
||||
public set(kind: string, func: NodeFactoryMethod) {
|
||||
this.factory[kind] = func;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a set of node creators to the factory.
|
||||
* @param {Object.<NodeFactoryMethod>} maps The set of functions.
|
||||
*/
|
||||
public setCreators(maps: {[kind: string]: NodeFactoryMethod}) {
|
||||
for (let kind in maps) {
|
||||
this.set(kind, maps[kind]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a node for the internal data structure from the factory.
|
||||
* @param {string} kind The type of node to be created.
|
||||
* @param {any[]} ...rest The arguments for the node.
|
||||
* @return {MmlNode} The created node.
|
||||
*/
|
||||
public create(kind: string, ...rest: any[]): MmlNode {
|
||||
const func = this.factory[kind] || this.factory['node'];
|
||||
const node = func(this, rest[0], ...rest.slice(1));
|
||||
if (kind === 'node') {
|
||||
this.configuration.addNode(rest[0], node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} kind The method for generating a node of given kind.
|
||||
*/
|
||||
public get(kind: string) {
|
||||
return this.factory[kind];
|
||||
}
|
||||
|
||||
}
|
||||
306
node_modules/mathjax-full/ts/input/tex/NodeUtil.ts
generated
vendored
Normal file
306
node_modules/mathjax-full/ts/input/tex/NodeUtil.ts
generated
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Node utility methods.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {TextNode, MMLNODE, MmlNode, AbstractMmlNode, AbstractMmlEmptyNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import {MmlMo} from '../../core/MmlTree/MmlNodes/mo.js';
|
||||
import {Property, PropertyList} from '../../core/Tree/Node.js';
|
||||
import {Args} from './Types.js';
|
||||
import {OperatorDef} from '../../core/MmlTree/OperatorDictionary.js';
|
||||
|
||||
|
||||
namespace NodeUtil {
|
||||
|
||||
const attrs: Map<String, boolean> = new Map([
|
||||
['autoOP', true],
|
||||
['fnOP', true],
|
||||
['movesupsub', true],
|
||||
['subsupOK', true],
|
||||
['texprimestyle', true],
|
||||
['useHeight', true],
|
||||
['variantForm', true],
|
||||
['withDelims', true],
|
||||
['mathaccent', true],
|
||||
['open', true],
|
||||
['close', true]
|
||||
]);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a single character from a unicode hex string.
|
||||
* @param {string} code The code.
|
||||
* @return {string} The newly created entity.
|
||||
*/
|
||||
export function createEntity(code: string): string {
|
||||
return String.fromCodePoint(parseInt(code, 16));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the children of the a node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @return {MMLNODE[]} Its children.
|
||||
*/
|
||||
export function getChildren(node: MmlNode): MMLNODE[] {
|
||||
return (node.childNodes as MMLNODE[]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get text content of a node.
|
||||
* @param {TextNode} node The node.
|
||||
* @return {string} Its text content.
|
||||
*/
|
||||
export function getText(node: TextNode): string {
|
||||
return node.getText();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Append children to a node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {MMLNODE[]} children A list of new children.
|
||||
*/
|
||||
export function appendChildren(node: MmlNode, children: MMLNODE[]) {
|
||||
for (let child of children) {
|
||||
node.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets an attribute of a node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {string} attribute An attribute.
|
||||
* @param {Args} value The attribute value.
|
||||
*/
|
||||
export function setAttribute(node: MmlNode, attribute: string, value: Args) {
|
||||
node.attributes.set(attribute, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a property of a node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {string} property The property.
|
||||
* @param {Args} value The property value.
|
||||
*/
|
||||
export function setProperty(node: MmlNode, property: string, value: Args) {
|
||||
node.setProperty(property, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets properties and attributes of a node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {PropertyList} properties A list of property/attribute value pairs.
|
||||
*/
|
||||
export function setProperties(node: MmlNode, properties: PropertyList) {
|
||||
for (const name of Object.keys(properties)) {
|
||||
let value = properties[name];
|
||||
if (name === 'texClass') {
|
||||
node.texClass = (value as number);
|
||||
node.setProperty(name, value);
|
||||
} else if (name === 'movablelimits') {
|
||||
node.setProperty('movablelimits', value);
|
||||
if (node.isKind('mo') || node.isKind('mstyle')) {
|
||||
node.attributes.set('movablelimits', value);
|
||||
}
|
||||
} else if (name === 'inferred') {
|
||||
// ignore
|
||||
} else if (attrs.has(name)) {
|
||||
node.setProperty(name, value);
|
||||
} else {
|
||||
node.attributes.set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the property of a node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {string} property A property name.
|
||||
* @return {Property} Value of the property.
|
||||
*/
|
||||
export function getProperty(node: MmlNode, property: string): Property {
|
||||
return node.getProperty(property);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the attribute of a node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {string} attr A attribute name.
|
||||
* @return {Property} Value of the attribute.
|
||||
*/
|
||||
export function getAttribute(node: MmlNode, attr: string): Property {
|
||||
return node.attributes.get(attr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a set of properties from a node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {string[]} ...properties A list of properties.
|
||||
*/
|
||||
export function removeProperties(node: MmlNode, ...properties: string[]) {
|
||||
node.removeProperty(...properties);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a child node at a given position.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {number} position The position of the child.
|
||||
* @return {MMLNODE} The child node at position.
|
||||
*/
|
||||
export function getChildAt(node: MmlNode, position: number): MMLNODE {
|
||||
return (node.childNodes[position] as MMLNODE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set node child at position.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {number} position The position of the new child.
|
||||
* @param {MmlNode} child The new child.
|
||||
*/
|
||||
export function setChild(node: MmlNode, position: number, child: MmlNode) {
|
||||
let children = node.childNodes;
|
||||
children[position] = child;
|
||||
if (child) {
|
||||
child.parent = node;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies children between nodes.
|
||||
* @param {MmlNode} oldNode The source node.
|
||||
* @param {MmlNode} newNode The target node.
|
||||
*/
|
||||
export function copyChildren(oldNode: MmlNode, newNode: MmlNode) {
|
||||
let children = oldNode.childNodes as (TextNode | MmlNode)[];
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
setChild(newNode, i, children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies attributes between nodes.
|
||||
* @param {MmlNode} oldNode The source node.
|
||||
* @param {MmlNode} newNode The target node.
|
||||
*/
|
||||
export function copyAttributes(oldNode: MmlNode, newNode: MmlNode) {
|
||||
newNode.attributes = oldNode.attributes;
|
||||
setProperties(newNode, oldNode.getAllProperties());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if node is of a particular type.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {string} kind The type to check.
|
||||
* @return {boolean} True if node is of the given type.
|
||||
*/
|
||||
export function isType(node: MmlNode, kind: string): boolean {
|
||||
return node.isKind(kind);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the node is embellished.
|
||||
* @param {MmlNode} node The node.
|
||||
* @return {boolean} True if node is embellished.
|
||||
*/
|
||||
export function isEmbellished(node: MmlNode): boolean {
|
||||
return node.isEmbellished;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the texclass of a node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @return {number} Its texclass.
|
||||
*/
|
||||
export function getTexClass(node: MmlNode): number {
|
||||
return node.texClass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the mo element at the core of the node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @return {MmlNode} The MO node at the core.
|
||||
*/
|
||||
export function getCoreMO(node: MmlNode): MmlNode {
|
||||
return node.coreMO();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if an object is a node.
|
||||
* @param {any} item The object.
|
||||
* @return {boolean} True if it is a node.
|
||||
*/
|
||||
export function isNode(item: any): boolean {
|
||||
return item instanceof AbstractMmlNode || item instanceof AbstractMmlEmptyNode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the node is an inferred mrow.
|
||||
* @param {MmlNode} node The node.
|
||||
* @return {boolean} True if the node is an inferred mrow.
|
||||
*/
|
||||
export function isInferred(node: MmlNode): boolean {
|
||||
return node.isInferred;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the operator definition of a node.
|
||||
* @param {MmlNode} node The node.
|
||||
* @return {OperatorDef} If node is an MO returns the operator definition. O/w
|
||||
* null.
|
||||
*/
|
||||
export function getForm(node: MmlNode): OperatorDef {
|
||||
if (!isType(node, 'mo')) {
|
||||
return null;
|
||||
}
|
||||
let mo = node as MmlMo;
|
||||
let forms = mo.getForms();
|
||||
for (let form of forms) {
|
||||
let symbol = MmlMo.OPTABLE[form][mo.getText()];
|
||||
if (symbol) {
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeUtil;
|
||||
165
node_modules/mathjax-full/ts/input/tex/ParseMethods.ts
generated
vendored
Normal file
165
node_modules/mathjax-full/ts/input/tex/ParseMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Base methods for TeX Parsing.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Symbol} from './Symbol.js';
|
||||
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';
|
||||
|
||||
|
||||
namespace ParseMethods {
|
||||
|
||||
/**
|
||||
* Handle a variable (a single letter or multi-letter if allowed).
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} c The letter to transform into an mi.
|
||||
*/
|
||||
export function variable(parser: TexParser, c: string) {
|
||||
// @test Identifier Font
|
||||
const def = ParseUtil.getFontDef(parser);
|
||||
const env = parser.stack.env;
|
||||
if (env.multiLetterIdentifiers && env.font !== '') {
|
||||
c = parser.string.substr(parser.i - 1).match(env.multiLetterIdentifiers as any as RegExp)[0];
|
||||
parser.i += c.length - 1;
|
||||
if (def.mathvariant === TexConstant.Variant.NORMAL && env.noAutoOP && c.length > 1) {
|
||||
def.autoOP = false;
|
||||
}
|
||||
}
|
||||
// @test Identifier
|
||||
const node = parser.create('token', 'mi', def, c);
|
||||
parser.Push(node);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle a number (a sequence of digits, with decimal separator, etc.).
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} c The first character of a number than can be parsed with
|
||||
* the digits pattern.
|
||||
*/
|
||||
export function digit(parser: TexParser, c: string) {
|
||||
let mml: MmlNode;
|
||||
const pattern = parser.configuration.options['digits'];
|
||||
const n = parser.string.slice(parser.i - 1).match(pattern);
|
||||
// @test Integer Font
|
||||
const def = ParseUtil.getFontDef(parser);
|
||||
if (n) {
|
||||
// @test Integer, Number, Decimal (European)
|
||||
mml = parser.create('token', 'mn', def, n[0].replace(/[{}]/g, ''));
|
||||
parser.i += n[0].length - 1;
|
||||
} else {
|
||||
// @test Decimal Point, Decimal Point European
|
||||
mml = parser.create('token', 'mo', def, c);
|
||||
}
|
||||
parser.Push(mml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a control-sequence and process it.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} c The string '\'.
|
||||
*/
|
||||
export function controlSequence(parser: TexParser, _c: string) {
|
||||
const name = parser.GetCS();
|
||||
parser.parse('macro', [parser, name]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle normal mathchar (as an mi).
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {Symbol} mchar The parsed symbol.
|
||||
*/
|
||||
export function mathchar0mi(parser: TexParser, mchar: Symbol) {
|
||||
const def = mchar.attributes || {mathvariant: TexConstant.Variant.ITALIC};
|
||||
// @test Greek
|
||||
const node = parser.create('token', 'mi', def, mchar.char);
|
||||
parser.Push(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle normal mathchar (as an mo).
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {Symbol} mchar The parsed symbol.
|
||||
*/
|
||||
export function mathchar0mo(parser: TexParser, mchar: Symbol) {
|
||||
const def = mchar.attributes || {};
|
||||
def['stretchy'] = false;
|
||||
// @test Large Set
|
||||
const node = parser.create('token', 'mo', def, mchar.char);
|
||||
NodeUtil.setProperty(node, 'fixStretchy', true);
|
||||
parser.configuration.addNode('fixStretchy', node);
|
||||
// PROBLEM: Attributes stop working when Char7 are explicitly set.
|
||||
parser.Push(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle mathchar in current family.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {Symbol} mchar The parsed symbol.
|
||||
*/
|
||||
export function mathchar7(parser: TexParser, mchar: Symbol) {
|
||||
const def = mchar.attributes || {mathvariant: TexConstant.Variant.NORMAL};
|
||||
if (parser.stack.env['font']) {
|
||||
// @test MathChar7 Single Font
|
||||
def['mathvariant'] = parser.stack.env['font'];
|
||||
}
|
||||
// @test MathChar7 Single, MathChar7 Operator, MathChar7 Multi
|
||||
const node = parser.create('token', 'mi', def, mchar.char);
|
||||
parser.Push(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle delimiter.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {Symbol} delim The parsed delimiter symbol.
|
||||
*/
|
||||
export function delimiter(parser: TexParser, delim: Symbol) {
|
||||
let def = delim.attributes || {};
|
||||
// @test Fenced2, Delimiter (AMS)
|
||||
def = Object.assign({fence: false, stretchy: false}, def);
|
||||
const node = parser.create('token', 'mo', def, delim.char);
|
||||
parser.Push(node);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse an environment.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} env The name of the environment.
|
||||
* @param {Function} func The parse method for the environment.
|
||||
* @param {any[]} args A list of additional arguments.
|
||||
*/
|
||||
export function environment(parser: TexParser, env: string, func: Function, args: any[]) {
|
||||
const end = args[0];
|
||||
let mml = parser.itemFactory.create('begin').setProperties({name: env, end: end});
|
||||
mml = func(parser, mml, ...args.slice(1));
|
||||
parser.Push(mml);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ParseMethods;
|
||||
241
node_modules/mathjax-full/ts/input/tex/ParseOptions.ts
generated
vendored
Normal file
241
node_modules/mathjax-full/ts/input/tex/ParseOptions.ts
generated
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Factory generating maps to keep options for the TeX parser.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import StackItemFactory from './StackItemFactory.js';
|
||||
import {Tags} from './Tags.js';
|
||||
import {SubHandlers} from './MapHandler.js';
|
||||
import {NodeFactory} from './NodeFactory.js';
|
||||
import NodeUtil from './NodeUtil.js';
|
||||
import {MmlNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import TexParser from './TexParser.js';
|
||||
import {defaultOptions, OptionList} from '../../util/Options.js';
|
||||
import {ParserConfiguration} from './Configuration.js';
|
||||
|
||||
|
||||
/**
|
||||
* @class
|
||||
*/
|
||||
export default class ParseOptions {
|
||||
|
||||
/**
|
||||
* A set of sub handlers
|
||||
* @type {SubHandlers}
|
||||
*/
|
||||
public handlers: SubHandlers;
|
||||
|
||||
/**
|
||||
* A set of options, mapping names to string or boolean values.
|
||||
* @type {OptionList}
|
||||
*/
|
||||
public options: OptionList = {};
|
||||
|
||||
/**
|
||||
* The current item factory.
|
||||
* @type {StackItemFactory}
|
||||
*/
|
||||
public itemFactory: StackItemFactory;
|
||||
|
||||
/**
|
||||
* The current node factory.
|
||||
* @type {NodeFactory}
|
||||
*/
|
||||
public nodeFactory: NodeFactory;
|
||||
|
||||
/**
|
||||
* The current tagging object.
|
||||
* @type {Tags}
|
||||
*/
|
||||
public tags: Tags;
|
||||
|
||||
/**
|
||||
* Storage area for parser-specific package data (indexed by package name)
|
||||
* @type {Map<string, any>}
|
||||
*/
|
||||
public packageData: Map<string, any> = new Map();
|
||||
|
||||
// Fields for ephemeral options, i.e., options that will be cleared for each
|
||||
// run of the parser.
|
||||
/**
|
||||
* Stack of previous tex parsers. This is used to keep track of parser
|
||||
* settings when expressions are recursively parsed.
|
||||
* @type {TexParser[]}
|
||||
*/
|
||||
public parsers: TexParser[] = [];
|
||||
|
||||
|
||||
/**
|
||||
* The current root node.
|
||||
* @type {MmlNode}
|
||||
*/
|
||||
public root: MmlNode = null;
|
||||
|
||||
/**
|
||||
* List of node lists saved with respect to some property or their kind.
|
||||
* @type {{[key: string]: MmlNode[]}}
|
||||
*/
|
||||
public nodeLists: {[key: string]: MmlNode[]} = {};
|
||||
|
||||
/**
|
||||
* Error state of the parser.
|
||||
* @type {boolean}
|
||||
*/
|
||||
public error: boolean = false;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {Configuration} configuration Configuration object of the current
|
||||
* TeX parser.
|
||||
* @param {OptionList[]} options [TeX options, Tag options, {packages}]
|
||||
*/
|
||||
public constructor(configuration: ParserConfiguration, options: OptionList[] = []) {
|
||||
this.handlers = configuration.handlers;
|
||||
// Add node factory methods from packages.
|
||||
this.nodeFactory = new NodeFactory();
|
||||
this.nodeFactory.configuration = this;
|
||||
this.nodeFactory.setCreators(configuration.nodes);
|
||||
// Add stackitems from packages.
|
||||
this.itemFactory = new StackItemFactory(configuration.items);
|
||||
this.itemFactory.configuration = this;
|
||||
// Set default options for parser from packages and for tags.
|
||||
defaultOptions(this.options, ...options);
|
||||
defaultOptions(this.options, configuration.options);
|
||||
}
|
||||
|
||||
|
||||
// Methods for dealing with ephemeral fields.
|
||||
/**
|
||||
* Pushes a new tex parser onto the stack.
|
||||
* @param {TexParser} parser The new parser.
|
||||
*/
|
||||
public pushParser(parser: TexParser) {
|
||||
this.parsers.unshift(parser);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pops a parser of the tex parser stack.
|
||||
*/
|
||||
public popParser() {
|
||||
this.parsers.shift();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {TexParser} The currently active tex parser.
|
||||
*/
|
||||
public get parser(): TexParser {
|
||||
return this.parsers[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all the ephemeral options.
|
||||
*/
|
||||
public clear() {
|
||||
this.parsers = [];
|
||||
this.root = null;
|
||||
this.nodeLists = {};
|
||||
this.error = false;
|
||||
this.tags.resetTag();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Saves a tree node to a list of nodes for post processing.
|
||||
* @param {string} property The property name that will be used for
|
||||
* postprocessing.
|
||||
* @param {MmlNode} node The node to save.
|
||||
*/
|
||||
public addNode(property: string, node: MmlNode) {
|
||||
let list = this.nodeLists[property];
|
||||
if (!list) {
|
||||
list = this.nodeLists[property] = [];
|
||||
}
|
||||
list.push(node);
|
||||
if (node.kind !== property) {
|
||||
//
|
||||
// If the list is not just for its kind, record that it is in this list
|
||||
// so that if it is copied, the copy can also be added to the list.
|
||||
//
|
||||
const inlists = (NodeUtil.getProperty(node, 'in-lists') as string || '');
|
||||
const lists = (inlists ? inlists.split(/,/) : []).concat(property).join(',');
|
||||
NodeUtil.setProperty(node, 'in-lists', lists);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a saved node list with respect to a given property. It first ensures
|
||||
* that all the nodes are "live", i.e., actually live in the current
|
||||
* tree. Sometimes nodes are created, saved in the node list but discarded
|
||||
* later in the parsing. These will be filtered out here.
|
||||
*
|
||||
* NB: Do not use this method before the root field of the options is
|
||||
* set. Otherwise, your node list will always be empty!
|
||||
* @param {string} property The property for which to retrieve the node list.
|
||||
*/
|
||||
public getList(property: string) {
|
||||
let list = this.nodeLists[property] || [];
|
||||
let result = [];
|
||||
for (let node of list) {
|
||||
if (this.inTree(node)) {
|
||||
result.push(node);
|
||||
}
|
||||
}
|
||||
this.nodeLists[property] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a list of nodes from a saved list (e.g., when a filter removes the
|
||||
* node from the DOM, like for munderover => munder).
|
||||
*
|
||||
* @param {string} property The property from which to remove nodes.
|
||||
* @param {MmlNode[]} nodes The nodes to remove.
|
||||
*/
|
||||
public removeFromList(property: string, nodes: MmlNode[]) {
|
||||
const list = this.nodeLists[property] || [];
|
||||
for (const node of nodes) {
|
||||
const i = list.indexOf(node);
|
||||
if (i >= 0) {
|
||||
list.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests if the node is in the tree spanned by the current root node.
|
||||
* @param {MmlNode} node The node to test.
|
||||
*/
|
||||
private inTree(node: MmlNode) {
|
||||
while (node && node !== this.root) {
|
||||
node = node.parent;
|
||||
}
|
||||
return !!node;
|
||||
}
|
||||
|
||||
}
|
||||
713
node_modules/mathjax-full/ts/input/tex/ParseUtil.ts
generated
vendored
Normal file
713
node_modules/mathjax-full/ts/input/tex/ParseUtil.ts
generated
vendored
Normal file
@@ -0,0 +1,713 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A namespace for utility functions for the TeX Parser.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {TEXCLASS, MmlNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import {EnvList} from './StackItem.js';
|
||||
import {ArrayItem} from './base/BaseItems.js';
|
||||
import ParseOptions from './ParseOptions.js';
|
||||
import NodeUtil from './NodeUtil.js';
|
||||
import TexParser from './TexParser.js';
|
||||
import TexError from './TexError.js';
|
||||
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.
|
||||
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.
|
||||
* @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 <mo>, precede it by an empty <mi> to force the <mo> to
|
||||
* be infix.
|
||||
* @param {ParseOptions} configuration The current parse options.
|
||||
* @param {MmlNode[]} nodes The row of nodes to scan for an initial <mo>
|
||||
*/
|
||||
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[] {
|
||||
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*\{/)) {
|
||||
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
|
||||
mml.push(internalText(parser, text.slice(k, i - 1), def));
|
||||
}
|
||||
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
|
||||
braces--;
|
||||
}
|
||||
}
|
||||
} else if (c === '\\') {
|
||||
// @test Mbox Eqref, Mbox CR
|
||||
if (match === '' && text.substr(i).match(/^(eq)?ref\s*\{/)) {
|
||||
// @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) {
|
||||
// @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.substr(0, i - 1) + text.substr(i); // remove \ from \$, \{, \}, or \\
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 (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(/^\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 <mi> 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});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return {ArrayItem} The altered array item.
|
||||
*/
|
||||
export function setArrayAlign(array: ArrayItem, align: string): ArrayItem {
|
||||
// @test Array1, Array2, Array Test
|
||||
align = ParseUtil.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) {
|
||||
array.arraydef.align = align;
|
||||
} // FIXME: should be an error?
|
||||
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 = '';
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (parser.stack.global.eqnenv) {
|
||||
// @test ErroneousNestingEq
|
||||
throw new TexError('ErroneousNestingEq', 'Erroneous nesting of equation structures');
|
||||
}
|
||||
parser.stack.global.eqnenv = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() as MmlNode;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 '{':
|
||||
if (startCount) { // Count start left braces at start.
|
||||
start++;
|
||||
} else {
|
||||
stopCount = false;
|
||||
if (start > braces) { // Some start left braces have been closed.
|
||||
start = braces;
|
||||
}
|
||||
}
|
||||
braces++;
|
||||
break;
|
||||
case '}':
|
||||
if (braces) { // Closing braces.
|
||||
braces--;
|
||||
}
|
||||
if (startCount || stopCount) { // Closing braces at the start.
|
||||
start--;
|
||||
stopCount = true; // Continue to close braces.
|
||||
}
|
||||
startCount = false; // Stop counting start left braces.
|
||||
break;
|
||||
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)];
|
||||
}
|
||||
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)];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ParseUtil;
|
||||
158
node_modules/mathjax-full/ts/input/tex/Stack.ts
generated
vendored
Normal file
158
node_modules/mathjax-full/ts/input/tex/Stack.ts
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview The Stack for the TeX parser.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import NodeUtil from './NodeUtil.js';
|
||||
import {MmlNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import {StackItem, EnvList} from './StackItem.js';
|
||||
import StackItemFactory from './StackItemFactory.js';
|
||||
|
||||
|
||||
export default class Stack {
|
||||
|
||||
/**
|
||||
* @type {EnvList}
|
||||
*/
|
||||
public global: EnvList = {};
|
||||
|
||||
/**
|
||||
* The actual stack, a list of stack items.
|
||||
* @type {Array.<StackItem>}
|
||||
*/
|
||||
private stack: StackItem[] = [];
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {StackItemFactory} factory The stack item factory.
|
||||
* @param {EnvList} env The environment.
|
||||
* @param {boolean} inner True if parser has been called recursively.
|
||||
*/
|
||||
constructor(private _factory: StackItemFactory,
|
||||
private _env: EnvList, inner: boolean) {
|
||||
this.global = {isInner: inner};
|
||||
this.stack = [ this._factory.create('start', this.global) ];
|
||||
if (_env) {
|
||||
this.stack[0].env = _env;
|
||||
}
|
||||
this.env = this.stack[0].env;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the environment of the stack.
|
||||
* @param {EnvList} env The new environment.
|
||||
*/
|
||||
public set env(env: EnvList) {
|
||||
this._env = env;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the environment of that stack.
|
||||
* @return {EnvList} The current environment.
|
||||
*/
|
||||
public get env(): EnvList {
|
||||
return this._env;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pushes items or nodes onto stack.
|
||||
* @param {...StackItem|MmlNode} args A list of items to push.
|
||||
*/
|
||||
public Push(...args: (StackItem | MmlNode)[]) {
|
||||
for (const node of args) {
|
||||
if (!node) {
|
||||
continue;
|
||||
}
|
||||
const item = NodeUtil.isNode(node) ?
|
||||
this._factory.create('mml', node) : node as StackItem;
|
||||
item.global = this.global;
|
||||
const [top, success] =
|
||||
this.stack.length ? this.Top().checkItem(item) : [null, true];
|
||||
if (!success) {
|
||||
continue;
|
||||
}
|
||||
if (top) {
|
||||
this.Pop();
|
||||
this.Push(...top);
|
||||
continue;
|
||||
}
|
||||
this.stack.push(item);
|
||||
if (item.env) {
|
||||
if (item.copyEnv) {
|
||||
Object.assign(item.env, this.env);
|
||||
}
|
||||
this.env = item.env;
|
||||
} else {
|
||||
item.env = this.env;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pop the topmost elements off the stack.
|
||||
* @return {StackItem} A stack item.
|
||||
*/
|
||||
public Pop(): StackItem {
|
||||
const item = this.stack.pop();
|
||||
if (!item.isOpen) {
|
||||
delete item.env;
|
||||
}
|
||||
this.env = (this.stack.length ? this.Top().env : {});
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lookup the nth elements on the stack without removing them.
|
||||
* @param {number=} n Position of element that should be returned. Default 1.
|
||||
* @return {StackItem} Nth item on the stack.
|
||||
*/
|
||||
public Top(n: number = 1): StackItem {
|
||||
return this.stack.length < n ? null : this.stack[this.stack.length - n];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lookup the topmost element on the stack, returning the Mml node in that
|
||||
* item. Optionally pops the Mml node from that stack item.
|
||||
* @param {boolean=} noPop Pop top item if true.
|
||||
* @return {MmlNode} The Mml node in the topmost stack item.
|
||||
*/
|
||||
public Prev(noPop?: boolean): MmlNode | void {
|
||||
const top = this.Top();
|
||||
return noPop ? top.First : top.Pop();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public toString() {
|
||||
return 'stack[\n ' + this.stack.join('\n ') + '\n]';
|
||||
}
|
||||
|
||||
}
|
||||
537
node_modules/mathjax-full/ts/input/tex/StackItem.ts
generated
vendored
Normal file
537
node_modules/mathjax-full/ts/input/tex/StackItem.ts
generated
vendored
Normal file
@@ -0,0 +1,537 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Stack items hold information on the TexParser stack.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {MmlNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import {FactoryNodeClass} from '../../core/Tree/Factory.js';
|
||||
import TexError from './TexError.js';
|
||||
import StackItemFactory from './StackItemFactory.js';
|
||||
|
||||
// Union types for abbreviation.
|
||||
export type EnvProp = string | number | boolean;
|
||||
|
||||
export type EnvList = {[key: string]: EnvProp};
|
||||
|
||||
// This is the type for all fields that used to be set with With.
|
||||
export type Prop = string | number | boolean | MmlNode | PropList;
|
||||
|
||||
export type PropList = {[key: string]: Prop};
|
||||
|
||||
export type CheckType = [(MmlNode | StackItem)[], boolean];
|
||||
|
||||
|
||||
export interface NodeStack {
|
||||
|
||||
/**
|
||||
* Get or set the topmost element on the node stack without removing it.
|
||||
* @return {MmlNode} The topmost node on the stack.
|
||||
*/
|
||||
First: MmlNode;
|
||||
|
||||
/**
|
||||
* Get or set the last element on the node stack without removing it.
|
||||
* @return {MmlNode} The last node on the stack.
|
||||
*/
|
||||
Last: MmlNode;
|
||||
|
||||
/**
|
||||
* @return {MmlNode} The topmost node on the item's node stack.
|
||||
*/
|
||||
Pop(): MmlNode | void;
|
||||
|
||||
/**
|
||||
* Pushes new nodes onto the items node stack.
|
||||
* @param {MmlNode[]} ...nodes A list of nodes.
|
||||
*/
|
||||
Push(...nodes: MmlNode[]): void;
|
||||
|
||||
/**
|
||||
* Get the top n elements on the node stack without removing them.
|
||||
* @param {number=} n Number of elements that should be returned.
|
||||
* @return {MmlNode[]} List of nodes on top of stack.
|
||||
*/
|
||||
Peek(n?: number): MmlNode[];
|
||||
|
||||
/**
|
||||
* @return {number} The size of the stack.
|
||||
*/
|
||||
Size(): number;
|
||||
|
||||
/**
|
||||
* Clears the stack.
|
||||
*/
|
||||
Clear(): void;
|
||||
|
||||
/**
|
||||
* Returns nodes on the stack item's node stack as an Mml node. I.e., in case
|
||||
* the item contains more than one node, it creates an mrow.
|
||||
* @param {boolean=} inferred If set the mrow will be an inferred mrow.
|
||||
* @param {boolean=} forceRow If set an mrow will be created, regardless of
|
||||
* how many nodes the item contains.
|
||||
* @return {MmlNode} The topmost Mml node.
|
||||
*/
|
||||
toMml(inferred?: boolean, forceRow?: boolean): MmlNode;
|
||||
|
||||
}
|
||||
|
||||
|
||||
export abstract class MmlStack implements NodeStack {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {NodeStack}
|
||||
* @param {MmlNode[]} nodes An initial list of nodes to put on the stack.
|
||||
*/
|
||||
constructor(private _nodes: MmlNode[]) { }
|
||||
|
||||
/**
|
||||
* @return {MmlNode[]} The nodes on the stack.
|
||||
*/
|
||||
protected get nodes(): MmlNode[] {
|
||||
return this._nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public Push(...nodes: MmlNode[]) {
|
||||
this._nodes.push(...nodes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public Pop(): MmlNode {
|
||||
return this._nodes.pop();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public get First(): MmlNode {
|
||||
return this._nodes[this.Size() - 1];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public set First(node: MmlNode) {
|
||||
this._nodes[this.Size() - 1] = node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public get Last(): MmlNode {
|
||||
return this._nodes[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public set Last(node: MmlNode) {
|
||||
this._nodes[0] = node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public Peek(n?: number): MmlNode[] {
|
||||
if (n == null) {
|
||||
n = 1;
|
||||
}
|
||||
return this._nodes.slice(this.Size() - n);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public Size(): number {
|
||||
return this._nodes.length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public Clear(): void {
|
||||
this._nodes = [];
|
||||
}
|
||||
|
||||
|
||||
protected abstract get factory(): StackItemFactory;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public toMml(inferred: boolean = true, forceRow?: boolean) {
|
||||
if (this._nodes.length === 1 && !forceRow) {
|
||||
return this.First;
|
||||
}
|
||||
// @test Two Identifiers
|
||||
return this.create(
|
||||
'node', inferred ? 'inferredMrow' : 'mrow', this._nodes, {});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method to create nodes with the node factory on this stack.
|
||||
* @param {string} kind The kind of node to create.
|
||||
* @param {any[]} ...rest The remaining arguments for the creation method.
|
||||
* @return {MmlNode} The newly created node.
|
||||
*/
|
||||
public create(kind: string, ...rest: any[]): MmlNode {
|
||||
return this.factory.configuration.nodeFactory.create(kind, ...rest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export interface StackItem extends NodeStack {
|
||||
|
||||
|
||||
/**
|
||||
* Type of stack item.
|
||||
* @type {string}
|
||||
*/
|
||||
kind: string;
|
||||
|
||||
/**
|
||||
* Is this a closing item, e.g., end.
|
||||
* @type {boolean}
|
||||
*/
|
||||
isClose: boolean;
|
||||
|
||||
/**
|
||||
* Is this an opening item, e.g., begin.
|
||||
* @type {boolean}
|
||||
*/
|
||||
isOpen: boolean;
|
||||
|
||||
/**
|
||||
* Is this a finalising item, i.e., one that only collects nodes.
|
||||
* @type {boolean}
|
||||
*/
|
||||
isFinal: boolean;
|
||||
|
||||
/**
|
||||
* Global properties of the parser.
|
||||
* @type {EnvList}
|
||||
*/
|
||||
global: EnvList;
|
||||
|
||||
/**
|
||||
* Local properties of the stack item.
|
||||
* @type {EnvList}
|
||||
*/
|
||||
env: EnvList;
|
||||
|
||||
/**
|
||||
* Copy local properties when pushed to stack?
|
||||
* @type {boolean}
|
||||
*/
|
||||
copyEnv: boolean;
|
||||
|
||||
/**
|
||||
* Tests if item is of the given type.
|
||||
* @param {string} kind The type.
|
||||
* @return {boolean} True if item is of that type.
|
||||
*/
|
||||
isKind(kind: string): boolean;
|
||||
|
||||
/**
|
||||
* Get a property of the item.
|
||||
* @param {string} key Property name.
|
||||
* @return {Prop} Property value if it exists.
|
||||
*/
|
||||
getProperty(key: string): Prop;
|
||||
|
||||
/**
|
||||
* Set a property.
|
||||
* @param {string} key Property name.
|
||||
* @param {Prop} value Property value.
|
||||
* @return {StackItem} The item for pipelining.
|
||||
*/
|
||||
setProperty(key: string, value: Prop): StackItem;
|
||||
|
||||
/**
|
||||
* Sets a list of properties.
|
||||
* @param {PropList} def The properties to set.
|
||||
* @return {StackItem} Returns the stack item object for pipelining.
|
||||
*/
|
||||
setProperties(def: PropList): StackItem;
|
||||
|
||||
/**
|
||||
* Convenience method for returning the string property "name".
|
||||
* @return {string} The value for the name property.
|
||||
*/
|
||||
getName(): string;
|
||||
|
||||
/**
|
||||
* TeX parsing in MathJax is essentially implemented via a nested stack
|
||||
* automaton. That is the tex parser works on a stack, and each item on the
|
||||
* stack can have a data stack of its own. Data on the stack is either a stack
|
||||
* item or a node.
|
||||
*
|
||||
* The checkItem method effectively implements the recursive checking of
|
||||
* input data from the parser against data recursively given on the stack.
|
||||
*
|
||||
* I.e., new input is parsed resulting in a new item. When pushed on the stack
|
||||
* it is checked against the top most item on the stack. This either leads to
|
||||
* the item being pushed onto the stack or combined with the top most
|
||||
* element(s), pushing a new item, which is recursively checked, unless an
|
||||
* error is thrown.
|
||||
*
|
||||
* A simple example: If \\end{foo} is parsed, an endItem is created, pushed on
|
||||
* the stack. Nodes on the stack are collapsed into content of the 'foo'
|
||||
* environment, until a beginItem for 'foo' is found. If a beginItem is not
|
||||
* for 'foo' or does not exist an error is thrown.
|
||||
*
|
||||
* @param {StackItem} item The pushed item.
|
||||
* @return {CheckType} True/false or an item or node.
|
||||
*/
|
||||
checkItem(item: StackItem): CheckType;
|
||||
|
||||
}
|
||||
|
||||
export interface StackItemClass extends FactoryNodeClass<StackItem> {
|
||||
// new (factory: StackItemFactory, ...args: any[]): StackItem;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Abstract basic item class that implements most of the stack item
|
||||
* functionality. In particular, it contains the base method for checkItem.
|
||||
*/
|
||||
export abstract class BaseItem extends MmlStack implements StackItem {
|
||||
|
||||
/**
|
||||
* The fail value.
|
||||
* @type {CheckType}
|
||||
*/
|
||||
protected static fail: CheckType = [null, false];
|
||||
|
||||
/**
|
||||
* The success value.
|
||||
* @type {CheckType}
|
||||
*/
|
||||
protected static success: CheckType = [null, true];
|
||||
|
||||
/**
|
||||
* A list of basic errors.
|
||||
* @type {{[key: string]: string[]}}
|
||||
*/
|
||||
protected static errors: {[key: string]: string[]} = {
|
||||
// @test ExtraOpenMissingClose
|
||||
end: ['MissingBeginExtraEnd', 'Missing \\begin{%1} or extra \\end{%1}'],
|
||||
// @test ExtraCloseMissingOpen
|
||||
close: ['ExtraCloseMissingOpen', 'Extra close brace or missing open brace'],
|
||||
// @test MissingLeftExtraRight
|
||||
right: ['MissingLeftExtraRight', 'Missing \\left or extra \\right'],
|
||||
middle: ['ExtraMiddle', 'Extra \\middle']
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public global: EnvList = {};
|
||||
|
||||
private _env: EnvList;
|
||||
|
||||
private _properties: PropList = {};
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {MmlStack}
|
||||
*/
|
||||
constructor(protected factory: StackItemFactory, ...nodes: MmlNode[]) {
|
||||
super(nodes);
|
||||
if (this.isOpen) {
|
||||
this._env = {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string} The type of the stack item.
|
||||
*/
|
||||
public get kind(): string {
|
||||
return 'base';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {EnvList} Get the private environment
|
||||
*/
|
||||
public get env(): EnvList {
|
||||
return this._env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the private environment
|
||||
* @param {EnvList} value New private environemt.
|
||||
*/
|
||||
public set env(value: EnvList) {
|
||||
this._env = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default is to copy local environment when pushed on stack
|
||||
*/
|
||||
public get copyEnv() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public getProperty(key: string): Prop {
|
||||
return this._properties[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public setProperty(key: string, value: Prop) {
|
||||
this._properties[key] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True if item is an opening entity, i.e., it expects a
|
||||
* closing counterpart on the stack later.
|
||||
*/
|
||||
get isOpen(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean} True if item is an closing entity, i.e., it needs an
|
||||
* opening counterpart already on the stack.
|
||||
*/
|
||||
get isClose(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True if item is final, i.e., it contains one or multiple
|
||||
* finished parsed nodes.
|
||||
*/
|
||||
get isFinal(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public isKind(kind: string) {
|
||||
return kind === this.kind;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public checkItem(item: StackItem): CheckType {
|
||||
if (item.isKind('over') && this.isOpen) {
|
||||
item.setProperty('num', this.toMml(false));
|
||||
this.Clear();
|
||||
}
|
||||
if (item.isKind('cell') && this.isOpen) {
|
||||
if (item.getProperty('linebreak')) {
|
||||
return BaseItem.fail;
|
||||
}
|
||||
// @test Ampersand-error
|
||||
throw new TexError('Misplaced', 'Misplaced %1', item.getName());
|
||||
}
|
||||
if (item.isClose && this.getErrors(item.kind)) {
|
||||
// @test ExtraOpenMissingClose, ExtraCloseMissingOpen,
|
||||
// MissingLeftExtraRight, MissingBeginExtraEnd
|
||||
const [id, message] = this.getErrors(item.kind);
|
||||
throw new TexError(id, message, item.getName());
|
||||
}
|
||||
if (!item.isFinal) {
|
||||
return BaseItem.success;
|
||||
}
|
||||
this.Push(item.First);
|
||||
return BaseItem.fail;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears the item's environment.
|
||||
*/
|
||||
public clearEnv() {
|
||||
for (const id of Object.keys(this.env)) {
|
||||
delete this.env[id];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public setProperties(def: PropList) {
|
||||
Object.assign(this._properties, def);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public getName() {
|
||||
return this.getProperty('name') as string;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public toString() {
|
||||
return this.kind + '[' + this.nodes.join('; ') + ']';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get error messages for a particular types of stack items. This reads error
|
||||
* messages from the static errors object, which can be extended in
|
||||
* subclasses.
|
||||
* @param {string} kind The stack item type.
|
||||
* @return {string[]} The list of arguments for the TeXError.
|
||||
*/
|
||||
public getErrors(kind: string): string[] {
|
||||
const CLASS = (this.constructor as typeof BaseItem);
|
||||
return (CLASS.errors || {})[kind] || BaseItem.errors[kind];
|
||||
}
|
||||
|
||||
}
|
||||
62
node_modules/mathjax-full/ts/input/tex/StackItemFactory.ts
generated
vendored
Normal file
62
node_modules/mathjax-full/ts/input/tex/StackItemFactory.ts
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A factory for stack items. This allows particular items to be
|
||||
* overwritten later.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {StackItemClass, StackItem, BaseItem} from './StackItem.js';
|
||||
import ParseOptions from './ParseOptions.js';
|
||||
import {AbstractFactory} from '../../core/Tree/Factory.js';
|
||||
|
||||
|
||||
class DummyItem extends BaseItem {}
|
||||
|
||||
/**
|
||||
* The StackItemFactory is initially populated with the default stack item
|
||||
* classes. They can be changed, deleted or added to, if and when necessary.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {AbstractFactory}
|
||||
*/
|
||||
export default class StackItemFactory extends AbstractFactory<StackItem, StackItemClass> {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public static DefaultStackItems: {[kind: string]: StackItemClass} = {
|
||||
[DummyItem.prototype.kind]: DummyItem
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public defaultKind = 'dummy';
|
||||
|
||||
|
||||
/**
|
||||
* The parser configuration.
|
||||
* @type {ParseOptions}
|
||||
*/
|
||||
public configuration: ParseOptions = null;
|
||||
|
||||
}
|
||||
82
node_modules/mathjax-full/ts/input/tex/Symbol.ts
generated
vendored
Normal file
82
node_modules/mathjax-full/ts/input/tex/Symbol.ts
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Symbol classes.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Args, Attributes, ParseMethod} from './Types.js';
|
||||
|
||||
|
||||
/**
|
||||
* Symbol class
|
||||
*/
|
||||
export class Symbol {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string} symbol The symbol parsed.
|
||||
* @param {string} char The corresponding translation.
|
||||
* @param {Attributes} attributes The attributes for the translation.
|
||||
*/
|
||||
constructor(private _symbol: string, private _char: string,
|
||||
private _attributes: Attributes) {
|
||||
}
|
||||
|
||||
public get symbol(): string {
|
||||
return this._symbol;
|
||||
}
|
||||
|
||||
public get char(): string {
|
||||
return this._char;
|
||||
}
|
||||
|
||||
public get attributes(): Attributes {
|
||||
return this._attributes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export class Macro {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string} symbol The symbol parsed
|
||||
* @param {ParseMethod} func The parsing function for that symbol.
|
||||
* @param {Args[]} args Additional arguments for the function.
|
||||
*/
|
||||
constructor(private _symbol: string, private _func: ParseMethod,
|
||||
private _args: Args[] = []) {
|
||||
}
|
||||
|
||||
public get symbol(): string {
|
||||
return this._symbol;
|
||||
}
|
||||
|
||||
public get func(): ParseMethod {
|
||||
return this._func;
|
||||
}
|
||||
|
||||
public get args(): Args[] {
|
||||
return this._args;
|
||||
}
|
||||
|
||||
}
|
||||
392
node_modules/mathjax-full/ts/input/tex/SymbolMap.ts
generated
vendored
Normal file
392
node_modules/mathjax-full/ts/input/tex/SymbolMap.ts
generated
vendored
Normal file
@@ -0,0 +1,392 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Symbol map classes.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Attributes, Args, ParseMethod, ParseInput, ParseResult} from './Types.js';
|
||||
import {Symbol, Macro} from './Symbol.js';
|
||||
import {MapHandler} from './MapHandler.js';
|
||||
|
||||
|
||||
/**
|
||||
* SymbolMaps are the base components for the input parsers.
|
||||
*
|
||||
* They provide a contains method that checks if a map is applicable (contains)
|
||||
* a particular string. Implementing classes then perform the actual symbol
|
||||
* parsing, from simple regular expression test, straight forward symbol mapping
|
||||
* to transformational functionality on the parsed string.
|
||||
*
|
||||
* @interface
|
||||
*/
|
||||
export interface SymbolMap {
|
||||
|
||||
/**
|
||||
* @return {string} The name of the map.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* @return {ParseMethod} The default parsing method.
|
||||
*/
|
||||
parser: ParseMethod;
|
||||
|
||||
/**
|
||||
* @param {string} symbol A symbol to parse.
|
||||
* @return {boolean} True if the symbol map applies to the symbol.
|
||||
*/
|
||||
contains(symbol: string): boolean;
|
||||
|
||||
/**
|
||||
* @param {string} symbol A symbol to parse.
|
||||
* @return {ParseMethod} A parse method for the symbol.
|
||||
*/
|
||||
parserFor(symbol: string): ParseMethod;
|
||||
|
||||
/**
|
||||
* @param {TexParser} env The current parser.
|
||||
* @param {string} symbol A symbol to parse.
|
||||
* @return {ParseResult} The parsed symbol and the rest of the string.
|
||||
*/
|
||||
parse([env, symbol]: ParseInput): ParseResult;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ParseResult} result The result to check
|
||||
* @return {ParseResult} True if result was void, result otherwise
|
||||
*/
|
||||
export function parseResult(result: ParseResult): ParseResult {
|
||||
return result === void 0 ? true : result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract implementation of symbol maps.
|
||||
* @template T
|
||||
*/
|
||||
export abstract class AbstractSymbolMap<T> implements SymbolMap {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {SymbolMap}
|
||||
* @param {string} name Name of the mapping.
|
||||
* @param {ParseMethod} parser The parser for the mappiong.
|
||||
*/
|
||||
constructor(private _name: string, private _parser: ParseMethod) {
|
||||
MapHandler.register(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public get name(): string {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public abstract contains(symbol: string): boolean;
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public parserFor(symbol: string) {
|
||||
return this.contains(symbol) ? this.parser : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public parse([env, symbol]: ParseInput) {
|
||||
let parser = this.parserFor(symbol);
|
||||
let mapped = this.lookup(symbol);
|
||||
return (parser && mapped) ? parseResult(parser(env, mapped as any)) : null;
|
||||
}
|
||||
|
||||
|
||||
public set parser(parser: ParseMethod) {
|
||||
this._parser = parser;
|
||||
}
|
||||
|
||||
public get parser(): ParseMethod {
|
||||
return this._parser;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} symbol
|
||||
* @return {T}
|
||||
*/
|
||||
public abstract lookup(symbol: string): T;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Regular expressions used for parsing strings.
|
||||
*/
|
||||
export class RegExpMap extends AbstractSymbolMap<string> {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {AbstractSymbolMap}
|
||||
* @param {string} name Name of the mapping.
|
||||
* @param {ParseMethod} parser The parser for the mappiong.
|
||||
* @param {RegExp} regexp The regular expression.
|
||||
*/
|
||||
constructor(name: string, parser: ParseMethod, private _regExp: RegExp) {
|
||||
super(name, parser);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public contains(symbol: string) {
|
||||
return this._regExp.test(symbol);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public lookup(symbol: string): string {
|
||||
return this.contains(symbol) ? symbol : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse maps associate strings with parsing functionality.
|
||||
* @constructor
|
||||
* @extends {AbstractSymbolMap}
|
||||
* @template K
|
||||
*/
|
||||
export abstract class AbstractParseMap<K> extends AbstractSymbolMap<K> {
|
||||
|
||||
private map: Map<string, K> = new Map<string, K>();
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public lookup(symbol: string): K {
|
||||
return this.map.get(symbol);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public contains(symbol: string) {
|
||||
return this.map.has(symbol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets mapping for a symbol.
|
||||
* @param {string} symbol The symbol to map.
|
||||
* @param {K} object The symbols value in the mapping's codomain.
|
||||
*/
|
||||
public add(symbol: string, object: K) {
|
||||
this.map.set(symbol, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a symbol from the map
|
||||
* @param {string} symbol The symbol to remove
|
||||
*/
|
||||
public remove(symbol: string) {
|
||||
this.map.delete(symbol);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps symbols that can all be parsed with the same method.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {AbstractParseMap}
|
||||
*/
|
||||
export class CharacterMap extends AbstractParseMap<Symbol> {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string} name Name of the mapping.
|
||||
* @param {ParseMethod} parser The parser for the mapping.
|
||||
* @param {JSON} json The JSON representation of the character mapping.
|
||||
*/
|
||||
constructor(name: string, parser: ParseMethod,
|
||||
json: {[index: string]: string | [string, Attributes]}) {
|
||||
super(name, parser);
|
||||
for (const key of Object.keys(json)) {
|
||||
let value = json[key];
|
||||
let [char, attrs] = (typeof(value) === 'string') ? [value, null] : value;
|
||||
let character = new Symbol(key, char, attrs);
|
||||
this.add(key, character);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps symbols that are delimiters, that are all parsed with the same method.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {CharacterMap}
|
||||
*/
|
||||
export class DelimiterMap extends CharacterMap {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public parse([env, symbol]: ParseInput) {
|
||||
return super.parse([env, '\\' + symbol]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps macros that all bring their own parsing method.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {AbstractParseMap}
|
||||
*/
|
||||
export class MacroMap extends AbstractParseMap<Macro> {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string} name Name of the mapping.
|
||||
* @param {JSON} json The JSON representation of the macro map.
|
||||
* @param {Record<string, ParseMethod>} functionMap Collection of parse
|
||||
* functions for the single macros.
|
||||
*/
|
||||
constructor(name: string,
|
||||
json: {[index: string]: string | Args[]},
|
||||
functionMap: Record<string, ParseMethod>) {
|
||||
super(name, null);
|
||||
for (const key of Object.keys(json)) {
|
||||
let value = json[key];
|
||||
let [func, ...attrs] = (typeof(value) === 'string') ? [value] : value;
|
||||
let character = new Macro(key, functionMap[func as string], attrs);
|
||||
this.add(key, character);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public parserFor(symbol: string) {
|
||||
let macro = this.lookup(symbol);
|
||||
return macro ? macro.func : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public parse([env, symbol]: ParseInput) {
|
||||
let macro = this.lookup(symbol);
|
||||
let parser = this.parserFor(symbol);
|
||||
if (!macro || !parser) {
|
||||
return null;
|
||||
}
|
||||
return parseResult(parser(env, macro.symbol, ...macro.args));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps macros that all bring their own parsing method.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {MacroMap}
|
||||
*/
|
||||
export class CommandMap extends MacroMap {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public parse([env, symbol]: ParseInput) {
|
||||
let macro = this.lookup(symbol);
|
||||
let parser = this.parserFor(symbol);
|
||||
if (!macro || !parser) {
|
||||
return null;
|
||||
}
|
||||
let saveCommand = env.currentCS;
|
||||
env.currentCS = '\\' + symbol;
|
||||
let result = parser(env, '\\' + macro.symbol, ...macro.args);
|
||||
env.currentCS = saveCommand;
|
||||
return parseResult(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps macros for environments. It has a general parsing method for
|
||||
* environments, i.e., one that deals with begin/end, and each environment has
|
||||
* its own parsing method returning the content.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {MacroMap}
|
||||
*/
|
||||
export class EnvironmentMap extends MacroMap {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string} name Name of the mapping.
|
||||
* @param {ParseMethod} parser The parser for the environments.
|
||||
* @param {JSON} json The JSON representation of the macro map.
|
||||
* @param {Record<string, ParseMethod>} functionMap Collection of parse
|
||||
* functions for the single macros.
|
||||
*/
|
||||
constructor(name: string,
|
||||
parser: ParseMethod,
|
||||
json: {[index: string]: string | Args[]},
|
||||
functionMap: Record<string, ParseMethod>) {
|
||||
super(name, json, functionMap);
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public parse([env, symbol]: ParseInput) {
|
||||
let macro = this.lookup(symbol);
|
||||
let envParser = this.parserFor(symbol);
|
||||
if (!macro || !envParser) {
|
||||
return null;
|
||||
}
|
||||
return parseResult(this.parser(env, macro.symbol, envParser, macro.args));
|
||||
}
|
||||
|
||||
}
|
||||
680
node_modules/mathjax-full/ts/input/tex/Tags.ts
generated
vendored
Normal file
680
node_modules/mathjax-full/ts/input/tex/Tags.ts
generated
vendored
Normal file
@@ -0,0 +1,680 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Class for generating tags, references, etc.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import TexParser from './TexParser.js';
|
||||
import {MmlNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import {MathItem} from '../../core/MathItem.js';
|
||||
import {EnvList} from './StackItem.js';
|
||||
import ParseOptions from './ParseOptions.js';
|
||||
import {OptionList} from '../../util/Options.js';
|
||||
|
||||
|
||||
/**
|
||||
* Simple class for label objects.
|
||||
*/
|
||||
export class Label {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string=} tag The tag that's displayed.
|
||||
* @param {string=} id The id that serves as reference.
|
||||
*/
|
||||
constructor(public tag: string = '???', public id: string = '') {}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A simple class for keeping track of tag information.
|
||||
*/
|
||||
export class TagInfo {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string} env The environment name (e.g., align).
|
||||
* @param {boolean} taggable Environment supports tags (e.g., align* does, but
|
||||
* split does not.)
|
||||
* @param {boolean} defaultTags Environment is tagged by default (e.g., align
|
||||
* is, but align* is not).
|
||||
* @param {string} tag The tag name (e.g., 1).
|
||||
* @param {string} tagId The unique id for that tag (e.g., mjx-eqn:1).
|
||||
* @param {string} tagFormat The formatted tag (e.g., "(1)").
|
||||
* @param {boolean} noTag A no tagging command has been set (e.g., \notag,
|
||||
* \nonumber).
|
||||
* @param {string} labelId The label referring to the tag.
|
||||
*/
|
||||
constructor(readonly env: string = '',
|
||||
readonly taggable: boolean = false,
|
||||
readonly defaultTags: boolean = false,
|
||||
public tag: string = null,
|
||||
public tagId: string = '',
|
||||
public tagFormat: string = '',
|
||||
public noTag: boolean = false,
|
||||
public labelId: string = '') {}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export interface Tags {
|
||||
|
||||
/**
|
||||
* The global configurations in which the parsing takes place.
|
||||
* @type {ParseOptions}
|
||||
*/
|
||||
configuration: ParseOptions;
|
||||
|
||||
/**
|
||||
* IDs used in this equation.
|
||||
* @type {Object.<boolean>}
|
||||
*/
|
||||
ids: {[key: string]: boolean};
|
||||
|
||||
/**
|
||||
* IDs used in previous equations.
|
||||
* @type {Object.<boolean>}
|
||||
*/
|
||||
allIds: {[key: string]: boolean};
|
||||
|
||||
/**
|
||||
* Labels in the current equation.
|
||||
* @type {Object.<Label>}
|
||||
*/
|
||||
labels: {[key: string]: Label};
|
||||
|
||||
/**
|
||||
* Labels in previous equations.
|
||||
* @type {Object.<Label>}
|
||||
*/
|
||||
allLabels: {[key: string]: Label};
|
||||
|
||||
/**
|
||||
* The label to use for the next tag.
|
||||
* @type {string}
|
||||
*/
|
||||
label: string;
|
||||
|
||||
/**
|
||||
* True if the equation contains an undefined label and must be reprocessed later.
|
||||
* @type {boolean}
|
||||
*/
|
||||
redo: boolean;
|
||||
|
||||
/**
|
||||
* True when recompiling to update undefined references
|
||||
* @type {boolean}
|
||||
*/
|
||||
refUpdate: boolean;
|
||||
|
||||
/**
|
||||
* The environment that is currently tagged.
|
||||
* @type {string}
|
||||
*/
|
||||
env: string;
|
||||
|
||||
/**
|
||||
* The currently active tag.
|
||||
* @type {TagInfo}
|
||||
*/
|
||||
currentTag: TagInfo;
|
||||
|
||||
/**
|
||||
* How to format tags.
|
||||
* @param {string} tag The tag string.
|
||||
* @return {string} The formatted numbered tag.
|
||||
*/
|
||||
formatTag(tag: string): string;
|
||||
|
||||
/**
|
||||
* How to format URLs for references.
|
||||
* @param {string} id The reference id.
|
||||
* @param {string} base The base URL in the reference.
|
||||
* @return {}
|
||||
*/
|
||||
formatUrl(id: string, base: string): string;
|
||||
|
||||
/**
|
||||
* Set the tag automatically, by incrementing equation number.
|
||||
*/
|
||||
autoTag(): void;
|
||||
|
||||
/**
|
||||
* @return {MmlNode|void} Generates and returns the tag node.
|
||||
*/
|
||||
getTag(): MmlNode | void;
|
||||
|
||||
/**
|
||||
* Clears tagging information.
|
||||
*/
|
||||
clearTag(): void;
|
||||
|
||||
/**
|
||||
* Resets the tag structure after an expression has been typeset.
|
||||
*/
|
||||
resetTag(): void;
|
||||
|
||||
/**
|
||||
* Fully resets the tag structure, in particular all the tagging and label
|
||||
* history.
|
||||
* @param {number} offset A new offset value to start counting ids from.
|
||||
*/
|
||||
reset(offset?: number): void;
|
||||
|
||||
/**
|
||||
* Initialise tagging for a MathItem
|
||||
* (clear equation-specific labels and ids, set counter
|
||||
* and check for recompile)
|
||||
* @param {MathItem} math The MathItem for the current equation
|
||||
*/
|
||||
startEquation(math: MathItem<any, any, any>): void;
|
||||
|
||||
/**
|
||||
* Move equation-specific labels and ids to global ones,
|
||||
* save the counter, and mark the MathItem for redos
|
||||
*/
|
||||
finishEquation(math: MathItem<any, any, any>): void;
|
||||
|
||||
/**
|
||||
* Finalizes tag creation.
|
||||
* @param {MmlNode} node
|
||||
* @param {EnvList} env List of environment properties.
|
||||
* @return {MmlNode} The newly created tag.
|
||||
*/
|
||||
finalize(node: MmlNode, env: EnvList): MmlNode;
|
||||
|
||||
/**
|
||||
* Starts tagging on a given environment.
|
||||
* @param {string} env The name of the environment.
|
||||
* @param {boolean} taggable True if taggable.
|
||||
* @param {boolean} defaultTags True if tagged by default.
|
||||
*/
|
||||
start(env: string, taggable: boolean, defaultTags: boolean): void;
|
||||
|
||||
/**
|
||||
* End tagging.
|
||||
*/
|
||||
end(): void;
|
||||
|
||||
/**
|
||||
* Computes the next tag.
|
||||
* @param {string} tag The tag content.
|
||||
* @param {boolean} noFormat True if tag should not be formatted.
|
||||
*/
|
||||
tag(tag: string, noFormat: boolean): void;
|
||||
|
||||
/**
|
||||
* Call an explicit no tag.
|
||||
*/
|
||||
notag(): void;
|
||||
|
||||
/**
|
||||
* Entag an element by creating a table around it.
|
||||
* @param {MmlNode} node The node to be tagged.
|
||||
* @param {MmlNode} tag The tag node.
|
||||
* @return {MmlNode} The table node containing the original node and tag.
|
||||
*/
|
||||
enTag(node: MmlNode, tag: MmlNode): MmlNode;
|
||||
}
|
||||
|
||||
|
||||
export class AbstractTags implements Tags {
|
||||
|
||||
/**
|
||||
* Current equation number.
|
||||
* @type {number}
|
||||
*/
|
||||
protected counter: number = 0;
|
||||
|
||||
/**
|
||||
* Equation number as equation begins.
|
||||
* @type {number}
|
||||
*/
|
||||
protected allCounter: number = 0;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public configuration: ParseOptions = null;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public ids: {[key: string]: boolean} = {};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public allIds: {[key: string]: boolean} = {};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public labels: {[key: string]: Label} = {};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public allLabels: {[key: string]: Label} = {};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public redo: boolean = false;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public refUpdate: boolean = false;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public currentTag: TagInfo = new TagInfo();
|
||||
|
||||
|
||||
/**
|
||||
* Chronology of all previous tags, in case we need to look something up in
|
||||
* the finalize method.
|
||||
* @type {TagInfo[]}
|
||||
*/
|
||||
protected history: TagInfo[] = [];
|
||||
|
||||
private stack: TagInfo[] = [];
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public start(env: string, taggable: boolean, defaultTags: boolean) {
|
||||
if (this.currentTag) {
|
||||
this.stack.push(this.currentTag);
|
||||
}
|
||||
this.currentTag = new TagInfo(env, taggable, defaultTags);
|
||||
}
|
||||
|
||||
public get env() {
|
||||
return this.currentTag.env;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public end() {
|
||||
this.history.push(this.currentTag);
|
||||
this.currentTag = this.stack.pop();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public tag(tag: string, noFormat: boolean) {
|
||||
this.currentTag.tag = tag;
|
||||
this.currentTag.tagFormat = noFormat ? tag : this.formatTag(tag);
|
||||
this.currentTag.noTag = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public notag() {
|
||||
this.tag('', true);
|
||||
this.currentTag.noTag = true;
|
||||
}
|
||||
|
||||
protected get noTag(): boolean {
|
||||
return this.currentTag.noTag;
|
||||
}
|
||||
|
||||
public set label(label: string) {
|
||||
this.currentTag.labelId = label;
|
||||
}
|
||||
|
||||
public get label() {
|
||||
return this.currentTag.labelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public formatUrl(id: string, base: string) {
|
||||
return base + '#' + encodeURIComponent(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public formatTag(tag: string) {
|
||||
return '(' + tag + ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* How to format ids for labelling equations.
|
||||
* @param {string} id The unique part of the id (e.g., label or number).
|
||||
* @return {string} The formatted id.
|
||||
*/
|
||||
protected formatId(id: string): string {
|
||||
return 'mjx-eqn:' + id.replace(/\s/g, '_');
|
||||
}
|
||||
|
||||
/**
|
||||
* How to format numbers in tags.
|
||||
* @param {number} n The tag number.
|
||||
* @return {string} The formatted number.
|
||||
*/
|
||||
protected formatNumber(n: number): string {
|
||||
return n.toString();
|
||||
}
|
||||
|
||||
// Tag handling functions.
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public autoTag() {
|
||||
if (this.currentTag.tag == null) {
|
||||
this.counter++;
|
||||
this.tag(this.formatNumber(this.counter), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public clearTag() {
|
||||
this.label = '';
|
||||
this.tag(null, true);
|
||||
this.currentTag.tagId = '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public getTag(force: boolean = false) {
|
||||
if (force) {
|
||||
this.autoTag();
|
||||
return this.makeTag();
|
||||
}
|
||||
const ct = this.currentTag;
|
||||
if (ct.taggable && !ct.noTag) {
|
||||
if (ct.defaultTags) {
|
||||
this.autoTag();
|
||||
}
|
||||
if (ct.tag) {
|
||||
return this.makeTag();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public resetTag() {
|
||||
this.history = [];
|
||||
this.redo = false;
|
||||
this.refUpdate = false;
|
||||
this.clearTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public reset(offset: number = 0) {
|
||||
this.resetTag();
|
||||
this.counter = this.allCounter = offset;
|
||||
this.allLabels = {};
|
||||
this.allIds = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public startEquation(math: MathItem<any, any, any>) {
|
||||
this.history = [];
|
||||
this.stack = [];
|
||||
this.clearTag();
|
||||
this.currentTag = new TagInfo('', undefined, undefined);
|
||||
this.labels = {};
|
||||
this.ids = {};
|
||||
this.counter = this.allCounter;
|
||||
this.redo = false;
|
||||
const recompile = math.inputData.recompile;
|
||||
if (recompile) {
|
||||
this.refUpdate = true;
|
||||
this.counter = recompile.counter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public finishEquation(math: MathItem<any, any, any>) {
|
||||
if (this.redo) {
|
||||
math.inputData.recompile = {
|
||||
state: math.state(),
|
||||
counter: this.allCounter
|
||||
};
|
||||
}
|
||||
if (!this.refUpdate) {
|
||||
this.allCounter = this.counter;
|
||||
}
|
||||
Object.assign(this.allIds, this.ids);
|
||||
Object.assign(this.allLabels, this.labels);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public finalize(node: MmlNode, env: EnvList): MmlNode {
|
||||
if (!env.display || this.currentTag.env ||
|
||||
this.currentTag.tag == null) {
|
||||
return node;
|
||||
}
|
||||
let tag = this.makeTag();
|
||||
let table = this.enTag(node, tag);
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public enTag = function(node: MmlNode, tag: MmlNode): MmlNode {
|
||||
let nf = this.configuration.nodeFactory;
|
||||
let cell = nf.create('node', 'mtd', [node]);
|
||||
let row = nf.create('node', 'mlabeledtr', [tag, cell]);
|
||||
let table = nf.create('node', 'mtable', [row], {
|
||||
side: this.configuration.options['tagSide'],
|
||||
minlabelspacing: this.configuration.options['tagIndent'],
|
||||
displaystyle: true
|
||||
});
|
||||
return table;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the tag id.
|
||||
*/
|
||||
private makeId() {
|
||||
this.currentTag.tagId = this.formatId(
|
||||
this.configuration.options['useLabelIds'] ?
|
||||
(this.label || this.currentTag.tag) : this.currentTag.tag);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {MmlNode} The actual tag node as an mtd.
|
||||
*/
|
||||
private makeTag(): MmlNode {
|
||||
this.makeId();
|
||||
if (this.label) {
|
||||
this.labels[this.label] = new Label(this.currentTag.tag, this.currentTag.tagId);
|
||||
}
|
||||
let mml = new TexParser('\\text{' + this.currentTag.tagFormat + '}', {},
|
||||
this.configuration).mml();
|
||||
return this.configuration.nodeFactory.create('node', 'mtd', [mml],
|
||||
{id: this.currentTag.tagId});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* No tags, except where explicitly set.
|
||||
* @constructor
|
||||
* @extends {AbstractTags}
|
||||
*/
|
||||
export class NoTags extends AbstractTags {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public autoTag() {}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public getTag() {
|
||||
return !this.currentTag.tag ? null : super.getTag();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tags every display formula. Exceptions are: Environments that explicitly
|
||||
* disallow tags, e.g., equation*.
|
||||
* @constructor
|
||||
* @extends {AbstractTags}
|
||||
*/
|
||||
export class AllTags extends AbstractTags {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public finalize(node: MmlNode, env: EnvList) {
|
||||
if (!env.display || this.history.find(
|
||||
function(x: TagInfo) { return x.taggable; })) {
|
||||
return node;
|
||||
}
|
||||
let tag = this.getTag(true);
|
||||
return this.enTag(node, tag);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class interface for factory.
|
||||
* @interface
|
||||
*/
|
||||
export interface TagsClass {
|
||||
new (): Tags;
|
||||
}
|
||||
|
||||
|
||||
export namespace TagsFactory {
|
||||
|
||||
let tagsMapping = new Map<string, TagsClass>([
|
||||
['none', NoTags],
|
||||
['all', AllTags]
|
||||
]);
|
||||
|
||||
let defaultTags = 'none';
|
||||
|
||||
/**
|
||||
* The default options for tagging
|
||||
* @type {OptionList}
|
||||
*/
|
||||
export let OPTIONS: OptionList = {
|
||||
// Tagging style, used to be autonumber in v2.
|
||||
tags: defaultTags,
|
||||
// This specifies the side on which \tag{} macros will place the tags.
|
||||
// Set to 'left' to place on the left-hand side.
|
||||
tagSide: 'right',
|
||||
// This is the amount of indentation (from right or left) for the tags.
|
||||
tagIndent: '0.8em',
|
||||
// make element ID's use \label name rather than equation number
|
||||
// MJ puts in an equation prefix: mjx-eqn
|
||||
// When true it uses the label name XXX as mjx-eqn:XXX
|
||||
// If false it uses the actual number N that is displayed: mjx-eqn:N
|
||||
useLabelIds: true,
|
||||
// Set to true in order to prevent error messages for duplicate label ids
|
||||
ignoreDuplicateLabels: false
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add a tagging object.
|
||||
* @param {string} name Name of the tagging object.
|
||||
* @param {TagsClass} constr The class of the Tagging object.
|
||||
*/
|
||||
export let add = function(name: string, constr: TagsClass) {
|
||||
tagsMapping.set(name, constr);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a list of tagging objects to the factory.
|
||||
* @param {{[name: string]: TagsClass}} tags The list of tagging objects.
|
||||
*/
|
||||
export let addTags = function(tags: {[name: string]: TagsClass}) {
|
||||
for (const key of Object.keys(tags)) {
|
||||
TagsFactory.add(key, tags[key]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new tagging object.
|
||||
* @param {string} name The name of the tagging object.
|
||||
* @return {Tags} The newly created object.
|
||||
*/
|
||||
export let create = function(name: string): Tags {
|
||||
let constr = tagsMapping.get(name) || tagsMapping.get(defaultTags);
|
||||
if (!constr) {
|
||||
throw Error('Unknown tags class');
|
||||
}
|
||||
return new constr();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of the default tagging object.
|
||||
* @param {string} name The default.
|
||||
*/
|
||||
export let setDefault = function(name: string) {
|
||||
defaultTags = name;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Tags} The default tagging object.
|
||||
*/
|
||||
export let getDefault = function(): Tags {
|
||||
return TagsFactory.create(defaultTags);
|
||||
};
|
||||
|
||||
}
|
||||
169
node_modules/mathjax-full/ts/input/tex/TexConstants.ts
generated
vendored
Normal file
169
node_modules/mathjax-full/ts/input/tex/TexConstants.ts
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Constant definitions for the TeX Parser. These should
|
||||
* eventually be combined with the MathML structure.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
export namespace TexConstant {
|
||||
|
||||
export const Variant = {
|
||||
NORMAL: 'normal',
|
||||
BOLD: 'bold',
|
||||
ITALIC: 'italic',
|
||||
BOLDITALIC: 'bold-italic',
|
||||
DOUBLESTRUCK: 'double-struck',
|
||||
FRAKTUR: 'fraktur',
|
||||
BOLDFRAKTUR: 'bold-fraktur',
|
||||
SCRIPT: 'script',
|
||||
BOLDSCRIPT: 'bold-script',
|
||||
SANSSERIF: 'sans-serif',
|
||||
BOLDSANSSERIF: 'bold-sans-serif',
|
||||
SANSSERIFITALIC: 'sans-serif-italic',
|
||||
SANSSERIFBOLDITALIC: 'sans-serif-bold-italic',
|
||||
MONOSPACE: 'monospace',
|
||||
INITIAL: 'inital',
|
||||
TAILED: 'tailed',
|
||||
LOOPED: 'looped',
|
||||
STRETCHED: 'stretched',
|
||||
CALLIGRAPHIC: '-tex-calligraphic',
|
||||
BOLDCALLIGRAPHIC: '-tex-bold-calligraphic',
|
||||
OLDSTYLE: '-tex-oldstyle',
|
||||
BOLDOLDSTYLE: '-tex-bold-oldstyle',
|
||||
MATHITALIC: '-tex-mathit'
|
||||
};
|
||||
|
||||
export const Form = {
|
||||
PREFIX: 'prefix',
|
||||
INFIX: 'infix',
|
||||
POSTFIX: 'postfix'
|
||||
};
|
||||
|
||||
export const LineBreak = {
|
||||
AUTO: 'auto',
|
||||
NEWLINE: 'newline',
|
||||
NOBREAK: 'nobreak',
|
||||
GOODBREAK: 'goodbreak',
|
||||
BADBREAK: 'badbreak'
|
||||
};
|
||||
|
||||
export const LineBreakStyle = {
|
||||
BEFORE: 'before',
|
||||
AFTER: 'after',
|
||||
DUPLICATE: 'duplicate',
|
||||
INFIXLINBREAKSTYLE: 'infixlinebreakstyle'
|
||||
};
|
||||
|
||||
export const IndentAlign = {
|
||||
LEFT: 'left',
|
||||
CENTER: 'center',
|
||||
RIGHT: 'right',
|
||||
AUTO: 'auto',
|
||||
ID: 'id',
|
||||
INDENTALIGN: 'indentalign'
|
||||
};
|
||||
|
||||
export const IndentShift = {
|
||||
INDENTSHIFT: 'indentshift'
|
||||
};
|
||||
|
||||
export const LineThickness = {
|
||||
THIN: 'thin',
|
||||
MEDIUM: 'medium',
|
||||
THICK: 'thick'
|
||||
};
|
||||
|
||||
export const Notation = {
|
||||
LONGDIV: 'longdiv',
|
||||
ACTUARIAL: 'actuarial',
|
||||
PHASORANGLE: 'phasorangle',
|
||||
RADICAL: 'radical',
|
||||
BOX: 'box',
|
||||
ROUNDEDBOX: 'roundedbox',
|
||||
CIRCLE: 'circle',
|
||||
LEFT: 'left',
|
||||
RIGHT: 'right',
|
||||
TOP: 'top',
|
||||
BOTTOM: 'bottom',
|
||||
UPDIAGONALSTRIKE: 'updiagonalstrike',
|
||||
DOWNDIAGONALSTRIKE: 'downdiagonalstrike',
|
||||
VERTICALSTRIKE: 'verticalstrike',
|
||||
HORIZONTALSTRIKE: 'horizontalstrike',
|
||||
NORTHEASTARROW: 'northeastarrow',
|
||||
MADRUWB: 'madruwb',
|
||||
UPDIAGONALARROW: 'updiagonalarrow'
|
||||
};
|
||||
|
||||
export const Align = {
|
||||
TOP: 'top',
|
||||
BOTTOM: 'bottom',
|
||||
CENTER: 'center',
|
||||
BASELINE: 'baseline',
|
||||
AXIS: 'axis',
|
||||
LEFT: 'left',
|
||||
RIGHT: 'right'
|
||||
};
|
||||
|
||||
export const Lines = {
|
||||
NONE: 'none',
|
||||
SOLID: 'solid',
|
||||
DASHED: 'dashed'
|
||||
};
|
||||
|
||||
export const Side = {
|
||||
LEFT: 'left',
|
||||
RIGHT: 'right',
|
||||
LEFTOVERLAP: 'leftoverlap',
|
||||
RIGHTOVERLAP: 'rightoverlap'
|
||||
};
|
||||
|
||||
export const Width = {
|
||||
AUTO: 'auto',
|
||||
FIT: 'fit'
|
||||
};
|
||||
|
||||
export const Actiontype = {
|
||||
TOGGLE: 'toggle',
|
||||
STATUSLINE: 'statusline',
|
||||
TOOLTIP: 'tooltip',
|
||||
INPUT: 'input'
|
||||
};
|
||||
|
||||
export const Overflow = {
|
||||
LINBREAK: 'linebreak',
|
||||
SCROLL: 'scroll',
|
||||
ELIDE: 'elide',
|
||||
TRUNCATE: 'truncate',
|
||||
SCALE: 'scale'
|
||||
};
|
||||
|
||||
export const Unit = {
|
||||
EM: 'em',
|
||||
EX: 'ex',
|
||||
PX: 'px',
|
||||
IN: 'in',
|
||||
CM: 'cm',
|
||||
MM: 'mm',
|
||||
PT: 'pt',
|
||||
PC: 'pc'
|
||||
};
|
||||
|
||||
}
|
||||
85
node_modules/mathjax-full/ts/input/tex/TexError.ts
generated
vendored
Normal file
85
node_modules/mathjax-full/ts/input/tex/TexError.ts
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Error class for the TeX parser.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
export default class TexError {
|
||||
|
||||
private static pattern =
|
||||
/%(\d+|\{\d+\}|\{[a-z]+:\%\d+(?:\|(?:%\{\d+\}|%.|[^\}])*)+\}|.)/g;
|
||||
|
||||
/**
|
||||
* Default error message.
|
||||
* @type {string}
|
||||
*/
|
||||
public message: string;
|
||||
|
||||
/**
|
||||
* The old MathJax processing function.
|
||||
* @param {string} str The basic error message.
|
||||
* @param {string[]} args The arguments to be replaced in the error message.
|
||||
* @return {string} The processed error string.
|
||||
*/
|
||||
private static processString(str: string, args: string[]): string {
|
||||
let parts = str.split(TexError.pattern);
|
||||
for (let i = 1, m = parts.length; i < m; i += 2) {
|
||||
let c = parts[i].charAt(0); // first char will be { or \d or a char to be
|
||||
// kept literally
|
||||
if (c >= '0' && c <= '9') { // %n
|
||||
parts[i] = args[parseInt(parts[i], 10) - 1];
|
||||
if (typeof parts[i] === 'number') {
|
||||
parts[i] = parts[i].toString();
|
||||
}
|
||||
} else if (c === '{') { // %{n} or %{plural:%n|...}
|
||||
c = parts[i].substr(1);
|
||||
if (c >= '0' && c <= '9') { // %{n}
|
||||
parts[i] = args[parseInt(parts[i].substr(1, parts[i].length - 2), 10) - 1];
|
||||
if (typeof parts[i] === 'number') {
|
||||
parts[i] = parts[i].toString();
|
||||
}
|
||||
} else { // %{plural:%n|...}
|
||||
let match = parts[i].match(/^\{([a-z]+):%(\d+)\|(.*)\}$/);
|
||||
if (match) {
|
||||
// Removed plural here.
|
||||
parts[i] = '%' + parts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parts[i] == null) {
|
||||
parts[i] = '???';
|
||||
}
|
||||
}
|
||||
return parts.join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param{string} id message id (for localization)
|
||||
* @param{string} message text of English message
|
||||
* @param{string[]=} rest any substitution arguments
|
||||
*/
|
||||
constructor(public id: string, message: string, ...rest: string[]) {
|
||||
this.message = TexError.processString(message, rest);
|
||||
}
|
||||
|
||||
}
|
||||
514
node_modules/mathjax-full/ts/input/tex/TexParser.ts
generated
vendored
Normal file
514
node_modules/mathjax-full/ts/input/tex/TexParser.ts
generated
vendored
Normal file
@@ -0,0 +1,514 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview The TexParser. Implements the basic parsing functionality and
|
||||
* administers the global stack and tree objects.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import ParseUtil from './ParseUtil.js';
|
||||
import {HandlerType} from './MapHandler.js';
|
||||
import Stack from './Stack.js';
|
||||
import StackItemFactory from './StackItemFactory.js';
|
||||
import {Tags} from './Tags.js';
|
||||
import TexError from './TexError.js';
|
||||
import {MmlNode, AbstractMmlNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import {ParseInput, ParseResult} from './Types.js';
|
||||
import ParseOptions from './ParseOptions.js';
|
||||
import {StackItem, EnvList} from './StackItem.js';
|
||||
import {Symbol} from './Symbol.js';
|
||||
import {OptionList} from '../../util/Options.js';
|
||||
|
||||
|
||||
/**
|
||||
* The main Tex Parser class.
|
||||
*/
|
||||
export default class TexParser {
|
||||
|
||||
/**
|
||||
* Counter for recursive macros.
|
||||
* @type {number}
|
||||
*/
|
||||
public macroCount: number = 0;
|
||||
|
||||
/**
|
||||
* The stack for items and created nodes.
|
||||
* @type {Stack}
|
||||
*/
|
||||
public stack: Stack;
|
||||
|
||||
/**
|
||||
* Current position in the string that is parsed.
|
||||
* @type {number}
|
||||
*/
|
||||
public i: number = 0;
|
||||
|
||||
/**
|
||||
* The last command sequence
|
||||
* @type {string}
|
||||
*/
|
||||
public currentCS: string = '';
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string} string The string to parse.
|
||||
* @param {EnvList} env The intial environment representing the current parse
|
||||
* state of the overall expression translation.
|
||||
* @param {ParseOptions} configuration A parser configuration.
|
||||
*/
|
||||
constructor(private _string: string, env: EnvList, public configuration: ParseOptions) {
|
||||
const inner = env.hasOwnProperty('isInner');
|
||||
const isInner = env['isInner'] as boolean;
|
||||
delete env['isInner'];
|
||||
let ENV: EnvList;
|
||||
if (env) {
|
||||
ENV = {};
|
||||
for (const id of Object.keys(env)) {
|
||||
ENV[id] = env[id];
|
||||
}
|
||||
}
|
||||
this.configuration.pushParser(this);
|
||||
this.stack = new Stack(this.itemFactory, ENV, inner ? isInner : true);
|
||||
this.Parse();
|
||||
this.Push(this.itemFactory.create('stop'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {OptionList} The configuration options.
|
||||
*/
|
||||
get options(): OptionList {
|
||||
return this.configuration.options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {StackItemFactory} The factory for stack items.
|
||||
*/
|
||||
get itemFactory(): StackItemFactory {
|
||||
return this.configuration.itemFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Tags} The tags style of this configuration.
|
||||
*/
|
||||
get tags(): Tags {
|
||||
return this.configuration.tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the string that should be parsed.
|
||||
* @param {string} str The new string to parse.
|
||||
*/
|
||||
set string(str: string) {
|
||||
this._string = str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string} The string that is currently parsed.
|
||||
*/
|
||||
get string(): string {
|
||||
return this._string;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the input with the specified kind of map.
|
||||
* @param {HandlerType} kind Configuration name.
|
||||
* @param {ParseInput} input Input to be parsed.
|
||||
* @return {ParseResult} The output of the parsing function.
|
||||
*/
|
||||
public parse(kind: HandlerType, input: ParseInput): ParseResult {
|
||||
return this.configuration.handlers.get(kind).parse(input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps a symbol to its "parse value" if it exists.
|
||||
* @param {HandlerType} kind Configuration name.
|
||||
* @param {string} symbol The symbol to parse.
|
||||
* @return {any} A boolean, Character, or Macro.
|
||||
*/
|
||||
public lookup(kind: HandlerType, symbol: string): any {
|
||||
return this.configuration.handlers.get(kind).lookup(symbol);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a symbol is contained in one of the symbol mappings of the
|
||||
* specified kind.
|
||||
* @param {HandlerType} kind Configuration name.
|
||||
* @param {string} symbol The symbol to parse.
|
||||
* @return {boolean} True if the symbol is contained in the given types of
|
||||
* symbol mapping.
|
||||
*/
|
||||
public contains(kind: HandlerType, symbol: string): boolean {
|
||||
return this.configuration.handlers.get(kind).contains(symbol);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public toString(): string {
|
||||
let str = '';
|
||||
for (const config of Array.from(this.configuration.handlers.keys())) {
|
||||
str += config + ': ' +
|
||||
this.configuration.handlers.get(config as HandlerType) + '\n';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the current input string.
|
||||
*/
|
||||
public Parse() {
|
||||
let c: string;
|
||||
while (this.i < this.string.length) {
|
||||
c = this.getCodePoint();
|
||||
this.i += c.length;
|
||||
this.parse('character', [this, c]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pushes a new item onto the stack. The item can also be a Mml node,
|
||||
* but if the mml item is an inferred row, push its children instead.
|
||||
* @param {StackItem|MmlNode} arg The new item.
|
||||
*/
|
||||
public Push(arg: StackItem | MmlNode) {
|
||||
if (arg instanceof AbstractMmlNode && arg.isInferred) {
|
||||
this.PushAll(arg.childNodes);
|
||||
} else {
|
||||
this.stack.Push(arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pushes a list of new items onto the stack.
|
||||
* @param {StackItem|MmlNode[]} args The new items.
|
||||
*/
|
||||
public PushAll(args: (StackItem | MmlNode)[]) {
|
||||
for (const arg of args) {
|
||||
this.stack.Push(arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {MmlNode} The internal Mathml structure.
|
||||
*/
|
||||
public mml(): MmlNode {
|
||||
if (!this.stack.Top().isKind('mml')) {
|
||||
return null;
|
||||
}
|
||||
let node = this.stack.Top().First;
|
||||
this.configuration.popParser();
|
||||
return node;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* String handling routines
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert delimiter to character.
|
||||
* @param {string} c The delimiter name.
|
||||
* @return {string} The corresponding character.
|
||||
*/
|
||||
public convertDelimiter(c: string): string {
|
||||
const symbol = this.lookup('delimiter', c) as Symbol;
|
||||
return symbol ? symbol.char : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string} Get the next unicode character in the string
|
||||
*/
|
||||
public getCodePoint(): string {
|
||||
const code = this.string.codePointAt(this.i);
|
||||
return code === undefined ? '' : String.fromCodePoint(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean} True if the next character to parse is a space.
|
||||
*/
|
||||
public nextIsSpace(): boolean {
|
||||
return !!this.string.charAt(this.i).match(/\s/);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string} Get the next non-space character.
|
||||
*/
|
||||
public GetNext(): string {
|
||||
while (this.nextIsSpace()) {
|
||||
this.i++;
|
||||
}
|
||||
return this.getCodePoint();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string} Get and return a control-sequence name
|
||||
*/
|
||||
public GetCS(): string {
|
||||
let CS = this.string.slice(this.i).match(/^(([a-z]+) ?|[\uD800-\uDBFF].|.)/i);
|
||||
if (CS) {
|
||||
this.i += CS[0].length;
|
||||
return CS[2] || CS[1];
|
||||
} else {
|
||||
this.i++;
|
||||
return ' ';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and return a TeX argument (either a single character or control
|
||||
* sequence, or the contents of the next set of braces).
|
||||
* @param {string} name Name of the current control sequence.
|
||||
* @param {boolean} noneOK? True if no argument is OK.
|
||||
* @return {string} The next argument.
|
||||
*/
|
||||
public GetArgument(_name: string, noneOK?: boolean): string {
|
||||
switch (this.GetNext()) {
|
||||
case '':
|
||||
if (!noneOK) {
|
||||
// @test MissingArgFor
|
||||
throw new TexError('MissingArgFor', 'Missing argument for %1', this.currentCS);
|
||||
}
|
||||
return null;
|
||||
case '}':
|
||||
if (!noneOK) {
|
||||
// @test ExtraCloseMissingOpen
|
||||
throw new TexError('ExtraCloseMissingOpen',
|
||||
'Extra close brace or missing open brace');
|
||||
}
|
||||
return null;
|
||||
case '\\':
|
||||
this.i++;
|
||||
return '\\' + this.GetCS();
|
||||
case '{':
|
||||
let j = ++this.i, parens = 1;
|
||||
while (this.i < this.string.length) {
|
||||
switch (this.string.charAt(this.i++)) {
|
||||
case '\\': this.i++; break;
|
||||
case '{': parens++; break;
|
||||
case '}':
|
||||
if (--parens === 0) {
|
||||
return this.string.slice(j, this.i - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// @test MissingCloseBrace
|
||||
throw new TexError('MissingCloseBrace', 'Missing close brace');
|
||||
}
|
||||
const c = this.getCodePoint();
|
||||
this.i += c.length;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an optional LaTeX argument in brackets.
|
||||
* @param {string} name Name of the current control sequence.
|
||||
* @param {string} def? The default value for the optional argument.
|
||||
* @return {string} The optional argument.
|
||||
*/
|
||||
public GetBrackets(_name: string, def?: string): string {
|
||||
if (this.GetNext() !== '[') {
|
||||
return def;
|
||||
}
|
||||
let j = ++this.i, parens = 0;
|
||||
while (this.i < this.string.length) {
|
||||
switch (this.string.charAt(this.i++)) {
|
||||
case '{': parens++; break;
|
||||
case '\\': this.i++; break;
|
||||
case '}':
|
||||
if (parens-- <= 0) {
|
||||
// @test ExtraCloseLooking1
|
||||
throw new TexError('ExtraCloseLooking',
|
||||
'Extra close brace while looking for %1', '\']\'');
|
||||
}
|
||||
break;
|
||||
case ']':
|
||||
if (parens === 0) {
|
||||
return this.string.slice(j, this.i - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// @test MissingCloseBracket
|
||||
throw new TexError('MissingCloseBracket',
|
||||
'Could not find closing \']\' for argument to %1', this.currentCS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of a delimiter (check it in the delimiter list).
|
||||
* @param {string} name Name of the current control sequence.
|
||||
* @param {boolean} braceOK? Are braces around the delimiter OK.
|
||||
* @return {string} The delimiter name.
|
||||
*/
|
||||
public GetDelimiter(name: string, braceOK?: boolean): string {
|
||||
let c = this.GetNext(); this.i += c.length;
|
||||
if (this.i <= this.string.length) {
|
||||
if (c === '\\') {
|
||||
c += this.GetCS();
|
||||
} else if (c === '{' && braceOK) {
|
||||
this.i--;
|
||||
c = this.GetArgument(name).trim();
|
||||
}
|
||||
if (this.contains('delimiter', c)) {
|
||||
return this.convertDelimiter(c);
|
||||
}
|
||||
}
|
||||
// @test MissingOrUnrecognizedDelim1, MissingOrUnrecognizedDelim2
|
||||
throw new TexError('MissingOrUnrecognizedDelim',
|
||||
'Missing or unrecognized delimiter for %1', this.currentCS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a dimension (including its units).
|
||||
* @param {string} name Name of the current control sequence.
|
||||
* @return {string} The dimension string.
|
||||
*/
|
||||
public GetDimen(name: string): string {
|
||||
if (this.GetNext() === '{') {
|
||||
let dimen = this.GetArgument(name);
|
||||
let [value, unit] = ParseUtil.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);
|
||||
if (value) {
|
||||
this.i += length;
|
||||
return value + unit;
|
||||
}
|
||||
}
|
||||
// @test MissingDimOrUnits
|
||||
throw new TexError('MissingDimOrUnits',
|
||||
'Missing dimension or its units for %1', this.currentCS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get everything up to the given control sequence (token)
|
||||
* @param {string} name Name of the current control sequence.
|
||||
* @param {string} token The element until where to parse.
|
||||
* @return {string} The text between the current position and the given token.
|
||||
*/
|
||||
public GetUpTo(_name: string, token: string): string {
|
||||
while (this.nextIsSpace()) {
|
||||
this.i++;
|
||||
}
|
||||
let j = this.i;
|
||||
let parens = 0;
|
||||
while (this.i < this.string.length) {
|
||||
let k = this.i;
|
||||
let c = this.GetNext(); this.i += c.length;
|
||||
switch (c) {
|
||||
case '\\': c += this.GetCS(); break;
|
||||
case '{': parens++; break;
|
||||
case '}':
|
||||
if (parens === 0) {
|
||||
// @test ExtraCloseLooking2
|
||||
throw new TexError('ExtraCloseLooking',
|
||||
'Extra close brace while looking for %1', token);
|
||||
}
|
||||
parens--;
|
||||
break;
|
||||
}
|
||||
if (parens === 0 && c === token) {
|
||||
return this.string.slice(j, k);
|
||||
}
|
||||
}
|
||||
// @test TokenNotFoundForCommand
|
||||
throw new TexError('TokenNotFoundForCommand',
|
||||
'Could not find %1 for %2', token, this.currentCS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the arguments of a control sequence in a new parser instance.
|
||||
* @param {string} name Name of the current control sequence.
|
||||
* @return {MmlNode} The parsed node.
|
||||
*/
|
||||
public ParseArg(name: string): MmlNode {
|
||||
return new TexParser(this.GetArgument(name), this.stack.env,
|
||||
this.configuration).mml();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a given string up to a given token in a new parser instance.
|
||||
* @param {string} name Name of the current control sequence.
|
||||
* @param {string} token A Token at which to end parsing.
|
||||
* @return {MmlNode} The parsed node.
|
||||
*/
|
||||
public ParseUpTo(name: string, token: string): MmlNode {
|
||||
return new TexParser(this.GetUpTo(name, token), this.stack.env,
|
||||
this.configuration).mml();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a delimiter or empty argument
|
||||
* @param {string} name Name of the current control sequence.
|
||||
* @return {string} The delimiter.
|
||||
*/
|
||||
public GetDelimiterArg(name: string): string {
|
||||
let c = ParseUtil.trimSpaces(this.GetArgument(name));
|
||||
if (c === '') {
|
||||
return null;
|
||||
}
|
||||
if (this.contains('delimiter', c)) {
|
||||
return c;
|
||||
}
|
||||
// @test MissingOrUnrecognizedDelim
|
||||
throw new TexError('MissingOrUnrecognizedDelim',
|
||||
'Missing or unrecognized delimiter for %1', this.currentCS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean} True if a star follows the control sequence name.
|
||||
*/
|
||||
public GetStar(): boolean {
|
||||
let star = (this.GetNext() === '*');
|
||||
if (star) {
|
||||
this.i++;
|
||||
}
|
||||
return star;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method to create nodes with the node factory of the current
|
||||
* configuration.
|
||||
* @param {string} kind The kind of node to create.
|
||||
* @param {any[]} ...rest The remaining arguments for the creation method.
|
||||
* @return {MmlNode} The newly created node.
|
||||
*/
|
||||
public create(kind: string, ...rest: any[]): MmlNode {
|
||||
return this.configuration.nodeFactory.create(kind, ...rest);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
38
node_modules/mathjax-full/ts/input/tex/Types.ts
generated
vendored
Normal file
38
node_modules/mathjax-full/ts/input/tex/Types.ts
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Basic type definitions.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {StackItem} from './StackItem.js';
|
||||
import {Symbol} from './Symbol.js';
|
||||
import TexParser from './TexParser.js';
|
||||
|
||||
export type Args = boolean | number | string | null;
|
||||
|
||||
export type Attributes = Record<string, Args>;
|
||||
|
||||
export type Environment = Record<string, Args>;
|
||||
|
||||
export type ParseInput = [TexParser, string];
|
||||
export type ParseResult = void | boolean | StackItem;
|
||||
|
||||
export type ParseMethod = (parser: TexParser, c: string | Symbol | StackItem, ...rest: any[]) => ParseResult;
|
||||
78
node_modules/mathjax-full/ts/input/tex/action/ActionConfiguration.ts
generated
vendored
Normal file
78
node_modules/mathjax-full/ts/input/tex/action/ActionConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the action package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import BaseMethods from '../base/BaseMethods.js';
|
||||
|
||||
|
||||
// Namespace
|
||||
export let ActionMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
ActionMethods.Macro = BaseMethods.Macro;
|
||||
|
||||
/**
|
||||
* Implement \toggle {math1} {math2} ... \endtoggle
|
||||
* (as an <maction actiontype="toggle">)
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the calling macro.
|
||||
*/
|
||||
ActionMethods.Toggle = function(parser: TexParser, name: string) {
|
||||
const children = [];
|
||||
let arg;
|
||||
while ((arg = parser.GetArgument(name)) !== '\\endtoggle') {
|
||||
children.push(
|
||||
new TexParser(arg, parser.stack.env, parser.configuration).mml());
|
||||
}
|
||||
parser.Push(
|
||||
parser.create('node', 'maction', children, {actiontype: 'toggle'}));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implement \mathtip{math}{tip}
|
||||
* (an an <maction actiontype="tooltip">)
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the calling macro.
|
||||
*/
|
||||
ActionMethods.Mathtip = function(parser: TexParser, name: string) {
|
||||
const arg = parser.ParseArg(name);
|
||||
const tip = parser.ParseArg(name);
|
||||
parser.Push(
|
||||
parser.create('node', 'maction', [arg, tip], {actiontype: 'tooltip'}));
|
||||
};
|
||||
|
||||
|
||||
new CommandMap('action-macros', {
|
||||
toggle: 'Toggle',
|
||||
mathtip: 'Mathtip',
|
||||
texttip: ['Macro', '\\mathtip{#1}{\\text{#2}}', 2]
|
||||
}, ActionMethods);
|
||||
|
||||
|
||||
export const ActionConfiguration = Configuration.create(
|
||||
'action', {handler: {macro: ['action-macros']}}
|
||||
);
|
||||
86
node_modules/mathjax-full/ts/input/tex/ams/AmsConfiguration.ts
generated
vendored
Normal file
86
node_modules/mathjax-full/ts/input/tex/ams/AmsConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the AMS package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration, ParserConfiguration} from '../Configuration.js';
|
||||
import {MultlineItem, FlalignItem} from './AmsItems.js';
|
||||
import {AbstractTags} from '../Tags.js';
|
||||
import {NEW_OPS} from './AmsMethods.js';
|
||||
import './AmsMappings.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
|
||||
|
||||
/**
|
||||
* Standard AMS style tagging.
|
||||
* @constructor
|
||||
* @extends {AbstractTags}
|
||||
*/
|
||||
export class AmsTags extends AbstractTags { }
|
||||
|
||||
|
||||
/**
|
||||
* Init method for AMS package.
|
||||
* @param {ParserConfiguration} config The current configuration.
|
||||
*/
|
||||
let init = function(config: ParserConfiguration) {
|
||||
new CommandMap(NEW_OPS, {}, {});
|
||||
config.append(Configuration.local({handler: {macro: [NEW_OPS]},
|
||||
priority: -1}));
|
||||
};
|
||||
|
||||
export const AmsConfiguration = Configuration.create(
|
||||
'ams', {
|
||||
handler: {
|
||||
character: ['AMSmath-operatorLetter'],
|
||||
delimiter: ['AMSsymbols-delimiter', 'AMSmath-delimiter'],
|
||||
macro: ['AMSsymbols-mathchar0mi', 'AMSsymbols-mathchar0mo',
|
||||
'AMSsymbols-delimiter', 'AMSsymbols-macros',
|
||||
'AMSmath-mathchar0mo', 'AMSmath-macros', 'AMSmath-delimiter'],
|
||||
environment: ['AMSmath-environment']
|
||||
},
|
||||
items: {
|
||||
[MultlineItem.prototype.kind]: MultlineItem,
|
||||
[FlalignItem.prototype.kind]: FlalignItem,
|
||||
},
|
||||
tags: {'ams': AmsTags},
|
||||
init: init,
|
||||
config: (_config: ParserConfiguration, jax: any) => {
|
||||
//
|
||||
// Move multlineWidth from old location to ams block (remove in next version)
|
||||
//
|
||||
if (jax.parseOptions.options.multlineWidth) {
|
||||
jax.parseOptions.options.ams.multlineWidth = jax.parseOptions.options.multlineWidth;
|
||||
}
|
||||
delete jax.parseOptions.options.multlineWidth;
|
||||
},
|
||||
options: {
|
||||
multlineWidth: '',
|
||||
ams: {
|
||||
multlineWidth: '100%', // The width to use for multline environments.
|
||||
multlineIndent: '1em', // The margin to use on both sides of multline environments.
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
224
node_modules/mathjax-full/ts/input/tex/ams/AmsItems.ts
generated
vendored
Normal file
224
node_modules/mathjax-full/ts/input/tex/ams/AmsItems.ts
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview StackItems needed for parsing AMS math commands.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import {ArrayItem, EqnArrayItem} from '../base/BaseItems.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import TexError from '../TexError.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
|
||||
|
||||
/**
|
||||
* Item dealing with multiline environments as a special case of arrays. Note,
|
||||
* that all other AMS equation environments (e.g., align, split) can be handled
|
||||
* by the regular EqnArrayItem class.
|
||||
*
|
||||
* Handles tagging information according to the given tagging style.
|
||||
*/
|
||||
export class MultlineItem extends ArrayItem {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
constructor(factory: any, ...args: any[]) {
|
||||
super(factory);
|
||||
this.factory.configuration.tags.start('multline', true, args[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
get kind() {
|
||||
return 'multline';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public EndEntry() {
|
||||
if (this.table.length) {
|
||||
ParseUtil.fixInitialMO(this.factory.configuration, this.nodes);
|
||||
}
|
||||
const shove = this.getProperty('shove');
|
||||
const mtd = this.create('node',
|
||||
'mtd', this.nodes, shove ? {columnalign: shove} : {});
|
||||
this.setProperty('shove', null);
|
||||
this.row.push(mtd);
|
||||
this.Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public EndRow() {
|
||||
if (this.row.length !== 1) {
|
||||
// @test MultlineRowsOneCol
|
||||
throw new TexError(
|
||||
'MultlineRowsOneCol',
|
||||
'The rows within the %1 environment must have exactly one column',
|
||||
'multline');
|
||||
}
|
||||
let row = this.create('node', 'mtr', this.row);
|
||||
this.table.push(row);
|
||||
this.row = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public EndTable() {
|
||||
super.EndTable();
|
||||
if (this.table.length) {
|
||||
let m = this.table.length - 1, label = -1;
|
||||
if (!NodeUtil.getAttribute(
|
||||
NodeUtil.getChildren(this.table[0])[0], 'columnalign')) {
|
||||
NodeUtil.setAttribute(NodeUtil.getChildren(this.table[0])[0],
|
||||
'columnalign', TexConstant.Align.LEFT);
|
||||
}
|
||||
if (!NodeUtil.getAttribute(
|
||||
NodeUtil.getChildren(this.table[m])[0], 'columnalign')) {
|
||||
NodeUtil.setAttribute(NodeUtil.getChildren(this.table[m])[0],
|
||||
'columnalign', TexConstant.Align.RIGHT);
|
||||
}
|
||||
let tag = this.factory.configuration.tags.getTag();
|
||||
if (tag) {
|
||||
label = (this.arraydef.side === TexConstant.Align.LEFT ? 0 : this.table.length - 1);
|
||||
const mtr = this.table[label];
|
||||
const mlabel = this.create('node', 'mlabeledtr',
|
||||
[tag].concat(NodeUtil.getChildren(mtr)));
|
||||
NodeUtil.copyAttributes(mtr, mlabel);
|
||||
this.table[label] = mlabel;
|
||||
}
|
||||
}
|
||||
this.factory.configuration.tags.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* StackItem for handling flalign, xalignat, and xxalignat environments.
|
||||
*/
|
||||
export class FlalignItem extends EqnArrayItem {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
get kind() {
|
||||
return 'flalign';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
constructor(factory: any, public name: string, public numbered: boolean,
|
||||
public padded: boolean, public center: boolean) {
|
||||
super(factory);
|
||||
this.factory.configuration.tags.start(name, numbered, numbered);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public EndEntry() {
|
||||
super.EndEntry();
|
||||
const n = this.getProperty('xalignat') as number;
|
||||
if (!n) return;
|
||||
if (this.row.length > n) {
|
||||
throw new TexError('XalignOverflow', 'Extra %1 in row of %2', '&', this.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public EndRow() {
|
||||
let cell: MmlNode;
|
||||
let row = this.row;
|
||||
//
|
||||
// For xalignat and xxalignat, pad the row to the expected number if it is too short.
|
||||
//
|
||||
const n = this.getProperty('xalignat') as number;
|
||||
while (row.length < n) {
|
||||
row.push(this.create('node', 'mtd'));
|
||||
}
|
||||
//
|
||||
// Insert padding cells between pairs of entries, as needed for "fit" columns,
|
||||
// and include initial and end cells if that is needed.
|
||||
//
|
||||
this.row = [];
|
||||
if (this.padded) {
|
||||
this.row.push(this.create('node', 'mtd'));
|
||||
}
|
||||
while ((cell = row.shift())) {
|
||||
this.row.push(cell);
|
||||
cell = row.shift();
|
||||
if (cell) this.row.push(cell);
|
||||
if (row.length || this.padded) {
|
||||
this.row.push(this.create('node', 'mtd'));
|
||||
}
|
||||
}
|
||||
//
|
||||
if (this.row.length > this.maxrow) {
|
||||
this.maxrow = this.row.length;
|
||||
}
|
||||
super.EndRow();
|
||||
//
|
||||
// For full-width environments with labels that aren't supposed to take up space,
|
||||
// move the label into a zero-width mpadded element that laps in the proper direction.
|
||||
//
|
||||
const mtr = this.table[this.table.length - 1];
|
||||
if (this.getProperty('zeroWidthLabel') && mtr.isKind('mlabeledtr')) {
|
||||
const mtd = NodeUtil.getChildren(mtr)[0];
|
||||
const side = this.factory.configuration.options['tagSide'];
|
||||
const def = {width: 0, ...(side === 'right' ? {lspace: '-1width'} : {})};
|
||||
const mpadded = this.create('node', 'mpadded', NodeUtil.getChildren(mtd), def);
|
||||
mtd.setChildren([mpadded]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public EndTable() {
|
||||
super.EndTable();
|
||||
if (this.center) {
|
||||
//
|
||||
// If there is only one equation (one pair):
|
||||
// Don't make it 100%, and don't change the indentalign.
|
||||
//
|
||||
if (this.maxrow <= 2) {
|
||||
const def = this.arraydef;
|
||||
delete def.width;
|
||||
delete this.global.indentalign;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
443
node_modules/mathjax-full/ts/input/tex/ams/AmsMappings.ts
generated
vendored
Normal file
443
node_modules/mathjax-full/ts/input/tex/ams/AmsMappings.ts
generated
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Mappings for TeX parsing of the AMS math package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {AmsMethods} from './AmsMethods.js';
|
||||
import * as sm from '../SymbolMap.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import ParseMethods from '../ParseMethods.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
|
||||
import {MATHSPACE} from '../../../util/lengths.js';
|
||||
|
||||
|
||||
/**
|
||||
* Operators from the AMS Math package.
|
||||
*/
|
||||
new sm.CharacterMap('AMSmath-mathchar0mo', ParseMethods.mathchar0mo, {
|
||||
iiiint: ['\u2A0C', {texClass: TEXCLASS.OP}]
|
||||
});
|
||||
|
||||
/**
|
||||
* Extra characters that are letters in \operatorname
|
||||
*/
|
||||
new sm.RegExpMap('AMSmath-operatorLetter', AmsMethods.operatorLetter, /[-*]/i);
|
||||
|
||||
/**
|
||||
* Macros from the AMS Math package.
|
||||
*/
|
||||
new sm.CommandMap('AMSmath-macros', {
|
||||
mathring: ['Accent', '02DA'], // or 0x30A
|
||||
nobreakspace: 'Tilde',
|
||||
negmedspace: ['Spacer', MATHSPACE.negativemediummathspace],
|
||||
negthickspace: ['Spacer', MATHSPACE.negativethickmathspace],
|
||||
|
||||
idotsint: ['MultiIntegral', '\\int\\cdots\\int'],
|
||||
|
||||
dddot: ['Accent', '20DB'],
|
||||
ddddot: ['Accent', '20DC'],
|
||||
|
||||
sideset: 'SideSet',
|
||||
|
||||
boxed: ['Macro', '\\fbox{$\\displaystyle{#1}$}', 1],
|
||||
|
||||
tag: 'HandleTag',
|
||||
notag: 'HandleNoTag',
|
||||
eqref: ['HandleRef', true],
|
||||
|
||||
substack: ['Macro', '\\begin{subarray}{c}#1\\end{subarray}', 1],
|
||||
|
||||
injlim: ['NamedOp', 'inj lim'],
|
||||
projlim: ['NamedOp', 'proj lim'],
|
||||
varliminf: ['Macro', '\\mathop{\\underline{\\mmlToken{mi}{lim}}}'],
|
||||
varlimsup: ['Macro', '\\mathop{\\overline{\\mmlToken{mi}{lim}}}'],
|
||||
varinjlim: ['Macro', '\\mathop{\\underrightarrow{\\mmlToken{mi}{lim}}}'],
|
||||
varprojlim: ['Macro', '\\mathop{\\underleftarrow{\\mmlToken{mi}{lim}}}'],
|
||||
|
||||
DeclareMathOperator: 'HandleDeclareOp',
|
||||
operatorname: 'HandleOperatorName',
|
||||
|
||||
genfrac: 'Genfrac',
|
||||
frac: ['Genfrac', '', '', '', ''],
|
||||
tfrac: ['Genfrac', '', '', '', '1'],
|
||||
dfrac: ['Genfrac', '', '', '', '0'],
|
||||
binom: ['Genfrac', '(', ')', '0', ''],
|
||||
tbinom: ['Genfrac', '(', ')', '0', '1'],
|
||||
dbinom: ['Genfrac', '(', ')', '0', '0'],
|
||||
|
||||
cfrac: 'CFrac',
|
||||
|
||||
shoveleft: ['HandleShove', TexConstant.Align.LEFT],
|
||||
shoveright: ['HandleShove', TexConstant.Align.RIGHT],
|
||||
|
||||
xrightarrow: ['xArrow', 0x2192, 5, 10],
|
||||
xleftarrow: ['xArrow', 0x2190, 10, 5]
|
||||
}, AmsMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Environments from the AMS Math package.
|
||||
*/
|
||||
new sm.EnvironmentMap('AMSmath-environment', ParseMethods.environment, {
|
||||
'equation*': ['Equation', null, false],
|
||||
'eqnarray*': ['EqnArray', null, false, true, 'rcl',
|
||||
ParseUtil.cols(0, MATHSPACE.thickmathspace), '.5em'],
|
||||
align: ['EqnArray', null, true, true, 'rl', ParseUtil.cols(0, 2)],
|
||||
'align*': ['EqnArray', null, false, true, 'rl', ParseUtil.cols(0, 2)],
|
||||
multline: ['Multline', null, true],
|
||||
'multline*': ['Multline', null, false],
|
||||
split: ['EqnArray', null, false, false, 'rl', ParseUtil.cols(0)],
|
||||
gather: ['EqnArray', null, true, true, 'c'],
|
||||
'gather*': ['EqnArray', null, false, true, 'c'],
|
||||
|
||||
alignat: ['AlignAt', null, true, true],
|
||||
'alignat*': ['AlignAt', null, false, true],
|
||||
alignedat: ['AlignAt', null, false, false],
|
||||
|
||||
aligned: ['AmsEqnArray', null, null, null, 'rl', ParseUtil.cols(0, 2), '.5em', 'D'],
|
||||
gathered: ['AmsEqnArray', null, null, null, 'c', null, '.5em', 'D'],
|
||||
|
||||
xalignat: ['XalignAt', null, true, true],
|
||||
'xalignat*': ['XalignAt', null, false, true],
|
||||
xxalignat: ['XalignAt', null, false, false],
|
||||
flalign: ['FlalignArray', null, true, false, true, 'rlc', 'auto auto fit'],
|
||||
'flalign*': ['FlalignArray', null, false, false, true, 'rlc', 'auto auto fit'],
|
||||
|
||||
subarray: ['Array', null, null, null, null, ParseUtil.cols(0), '0.1em', 'S', 1],
|
||||
smallmatrix: ['Array', null, null, null, 'c', ParseUtil.cols(1 / 3),
|
||||
'.2em', 'S', 1],
|
||||
matrix: ['Array', null, null, null, 'c'],
|
||||
pmatrix: ['Array', null, '(', ')', 'c'],
|
||||
bmatrix: ['Array', null, '[', ']', 'c'],
|
||||
Bmatrix: ['Array', null, '\\{', '\\}', 'c'],
|
||||
vmatrix: ['Array', null, '\\vert', '\\vert', 'c'],
|
||||
Vmatrix: ['Array', null, '\\Vert', '\\Vert', 'c'],
|
||||
cases: ['Array', null, '\\{', '.', 'll', null, '.2em', 'T']
|
||||
}, AmsMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Delimiters from the AMS Math package.
|
||||
*/
|
||||
new sm.DelimiterMap('AMSmath-delimiter', ParseMethods.delimiter, {
|
||||
'\\lvert': ['\u007C', {texClass: TEXCLASS.OPEN}],
|
||||
'\\rvert': ['\u007C', {texClass: TEXCLASS.CLOSE}],
|
||||
'\\lVert': ['\u2016', {texClass: TEXCLASS.OPEN}],
|
||||
'\\rVert': ['\u2016', {texClass: TEXCLASS.CLOSE}]
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Identifiers from the AMS Symbols package.
|
||||
*/
|
||||
new sm.CharacterMap('AMSsymbols-mathchar0mi', ParseMethods.mathchar0mi, {
|
||||
// Lowercase Greek letters
|
||||
digamma: '\u03DD',
|
||||
varkappa: '\u03F0',
|
||||
|
||||
// Uppercase Greek letters
|
||||
varGamma: ['\u0393', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
varDelta: ['\u0394', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
varTheta: ['\u0398', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
varLambda: ['\u039B', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
varXi: ['\u039E', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
varPi: ['\u03A0', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
varSigma: ['\u03A3', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
varUpsilon: ['\u03A5', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
varPhi: ['\u03A6', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
varPsi: ['\u03A8', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
varOmega: ['\u03A9', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
|
||||
// Hebrew letters
|
||||
beth: '\u2136',
|
||||
gimel: '\u2137',
|
||||
daleth: '\u2138',
|
||||
|
||||
// Miscellaneous symbols
|
||||
// hbar: '\u0127', // in TeX/jax.js
|
||||
backprime: ['\u2035', {variantForm: true}],
|
||||
hslash: '\u210F',
|
||||
varnothing: ['\u2205', {variantForm: true}],
|
||||
blacktriangle: '\u25B4',
|
||||
triangledown: ['\u25BD', {variantForm: true}],
|
||||
blacktriangledown: '\u25BE',
|
||||
square: '\u25FB',
|
||||
Box: '\u25FB',
|
||||
blacksquare: '\u25FC',
|
||||
lozenge: '\u25CA',
|
||||
Diamond: '\u25CA',
|
||||
blacklozenge: '\u29EB',
|
||||
circledS: ['\u24C8', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
bigstar: '\u2605',
|
||||
// angle: '\u2220', // in TeX/jax.js
|
||||
sphericalangle: '\u2222',
|
||||
measuredangle: '\u2221',
|
||||
nexists: '\u2204',
|
||||
complement: '\u2201',
|
||||
mho: '\u2127',
|
||||
eth: ['\u00F0', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
Finv: '\u2132',
|
||||
diagup: '\u2571',
|
||||
Game: '\u2141',
|
||||
diagdown: '\u2572',
|
||||
Bbbk: ['\u006B',
|
||||
{mathvariant: TexConstant.Variant.DOUBLESTRUCK}],
|
||||
|
||||
yen: '\u00A5',
|
||||
circledR: '\u00AE',
|
||||
checkmark: '\u2713',
|
||||
maltese: '\u2720'
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Operators from the AMS Symbols package.
|
||||
*/
|
||||
new sm.CharacterMap('AMSsymbols-mathchar0mo', ParseMethods.mathchar0mo, {
|
||||
// Binary operators
|
||||
dotplus: '\u2214',
|
||||
ltimes: '\u22C9',
|
||||
smallsetminus: ['\u2216', {variantForm: true}],
|
||||
rtimes: '\u22CA',
|
||||
Cap: '\u22D2',
|
||||
doublecap: '\u22D2',
|
||||
leftthreetimes: '\u22CB',
|
||||
Cup: '\u22D3',
|
||||
doublecup: '\u22D3',
|
||||
rightthreetimes: '\u22CC',
|
||||
barwedge: '\u22BC',
|
||||
curlywedge: '\u22CF',
|
||||
veebar: '\u22BB',
|
||||
curlyvee: '\u22CE',
|
||||
doublebarwedge: '\u2A5E',
|
||||
boxminus: '\u229F',
|
||||
circleddash: '\u229D',
|
||||
boxtimes: '\u22A0',
|
||||
circledast: '\u229B',
|
||||
boxdot: '\u22A1',
|
||||
circledcirc: '\u229A',
|
||||
boxplus: '\u229E',
|
||||
centerdot: ['\u22C5', {variantForm: true}],
|
||||
divideontimes: '\u22C7',
|
||||
intercal: '\u22BA',
|
||||
|
||||
// Binary relations
|
||||
leqq: '\u2266',
|
||||
geqq: '\u2267',
|
||||
leqslant: '\u2A7D',
|
||||
geqslant: '\u2A7E',
|
||||
eqslantless: '\u2A95',
|
||||
eqslantgtr: '\u2A96',
|
||||
lesssim: '\u2272',
|
||||
gtrsim: '\u2273',
|
||||
lessapprox: '\u2A85',
|
||||
gtrapprox: '\u2A86',
|
||||
approxeq: '\u224A',
|
||||
lessdot: '\u22D6',
|
||||
gtrdot: '\u22D7',
|
||||
lll: '\u22D8',
|
||||
llless: '\u22D8',
|
||||
ggg: '\u22D9',
|
||||
gggtr: '\u22D9',
|
||||
lessgtr: '\u2276',
|
||||
gtrless: '\u2277',
|
||||
lesseqgtr: '\u22DA',
|
||||
gtreqless: '\u22DB',
|
||||
lesseqqgtr: '\u2A8B',
|
||||
gtreqqless: '\u2A8C',
|
||||
doteqdot: '\u2251',
|
||||
Doteq: '\u2251',
|
||||
eqcirc: '\u2256',
|
||||
risingdotseq: '\u2253',
|
||||
circeq: '\u2257',
|
||||
fallingdotseq: '\u2252',
|
||||
triangleq: '\u225C',
|
||||
backsim: '\u223D',
|
||||
thicksim: ['\u223C', {variantForm: true}],
|
||||
backsimeq: '\u22CD',
|
||||
thickapprox: ['\u2248', {variantForm: true}],
|
||||
subseteqq: '\u2AC5',
|
||||
supseteqq: '\u2AC6',
|
||||
Subset: '\u22D0',
|
||||
Supset: '\u22D1',
|
||||
sqsubset: '\u228F',
|
||||
sqsupset: '\u2290',
|
||||
preccurlyeq: '\u227C',
|
||||
succcurlyeq: '\u227D',
|
||||
curlyeqprec: '\u22DE',
|
||||
curlyeqsucc: '\u22DF',
|
||||
precsim: '\u227E',
|
||||
succsim: '\u227F',
|
||||
precapprox: '\u2AB7',
|
||||
succapprox: '\u2AB8',
|
||||
vartriangleleft: '\u22B2',
|
||||
lhd: '\u22B2',
|
||||
vartriangleright: '\u22B3',
|
||||
rhd: '\u22B3',
|
||||
trianglelefteq: '\u22B4',
|
||||
unlhd: '\u22B4',
|
||||
trianglerighteq: '\u22B5',
|
||||
unrhd: '\u22B5',
|
||||
vDash: ['\u22A8', {variantForm: true}],
|
||||
Vdash: '\u22A9',
|
||||
Vvdash: '\u22AA',
|
||||
smallsmile: ['\u2323', {variantForm: true}],
|
||||
shortmid: ['\u2223', {variantForm: true}],
|
||||
smallfrown: ['\u2322', {variantForm: true}],
|
||||
shortparallel: ['\u2225', {variantForm: true}],
|
||||
bumpeq: '\u224F',
|
||||
between: '\u226C',
|
||||
Bumpeq: '\u224E',
|
||||
pitchfork: '\u22D4',
|
||||
varpropto: ['\u221D', {variantForm: true}],
|
||||
backepsilon: '\u220D',
|
||||
blacktriangleleft: '\u25C2',
|
||||
blacktriangleright: '\u25B8',
|
||||
therefore: '\u2234',
|
||||
because: '\u2235',
|
||||
eqsim: '\u2242',
|
||||
vartriangle: ['\u25B3', {variantForm: true}],
|
||||
Join: '\u22C8',
|
||||
|
||||
// Negated relations
|
||||
nless: '\u226E',
|
||||
ngtr: '\u226F',
|
||||
nleq: '\u2270',
|
||||
ngeq: '\u2271',
|
||||
nleqslant: ['\u2A87', {variantForm: true}],
|
||||
ngeqslant: ['\u2A88', {variantForm: true}],
|
||||
nleqq: ['\u2270', {variantForm: true}],
|
||||
ngeqq: ['\u2271', {variantForm: true}],
|
||||
lneq: '\u2A87',
|
||||
gneq: '\u2A88',
|
||||
lneqq: '\u2268',
|
||||
gneqq: '\u2269',
|
||||
lvertneqq: ['\u2268', {variantForm: true}],
|
||||
gvertneqq: ['\u2269', {variantForm: true}],
|
||||
lnsim: '\u22E6',
|
||||
gnsim: '\u22E7',
|
||||
lnapprox: '\u2A89',
|
||||
gnapprox: '\u2A8A',
|
||||
nprec: '\u2280',
|
||||
nsucc: '\u2281',
|
||||
npreceq: ['\u22E0', {variantForm: true}],
|
||||
nsucceq: ['\u22E1', {variantForm: true}],
|
||||
precneqq: '\u2AB5',
|
||||
succneqq: '\u2AB6',
|
||||
precnsim: '\u22E8',
|
||||
succnsim: '\u22E9',
|
||||
precnapprox: '\u2AB9',
|
||||
succnapprox: '\u2ABA',
|
||||
nsim: '\u2241',
|
||||
ncong: '\u2247',
|
||||
nshortmid: ['\u2224', {variantForm: true}],
|
||||
nshortparallel: ['\u2226', {variantForm: true}],
|
||||
nmid: '\u2224',
|
||||
nparallel: '\u2226',
|
||||
nvdash: '\u22AC',
|
||||
nvDash: '\u22AD',
|
||||
nVdash: '\u22AE',
|
||||
nVDash: '\u22AF',
|
||||
ntriangleleft: '\u22EA',
|
||||
ntriangleright: '\u22EB',
|
||||
ntrianglelefteq: '\u22EC',
|
||||
ntrianglerighteq: '\u22ED',
|
||||
nsubseteq: '\u2288',
|
||||
nsupseteq: '\u2289',
|
||||
nsubseteqq: ['\u2288', {variantForm: true}],
|
||||
nsupseteqq: ['\u2289', {variantForm: true}],
|
||||
subsetneq: '\u228A',
|
||||
supsetneq: '\u228B',
|
||||
varsubsetneq: ['\u228A', {variantForm: true}],
|
||||
varsupsetneq: ['\u228B', {variantForm: true}],
|
||||
subsetneqq: '\u2ACB',
|
||||
supsetneqq: '\u2ACC',
|
||||
varsubsetneqq: ['\u2ACB', {variantForm: true}],
|
||||
varsupsetneqq: ['\u2ACC', {variantForm: true}],
|
||||
|
||||
|
||||
// Arrows
|
||||
leftleftarrows: '\u21C7',
|
||||
rightrightarrows: '\u21C9',
|
||||
leftrightarrows: '\u21C6',
|
||||
rightleftarrows: '\u21C4',
|
||||
Lleftarrow: '\u21DA',
|
||||
Rrightarrow: '\u21DB',
|
||||
twoheadleftarrow: '\u219E',
|
||||
twoheadrightarrow: '\u21A0',
|
||||
leftarrowtail: '\u21A2',
|
||||
rightarrowtail: '\u21A3',
|
||||
looparrowleft: '\u21AB',
|
||||
looparrowright: '\u21AC',
|
||||
leftrightharpoons: '\u21CB',
|
||||
rightleftharpoons: ['\u21CC', {variantForm: true}],
|
||||
curvearrowleft: '\u21B6',
|
||||
curvearrowright: '\u21B7',
|
||||
circlearrowleft: '\u21BA',
|
||||
circlearrowright: '\u21BB',
|
||||
Lsh: '\u21B0',
|
||||
Rsh: '\u21B1',
|
||||
upuparrows: '\u21C8',
|
||||
downdownarrows: '\u21CA',
|
||||
upharpoonleft: '\u21BF',
|
||||
upharpoonright: '\u21BE',
|
||||
downharpoonleft: '\u21C3',
|
||||
restriction: '\u21BE',
|
||||
multimap: '\u22B8',
|
||||
downharpoonright: '\u21C2',
|
||||
leftrightsquigarrow: '\u21AD',
|
||||
rightsquigarrow: '\u21DD',
|
||||
leadsto: '\u21DD',
|
||||
dashrightarrow: '\u21E2',
|
||||
dashleftarrow: '\u21E0',
|
||||
|
||||
// Negated arrows
|
||||
nleftarrow: '\u219A',
|
||||
nrightarrow: '\u219B',
|
||||
nLeftarrow: '\u21CD',
|
||||
nRightarrow: '\u21CF',
|
||||
nleftrightarrow: '\u21AE',
|
||||
nLeftrightarrow: '\u21CE'
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Delimiters from the AMS Symbols package.
|
||||
*/
|
||||
new sm.DelimiterMap('AMSsymbols-delimiter', ParseMethods.delimiter, {
|
||||
// corners
|
||||
'\\ulcorner': '\u231C',
|
||||
'\\urcorner': '\u231D',
|
||||
'\\llcorner': '\u231E',
|
||||
'\\lrcorner': '\u231F'
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Macros from the AMS Symbols package.
|
||||
*/
|
||||
new sm.CommandMap('AMSsymbols-macros', {
|
||||
implies: ['Macro', '\\;\\Longrightarrow\\;'],
|
||||
impliedby: ['Macro', '\\;\\Longleftarrow\\;']
|
||||
}, AmsMethods);
|
||||
602
node_modules/mathjax-full/ts/input/tex/ams/AmsMethods.ts
generated
vendored
Normal file
602
node_modules/mathjax-full/ts/input/tex/ams/AmsMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,602 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview The AMS Parse methods.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import {StackItem} from '../StackItem.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import ParseMethods from '../ParseMethods.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import TexError from '../TexError.js';
|
||||
import {Macro} from '../Symbol.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ArrayItem} from '../base/BaseItems.js';
|
||||
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 {MmlNode, AbstractMmlTokenNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
|
||||
|
||||
// Namespace
|
||||
export const AmsMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
|
||||
/**
|
||||
* Handle AMS array environments.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {StackItem} begin The opening stackitem.
|
||||
* @param {boolean} numbered Environment numbered.
|
||||
* @param {boolean} taggable Environment taggable (e.g., align* is taggable,
|
||||
* split is not).
|
||||
* @param {string} align Column alignment.
|
||||
* @param {string} spacing Column spacing.
|
||||
* @param {string} style Display style indicator.
|
||||
*/
|
||||
AmsMethods.AmsEqnArray = function(parser: TexParser, begin: StackItem,
|
||||
numbered: boolean, taggable: boolean,
|
||||
align: string, spacing: string,
|
||||
style: string) {
|
||||
// @test Aligned, Gathered
|
||||
const args = parser.GetBrackets('\\begin{' + begin.getName() + '}');
|
||||
const array = BaseMethods.EqnArray(parser, begin, numbered, taggable, align, spacing, style);
|
||||
return ParseUtil.setArrayAlign(array as ArrayItem, args);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle AMS alignat environments.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {StackItem} begin The opening stackitem.
|
||||
* @param {boolean} numbered Environment numbered.
|
||||
* @param {boolean} taggable Environment taggable (e.g., align* is taggable,
|
||||
* split is not).
|
||||
*/
|
||||
AmsMethods.AlignAt = function(parser: TexParser, begin: StackItem,
|
||||
numbered: boolean, taggable: boolean) {
|
||||
const name = begin.getName();
|
||||
let n, valign, align = '', spacing = [];
|
||||
if (!taggable) {
|
||||
// @test Alignedat
|
||||
valign = parser.GetBrackets('\\begin{' + name + '}');
|
||||
}
|
||||
n = parser.GetArgument('\\begin{' + name + '}');
|
||||
if (n.match(/[^0-9]/)) {
|
||||
// @test PositiveIntegerArg
|
||||
throw new TexError('PositiveIntegerArg',
|
||||
'Argument to %1 must me a positive integer',
|
||||
'\\begin{' + name + '}');
|
||||
}
|
||||
let count = parseInt(n, 10);
|
||||
while (count > 0) {
|
||||
align += 'rl';
|
||||
spacing.push('0em 0em');
|
||||
count--;
|
||||
}
|
||||
let spaceStr = spacing.join(' ');
|
||||
if (taggable) {
|
||||
// @test Alignat, Alignat Star
|
||||
return AmsMethods.EqnArray(parser, begin, numbered, taggable, align, spaceStr);
|
||||
}
|
||||
// @test Alignedat
|
||||
let array = AmsMethods.EqnArray(parser, begin, numbered, taggable, align, spaceStr);
|
||||
return ParseUtil.setArrayAlign(array as ArrayItem, valign);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements multline environment (mostly handled through STACKITEM below)
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {StackItem} begin The opening stackitem.
|
||||
* @param {boolean} numbered Environment numbered.
|
||||
*/
|
||||
AmsMethods.Multline = function (parser: TexParser, begin: StackItem, numbered: boolean) {
|
||||
// @test Shove*, Multline
|
||||
parser.Push(begin);
|
||||
ParseUtil.checkEqnEnv(parser);
|
||||
const item = parser.itemFactory.create('multline', numbered, parser.stack) as ArrayItem;
|
||||
item.arraydef = {
|
||||
displaystyle: true,
|
||||
rowspacing: '.5em',
|
||||
columnspacing: '100%',
|
||||
width: parser.options.ams['multlineWidth'],
|
||||
side: parser.options['tagSide'],
|
||||
minlabelspacing: parser.options['tagIndent'],
|
||||
framespacing: parser.options.ams['multlineIndent'] + ' 0',
|
||||
frame: '', // Use frame spacing with no actual frame
|
||||
'data-width-includes-label': true // take label space out of 100% width
|
||||
};
|
||||
return item;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate an align at environment.
|
||||
* @param {TexParser} parser The current TeX parser.
|
||||
* @param {StackItem} begin The begin stackitem.
|
||||
* @param {boolean} numbered Is this a numbered array.
|
||||
* @param {boolean} padded Is it padded.
|
||||
*/
|
||||
AmsMethods.XalignAt = function(parser: TexParser, begin: StackItem,
|
||||
numbered: boolean, padded: boolean) {
|
||||
let n = parser.GetArgument('\\begin{' + begin.getName() + '}');
|
||||
if (n.match(/[^0-9]/)) {
|
||||
throw new TexError('PositiveIntegerArg',
|
||||
'Argument to %1 must me a positive integer',
|
||||
'\\begin{' + begin.getName() + '}');
|
||||
}
|
||||
const align = (padded ? 'crl' : 'rlc');
|
||||
const width = (padded ? 'fit auto auto' : 'auto auto fit');
|
||||
const item = AmsMethods.FlalignArray(parser, begin, numbered, padded, false, align, width, true) as FlalignItem;
|
||||
item.setProperty('xalignat', 2 * parseInt(n));
|
||||
return item;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate an flalign environment.
|
||||
* @param {TexParser} parser The current TeX parser.
|
||||
* @param {StackItem} begin The begin stackitem.
|
||||
* @param {boolean} numbered Is this a numbered array.
|
||||
* @param {boolean} padded Is it padded.
|
||||
* @param {boolean} center Is it centered.
|
||||
* @param {string} align The horizontal alignment for columns
|
||||
* @param {string} width The column widths of the table
|
||||
* @param {boolean} zeroWidthLabel True if the label should be in llap/rlap
|
||||
*/
|
||||
AmsMethods.FlalignArray = function(parser: TexParser, begin: StackItem, numbered: boolean,
|
||||
padded: boolean, center: boolean, align: string,
|
||||
width: string, zeroWidthLabel: boolean = false) {
|
||||
parser.Push(begin);
|
||||
ParseUtil.checkEqnEnv(parser);
|
||||
align = align
|
||||
.split('')
|
||||
.join(' ')
|
||||
.replace(/r/g, 'right')
|
||||
.replace(/l/g, 'left')
|
||||
.replace(/c/g, 'center');
|
||||
const item = parser.itemFactory.create(
|
||||
'flalign', begin.getName(), numbered, padded, center, parser.stack) as FlalignItem;
|
||||
item.arraydef = {
|
||||
width: '100%',
|
||||
displaystyle: true,
|
||||
columnalign: align,
|
||||
columnspacing: '0em',
|
||||
columnwidth: width,
|
||||
rowspacing: '3pt',
|
||||
side: parser.options['tagSide'],
|
||||
minlabelspacing: (zeroWidthLabel ? '0' : parser.options['tagIndent']),
|
||||
'data-width-includes-label': true,
|
||||
};
|
||||
item.setProperty('zeroWidthLabel', zeroWidthLabel);
|
||||
return item;
|
||||
};
|
||||
|
||||
|
||||
export const NEW_OPS = 'ams-declare-ops';
|
||||
|
||||
/**
|
||||
* Handle DeclareMathOperator.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
AmsMethods.HandleDeclareOp = function (parser: TexParser, name: string) {
|
||||
let star = (parser.GetStar() ? '*' : '');
|
||||
let cs = ParseUtil.trimSpaces(parser.GetArgument(name));
|
||||
if (cs.charAt(0) === '\\') {
|
||||
cs = cs.substr(1);
|
||||
}
|
||||
let op = parser.GetArgument(name);
|
||||
(parser.configuration.handlers.retrieve(NEW_OPS) as CommandMap).
|
||||
add(cs, new Macro(cs, AmsMethods.Macro, [`\\operatorname${star}{${op}}`]));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle operatorname.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
AmsMethods.HandleOperatorName = function(parser: TexParser, name: string) {
|
||||
// @test Operatorname
|
||||
const star = parser.GetStar();
|
||||
//
|
||||
// Parse the argument using operator letters and grouping multiple letters.
|
||||
//
|
||||
let op = ParseUtil.trimSpaces(parser.GetArgument(name));
|
||||
let mml = new TexParser(op, {
|
||||
...parser.stack.env,
|
||||
font: TexConstant.Variant.NORMAL,
|
||||
multiLetterIdentifiers: /^[-*a-z]+/i as any,
|
||||
operatorLetters: true
|
||||
}, parser.configuration).mml();
|
||||
//
|
||||
// If we get something other than a single mi, wrap in a TeXAtom.
|
||||
//
|
||||
if (!mml.isKind('mi')) {
|
||||
mml = parser.create('node', 'TeXAtom', [mml]);
|
||||
}
|
||||
//
|
||||
// Mark the limit properties and the TeX class.
|
||||
//
|
||||
NodeUtil.setProperties(mml, {movesupsub: star, movablelimits: true, texClass: TEXCLASS.OP});
|
||||
//
|
||||
// Skip a following \limits macro if not a starred operator
|
||||
//
|
||||
if (!star) {
|
||||
const c = parser.GetNext(), i = parser.i;
|
||||
if (c === '\\' && ++parser.i && parser.GetCS() !== 'limits') {
|
||||
parser.i = i;
|
||||
}
|
||||
}
|
||||
//
|
||||
parser.Push(mml);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle sideset.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
AmsMethods.SideSet = function (parser: TexParser, name: string) {
|
||||
//
|
||||
// Get the pre- and post-scripts, and any extra material from the arguments
|
||||
//
|
||||
const [preScripts, preRest] = splitSideSet(parser.ParseArg(name));
|
||||
const [postScripts, postRest] = splitSideSet(parser.ParseArg(name));
|
||||
const base = parser.ParseArg(name);
|
||||
let mml = base;
|
||||
//
|
||||
// If there are pre-scripts...
|
||||
//
|
||||
if (preScripts) {
|
||||
//
|
||||
// If there is other material...
|
||||
//
|
||||
if (preRest) {
|
||||
//
|
||||
// Replace the empty base of the prescripts with a phantom element of the
|
||||
// original base, with width 0 (but still of the correct height and depth).
|
||||
// so the scripts will be at the right heights.
|
||||
//
|
||||
preScripts.replaceChild(
|
||||
parser.create('node', 'mphantom', [
|
||||
parser.create('node', 'mpadded', [ParseUtil.copyNode(base, parser)], {width: 0})
|
||||
]),
|
||||
NodeUtil.getChildAt(preScripts, 0)
|
||||
);
|
||||
} else {
|
||||
//
|
||||
// If there is no extra meterial, make a mmultiscripts element
|
||||
//
|
||||
mml = parser.create('node', 'mmultiscripts', [base]);
|
||||
//
|
||||
// Add any postscripts
|
||||
//
|
||||
if (postScripts) {
|
||||
NodeUtil.appendChildren(mml, [
|
||||
NodeUtil.getChildAt(postScripts, 1) || parser.create('node', 'none'),
|
||||
NodeUtil.getChildAt(postScripts, 2) || parser.create('node', 'none')
|
||||
]);
|
||||
}
|
||||
//
|
||||
// Add the prescripts (left aligned)
|
||||
//
|
||||
NodeUtil.setProperty(mml, 'scriptalign', 'left');
|
||||
NodeUtil.appendChildren(mml, [
|
||||
parser.create('node', 'mprescripts'),
|
||||
NodeUtil.getChildAt(preScripts, 1) || parser.create('node', 'none'),
|
||||
NodeUtil.getChildAt(preScripts, 2) || parser.create('node', 'none')
|
||||
]);
|
||||
}
|
||||
}
|
||||
//
|
||||
// If there are postscripts and we didn't make a mmultiscript element above...
|
||||
//
|
||||
if (postScripts && mml === base) {
|
||||
//
|
||||
// Replace the emtpy base with actual base, and use that as the mml
|
||||
//
|
||||
postScripts.replaceChild(base, NodeUtil.getChildAt(postScripts, 0));
|
||||
mml = postScripts;
|
||||
}
|
||||
//
|
||||
// Put the needed pieces into a TeXAtom of class OP.
|
||||
// Note that the postScripts are in the mml element,
|
||||
// either as part of the mmultiscripts node, or the
|
||||
// msubsup with the base inserted into it.
|
||||
//
|
||||
const mrow = parser.create('node', 'TeXAtom', [], {texClass: TEXCLASS.OP, movesupsub: true, movablelimits: true});
|
||||
if (preRest) {
|
||||
preScripts && mrow.appendChild(preScripts);
|
||||
mrow.appendChild(preRest);
|
||||
}
|
||||
mrow.appendChild(mml);
|
||||
postRest && mrow.appendChild(postRest);
|
||||
parser.Push(mrow);
|
||||
};
|
||||
|
||||
/**
|
||||
* Utility for breaking the \sideset scripts from any other material.
|
||||
* @param {MmlNode} mml The node to check.
|
||||
* @return {[MmlNode, MmlNode]} The msubsup with the scripts together with any extra nodes.
|
||||
*/
|
||||
function splitSideSet(mml: MmlNode): [MmlNode, MmlNode] {
|
||||
if (!mml || (mml.isInferred && mml.childNodes.length === 0)) return [null, null];
|
||||
if (mml.isKind('msubsup') && checkSideSetBase(mml)) return [mml, null];
|
||||
const child = NodeUtil.getChildAt(mml, 0);
|
||||
if (!(mml.isInferred && child && checkSideSetBase(child))) return [null, mml];
|
||||
mml.childNodes.splice(0, 1); // remove first child
|
||||
return [child, mml];
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for checking if a \sideset argument has scripts with an empty base.
|
||||
* @param {MmlNode} mml The node to check.
|
||||
* @return {boolean} True if the base is not and empty mi element.
|
||||
*/
|
||||
function checkSideSetBase(mml: MmlNode): boolean {
|
||||
const base = mml.childNodes[0];
|
||||
return base && base.isKind('mi') && (base as AbstractMmlTokenNode).getText() === '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle extra letters in \operatorname (- and *), default to normal otherwise.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} c The letter being checked
|
||||
*/
|
||||
AmsMethods.operatorLetter = function (parser: TexParser, c: string) {
|
||||
return parser.stack.env.operatorLetters ? ParseMethods.variable(parser, c) : false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle multi integral signs.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} integral The actual integral sign.
|
||||
*/
|
||||
AmsMethods.MultiIntegral = function(parser: TexParser, name: string,
|
||||
integral: string) {
|
||||
let next = parser.GetNext();
|
||||
if (next === '\\') {
|
||||
// @test MultiInt with Command
|
||||
let i = parser.i;
|
||||
next = parser.GetArgument(name);
|
||||
parser.i = i;
|
||||
if (next === '\\limits') {
|
||||
if (name === '\\idotsint') {
|
||||
// @test MultiInt with Limits
|
||||
integral = '\\!\\!\\mathop{\\,\\,' + integral + '}';
|
||||
}
|
||||
else {
|
||||
// Question: This is not used anymore?
|
||||
integral = '\\!\\!\\!\\mathop{\\,\\,\\,' + integral + '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
// @test MultiInt, MultiInt in Context
|
||||
parser.string = integral + ' ' + parser.string.slice(parser.i);
|
||||
parser.i = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle stretchable arrows.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {number} chr The arrow character in hex code.
|
||||
* @param {number} l Left width.
|
||||
* @param {number} r Right width.
|
||||
*/
|
||||
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 bot = parser.GetBrackets(name);
|
||||
let first = parser.ParseArg(name);
|
||||
let dstrut = parser.create('node', 'mspace', [], {depth: '.25em'});
|
||||
let arrow = parser.create('token',
|
||||
'mo', {stretchy: true, texClass: TEXCLASS.REL}, String.fromCodePoint(chr));
|
||||
arrow = parser.create('node', 'mstyle', [arrow], {scriptlevel: 0});
|
||||
let mml = parser.create('node', 'munderover', [arrow]) as MmlMunderover;
|
||||
let mpadded = parser.create('node', 'mpadded', [first, dstrut], def);
|
||||
NodeUtil.setAttribute(mpadded, 'voffset', '-.2em');
|
||||
NodeUtil.setAttribute(mpadded, 'height', '-.2em');
|
||||
NodeUtil.setChild(mml, mml.over, mpadded);
|
||||
if (bot) {
|
||||
// @test Above Below Left Arrow, Above Below Right Arrow
|
||||
let bottom = new TexParser(bot, parser.stack.env, parser.configuration).mml();
|
||||
let bstrut = parser.create('node', 'mspace', [], {height: '.75em'});
|
||||
mpadded = parser.create('node', 'mpadded', [bottom, bstrut], def);
|
||||
NodeUtil.setAttribute(mpadded, 'voffset', '.15em');
|
||||
NodeUtil.setAttribute(mpadded, 'depth', '-.15em');
|
||||
NodeUtil.setChild(mml, mml.under, mpadded);
|
||||
}
|
||||
// @test Above Left Arrow, Above Right Arrow, Above Left Arrow in Context,
|
||||
// Above Right Arrow in Context
|
||||
NodeUtil.setProperty(mml, 'subsupOK', true);
|
||||
parser.Push(mml);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Record presence of \shoveleft and \shoveright
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} shove The shove value.
|
||||
*/
|
||||
AmsMethods.HandleShove = function(parser: TexParser, _name: string,
|
||||
shove: string) {
|
||||
let top = parser.stack.Top();
|
||||
// @test Shove (Left|Right) (Top|Middle|Bottom)
|
||||
if (top.kind !== 'multline') {
|
||||
// @test Shove Error Environment
|
||||
throw new TexError('CommandOnlyAllowedInEnv',
|
||||
'%1 only allowed in %2 environment',
|
||||
parser.currentCS, 'multline');
|
||||
}
|
||||
if (top.Size()) {
|
||||
// @test Shove Error (Top|Middle|Bottom)
|
||||
throw new TexError('CommandAtTheBeginingOfLine',
|
||||
'%1 must come at the beginning of the line', parser.currentCS);
|
||||
}
|
||||
top.setProperty('shove', shove);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle \cfrac
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
AmsMethods.CFrac = function(parser: TexParser, name: string) {
|
||||
let lr = ParseUtil.trimSpaces(parser.GetBrackets(name, ''));
|
||||
let num = parser.GetArgument(name);
|
||||
let den = parser.GetArgument(name);
|
||||
let lrMap: {[key: string]: string} = {
|
||||
l: TexConstant.Align.LEFT, r: TexConstant.Align.RIGHT, '': ''};
|
||||
let numNode = new TexParser('\\strut\\textstyle{' + num + '}',
|
||||
parser.stack.env, parser.configuration).mml();
|
||||
let denNode = new TexParser('\\strut\\textstyle{' + den + '}',
|
||||
parser.stack.env, parser.configuration).mml();
|
||||
let frac = parser.create('node', 'mfrac', [numNode, denNode]);
|
||||
lr = lrMap[lr];
|
||||
if (lr == null) {
|
||||
// @test Center Fraction Error
|
||||
throw new TexError('IllegalAlign', 'Illegal alignment specified in %1', parser.currentCS);
|
||||
}
|
||||
if (lr) {
|
||||
// @test Right Fraction, Left Fraction
|
||||
NodeUtil.setProperties(frac, {numalign: lr, denomalign: lr});
|
||||
}
|
||||
// @test Center Fraction
|
||||
parser.Push(frac);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implement AMS generalized fraction.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} left Left delimiter.
|
||||
* @param {string} right Right delimiter.
|
||||
* @param {string} thick Line thickness.
|
||||
* @param {string} style Math style.
|
||||
*/
|
||||
AmsMethods.Genfrac = function(parser: TexParser, name: string, left: string,
|
||||
right: string, thick: string, style: string) {
|
||||
if (left == null) { // @test Genfrac
|
||||
left = parser.GetDelimiterArg(name);
|
||||
}
|
||||
if (right == null) { // @test Genfrac
|
||||
right = parser.GetDelimiterArg(name);
|
||||
}
|
||||
if (thick == null) { // @test Genfrac
|
||||
thick = parser.GetArgument(name);
|
||||
}
|
||||
if (style == null) { // @test Genfrac
|
||||
style = ParseUtil.trimSpaces(parser.GetArgument(name));
|
||||
}
|
||||
let num = parser.ParseArg(name);
|
||||
let den = parser.ParseArg(name);
|
||||
let frac = parser.create('node', 'mfrac', [num, den]);
|
||||
if (thick !== '') {
|
||||
// @test Normal Binomial, Text Binomial, Display Binomial
|
||||
NodeUtil.setAttribute(frac, 'linethickness', thick);
|
||||
}
|
||||
if (left || right) {
|
||||
// @test Normal Binomial, Text Binomial, Display Binomial
|
||||
NodeUtil.setProperty(frac, 'withDelims', true);
|
||||
frac = ParseUtil.fixedFence(parser.configuration, left, frac, right);
|
||||
}
|
||||
if (style !== '') {
|
||||
let styleDigit = parseInt(style, 10);
|
||||
let styleAlpha = ['D', 'T', 'S', 'SS'][styleDigit];
|
||||
if (styleAlpha == null) {
|
||||
// @test Genfrac Error
|
||||
throw new TexError('BadMathStyleFor', 'Bad math style for %1', parser.currentCS);
|
||||
}
|
||||
frac = parser.create('node', 'mstyle', [frac]);
|
||||
if (styleAlpha === 'D') {
|
||||
// @test Display Fraction, Display Sub Fraction, Display Binomial,
|
||||
// Display Sub Binomial
|
||||
NodeUtil.setProperties(frac, {displaystyle: true, scriptlevel: 0});
|
||||
}
|
||||
else {
|
||||
// @test Text Fraction, Text Sub Fraction, Text Binomial,
|
||||
// Text Sub Binomial
|
||||
NodeUtil.setProperties(frac, {displaystyle: false,
|
||||
scriptlevel: styleDigit - 1});
|
||||
}
|
||||
}
|
||||
// @test Text Fraction, Normal Sub Binomial, Normal Binomial
|
||||
parser.Push(frac);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add the tag to the environment (to be added to the table row later).
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
AmsMethods.HandleTag = function(parser: TexParser, name: string) {
|
||||
if (!parser.tags.currentTag.taggable && parser.tags.env) {
|
||||
// @test Illegal Tag Error
|
||||
throw new TexError('CommandNotAllowedInEnv',
|
||||
'%1 not allowed in %2 environment',
|
||||
parser.currentCS, parser.tags.env);
|
||||
}
|
||||
if (parser.tags.currentTag.tag) {
|
||||
// @test Double Tag Error
|
||||
throw new TexError('MultipleCommand', 'Multiple %1', parser.currentCS);
|
||||
}
|
||||
let star = parser.GetStar();
|
||||
let tagId = ParseUtil.trimSpaces(parser.GetArgument(name));
|
||||
parser.tags.tag(tagId, star);
|
||||
};
|
||||
|
||||
|
||||
AmsMethods.HandleNoTag = BaseMethods.HandleNoTag;
|
||||
|
||||
AmsMethods.HandleRef = BaseMethods.HandleRef;
|
||||
|
||||
AmsMethods.Macro = BaseMethods.Macro;
|
||||
|
||||
AmsMethods.Accent = BaseMethods.Accent;
|
||||
|
||||
AmsMethods.Tilde = BaseMethods.Tilde;
|
||||
|
||||
AmsMethods.Array = BaseMethods.Array;
|
||||
|
||||
AmsMethods.Spacer = BaseMethods.Spacer;
|
||||
|
||||
AmsMethods.NamedOp = BaseMethods.NamedOp;
|
||||
|
||||
AmsMethods.EqnArray = BaseMethods.EqnArray;
|
||||
|
||||
AmsMethods.Equation = BaseMethods.Equation;
|
||||
46
node_modules/mathjax-full/ts/input/tex/amscd/AmsCdConfiguration.ts
generated
vendored
Normal file
46
node_modules/mathjax-full/ts/input/tex/amscd/AmsCdConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the AMScd package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import './AmsCdMappings.js';
|
||||
|
||||
|
||||
export const AmsCdConfiguration = Configuration.create(
|
||||
'amscd', {
|
||||
handler: {
|
||||
character: ['amscd_special'],
|
||||
macro: ['amscd_macros'],
|
||||
environment: ['amscd_environment']
|
||||
},
|
||||
options: {
|
||||
amscd: {
|
||||
colspace: '5pt',
|
||||
rowspace: '5pt',
|
||||
harrowsize: '2.75em',
|
||||
varrowsize: '1.75em',
|
||||
hideHorizontalLabels: false
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
38
node_modules/mathjax-full/ts/input/tex/amscd/AmsCdMappings.ts
generated
vendored
Normal file
38
node_modules/mathjax-full/ts/input/tex/amscd/AmsCdMappings.ts
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Symbol mappings for the AMScd package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import * as sm from '../SymbolMap.js';
|
||||
import ParseMethods from '../ParseMethods.js';
|
||||
import AmsCdMethods from './AmsCdMethods.js';
|
||||
|
||||
|
||||
new sm.EnvironmentMap('amscd_environment', ParseMethods.environment,
|
||||
{CD: 'CD'}, AmsCdMethods);
|
||||
|
||||
new sm.CommandMap('amscd_macros', {
|
||||
minCDarrowwidth: 'minCDarrowwidth',
|
||||
minCDarrowheight: 'minCDarrowheight',
|
||||
}, AmsCdMethods);
|
||||
|
||||
new sm.MacroMap('amscd_special', {'@': 'arrow'}, AmsCdMethods);
|
||||
201
node_modules/mathjax-full/ts/input/tex/amscd/AmsCdMethods.ts
generated
vendored
Normal file
201
node_modules/mathjax-full/ts/input/tex/amscd/AmsCdMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Methods for the AMScd package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import TexParser from '../TexParser.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import {StackItem, EnvList} from '../StackItem.js';
|
||||
import {ArrayItem} from '../base/BaseItems.js';
|
||||
import {Other} from '../base/BaseConfiguration.js';
|
||||
import {MmlMunderover} from '../../../core/MmlTree/MmlNodes/munderover.js';
|
||||
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
|
||||
|
||||
// Namespace
|
||||
let AmsCdMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
|
||||
/**
|
||||
* Handles CD environment for commutative diagrams.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {StackItem} begin The opening stackitem.
|
||||
*/
|
||||
AmsCdMethods.CD = function(parser: TexParser, begin: StackItem) {
|
||||
parser.Push(begin);
|
||||
let item = parser.itemFactory.create('array') as ArrayItem;
|
||||
let options = parser.configuration.options.amscd;
|
||||
item.setProperties({
|
||||
minw: parser.stack.env.CD_minw || options.harrowsize,
|
||||
minh: parser.stack.env.CD_minh || options.varrowsize
|
||||
});
|
||||
item.arraydef = {
|
||||
columnalign: 'center',
|
||||
columnspacing: options.colspace,
|
||||
rowspacing: options.rowspace,
|
||||
displaystyle: true
|
||||
};
|
||||
return item;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts arrows.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
AmsCdMethods.arrow = function(parser: TexParser, name: string) {
|
||||
let c = parser.string.charAt(parser.i);
|
||||
if (!c.match(/[><VA.|=]/)) {
|
||||
return Other(parser, name);
|
||||
} else {
|
||||
parser.i++;
|
||||
}
|
||||
let first = parser.stack.Top();
|
||||
if (!first.isKind('array') || first.Size()) {
|
||||
AmsCdMethods.cell(parser, name);
|
||||
first = parser.stack.Top();
|
||||
}
|
||||
let top = first as ArrayItem;
|
||||
//
|
||||
// Add enough cells to place the arrow correctly
|
||||
//
|
||||
let arrowRow = ((top.table.length % 2) === 1);
|
||||
let n = (top.row.length + (arrowRow ? 0 : 1)) % 2;
|
||||
while (n) {
|
||||
AmsCdMethods.cell(parser, name);
|
||||
n--;
|
||||
}
|
||||
|
||||
let mml;
|
||||
let hdef = {minsize: top.getProperty('minw'), stretchy: true},
|
||||
vdef = {minsize: top.getProperty('minh'),
|
||||
stretchy: true, symmetric: true, lspace: 0, rspace: 0};
|
||||
|
||||
if (c === '.') {
|
||||
} else if (c === '|') {
|
||||
mml = parser.create('token', 'mo', vdef, '\u2225');
|
||||
} else if (c === '=') {
|
||||
mml = parser.create('token', 'mo', hdef, '=');
|
||||
} else {
|
||||
//
|
||||
// for @>>> @<<< @VVV and @AAA, get the arrow and labels
|
||||
//
|
||||
// TODO: cleanup!
|
||||
let arrow: string = ({
|
||||
'>': '\u2192', '<': '\u2190', 'V': '\u2193', 'A': '\u2191'} as {[key: string]: string}) [c];
|
||||
let a = parser.GetUpTo(name + c, c);
|
||||
let b = parser.GetUpTo(name + c, c);
|
||||
if (c === '>' || c === '<') {
|
||||
//
|
||||
// Lay out horizontal arrows with munderover if it has labels
|
||||
//
|
||||
mml = parser.create('token', 'mo', hdef, arrow);
|
||||
if (!a) {
|
||||
a = '\\kern ' + top.getProperty('minw');
|
||||
} // minsize needs work
|
||||
if (a || b) {
|
||||
let pad: EnvList = {width: '+.67em', lspace: '.33em'};
|
||||
mml = parser.create('node', 'munderover', [mml]) as MmlMunderover;
|
||||
if (a) {
|
||||
let nodeA = new TexParser(a, parser.stack.env, parser.configuration).mml();
|
||||
let mpadded = parser.create('node', 'mpadded', [nodeA], pad);
|
||||
NodeUtil.setAttribute(mpadded, 'voffset', '.1em');
|
||||
NodeUtil.setChild(mml, mml.over, mpadded);
|
||||
}
|
||||
if (b) {
|
||||
let nodeB = new TexParser(b, parser.stack.env, parser.configuration).mml();
|
||||
NodeUtil.setChild(mml, mml.under, parser.create('node', 'mpadded', [nodeB], pad));
|
||||
}
|
||||
if (parser.configuration.options.amscd.hideHorizontalLabels) {
|
||||
mml = parser.create('node', 'mpadded', mml, {depth: 0, height: '.67em'});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Lay out vertical arrows with mrow if there are labels
|
||||
//
|
||||
let arrowNode = parser.create('token', 'mo', vdef, arrow);
|
||||
mml = arrowNode;
|
||||
if (a || b) {
|
||||
mml = parser.create('node', 'mrow');
|
||||
if (a) {
|
||||
NodeUtil.appendChildren(
|
||||
mml, [new TexParser('\\scriptstyle\\llap{' + a + '}', parser.stack.env, parser.configuration).mml()]);
|
||||
}
|
||||
arrowNode.texClass = TEXCLASS.ORD;
|
||||
NodeUtil.appendChildren(mml, [arrowNode]);
|
||||
if (b) {
|
||||
NodeUtil.appendChildren(mml, [new TexParser('\\scriptstyle\\rlap{' + b + '}',
|
||||
parser.stack.env, parser.configuration).mml()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mml) {
|
||||
parser.Push(mml);
|
||||
}
|
||||
AmsCdMethods.cell(parser, name);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a cell in the diagram.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
AmsCdMethods.cell = function(parser: TexParser, name: string) {
|
||||
let top = parser.stack.Top() as ArrayItem;
|
||||
if ((top.table || []).length % 2 === 0 && (top.row || []).length === 0) {
|
||||
//
|
||||
// Add a strut to the first cell in even rows to get
|
||||
// better spacing of arrow rows.
|
||||
//
|
||||
parser.Push(parser.create('node', 'mpadded', [], {height: '8.5pt', depth: '2pt'}));
|
||||
}
|
||||
parser.Push(parser.itemFactory.create('cell').setProperties({isEntry: true, name: name}));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets minimal width for arrows.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
AmsCdMethods.minCDarrowwidth = function(parser: TexParser, name: string) {
|
||||
parser.stack.env.CD_minw = parser.GetDimen(name);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets minimal height for arrows.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
AmsCdMethods.minCDarrowheight = function(parser: TexParser, name: string) {
|
||||
parser.stack.env.CD_minh = parser.GetDimen(name);
|
||||
};
|
||||
|
||||
|
||||
export default AmsCdMethods;
|
||||
168
node_modules/mathjax-full/ts/input/tex/autoload/AutoloadConfiguration.ts
generated
vendored
Normal file
168
node_modules/mathjax-full/ts/input/tex/autoload/AutoloadConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the autoload package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {Configuration, ParserConfiguration} from '../Configuration.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {Macro} from '../Symbol.js';
|
||||
import {TeX} from '../../tex.js';
|
||||
|
||||
import {RequireLoad, RequireConfiguration} from '../require/RequireConfiguration.js';
|
||||
import {Package} from '../../../components/package.js';
|
||||
import {expandable, defaultOptions} from '../../../util/Options.js';
|
||||
|
||||
|
||||
/**
|
||||
* Autoload an extension when the first macro for it is encountered
|
||||
* (if the extension has already been loaded, remove the autoload
|
||||
* macros and environments so they won't try to load it again, and
|
||||
* back up to read the macro again, call the RequireLoad command to
|
||||
* either load the extension, or initialize it.)
|
||||
*
|
||||
* @param {TexParser} parser The TeX input parser
|
||||
* @param {string} name The control sequence that is running
|
||||
* @param {string} extension The extension to load
|
||||
* @param {boolean} isMacro True if this is a macro, false if an environment
|
||||
*/
|
||||
function Autoload(parser: TexParser, name: string, extension: string, isMacro: boolean) {
|
||||
if (Package.packages.has(parser.options.require.prefix + extension)) {
|
||||
const def = parser.options.autoload[extension];
|
||||
const [macros, envs] = (def.length === 2 && Array.isArray(def[0]) ? def : [def, []]);
|
||||
for (const macro of macros) {
|
||||
AutoloadMacros.remove(macro);
|
||||
}
|
||||
for (const env of envs) {
|
||||
AutoloadEnvironments.remove(env);
|
||||
}
|
||||
//
|
||||
// Put back the macro or \begin and read it again
|
||||
//
|
||||
parser.string = (isMacro ? name + ' ' : '\\begin{' + name.slice(1) + '}' ) + parser.string.slice(parser.i);
|
||||
parser.i = 0;
|
||||
}
|
||||
RequireLoad(parser, extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the require extension has been initialized
|
||||
* (If autoload has been included in the TeX packages, but require isn't, then we need
|
||||
* to set up the options here and configure the require package in configAutoload below.
|
||||
* the priorities of the initialization and configuration are set so that autoload
|
||||
* will run after require when both are used.)
|
||||
*/
|
||||
function initAutoload(config: ParserConfiguration) {
|
||||
if (!config.options.require) {
|
||||
defaultOptions(config.options, RequireConfiguration.options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the macros and environments for the extensions that need to be loaded.
|
||||
* Only ones that aren't already defined are made to autoload
|
||||
* (except for \color, which is overridden if present)
|
||||
*/
|
||||
function configAutoload(config: ParserConfiguration, jax: TeX<any, any, any>) {
|
||||
const parser = jax.parseOptions;
|
||||
const macros = parser.handlers.get('macro');
|
||||
const environments = parser.handlers.get('environment');
|
||||
const autoload = parser.options.autoload;
|
||||
parser.packageData.set('autoload', {Autoload}); // used by textmacros to tell if a macro is autoloading
|
||||
//
|
||||
// Loop through the autoload definitions
|
||||
//
|
||||
for (const extension of Object.keys(autoload)) {
|
||||
const def = autoload[extension];
|
||||
const [macs, envs] = (def.length === 2 && Array.isArray(def[0]) ? def : [def, []]);
|
||||
//
|
||||
// Create the macros
|
||||
//
|
||||
for (const name of macs) {
|
||||
if (!macros.lookup(name) || name === 'color') {
|
||||
AutoloadMacros.add(name, new Macro(name, Autoload, [extension, true]));
|
||||
}
|
||||
}
|
||||
//
|
||||
// Create the environments
|
||||
//
|
||||
for (const name of envs) {
|
||||
if (!environments.lookup(name)) {
|
||||
AutoloadEnvironments.add(name, new Macro(name, Autoload, [extension, false]));
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Check if the require extension needs to be configured
|
||||
//
|
||||
if (!parser.packageData.get('require')) {
|
||||
RequireConfiguration.config(config, jax);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The command and environment maps for the macros that autoload extensions
|
||||
*/
|
||||
const AutoloadMacros = new CommandMap('autoload-macros', {}, {});
|
||||
const AutoloadEnvironments = new CommandMap('autoload-environments', {}, {});
|
||||
|
||||
|
||||
/**
|
||||
* The configuration object for configmacros
|
||||
*/
|
||||
export const AutoloadConfiguration = Configuration.create(
|
||||
'autoload', {
|
||||
handler: {
|
||||
macro: ['autoload-macros'],
|
||||
environment: ['autoload-environments']
|
||||
},
|
||||
options: {
|
||||
//
|
||||
// These are the extension names and the macros and environments they contain.
|
||||
// The format is [macros...] or [[macros...], [environments...]]
|
||||
// You can prevent one from being autoloaded by setting
|
||||
// it to [] in the options when the TeX input jax is created.
|
||||
// You can include the prefix if it is not the default one from require
|
||||
//
|
||||
autoload: expandable({
|
||||
action: ['toggle', 'mathtip', 'texttip'],
|
||||
amscd: [[], ['CD']],
|
||||
bbox: ['bbox'],
|
||||
boldsymbol: ['boldsymbol'],
|
||||
braket: ['bra', 'ket', 'braket', 'set', 'Bra', 'Ket', 'Braket', 'Set', 'ketbra', 'Ketbra'],
|
||||
bussproofs: [[], ['prooftree']],
|
||||
cancel: ['cancel', 'bcancel', 'xcancel', 'cancelto'],
|
||||
color: ['color', 'definecolor', 'textcolor', 'colorbox', 'fcolorbox'],
|
||||
enclose: ['enclose'],
|
||||
extpfeil: ['xtwoheadrightarrow', 'xtwoheadleftarrow', 'xmapsto', 'xlongequal', 'xtofrom', 'Newextarrow'],
|
||||
html: ['href', 'class', 'style', 'cssId'],
|
||||
mhchem: ['ce', 'pu'],
|
||||
newcommand: ['newcommand', 'renewcommand', 'newenvironment', 'renewenvironment', 'def', 'let'],
|
||||
unicode: ['unicode'],
|
||||
verb: ['verb']
|
||||
})
|
||||
},
|
||||
config: configAutoload,
|
||||
init: initAutoload,
|
||||
priority: 10
|
||||
}
|
||||
);
|
||||
197
node_modules/mathjax-full/ts/input/tex/base/BaseConfiguration.ts
generated
vendored
Normal file
197
node_modules/mathjax-full/ts/input/tex/base/BaseConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration for the Base LaTeX parser.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {MapHandler} from '../MapHandler.js';
|
||||
import TexError from '../TexError.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {CharacterMap} from '../SymbolMap.js';
|
||||
import * as bitem from './BaseItems.js';
|
||||
import {AbstractTags} from '../Tags.js';
|
||||
import './BaseMappings.js';
|
||||
import {getRange} from '../../../core/MmlTree/OperatorDictionary.js';
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
import ParseOptions from '../ParseOptions.js';
|
||||
|
||||
/**
|
||||
* Remapping some ASCII characters to their Unicode operator equivalent.
|
||||
*/
|
||||
new CharacterMap('remap', null, {
|
||||
'-': '\u2212',
|
||||
'*': '\u2217',
|
||||
'`': '\u2018' // map ` to back quote
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Default handling of characters (as <mo> elements).
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} char The character to parse.
|
||||
*/
|
||||
export function Other(parser: TexParser, char: string) {
|
||||
const font = parser.stack.env['font'];
|
||||
let def = font ?
|
||||
// @test Other Font
|
||||
{mathvariant: parser.stack.env['font']} : {};
|
||||
const remap = (MapHandler.getMap('remap') as CharacterMap).lookup(char);
|
||||
const range = getRange(char);
|
||||
const type = (range ? range[3] : 'mo');
|
||||
// @test Other
|
||||
// @test Other Remap
|
||||
let mo = parser.create('token', type, def, (remap ? remap.char : char));
|
||||
range[4] && mo.attributes.set('mathvariant', range[4]);
|
||||
if (type === 'mo') {
|
||||
NodeUtil.setProperty(mo, 'fixStretchy', true);
|
||||
parser.configuration.addNode('fixStretchy', mo);
|
||||
}
|
||||
parser.Push(mo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle undefined control sequence.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the control sequence.
|
||||
*/
|
||||
function csUndefined(_parser: TexParser, name: string) {
|
||||
// @test Undefined-CS
|
||||
throw new TexError('UndefinedControlSequence',
|
||||
'Undefined control sequence %1', '\\' + name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle undefined environments.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the control sequence.
|
||||
*/
|
||||
function envUndefined(_parser: TexParser, env: string) {
|
||||
// @test Undefined-Env
|
||||
throw new TexError('UnknownEnv', 'Unknown environment \'%1\'', env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter for removing spacing following \nonscript
|
||||
* @param{ParseOptions} data The active tex parser.
|
||||
*/
|
||||
function filterNonscript({data}: {data: ParseOptions}) {
|
||||
for (const mml of data.getList('nonscript')) {
|
||||
//
|
||||
// This is the list of mspace elements or mrow > mstyle > mspace
|
||||
// that followed \nonscript macros to be tested for removal.
|
||||
//
|
||||
if (mml.attributes.get('scriptlevel') > 0) {
|
||||
//
|
||||
// The mspace needs to be removed, since we are in a script style.
|
||||
// Remove it from the DOM and from the list of mspace elements.
|
||||
//
|
||||
const parent = mml.parent;
|
||||
parent.childNodes.splice(parent.childIndex(mml), 1);
|
||||
data.removeFromList(mml.kind, [mml]);
|
||||
//
|
||||
// If it is an mrow > mstyle > mspace, then we have just
|
||||
// removed the mrow from its list, and must remove
|
||||
// the mstyle and mspace from their lists as well.
|
||||
//
|
||||
if (mml.isKind('mrow')) {
|
||||
const mstyle = mml.childNodes[0] as MmlNode;
|
||||
data.removeFromList('mstyle', [mstyle]);
|
||||
data.removeFromList('mspace', mstyle.childNodes[0].childNodes as MmlNode[]);
|
||||
}
|
||||
} else if (mml.isKind('mrow')) {
|
||||
//
|
||||
// This is an mrow > mstyle > mspace but we're not in a script
|
||||
// style, so remove the mrow that we had added in the NonscriptItem.
|
||||
//
|
||||
mml.parent.replaceChild(mml.childNodes[0], mml);
|
||||
data.removeFromList('mrow', [mml]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {AbstractTags}
|
||||
*/
|
||||
export class BaseTags extends AbstractTags { }
|
||||
|
||||
|
||||
/**
|
||||
* The base configuration.
|
||||
* @type {Configuration}
|
||||
*/
|
||||
export const BaseConfiguration: Configuration = Configuration.create(
|
||||
'base', {
|
||||
handler: {
|
||||
character: ['command', 'special', 'letter', 'digit'],
|
||||
delimiter: ['delimiter'],
|
||||
// Note, that the position of the delimiters here is important!
|
||||
macro: ['delimiter', 'macros', 'mathchar0mi', 'mathchar0mo', 'mathchar7'],
|
||||
environment: ['environment']
|
||||
},
|
||||
fallback: {
|
||||
character: Other,
|
||||
macro: csUndefined,
|
||||
environment: envUndefined
|
||||
},
|
||||
items: {
|
||||
// BaseItems
|
||||
[bitem.StartItem.prototype.kind]: bitem.StartItem,
|
||||
[bitem.StopItem.prototype.kind]: bitem.StopItem,
|
||||
[bitem.OpenItem.prototype.kind]: bitem.OpenItem,
|
||||
[bitem.CloseItem.prototype.kind]: bitem.CloseItem,
|
||||
[bitem.PrimeItem.prototype.kind]: bitem.PrimeItem,
|
||||
[bitem.SubsupItem.prototype.kind]: bitem.SubsupItem,
|
||||
[bitem.OverItem.prototype.kind]: bitem.OverItem,
|
||||
[bitem.LeftItem.prototype.kind]: bitem.LeftItem,
|
||||
[bitem.Middle.prototype.kind]: bitem.Middle,
|
||||
[bitem.RightItem.prototype.kind]: bitem.RightItem,
|
||||
[bitem.BeginItem.prototype.kind]: bitem.BeginItem,
|
||||
[bitem.EndItem.prototype.kind]: bitem.EndItem,
|
||||
[bitem.StyleItem.prototype.kind]: bitem.StyleItem,
|
||||
[bitem.PositionItem.prototype.kind]: bitem.PositionItem,
|
||||
[bitem.CellItem.prototype.kind]: bitem.CellItem,
|
||||
[bitem.MmlItem.prototype.kind]: bitem.MmlItem,
|
||||
[bitem.FnItem.prototype.kind]: bitem.FnItem,
|
||||
[bitem.NotItem.prototype.kind]: bitem.NotItem,
|
||||
[bitem.NonscriptItem.prototype.kind]: bitem.NonscriptItem,
|
||||
[bitem.DotsItem.prototype.kind]: bitem.DotsItem,
|
||||
[bitem.ArrayItem.prototype.kind]: bitem.ArrayItem,
|
||||
[bitem.EqnArrayItem.prototype.kind]: bitem.EqnArrayItem,
|
||||
[bitem.EquationItem.prototype.kind]: bitem.EquationItem
|
||||
},
|
||||
options: {
|
||||
maxMacros: 1000,
|
||||
baseURL: (typeof(document) === 'undefined' ||
|
||||
document.getElementsByTagName('base').length === 0) ?
|
||||
'' : String(document.location).replace(/#.*$/, '')
|
||||
},
|
||||
tags: {
|
||||
base: BaseTags
|
||||
},
|
||||
postprocessors: [[filterNonscript, -4]]
|
||||
}
|
||||
);
|
||||
1242
node_modules/mathjax-full/ts/input/tex/base/BaseItems.ts
generated
vendored
Normal file
1242
node_modules/mathjax-full/ts/input/tex/base/BaseItems.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
760
node_modules/mathjax-full/ts/input/tex/base/BaseMappings.ts
generated
vendored
Normal file
760
node_modules/mathjax-full/ts/input/tex/base/BaseMappings.ts
generated
vendored
Normal file
@@ -0,0 +1,760 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Base mappings for TeX Parsing.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import * as sm from '../SymbolMap.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import BaseMethods from './BaseMethods.js';
|
||||
import ParseMethods from '../ParseMethods.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
|
||||
import {MATHSPACE, em} from '../../../util/lengths.js';
|
||||
|
||||
|
||||
/**
|
||||
* Letter pattern for parsing identifiers and operators.
|
||||
*/
|
||||
new sm.RegExpMap('letter', ParseMethods.variable, /[a-z]/i);
|
||||
|
||||
|
||||
/**
|
||||
* Digit pattern for parsing numbers.
|
||||
*/
|
||||
new sm.RegExpMap('digit', ParseMethods.digit, /[0-9.,]/);
|
||||
|
||||
|
||||
/**
|
||||
* Pattern for spotting start of commands.
|
||||
*/
|
||||
new sm.RegExpMap('command', ParseMethods.controlSequence, /^\\/ );
|
||||
|
||||
|
||||
/**
|
||||
* Treatment of special characters in LaTeX.
|
||||
*/
|
||||
new sm.MacroMap('special', {
|
||||
|
||||
// This is now handled with a RegExp!
|
||||
// '\\': 'ControlSequence',
|
||||
|
||||
'{': 'Open',
|
||||
'}': 'Close',
|
||||
'~': 'Tilde',
|
||||
'^': 'Superscript',
|
||||
'_': 'Subscript',
|
||||
' ': 'Space',
|
||||
'\t': 'Space',
|
||||
'\r': 'Space',
|
||||
'\n': 'Space',
|
||||
'\'': 'Prime',
|
||||
'%': 'Comment',
|
||||
'&': 'Entry',
|
||||
'#': 'Hash',
|
||||
'\u00A0': 'Space',
|
||||
'\u2019': 'Prime'
|
||||
}, BaseMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Macros for identifiers.
|
||||
*/
|
||||
new sm.CharacterMap('mathchar0mi', ParseMethods.mathchar0mi, {
|
||||
// Lower-case greek
|
||||
alpha: '\u03B1',
|
||||
beta: '\u03B2',
|
||||
gamma: '\u03B3',
|
||||
delta: '\u03B4',
|
||||
epsilon: '\u03F5',
|
||||
zeta: '\u03B6',
|
||||
eta: '\u03B7',
|
||||
theta: '\u03B8',
|
||||
iota: '\u03B9',
|
||||
kappa: '\u03BA',
|
||||
lambda: '\u03BB',
|
||||
mu: '\u03BC',
|
||||
nu: '\u03BD',
|
||||
xi: '\u03BE',
|
||||
omicron: '\u03BF', // added for completeness
|
||||
pi: '\u03C0',
|
||||
rho: '\u03C1',
|
||||
sigma: '\u03C3',
|
||||
tau: '\u03C4',
|
||||
upsilon: '\u03C5',
|
||||
phi: '\u03D5',
|
||||
chi: '\u03C7',
|
||||
psi: '\u03C8',
|
||||
omega: '\u03C9',
|
||||
varepsilon: '\u03B5',
|
||||
vartheta: '\u03D1',
|
||||
varpi: '\u03D6',
|
||||
varrho: '\u03F1',
|
||||
varsigma: '\u03C2',
|
||||
varphi: '\u03C6',
|
||||
|
||||
// Ord symbols
|
||||
S: ['\u00A7', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
aleph: ['\u2135', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
hbar: ['\u210F', {variantForm: true}],
|
||||
imath: '\u0131',
|
||||
jmath: '\u0237',
|
||||
ell: '\u2113',
|
||||
wp: ['\u2118', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
Re: ['\u211C', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
Im: ['\u2111', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
partial: ['\u2202', {mathvariant: TexConstant.Variant.ITALIC}],
|
||||
infty: ['\u221E', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
prime: ['\u2032', {variantForm: true}],
|
||||
emptyset: ['\u2205', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
nabla: ['\u2207', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
top: ['\u22A4', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
bot: ['\u22A5', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
angle: ['\u2220', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
triangle: ['\u25B3', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
backslash: ['\u2216', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
forall: ['\u2200', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
exists: ['\u2203', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
neg: ['\u00AC', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
lnot: ['\u00AC', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
flat: ['\u266D', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
natural: ['\u266E', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
sharp: ['\u266F', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
clubsuit: ['\u2663', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
diamondsuit: ['\u2662', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
heartsuit: ['\u2661', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
spadesuit: ['\u2660', {mathvariant: TexConstant.Variant.NORMAL}]
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Macros for operators.
|
||||
*/
|
||||
new sm.CharacterMap('mathchar0mo', ParseMethods.mathchar0mo, {
|
||||
surd: '\u221A',
|
||||
|
||||
// big ops
|
||||
coprod: ['\u2210', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
bigvee: ['\u22C1', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
bigwedge: ['\u22C0', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
biguplus: ['\u2A04', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
bigcap: ['\u22C2', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
bigcup: ['\u22C3', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
'int': ['\u222B', {texClass: TEXCLASS.OP}],
|
||||
intop: ['\u222B', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true, movablelimits: true}],
|
||||
iint: ['\u222C', {texClass: TEXCLASS.OP}],
|
||||
iiint: ['\u222D', {texClass: TEXCLASS.OP}],
|
||||
prod: ['\u220F', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
sum: ['\u2211', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
bigotimes: ['\u2A02', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
bigoplus: ['\u2A01', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
bigodot: ['\u2A00', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
oint: ['\u222E', {texClass: TEXCLASS.OP}],
|
||||
bigsqcup: ['\u2A06', {texClass: TEXCLASS.OP,
|
||||
movesupsub: true}],
|
||||
smallint: ['\u222B', {largeop: false}],
|
||||
|
||||
// binary operations
|
||||
triangleleft: '\u25C3',
|
||||
triangleright: '\u25B9',
|
||||
bigtriangleup: '\u25B3',
|
||||
bigtriangledown: '\u25BD',
|
||||
wedge: '\u2227',
|
||||
land: '\u2227',
|
||||
vee: '\u2228',
|
||||
lor: '\u2228',
|
||||
cap: '\u2229',
|
||||
cup: '\u222A',
|
||||
ddagger: '\u2021',
|
||||
dagger: '\u2020',
|
||||
sqcap: '\u2293',
|
||||
sqcup: '\u2294',
|
||||
uplus: '\u228E',
|
||||
amalg: '\u2A3F',
|
||||
diamond: '\u22C4',
|
||||
bullet: '\u2219',
|
||||
wr: '\u2240',
|
||||
div: '\u00F7',
|
||||
divsymbol: '\u00F7',
|
||||
odot: ['\u2299', {largeop: false}],
|
||||
oslash: ['\u2298', {largeop: false}],
|
||||
otimes: ['\u2297', {largeop: false}],
|
||||
ominus: ['\u2296', {largeop: false}],
|
||||
oplus: ['\u2295', {largeop: false}],
|
||||
mp: '\u2213',
|
||||
pm: '\u00B1',
|
||||
circ: '\u2218',
|
||||
bigcirc: '\u25EF',
|
||||
setminus: '\u2216',
|
||||
cdot: '\u22C5',
|
||||
ast: '\u2217',
|
||||
times: '\u00D7',
|
||||
star: '\u22C6',
|
||||
|
||||
|
||||
// Relations
|
||||
propto: '\u221D',
|
||||
sqsubseteq: '\u2291',
|
||||
sqsupseteq: '\u2292',
|
||||
parallel: '\u2225',
|
||||
mid: '\u2223',
|
||||
dashv: '\u22A3',
|
||||
vdash: '\u22A2',
|
||||
leq: '\u2264',
|
||||
le: '\u2264',
|
||||
geq: '\u2265',
|
||||
ge: '\u2265',
|
||||
lt: '\u003C',
|
||||
gt: '\u003E',
|
||||
succ: '\u227B',
|
||||
prec: '\u227A',
|
||||
approx: '\u2248',
|
||||
succeq: '\u2AB0', // or '227C',
|
||||
preceq: '\u2AAF', // or '227D',
|
||||
supset: '\u2283',
|
||||
subset: '\u2282',
|
||||
supseteq: '\u2287',
|
||||
subseteq: '\u2286',
|
||||
'in': '\u2208',
|
||||
ni: '\u220B',
|
||||
notin: '\u2209',
|
||||
owns: '\u220B',
|
||||
gg: '\u226B',
|
||||
ll: '\u226A',
|
||||
sim: '\u223C',
|
||||
simeq: '\u2243',
|
||||
perp: '\u22A5',
|
||||
equiv: '\u2261',
|
||||
asymp: '\u224D',
|
||||
smile: '\u2323',
|
||||
frown: '\u2322',
|
||||
ne: '\u2260',
|
||||
neq: '\u2260',
|
||||
cong: '\u2245',
|
||||
doteq: '\u2250',
|
||||
bowtie: '\u22C8',
|
||||
models: '\u22A8',
|
||||
|
||||
notChar: '\u29F8',
|
||||
|
||||
|
||||
// Arrows
|
||||
Leftrightarrow: '\u21D4',
|
||||
Leftarrow: '\u21D0',
|
||||
Rightarrow: '\u21D2',
|
||||
leftrightarrow: '\u2194',
|
||||
leftarrow: '\u2190',
|
||||
gets: '\u2190',
|
||||
rightarrow: '\u2192',
|
||||
to: ['\u2192', {accent: false}],
|
||||
mapsto: '\u21A6',
|
||||
leftharpoonup: '\u21BC',
|
||||
leftharpoondown: '\u21BD',
|
||||
rightharpoonup: '\u21C0',
|
||||
rightharpoondown: '\u21C1',
|
||||
nearrow: '\u2197',
|
||||
searrow: '\u2198',
|
||||
nwarrow: '\u2196',
|
||||
swarrow: '\u2199',
|
||||
rightleftharpoons: '\u21CC',
|
||||
hookrightarrow: '\u21AA',
|
||||
hookleftarrow: '\u21A9',
|
||||
longleftarrow: '\u27F5',
|
||||
Longleftarrow: '\u27F8',
|
||||
longrightarrow: '\u27F6',
|
||||
Longrightarrow: '\u27F9',
|
||||
Longleftrightarrow: '\u27FA',
|
||||
longleftrightarrow: '\u27F7',
|
||||
longmapsto: '\u27FC',
|
||||
|
||||
|
||||
// Misc.
|
||||
ldots: '\u2026',
|
||||
cdots: '\u22EF',
|
||||
vdots: '\u22EE',
|
||||
ddots: '\u22F1',
|
||||
dotsc: '\u2026', // dots with commas
|
||||
dotsb: '\u22EF', // dots with binary ops and relations
|
||||
dotsm: '\u22EF', // dots with multiplication
|
||||
dotsi: '\u22EF', // dots with integrals
|
||||
dotso: '\u2026', // other dots
|
||||
|
||||
ldotp: ['\u002E', {texClass: TEXCLASS.PUNCT}],
|
||||
cdotp: ['\u22C5', {texClass: TEXCLASS.PUNCT}],
|
||||
colon: ['\u003A', {texClass: TEXCLASS.PUNCT}]
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Macros for special characters and identifiers.
|
||||
*/
|
||||
new sm.CharacterMap('mathchar7', ParseMethods.mathchar7, {
|
||||
Gamma: '\u0393',
|
||||
Delta: '\u0394',
|
||||
Theta: '\u0398',
|
||||
Lambda: '\u039B',
|
||||
Xi: '\u039E',
|
||||
Pi: '\u03A0',
|
||||
Sigma: '\u03A3',
|
||||
Upsilon: '\u03A5',
|
||||
Phi: '\u03A6',
|
||||
Psi: '\u03A8',
|
||||
Omega: '\u03A9',
|
||||
|
||||
'_': '\u005F',
|
||||
'#': '\u0023',
|
||||
'$': '\u0024',
|
||||
'%': '\u0025',
|
||||
'&': '\u0026',
|
||||
And: '\u0026'
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Macros for delimiters.
|
||||
*/
|
||||
new sm.DelimiterMap('delimiter', ParseMethods.delimiter, {
|
||||
'(': '(',
|
||||
')': ')',
|
||||
'[': '[',
|
||||
']': ']',
|
||||
'<': '\u27E8',
|
||||
'>': '\u27E9',
|
||||
'\\lt': '\u27E8',
|
||||
'\\gt': '\u27E9',
|
||||
'/': '/',
|
||||
'|': ['|', {texClass: TEXCLASS.ORD}],
|
||||
'.': '',
|
||||
'\\\\': '\\',
|
||||
'\\lmoustache': '\u23B0', // non-standard
|
||||
'\\rmoustache': '\u23B1', // non-standard
|
||||
'\\lgroup': '\u27EE', // non-standard
|
||||
'\\rgroup': '\u27EF', // non-standard
|
||||
'\\arrowvert': '\u23D0',
|
||||
'\\Arrowvert': '\u2016',
|
||||
'\\bracevert': '\u23AA', // non-standard
|
||||
'\\Vert': ['\u2016', {texClass: TEXCLASS.ORD}],
|
||||
'\\|': ['\u2016', {texClass: TEXCLASS.ORD}],
|
||||
'\\vert': ['|', {texClass: TEXCLASS.ORD}],
|
||||
'\\uparrow': '\u2191',
|
||||
'\\downarrow': '\u2193',
|
||||
'\\updownarrow': '\u2195',
|
||||
'\\Uparrow': '\u21D1',
|
||||
'\\Downarrow': '\u21D3',
|
||||
'\\Updownarrow': '\u21D5',
|
||||
'\\backslash': '\\',
|
||||
'\\rangle': '\u27E9',
|
||||
'\\langle': '\u27E8',
|
||||
'\\rbrace': '}',
|
||||
'\\lbrace': '{',
|
||||
'\\}': '}',
|
||||
'\\{': '{',
|
||||
'\\rceil': '\u2309',
|
||||
'\\lceil': '\u2308',
|
||||
'\\rfloor': '\u230B',
|
||||
'\\lfloor': '\u230A',
|
||||
'\\lbrack': '[',
|
||||
'\\rbrack': ']'
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Macros for LaTeX commands.
|
||||
*/
|
||||
new sm.CommandMap('macros', {
|
||||
displaystyle: ['SetStyle', 'D', true, 0],
|
||||
textstyle: ['SetStyle', 'T', false, 0],
|
||||
scriptstyle: ['SetStyle', 'S', false, 1],
|
||||
scriptscriptstyle: ['SetStyle', 'SS', false, 2],
|
||||
|
||||
rm: ['SetFont', TexConstant.Variant.NORMAL],
|
||||
mit: ['SetFont', TexConstant.Variant.ITALIC],
|
||||
oldstyle: ['SetFont', TexConstant.Variant.OLDSTYLE],
|
||||
cal: ['SetFont', TexConstant.Variant.CALLIGRAPHIC],
|
||||
it: ['SetFont', TexConstant.Variant.MATHITALIC], // needs special handling
|
||||
bf: ['SetFont', TexConstant.Variant.BOLD],
|
||||
bbFont: ['SetFont', TexConstant.Variant.DOUBLESTRUCK],
|
||||
scr: ['SetFont', TexConstant.Variant.SCRIPT],
|
||||
frak: ['SetFont', TexConstant.Variant.FRAKTUR],
|
||||
sf: ['SetFont', TexConstant.Variant.SANSSERIF],
|
||||
tt: ['SetFont', TexConstant.Variant.MONOSPACE],
|
||||
|
||||
mathrm: ['MathFont', TexConstant.Variant.NORMAL],
|
||||
mathup: ['MathFont', TexConstant.Variant.NORMAL],
|
||||
mathnormal: ['MathFont', ''],
|
||||
mathbf: ['MathFont', TexConstant.Variant.BOLD],
|
||||
mathbfup: ['MathFont', TexConstant.Variant.BOLD],
|
||||
mathit: ['MathFont', TexConstant.Variant.MATHITALIC],
|
||||
mathbfit: ['MathFont', TexConstant.Variant.BOLDITALIC],
|
||||
mathbb: ['MathFont', TexConstant.Variant.DOUBLESTRUCK],
|
||||
Bbb: ['MathFont', TexConstant.Variant.DOUBLESTRUCK],
|
||||
mathfrak: ['MathFont', TexConstant.Variant.FRAKTUR],
|
||||
mathbffrak: ['MathFont', TexConstant.Variant.BOLDFRAKTUR],
|
||||
mathscr: ['MathFont', TexConstant.Variant.SCRIPT],
|
||||
mathbfscr: ['MathFont', TexConstant.Variant.BOLDSCRIPT],
|
||||
mathsf: ['MathFont', TexConstant.Variant.SANSSERIF],
|
||||
mathsfup: ['MathFont', TexConstant.Variant.SANSSERIF],
|
||||
mathbfsf: ['MathFont', TexConstant.Variant.BOLDSANSSERIF],
|
||||
mathbfsfup: ['MathFont', TexConstant.Variant.BOLDSANSSERIF],
|
||||
mathsfit: ['MathFont', TexConstant.Variant.SANSSERIFITALIC],
|
||||
mathbfsfit: ['MathFont', TexConstant.Variant.SANSSERIFBOLDITALIC],
|
||||
mathtt: ['MathFont', TexConstant.Variant.MONOSPACE],
|
||||
mathcal: ['MathFont', TexConstant.Variant.CALLIGRAPHIC],
|
||||
mathbfcal: ['MathFont', TexConstant.Variant.BOLDCALLIGRAPHIC],
|
||||
|
||||
symrm: ['MathFont', TexConstant.Variant.NORMAL],
|
||||
symup: ['MathFont', TexConstant.Variant.NORMAL],
|
||||
symnormal: ['MathFont', ''],
|
||||
symbf: ['MathFont', TexConstant.Variant.BOLD],
|
||||
symbfup: ['MathFont', TexConstant.Variant.BOLD],
|
||||
symit: ['MathFont', TexConstant.Variant.ITALIC],
|
||||
symbfit: ['MathFont', TexConstant.Variant.BOLDITALIC],
|
||||
symbb: ['MathFont', TexConstant.Variant.DOUBLESTRUCK],
|
||||
symfrak: ['MathFont', TexConstant.Variant.FRAKTUR],
|
||||
symbffrak: ['MathFont', TexConstant.Variant.BOLDFRAKTUR],
|
||||
symscr: ['MathFont', TexConstant.Variant.SCRIPT],
|
||||
symbfscr: ['MathFont', TexConstant.Variant.BOLDSCRIPT],
|
||||
symsf: ['MathFont', TexConstant.Variant.SANSSERIF],
|
||||
symsfup: ['MathFont', TexConstant.Variant.SANSSERIF],
|
||||
symbfsf: ['MathFont', TexConstant.Variant.BOLDSANSSERIF],
|
||||
symbfsfup: ['MathFont', TexConstant.Variant.BOLDSANSSERIF],
|
||||
symsfit: ['MathFont', TexConstant.Variant.SANSSERIFITALIC],
|
||||
symbfsfit: ['MathFont', TexConstant.Variant.SANSSERIFBOLDITALIC],
|
||||
symtt: ['MathFont', TexConstant.Variant.MONOSPACE],
|
||||
symcal: ['MathFont', TexConstant.Variant.CALLIGRAPHIC],
|
||||
symbfcal: ['MathFont', TexConstant.Variant.BOLDCALLIGRAPHIC],
|
||||
|
||||
textrm: ['HBox', null, TexConstant.Variant.NORMAL],
|
||||
textup: ['HBox', null, TexConstant.Variant.NORMAL],
|
||||
textnormal: ['HBox'],
|
||||
textit: ['HBox', null, TexConstant.Variant.ITALIC],
|
||||
textbf: ['HBox', null, TexConstant.Variant.BOLD],
|
||||
textsf: ['HBox', null, TexConstant.Variant.SANSSERIF],
|
||||
texttt: ['HBox', null, TexConstant.Variant.MONOSPACE],
|
||||
|
||||
tiny: ['SetSize', 0.5],
|
||||
Tiny: ['SetSize', 0.6], // non-standard
|
||||
scriptsize: ['SetSize', 0.7],
|
||||
small: ['SetSize', 0.85],
|
||||
normalsize: ['SetSize', 1.0],
|
||||
large: ['SetSize', 1.2],
|
||||
Large: ['SetSize', 1.44],
|
||||
LARGE: ['SetSize', 1.73],
|
||||
huge: ['SetSize', 2.07],
|
||||
Huge: ['SetSize', 2.49],
|
||||
|
||||
arcsin: 'NamedFn',
|
||||
arccos: 'NamedFn',
|
||||
arctan: 'NamedFn',
|
||||
arg: 'NamedFn',
|
||||
cos: 'NamedFn',
|
||||
cosh: 'NamedFn',
|
||||
cot: 'NamedFn',
|
||||
coth: 'NamedFn',
|
||||
csc: 'NamedFn',
|
||||
deg: 'NamedFn',
|
||||
det: 'NamedOp',
|
||||
dim: 'NamedFn',
|
||||
exp: 'NamedFn',
|
||||
gcd: 'NamedOp',
|
||||
hom: 'NamedFn',
|
||||
inf: 'NamedOp',
|
||||
ker: 'NamedFn',
|
||||
lg: 'NamedFn',
|
||||
lim: 'NamedOp',
|
||||
liminf: ['NamedOp', 'lim inf'],
|
||||
limsup: ['NamedOp', 'lim sup'],
|
||||
ln: 'NamedFn',
|
||||
log: 'NamedFn',
|
||||
max: 'NamedOp',
|
||||
min: 'NamedOp',
|
||||
Pr: 'NamedOp',
|
||||
sec: 'NamedFn',
|
||||
sin: 'NamedFn',
|
||||
sinh: 'NamedFn',
|
||||
sup: 'NamedOp',
|
||||
tan: 'NamedFn',
|
||||
tanh: 'NamedFn',
|
||||
|
||||
limits: ['Limits', 1],
|
||||
nolimits: ['Limits', 0],
|
||||
|
||||
overline: ['UnderOver', '2015'],
|
||||
underline: ['UnderOver', '2015'],
|
||||
overbrace: ['UnderOver', '23DE', 1],
|
||||
underbrace: ['UnderOver', '23DF', 1],
|
||||
overparen: ['UnderOver', '23DC'],
|
||||
underparen: ['UnderOver', '23DD'],
|
||||
overrightarrow: ['UnderOver', '2192'],
|
||||
underrightarrow: ['UnderOver', '2192'],
|
||||
overleftarrow: ['UnderOver', '2190'],
|
||||
underleftarrow: ['UnderOver', '2190'],
|
||||
overleftrightarrow: ['UnderOver', '2194'],
|
||||
underleftrightarrow: ['UnderOver', '2194'],
|
||||
|
||||
overset: 'Overset',
|
||||
underset: 'Underset',
|
||||
overunderset: 'Overunderset',
|
||||
stackrel: ['Macro', '\\mathrel{\\mathop{#2}\\limits^{#1}}', 2],
|
||||
stackbin: ['Macro', '\\mathbin{\\mathop{#2}\\limits^{#1}}', 2],
|
||||
|
||||
over: 'Over',
|
||||
overwithdelims: 'Over',
|
||||
atop: 'Over',
|
||||
atopwithdelims: 'Over',
|
||||
above: 'Over',
|
||||
abovewithdelims: 'Over',
|
||||
brace: ['Over', '{', '}'],
|
||||
brack: ['Over', '[', ']'],
|
||||
choose: ['Over', '(', ')'],
|
||||
|
||||
frac: 'Frac',
|
||||
sqrt: 'Sqrt',
|
||||
root: 'Root',
|
||||
uproot: ['MoveRoot', 'upRoot'],
|
||||
leftroot: ['MoveRoot', 'leftRoot'],
|
||||
|
||||
left: 'LeftRight',
|
||||
right: 'LeftRight',
|
||||
middle: 'LeftRight',
|
||||
|
||||
llap: 'Lap',
|
||||
rlap: 'Lap',
|
||||
raise: 'RaiseLower',
|
||||
lower: 'RaiseLower',
|
||||
moveleft: 'MoveLeftRight',
|
||||
moveright: 'MoveLeftRight',
|
||||
|
||||
',': ['Spacer', MATHSPACE.thinmathspace],
|
||||
':': ['Spacer', MATHSPACE.mediummathspace],
|
||||
'>': ['Spacer', MATHSPACE.mediummathspace],
|
||||
';': ['Spacer', MATHSPACE.thickmathspace],
|
||||
'!': ['Spacer', MATHSPACE.negativethinmathspace],
|
||||
enspace: ['Spacer', .5],
|
||||
quad: ['Spacer', 1],
|
||||
qquad: ['Spacer', 2],
|
||||
thinspace: ['Spacer', MATHSPACE.thinmathspace],
|
||||
negthinspace: ['Spacer', MATHSPACE.negativethinmathspace],
|
||||
|
||||
hskip: 'Hskip',
|
||||
hspace: 'Hskip',
|
||||
kern: 'Hskip',
|
||||
mskip: 'Hskip',
|
||||
mspace: 'Hskip',
|
||||
mkern: 'Hskip',
|
||||
rule: 'rule',
|
||||
Rule: ['Rule'],
|
||||
Space: ['Rule', 'blank'],
|
||||
nonscript: 'Nonscript',
|
||||
|
||||
big: ['MakeBig', TEXCLASS.ORD, 0.85],
|
||||
Big: ['MakeBig', TEXCLASS.ORD, 1.15],
|
||||
bigg: ['MakeBig', TEXCLASS.ORD, 1.45],
|
||||
Bigg: ['MakeBig', TEXCLASS.ORD, 1.75],
|
||||
bigl: ['MakeBig', TEXCLASS.OPEN, 0.85],
|
||||
Bigl: ['MakeBig', TEXCLASS.OPEN, 1.15],
|
||||
biggl: ['MakeBig', TEXCLASS.OPEN, 1.45],
|
||||
Biggl: ['MakeBig', TEXCLASS.OPEN, 1.75],
|
||||
bigr: ['MakeBig', TEXCLASS.CLOSE, 0.85],
|
||||
Bigr: ['MakeBig', TEXCLASS.CLOSE, 1.15],
|
||||
biggr: ['MakeBig', TEXCLASS.CLOSE, 1.45],
|
||||
Biggr: ['MakeBig', TEXCLASS.CLOSE, 1.75],
|
||||
bigm: ['MakeBig', TEXCLASS.REL, 0.85],
|
||||
Bigm: ['MakeBig', TEXCLASS.REL, 1.15],
|
||||
biggm: ['MakeBig', TEXCLASS.REL, 1.45],
|
||||
Biggm: ['MakeBig', TEXCLASS.REL, 1.75],
|
||||
|
||||
mathord: ['TeXAtom', TEXCLASS.ORD],
|
||||
mathop: ['TeXAtom', TEXCLASS.OP],
|
||||
mathopen: ['TeXAtom', TEXCLASS.OPEN],
|
||||
mathclose: ['TeXAtom', TEXCLASS.CLOSE],
|
||||
mathbin: ['TeXAtom', TEXCLASS.BIN],
|
||||
mathrel: ['TeXAtom', TEXCLASS.REL],
|
||||
mathpunct: ['TeXAtom', TEXCLASS.PUNCT],
|
||||
mathinner: ['TeXAtom', TEXCLASS.INNER],
|
||||
|
||||
vcenter: ['TeXAtom', TEXCLASS.VCENTER],
|
||||
|
||||
buildrel: 'BuildRel',
|
||||
|
||||
hbox: ['HBox', 0],
|
||||
text: 'HBox',
|
||||
mbox: ['HBox', 0],
|
||||
fbox: 'FBox',
|
||||
boxed: ['Macro', '\\fbox{$\\displaystyle{#1}$}', 1],
|
||||
framebox: 'FrameBox',
|
||||
|
||||
strut: 'Strut',
|
||||
mathstrut: ['Macro', '\\vphantom{(}'],
|
||||
phantom: 'Phantom',
|
||||
vphantom: ['Phantom', 1, 0],
|
||||
hphantom: ['Phantom', 0, 1],
|
||||
smash: 'Smash',
|
||||
|
||||
acute: ['Accent', '00B4'], // or 0301 or 02CA
|
||||
grave: ['Accent', '0060'], // or 0300 or 02CB
|
||||
ddot: ['Accent', '00A8'], // or 0308
|
||||
tilde: ['Accent', '007E'], // or 0303 or 02DC
|
||||
bar: ['Accent', '00AF'], // or 0304 or 02C9
|
||||
breve: ['Accent', '02D8'], // or 0306
|
||||
check: ['Accent', '02C7'], // or 030C
|
||||
hat: ['Accent', '005E'], // or 0302 or 02C6
|
||||
vec: ['Accent', '2192'], // or 20D7
|
||||
dot: ['Accent', '02D9'], // or 0307
|
||||
widetilde: ['Accent', '007E', 1], // or 0303 or 02DC
|
||||
widehat: ['Accent', '005E', 1], // or 0302 or 02C6
|
||||
|
||||
matrix: 'Matrix',
|
||||
array: 'Matrix',
|
||||
pmatrix: ['Matrix', '(', ')'],
|
||||
cases: ['Matrix', '{', '', 'left left', null, '.1em', null,
|
||||
true],
|
||||
eqalign: ['Matrix', null, null, 'right left',
|
||||
em(MATHSPACE.thickmathspace), '.5em', 'D'],
|
||||
displaylines: ['Matrix', null, null, 'center', null, '.5em', 'D'],
|
||||
cr: 'Cr',
|
||||
'\\': 'CrLaTeX',
|
||||
newline: ['CrLaTeX', true],
|
||||
hline: ['HLine', 'solid'],
|
||||
hdashline: ['HLine', 'dashed'],
|
||||
// noalign: 'HandleNoAlign',
|
||||
eqalignno: ['Matrix', null, null, 'right left',
|
||||
em(MATHSPACE.thickmathspace), '.5em', 'D', null,
|
||||
'right'],
|
||||
leqalignno: ['Matrix', null, null, 'right left',
|
||||
em(MATHSPACE.thickmathspace), '.5em', 'D', null,
|
||||
'left'],
|
||||
hfill: 'HFill',
|
||||
hfil: 'HFill', // \hfil treated as \hfill for now
|
||||
hfilll: 'HFill', // \hfilll treated as \hfill for now
|
||||
|
||||
// TeX substitution macros
|
||||
bmod: ['Macro', '\\mmlToken{mo}[lspace="thickmathspace"' +
|
||||
' rspace="thickmathspace"]{mod}'],
|
||||
pmod: ['Macro', '\\pod{\\mmlToken{mi}{mod}\\kern 6mu #1}', 1],
|
||||
mod: ['Macro', '\\mathchoice{\\kern18mu}{\\kern12mu}' +
|
||||
'{\\kern12mu}{\\kern12mu}\\mmlToken{mi}{mod}\\,\\,#1',
|
||||
1],
|
||||
pod: ['Macro', '\\mathchoice{\\kern18mu}{\\kern8mu}' +
|
||||
'{\\kern8mu}{\\kern8mu}(#1)', 1],
|
||||
iff: ['Macro', '\\;\\Longleftrightarrow\\;'],
|
||||
skew: ['Macro', '{{#2{#3\\mkern#1mu}\\mkern-#1mu}{}}', 3],
|
||||
|
||||
pmb: ['Macro', '\\rlap{#1}\\kern1px{#1}', 1],
|
||||
TeX: ['Macro', 'T\\kern-.14em\\lower.5ex{E}\\kern-.115em X'],
|
||||
LaTeX: ['Macro', 'L\\kern-.325em\\raise.21em' +
|
||||
'{\\scriptstyle{A}}\\kern-.17em\\TeX'],
|
||||
' ': ['Macro', '\\text{ }'],
|
||||
|
||||
// Specially handled
|
||||
not: 'Not',
|
||||
dots: 'Dots',
|
||||
space: 'Tilde',
|
||||
'\u00A0': 'Tilde',
|
||||
|
||||
|
||||
// LaTeX
|
||||
begin: 'BeginEnd',
|
||||
end: 'BeginEnd',
|
||||
|
||||
label: 'HandleLabel',
|
||||
ref: 'HandleRef',
|
||||
nonumber: 'HandleNoTag',
|
||||
|
||||
// Internal use:
|
||||
mathchoice: 'MathChoice',
|
||||
mmlToken: 'MmlToken'
|
||||
}, BaseMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Macros for LaTeX environments.
|
||||
*/
|
||||
new sm.EnvironmentMap('environment', ParseMethods.environment, {
|
||||
array: ['AlignedArray'],
|
||||
equation: ['Equation', null, true],
|
||||
eqnarray: ['EqnArray', null, true, true, 'rcl',
|
||||
ParseUtil.cols(0, MATHSPACE.thickmathspace), '.5em']
|
||||
}, BaseMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Mapping for negated operators.
|
||||
*/
|
||||
new sm.CharacterMap('not_remap', null, {
|
||||
'\u2190': '\u219A',
|
||||
'\u2192': '\u219B',
|
||||
'\u2194': '\u21AE',
|
||||
'\u21D0': '\u21CD',
|
||||
'\u21D2': '\u21CF',
|
||||
'\u21D4': '\u21CE',
|
||||
'\u2208': '\u2209',
|
||||
'\u220B': '\u220C',
|
||||
'\u2223': '\u2224',
|
||||
'\u2225': '\u2226',
|
||||
'\u223C': '\u2241',
|
||||
'\u007E': '\u2241',
|
||||
'\u2243': '\u2244',
|
||||
'\u2245': '\u2247',
|
||||
'\u2248': '\u2249',
|
||||
'\u224D': '\u226D',
|
||||
'\u003D': '\u2260',
|
||||
'\u2261': '\u2262',
|
||||
'\u003C': '\u226E',
|
||||
'\u003E': '\u226F',
|
||||
'\u2264': '\u2270',
|
||||
'\u2265': '\u2271',
|
||||
'\u2272': '\u2274',
|
||||
'\u2273': '\u2275',
|
||||
'\u2276': '\u2278',
|
||||
'\u2277': '\u2279',
|
||||
'\u227A': '\u2280',
|
||||
'\u227B': '\u2281',
|
||||
'\u2282': '\u2284',
|
||||
'\u2283': '\u2285',
|
||||
'\u2286': '\u2288',
|
||||
'\u2287': '\u2289',
|
||||
'\u22A2': '\u22AC',
|
||||
'\u22A8': '\u22AD',
|
||||
'\u22A9': '\u22AE',
|
||||
'\u22AB': '\u22AF',
|
||||
'\u227C': '\u22E0',
|
||||
'\u227D': '\u22E1',
|
||||
'\u2291': '\u22E2',
|
||||
'\u2292': '\u22E3',
|
||||
'\u22B2': '\u22EA',
|
||||
'\u22B3': '\u22EB',
|
||||
'\u22B4': '\u22EC',
|
||||
'\u22B5': '\u22ED',
|
||||
'\u2203': '\u2204'
|
||||
});
|
||||
1618
node_modules/mathjax-full/ts/input/tex/base/BaseMethods.ts
generated
vendored
Normal file
1618
node_modules/mathjax-full/ts/input/tex/base/BaseMethods.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
123
node_modules/mathjax-full/ts/input/tex/bbox/BboxConfiguration.ts
generated
vendored
Normal file
123
node_modules/mathjax-full/ts/input/tex/bbox/BboxConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the bbox package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import TexError from '../TexError.js';
|
||||
|
||||
|
||||
// Namespace
|
||||
export let BboxMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
/**
|
||||
* Implements MathJax Bbox macro to pad and colorize background boxes.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the calling macro.
|
||||
*/
|
||||
BboxMethods.BBox = function(parser: TexParser, name: string) {
|
||||
const bbox = parser.GetBrackets(name, '');
|
||||
let math = parser.ParseArg(name);
|
||||
const parts = bbox.split(/,/);
|
||||
let def, background, style;
|
||||
for (let i = 0, m = parts.length; i < m; i++) {
|
||||
const part = parts[i].trim();
|
||||
const match = part.match(/^(\.\d+|\d+(\.\d*)?)(pt|em|ex|mu|px|in|cm|mm)$/);
|
||||
if (match) {
|
||||
// @test Bbox-Padding
|
||||
if (def) {
|
||||
// @test Bbox-Padding-Error
|
||||
throw new TexError('MultipleBBoxProperty', '%1 specified twice in %2', 'Padding', name);
|
||||
}
|
||||
const pad = BBoxPadding(match[1] + match[3]);
|
||||
if (pad) {
|
||||
// @test Bbox-Padding
|
||||
def = {
|
||||
height: '+' + pad,
|
||||
depth: '+' + pad,
|
||||
lspace: pad,
|
||||
width: '+' + (2 * parseInt(match[1], 10)) + match[3]
|
||||
};
|
||||
}
|
||||
} else if (part.match(/^([a-z0-9]+|\#[0-9a-f]{6}|\#[0-9a-f]{3})$/i)) {
|
||||
// @test Bbox-Background
|
||||
if (background) {
|
||||
// @test Bbox-Background-Error
|
||||
throw new TexError('MultipleBBoxProperty', '%1 specified twice in %2',
|
||||
'Background', name);
|
||||
}
|
||||
background = part;
|
||||
} else if (part.match(/^[-a-z]+:/i)) {
|
||||
// @test Bbox-Frame
|
||||
if (style) {
|
||||
// @test Bbox-Frame-Error
|
||||
throw new TexError('MultipleBBoxProperty', '%1 specified twice in %2',
|
||||
'Style', name);
|
||||
}
|
||||
style = BBoxStyle(part);
|
||||
} else if (part !== '') {
|
||||
// @test Bbox-General-Error
|
||||
throw new TexError(
|
||||
'InvalidBBoxProperty',
|
||||
'"%1" doesn\'t look like a color, a padding dimension, or a style',
|
||||
part);
|
||||
}
|
||||
}
|
||||
if (def) {
|
||||
// @test Bbox-Padding
|
||||
math = parser.create('node', 'mpadded', [math], def);
|
||||
}
|
||||
if (background || style) {
|
||||
def = {};
|
||||
if (background) {
|
||||
// @test Bbox-Background
|
||||
Object.assign(def, {mathbackground: background});
|
||||
}
|
||||
if (style) {
|
||||
// @test Bbox-Frame
|
||||
Object.assign(def, {style: style});
|
||||
}
|
||||
math = parser.create('node', 'mstyle', [math], def);
|
||||
}
|
||||
parser.Push(math);
|
||||
};
|
||||
|
||||
|
||||
// Dummy methods. Need to be made Safe with security check.
|
||||
let BBoxStyle = function(styles: string) {
|
||||
return styles;
|
||||
};
|
||||
|
||||
let BBoxPadding = function(pad: string) {
|
||||
return pad;
|
||||
};
|
||||
|
||||
|
||||
new CommandMap('bbox', {bbox: 'BBox'}, BboxMethods);
|
||||
|
||||
|
||||
export const BboxConfiguration = Configuration.create(
|
||||
'bbox', {handler: {macro: ['bbox']}}
|
||||
);
|
||||
113
node_modules/mathjax-full/ts/input/tex/boldsymbol/BoldsymbolConfiguration.ts
generated
vendored
Normal file
113
node_modules/mathjax-full/ts/input/tex/boldsymbol/BoldsymbolConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the boldsymbol package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import {NodeFactory} from '../NodeFactory.js';
|
||||
import ParseOptions from '../ParseOptions.js';
|
||||
|
||||
let BOLDVARIANT: {[key: string]: string} = {};
|
||||
BOLDVARIANT[TexConstant.Variant.NORMAL] = TexConstant.Variant.BOLD;
|
||||
BOLDVARIANT[TexConstant.Variant.ITALIC] = TexConstant.Variant.BOLDITALIC;
|
||||
BOLDVARIANT[TexConstant.Variant.FRAKTUR] = TexConstant.Variant.BOLDFRAKTUR;
|
||||
BOLDVARIANT[TexConstant.Variant.SCRIPT] = TexConstant.Variant.BOLDSCRIPT;
|
||||
BOLDVARIANT[TexConstant.Variant.SANSSERIF] = TexConstant.Variant.BOLDSANSSERIF;
|
||||
BOLDVARIANT['-tex-calligraphic'] = '-tex-bold-calligraphic';
|
||||
BOLDVARIANT['-tex-oldstyle'] = '-tex-bold-oldstyle';
|
||||
BOLDVARIANT['-tex-mathit'] = TexConstant.Variant.BOLDITALIC;
|
||||
|
||||
|
||||
// Namespace
|
||||
export let BoldsymbolMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
|
||||
/**
|
||||
* Parse function for boldsymbol macro.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the macro.
|
||||
*/
|
||||
BoldsymbolMethods.Boldsymbol = function(parser: TexParser, name: string) {
|
||||
let boldsymbol = parser.stack.env['boldsymbol'];
|
||||
parser.stack.env['boldsymbol'] = true;
|
||||
let mml = parser.ParseArg(name);
|
||||
parser.stack.env['boldsymbol'] = boldsymbol;
|
||||
parser.Push(mml);
|
||||
};
|
||||
|
||||
|
||||
new CommandMap('boldsymbol', {boldsymbol: 'Boldsymbol'}, BoldsymbolMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Creates token nodes in bold font if possible.
|
||||
* @param {NodeFactory} factory The current node factory.
|
||||
* @param {string} kind The type of token node to create.
|
||||
* @param {any} def Properties for the node.
|
||||
* @param {string} text The text content.
|
||||
* @return {MmlNode} The generated token node.
|
||||
*/
|
||||
export function createBoldToken(factory: NodeFactory, kind: string,
|
||||
def: any, text: string): MmlNode {
|
||||
let token = NodeFactory.createToken(factory, kind, def, text);
|
||||
if (kind !== 'mtext' &&
|
||||
factory.configuration.parser.stack.env['boldsymbol']) {
|
||||
NodeUtil.setProperty(token, 'fixBold', true);
|
||||
factory.configuration.addNode('fixBold', token);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Postprocessor to rewrite token nodes to bold font, if possible.
|
||||
* @param {ParseOptions} data The parse options.
|
||||
*/
|
||||
export function rewriteBoldTokens(arg: {data: ParseOptions}) {
|
||||
for (let node of arg.data.getList('fixBold')) {
|
||||
if (NodeUtil.getProperty(node, 'fixBold')) {
|
||||
let variant = NodeUtil.getAttribute(node, 'mathvariant') as string;
|
||||
if (variant == null) {
|
||||
NodeUtil.setAttribute(node, 'mathvariant', TexConstant.Variant.BOLD);
|
||||
} else {
|
||||
NodeUtil.setAttribute(node,
|
||||
'mathvariant', BOLDVARIANT[variant] || variant);
|
||||
}
|
||||
NodeUtil.removeProperties(node, 'fixBold');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const BoldsymbolConfiguration = Configuration.create(
|
||||
'boldsymbol', {
|
||||
handler: {macro: ['boldsymbol']},
|
||||
nodes: {'token': createBoldToken},
|
||||
postprocessors: [rewriteBoldTokens]
|
||||
}
|
||||
);
|
||||
42
node_modules/mathjax-full/ts/input/tex/braket/BraketConfiguration.ts
generated
vendored
Normal file
42
node_modules/mathjax-full/ts/input/tex/braket/BraketConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the Braket package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {BraketItem} from './BraketItems.js';
|
||||
import './BraketMappings.js';
|
||||
|
||||
|
||||
export const BraketConfiguration = Configuration.create(
|
||||
'braket', {
|
||||
handler: {
|
||||
character: ['Braket-characters'],
|
||||
macro: ['Braket-macros']
|
||||
},
|
||||
items: {
|
||||
[BraketItem.prototype.kind]: BraketItem,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
89
node_modules/mathjax-full/ts/input/tex/braket/BraketItems.ts
generated
vendored
Normal file
89
node_modules/mathjax-full/ts/input/tex/braket/BraketItems.ts
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Stack items for parsing the braket package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import {CheckType, BaseItem, StackItem} from '../StackItem.js';
|
||||
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
|
||||
|
||||
/**
|
||||
* A bra-ket command. Collates elements from the opening brace to the closing
|
||||
* brace, adding bars to a given maximal number (e.g., only one in case of
|
||||
* set). To finalise it adds the surrounding angle brackets or braces.
|
||||
*/
|
||||
export class BraketItem extends BaseItem {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
get kind() {
|
||||
return 'braket';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
get isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public checkItem(item: StackItem): CheckType {
|
||||
if (item.isKind('close')) {
|
||||
return [[this.factory.create('mml', this.toMml())], true];
|
||||
}
|
||||
if (item.isKind('mml')) {
|
||||
this.Push(item.toMml());
|
||||
if (this.getProperty('single')) {
|
||||
return [[this.toMml()], true];
|
||||
}
|
||||
return BaseItem.fail;
|
||||
}
|
||||
return super.checkItem(item);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public toMml() {
|
||||
let inner = super.toMml();
|
||||
let open = this.getProperty('open') as string;
|
||||
let close = this.getProperty('close') as string;
|
||||
if (this.getProperty('stretchy')) {
|
||||
return ParseUtil.fenced(this.factory.configuration, open, inner, close);
|
||||
}
|
||||
let attrs = {fence: true, stretchy: false, symmetric: true, texClass: TEXCLASS.OPEN};
|
||||
let openNode = this.create('token', 'mo', attrs, open);
|
||||
attrs.texClass = TEXCLASS.CLOSE;
|
||||
let closeNode = this.create('token', 'mo', attrs, close);
|
||||
let mrow = this.create('node', 'mrow', [openNode, inner, closeNode],
|
||||
{open: open, close: close, texClass: TEXCLASS.INNER});
|
||||
return mrow;
|
||||
}
|
||||
|
||||
}
|
||||
56
node_modules/mathjax-full/ts/input/tex/braket/BraketMappings.ts
generated
vendored
Normal file
56
node_modules/mathjax-full/ts/input/tex/braket/BraketMappings.ts
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Mappings for TeX parsing of the braket package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {CommandMap, MacroMap} from '../SymbolMap.js';
|
||||
import BraketMethods from './BraketMethods.js';
|
||||
|
||||
|
||||
/**
|
||||
* Macros for braket package.
|
||||
*/
|
||||
new CommandMap('Braket-macros', {
|
||||
bra: ['Macro', '{\\langle {#1} \\vert}', 1],
|
||||
ket: ['Macro', '{\\vert {#1} \\rangle}', 1],
|
||||
braket: ['Braket', '\u27E8', '\u27E9', false, Infinity],
|
||||
'set': ['Braket', '{', '}', false, 1],
|
||||
Bra: ['Macro', '{\\left\\langle {#1} \\right\\vert}', 1],
|
||||
Ket: ['Macro', '{\\left\\vert {#1} \\right\\rangle}', 1],
|
||||
Braket: ['Braket', '\u27E8', '\u27E9', true, Infinity],
|
||||
Set: ['Braket', '{', '}', true, 1],
|
||||
// Not part of the LaTeX package:
|
||||
ketbra: ['Macro', '{\\vert {#1} \\rangle\\langle {#2} \\vert}', 2],
|
||||
Ketbra: ['Macro', '{\\left\\vert {#1} \\right\\rangle\\left\\langle {#2} \\right\\vert}', 2],
|
||||
// Treatment of bar.
|
||||
'|': 'Bar'
|
||||
}, BraketMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Character map for braket package.
|
||||
*/
|
||||
new MacroMap('Braket-characters', {
|
||||
'|': 'Bar'
|
||||
}, BraketMethods);
|
||||
|
||||
|
||||
99
node_modules/mathjax-full/ts/input/tex/braket/BraketMethods.ts
generated
vendored
Normal file
99
node_modules/mathjax-full/ts/input/tex/braket/BraketMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Methods for TeX parsing of the braket package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import BaseMethods from '../base/BaseMethods.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
|
||||
import TexError from '../TexError.js';
|
||||
|
||||
|
||||
let BraketMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
BraketMethods.Macro = BaseMethods.Macro;
|
||||
|
||||
|
||||
/**
|
||||
* Generate a bra-ket expression.
|
||||
* @param {TexParser} parser The current TeX parser.
|
||||
* @param {string} name Name of the current control sequence.
|
||||
* @param {string} open Opening delimiter.
|
||||
* @param {string} close Closing delimiter.
|
||||
* @param {boolean} stretchy Is it stretchy.
|
||||
* @param {number} barmax Maximum number of bars allowed.
|
||||
*/
|
||||
BraketMethods.Braket = function(parser: TexParser, _name: string,
|
||||
open: string, close: string,
|
||||
stretchy: boolean, barmax: number) {
|
||||
let next = parser.GetNext();
|
||||
if (next === '') {
|
||||
throw new TexError('MissingArgFor', 'Missing argument for %1', parser.currentCS);
|
||||
}
|
||||
let single = true;
|
||||
if (next === '{') {
|
||||
parser.i++;
|
||||
single = false;
|
||||
}
|
||||
parser.Push(
|
||||
parser.itemFactory.create('braket')
|
||||
.setProperties({barmax: barmax, barcount: 0, open: open,
|
||||
close: close, stretchy: stretchy, single: single}));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate a bar. If inside a bra-ket expressions it's handled accordingly.
|
||||
* @param {TexParser} parser The current TeX parser.
|
||||
* @param {string} name Name of the current control sequence.
|
||||
*/
|
||||
BraketMethods.Bar = function(parser: TexParser, name: string) {
|
||||
let c = name === '|' ? '|' : '\u2225';
|
||||
let top = parser.stack.Top();
|
||||
if (top.kind !== 'braket' ||
|
||||
top.getProperty('barcount') >= top.getProperty('barmax')) {
|
||||
let mml = parser.create('token', 'mo', {texClass: TEXCLASS.ORD, stretchy: false}, c);
|
||||
parser.Push(mml);
|
||||
return;
|
||||
}
|
||||
if (c === '|' && parser.GetNext() === '|') {
|
||||
parser.i++;
|
||||
c = '\u2225';
|
||||
}
|
||||
let stretchy = top.getProperty('stretchy');
|
||||
if (!stretchy) {
|
||||
let node = parser.create('token', 'mo', {stretchy: false, braketbar: true}, c);
|
||||
parser.Push(node);
|
||||
return;
|
||||
}
|
||||
let node = parser.create('node', 'TeXAtom', [], {texClass: TEXCLASS.CLOSE});
|
||||
parser.Push(node);
|
||||
top.setProperty('barcount', top.getProperty('barcount') as number + 1);
|
||||
node = parser.create('token', 'mo', {stretchy: true, braketbar: true}, c);
|
||||
parser.Push(node);
|
||||
node = parser.create('node', 'TeXAtom', [], {texClass: TEXCLASS.OPEN});
|
||||
parser.Push(node);
|
||||
};
|
||||
|
||||
|
||||
export default BraketMethods;
|
||||
49
node_modules/mathjax-full/ts/input/tex/bussproofs/BussproofsConfiguration.ts
generated
vendored
Normal file
49
node_modules/mathjax-full/ts/input/tex/bussproofs/BussproofsConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the Bussproofs package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {ProofTreeItem} from './BussproofsItems.js';
|
||||
import {saveDocument, clearDocument, balanceRules, makeBsprAttributes} from './BussproofsUtil.js';
|
||||
import './BussproofsMappings.js';
|
||||
|
||||
|
||||
export const BussproofsConfiguration = Configuration.create(
|
||||
'bussproofs', {
|
||||
handler: {
|
||||
macro: ['Bussproofs-macros'],
|
||||
environment: ['Bussproofs-environments']
|
||||
},
|
||||
items: {
|
||||
[ProofTreeItem.prototype.kind]: ProofTreeItem,
|
||||
},
|
||||
preprocessors: [
|
||||
[saveDocument, 1]
|
||||
],
|
||||
postprocessors: [
|
||||
[clearDocument, 3],
|
||||
[makeBsprAttributes, 2],
|
||||
[balanceRules, 1]
|
||||
]
|
||||
}
|
||||
);
|
||||
88
node_modules/mathjax-full/ts/input/tex/bussproofs/BussproofsItems.ts
generated
vendored
Normal file
88
node_modules/mathjax-full/ts/input/tex/bussproofs/BussproofsItems.ts
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Items for TeX parsing of bussproofs.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import TexError from '../TexError.js';
|
||||
import {BaseItem, CheckType, StackItem} from '../StackItem.js';
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
import Stack from '../Stack.js';
|
||||
import * as BussproofsUtil from './BussproofsUtil.js';
|
||||
|
||||
|
||||
export class ProofTreeItem extends BaseItem {
|
||||
|
||||
|
||||
/**
|
||||
* The current left label.
|
||||
* @type {MmlNode[]}
|
||||
*/
|
||||
public leftLabel: MmlNode[] = null;
|
||||
|
||||
/**
|
||||
* The current right label.
|
||||
* @type {MmlNode[]}
|
||||
*/
|
||||
public rigthLabel: MmlNode[] = null;
|
||||
|
||||
private innerStack: Stack = new Stack(this.factory, {}, true);
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public get kind() {
|
||||
return 'proofTree';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public checkItem(item: StackItem): CheckType {
|
||||
if (item.isKind('end') && item.getName() === 'prooftree') {
|
||||
let node = this.toMml();
|
||||
BussproofsUtil.setProperty(node, 'proof', true);
|
||||
return [[this.factory.create('mml', node), item], true];
|
||||
}
|
||||
if (item.isKind('stop')) {
|
||||
throw new TexError('EnvMissingEnd', 'Missing \\end{%1}', this.getName());
|
||||
}
|
||||
this.innerStack.Push(item);
|
||||
return BaseItem.fail;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public toMml() {
|
||||
const tree = super.toMml();
|
||||
const start = this.innerStack.Top();
|
||||
if (start.isKind('start') && !start.Size()) {
|
||||
return tree;
|
||||
}
|
||||
this.innerStack.Push(this.factory.create('stop'));
|
||||
let prefix = this.innerStack.Top().toMml();
|
||||
return this.create('node', 'mrow', [prefix, tree], {});
|
||||
}
|
||||
}
|
||||
85
node_modules/mathjax-full/ts/input/tex/bussproofs/BussproofsMappings.ts
generated
vendored
Normal file
85
node_modules/mathjax-full/ts/input/tex/bussproofs/BussproofsMappings.ts
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Mappings for TeX parsing for Bussproofs package commands.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import BussproofsMethods from './BussproofsMethods.js';
|
||||
import ParseMethods from '../ParseMethods.js';
|
||||
import {CommandMap, EnvironmentMap} from '../SymbolMap.js';
|
||||
|
||||
|
||||
/**
|
||||
* Macros for bussproofs etc.
|
||||
*/
|
||||
new CommandMap('Bussproofs-macros', {
|
||||
AxiomC: 'Axiom',
|
||||
UnaryInfC: ['Inference', 1],
|
||||
BinaryInfC: ['Inference', 2],
|
||||
TrinaryInfC: ['Inference', 3],
|
||||
QuaternaryInfC: ['Inference', 4],
|
||||
QuinaryInfC: ['Inference', 5],
|
||||
RightLabel: ['Label', 'right'],
|
||||
LeftLabel: ['Label', 'left'],
|
||||
// Abbreviations are automatically enabled
|
||||
AXC: 'Axiom',
|
||||
UIC: ['Inference', 1],
|
||||
BIC: ['Inference', 2],
|
||||
TIC: ['Inference', 3],
|
||||
RL: ['Label', 'right'],
|
||||
LL: ['Label', 'left'],
|
||||
|
||||
noLine: ['SetLine', 'none', false],
|
||||
singleLine: ['SetLine', 'solid', false],
|
||||
solidLine: ['SetLine', 'solid', false],
|
||||
dashedLine: ['SetLine', 'dashed', false],
|
||||
// Not yet implemented in CSS!
|
||||
// doubleLine: ['SetLine', 'double', false],
|
||||
// dottedLine: ['SetLine', 'dotted', false],
|
||||
|
||||
alwaysNoLine: ['SetLine', 'none', true],
|
||||
alwaysSingleLine: ['SetLine', 'solid', true],
|
||||
alwaysSolidLine: ['SetLine', 'solid', true],
|
||||
alwaysDashedLine: ['SetLine', 'dashed', true],
|
||||
// Not yet implemented in CSS!
|
||||
// alwaysDoubleLine: ['SetLine', 'double', true],
|
||||
// alwaysDottedLine: ['SetLine', 'dotted', true],
|
||||
|
||||
rootAtTop: ['RootAtTop', true],
|
||||
alwaysRootAtTop: ['RootAtTop', true],
|
||||
|
||||
rootAtBottom: ['RootAtTop', false],
|
||||
alwaysRootAtBottom: ['RootAtTop', false],
|
||||
// TODO: always commands should be persistent.
|
||||
|
||||
fCenter: 'FCenter',
|
||||
Axiom: 'AxiomF',
|
||||
UnaryInf: ['InferenceF', 1],
|
||||
BinaryInf: ['InferenceF', 2],
|
||||
TrinaryInf: ['InferenceF', 3],
|
||||
QuaternaryInf: ['InferenceF', 4],
|
||||
QuinaryInf: ['InferenceF', 5]
|
||||
}, BussproofsMethods);
|
||||
|
||||
|
||||
new EnvironmentMap('Bussproofs-environments', ParseMethods.environment, {
|
||||
prooftree: ['Prooftree', null, false]
|
||||
}, BussproofsMethods);
|
||||
352
node_modules/mathjax-full/ts/input/tex/bussproofs/BussproofsMethods.ts
generated
vendored
Normal file
352
node_modules/mathjax-full/ts/input/tex/bussproofs/BussproofsMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Mappings for TeX parsing for the bussproofs package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import TexError from '../TexError.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import {StackItem} from '../StackItem.js';
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
import * as BussproofsUtil from './BussproofsUtil.js';
|
||||
|
||||
|
||||
// Namespace
|
||||
let BussproofsMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
/**
|
||||
* Implements the proof tree environment.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {StackItem} begin The opening element of the environment.
|
||||
* @return {StackItem} The proof tree stackitem.
|
||||
*/
|
||||
// TODO: Error handling if we have leftover elements or elements are not in the
|
||||
// required order.
|
||||
BussproofsMethods.Prooftree = function(parser: TexParser, begin: StackItem): StackItem {
|
||||
parser.Push(begin);
|
||||
// TODO: Check if opening a proof tree is legal.
|
||||
let newItem = parser.itemFactory.create('proofTree').
|
||||
setProperties({name: begin.getName(),
|
||||
line: 'solid', currentLine: 'solid', rootAtTop: false});
|
||||
// parser.Push(item);
|
||||
return newItem;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements the Axiom command.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} name The name of the command.
|
||||
*/
|
||||
BussproofsMethods.Axiom = function(parser: TexParser, name: string) {
|
||||
let top = parser.stack.Top();
|
||||
// TODO: Label error
|
||||
if (top.kind !== 'proofTree') {
|
||||
throw new TexError('IllegalProofCommand',
|
||||
'Proof commands only allowed in prooftree environment.');
|
||||
}
|
||||
let content = paddedContent(parser, parser.GetArgument(name));
|
||||
BussproofsUtil.setProperty(content, 'axiom', true);
|
||||
top.Push(content);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pads content of an inference rule.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} content The content to be padded.
|
||||
* @return {MmlNode} The mrow element with padded content.
|
||||
*/
|
||||
const paddedContent = function(parser: TexParser, content: string): MmlNode {
|
||||
// Add padding on either site.
|
||||
let nodes = ParseUtil.internalMath(parser, ParseUtil.trimSpaces(content), 0);
|
||||
if (!nodes[0].childNodes[0].childNodes.length) {
|
||||
return parser.create('node', 'mrow', []);
|
||||
}
|
||||
let lpad = parser.create('node', 'mspace', [], {width: '.5ex'});
|
||||
let rpad = parser.create('node', 'mspace', [], {width: '.5ex'});
|
||||
return parser.create('node', 'mrow', [lpad, ...nodes, rpad]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements the Inference rule commands.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} name The name of the command.
|
||||
* @param {number} n Number of premises for this inference rule.
|
||||
*/
|
||||
BussproofsMethods.Inference = function(parser: TexParser, name: string, n: number) {
|
||||
let top = parser.stack.Top();
|
||||
if (top.kind !== 'proofTree') {
|
||||
throw new TexError('IllegalProofCommand',
|
||||
'Proof commands only allowed in prooftree environment.');
|
||||
}
|
||||
if (top.Size() < n) {
|
||||
throw new TexError('BadProofTree', 'Proof tree badly specified.');
|
||||
}
|
||||
const rootAtTop = top.getProperty('rootAtTop') as boolean;
|
||||
const childCount = (n === 1 && !top.Peek()[0].childNodes.length) ? 0 : n;
|
||||
let children: MmlNode[] = [];
|
||||
do {
|
||||
if (children.length) {
|
||||
children.unshift(parser.create('node', 'mtd', [], {}));
|
||||
}
|
||||
children.unshift(
|
||||
parser.create('node', 'mtd', [top.Pop()],
|
||||
{'rowalign': (rootAtTop ? 'top' : 'bottom')}));
|
||||
n--;
|
||||
} while (n > 0);
|
||||
let row = parser.create('node', 'mtr', children, {});
|
||||
let table = parser.create('node', 'mtable', [row], {framespacing: '0 0'});
|
||||
let conclusion = paddedContent(parser, parser.GetArgument(name));
|
||||
let style = top.getProperty('currentLine') as string;
|
||||
if (style !== top.getProperty('line')) {
|
||||
top.setProperty('currentLine', top.getProperty('line'));
|
||||
}
|
||||
let rule = createRule(
|
||||
parser, table, [conclusion], top.getProperty('left') as MmlNode,
|
||||
top.getProperty('right') as MmlNode, style, rootAtTop);
|
||||
top.setProperty('left', null);
|
||||
top.setProperty('right', null);
|
||||
BussproofsUtil.setProperty(rule, 'inference', childCount);
|
||||
parser.configuration.addNode('inference', rule);
|
||||
top.Push(rule);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a ND style inference rule.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {MmlNode} premise The premise (a single table).
|
||||
* @param {MmlNode[]} conclusions Elements that are combined into the conclusion.
|
||||
* @param {MmlNode|null} left The left label if it exists.
|
||||
* @param {MmlNode|null} right The right label if it exists.
|
||||
* @param {string} style Style of inference rule line.
|
||||
* @param {boolean} rootAtTop Direction of inference rule: true for root at top.
|
||||
*/
|
||||
function createRule(parser: TexParser, premise: MmlNode,
|
||||
conclusions: MmlNode[], left: MmlNode | null,
|
||||
right: MmlNode | null, style: string,
|
||||
rootAtTop: boolean) {
|
||||
const upper = parser.create(
|
||||
'node', 'mtr', [parser.create('node', 'mtd', [premise], {})], {});
|
||||
const lower = parser.create(
|
||||
'node', 'mtr', [parser.create('node', 'mtd', conclusions, {})], {});
|
||||
let rule = parser.create('node', 'mtable', rootAtTop ? [lower, upper] : [upper, lower],
|
||||
{align: 'top 2', rowlines: style, framespacing: '0 0'});
|
||||
BussproofsUtil.setProperty(rule, 'inferenceRule', rootAtTop ? 'up' : 'down');
|
||||
let leftLabel, rightLabel;
|
||||
if (left) {
|
||||
leftLabel = parser.create(
|
||||
'node', 'mpadded', [left],
|
||||
{height: '+.5em', width: '+.5em', voffset: '-.15em'});
|
||||
BussproofsUtil.setProperty(leftLabel, 'prooflabel', 'left');
|
||||
}
|
||||
if (right) {
|
||||
rightLabel = parser.create(
|
||||
'node', 'mpadded', [right],
|
||||
{height: '+.5em', width: '+.5em', voffset: '-.15em'});
|
||||
BussproofsUtil.setProperty(rightLabel, 'prooflabel', 'right');
|
||||
}
|
||||
let children, label;
|
||||
if (left && right) {
|
||||
children = [leftLabel, rule, rightLabel];
|
||||
label = 'both';
|
||||
} else if (left) {
|
||||
children = [leftLabel, rule];
|
||||
label = 'left';
|
||||
} else if (right) {
|
||||
children = [rule, rightLabel];
|
||||
label = 'right';
|
||||
} else {
|
||||
return rule;
|
||||
}
|
||||
rule = parser.create('node', 'mrow', children);
|
||||
BussproofsUtil.setProperty(rule, 'labelledRule', label);
|
||||
return rule;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements the label command.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} name The name of the command.
|
||||
* @param {string} side The side of the label.
|
||||
*/
|
||||
BussproofsMethods.Label = function(parser: TexParser, name: string, side: string) {
|
||||
let top = parser.stack.Top();
|
||||
// Label error
|
||||
if (top.kind !== 'proofTree') {
|
||||
throw new TexError('IllegalProofCommand',
|
||||
'Proof commands only allowed in prooftree environment.');
|
||||
}
|
||||
let content = ParseUtil.internalMath(parser, parser.GetArgument(name), 0);
|
||||
let label = (content.length > 1) ?
|
||||
parser.create('node', 'mrow', content, {}) : content[0];
|
||||
top.setProperty(side, label);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets line style for inference rules.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} name The name of the command.
|
||||
* @param {string} style The line style to set.
|
||||
* @param {boolean} always Set as permanent style.
|
||||
*/
|
||||
BussproofsMethods.SetLine = function(parser: TexParser, _name: string, style: string, always: boolean) {
|
||||
let top = parser.stack.Top();
|
||||
// Label error
|
||||
if (top.kind !== 'proofTree') {
|
||||
throw new TexError('IllegalProofCommand',
|
||||
'Proof commands only allowed in prooftree environment.');
|
||||
}
|
||||
top.setProperty('currentLine', style);
|
||||
if (always) {
|
||||
top.setProperty('line', style);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements commands indicating where the root of the proof tree is.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} name The name of the command.
|
||||
* @param {string} where If true root is at top, otherwise at bottom.
|
||||
*/
|
||||
BussproofsMethods.RootAtTop = function(parser: TexParser, _name: string, where: boolean) {
|
||||
let top = parser.stack.Top();
|
||||
if (top.kind !== 'proofTree') {
|
||||
throw new TexError('IllegalProofCommand',
|
||||
'Proof commands only allowed in prooftree environment.');
|
||||
}
|
||||
top.setProperty('rootAtTop', where);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements Axiom command for sequents.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} name The name of the command.
|
||||
*/
|
||||
BussproofsMethods.AxiomF = function(parser: TexParser, name: string) {
|
||||
let top = parser.stack.Top();
|
||||
if (top.kind !== 'proofTree') {
|
||||
throw new TexError('IllegalProofCommand',
|
||||
'Proof commands only allowed in prooftree environment.');
|
||||
}
|
||||
let line = parseFCenterLine(parser, name);
|
||||
BussproofsUtil.setProperty(line, 'axiom', true);
|
||||
top.Push(line);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses a line with a sequent (i.e., one containing \\fcenter).
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} name The name of the calling command.
|
||||
* @return {MmlNode} The parsed line.
|
||||
*/
|
||||
function parseFCenterLine(parser: TexParser, name: string): MmlNode {
|
||||
let dollar = parser.GetNext();
|
||||
if (dollar !== '$') {
|
||||
throw new TexError('IllegalUseOfCommand',
|
||||
'Use of %1 does not match it\'s definition.', name);
|
||||
}
|
||||
parser.i++;
|
||||
let axiom = parser.GetUpTo(name, '$');
|
||||
if (axiom.indexOf('\\fCenter') === -1) {
|
||||
throw new TexError('IllegalUseOfCommand',
|
||||
'Missing \\fCenter in %1.', name);
|
||||
}
|
||||
// Check for fCenter and throw error?
|
||||
let [prem, conc] = axiom.split('\\fCenter');
|
||||
let premise = (new TexParser(prem, parser.stack.env, parser.configuration)).mml();
|
||||
let conclusion = (new TexParser(conc, parser.stack.env, parser.configuration)).mml();
|
||||
let fcenter = (new TexParser('\\fCenter', parser.stack.env, parser.configuration)).mml();
|
||||
const left = parser.create('node', 'mtd', [premise], {});
|
||||
const middle = parser.create('node', 'mtd', [fcenter], {});
|
||||
const right = parser.create('node', 'mtd', [conclusion], {});
|
||||
const row = parser.create('node', 'mtr', [left, middle, right], {});
|
||||
const table = parser.create('node', 'mtable', [row], {columnspacing: '.5ex', columnalign: 'center 2'});
|
||||
BussproofsUtil.setProperty(table, 'sequent', true);
|
||||
parser.configuration.addNode('sequent', row);
|
||||
return table;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Placeholder for Fcenter macro that can be overwritten with renewcommand.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} name The name of the command.
|
||||
*/
|
||||
BussproofsMethods.FCenter = function(_parser: TexParser, _name: string) { };
|
||||
|
||||
|
||||
/**
|
||||
* Implements inference rules for sequents.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} name The name of the command.
|
||||
* @param {number} n Number of premises for this inference rule.
|
||||
*/
|
||||
BussproofsMethods.InferenceF = function(parser: TexParser, name: string, n: number) {
|
||||
let top = parser.stack.Top();
|
||||
if (top.kind !== 'proofTree') {
|
||||
throw new TexError('IllegalProofCommand',
|
||||
'Proof commands only allowed in prooftree environment.');
|
||||
}
|
||||
if (top.Size() < n) {
|
||||
throw new TexError('BadProofTree', 'Proof tree badly specified.');
|
||||
}
|
||||
const rootAtTop = top.getProperty('rootAtTop') as boolean;
|
||||
const childCount = (n === 1 && !top.Peek()[0].childNodes.length) ? 0 : n;
|
||||
let children: MmlNode[] = [];
|
||||
do {
|
||||
if (children.length) {
|
||||
children.unshift(parser.create('node', 'mtd', [], {}));
|
||||
}
|
||||
children.unshift(
|
||||
parser.create('node', 'mtd', [top.Pop()],
|
||||
{'rowalign': (rootAtTop ? 'top' : 'bottom')}));
|
||||
n--;
|
||||
} while (n > 0);
|
||||
let row = parser.create('node', 'mtr', children, {});
|
||||
let table = parser.create('node', 'mtable', [row], {framespacing: '0 0'});
|
||||
|
||||
let conclusion = parseFCenterLine(parser, name); // TODO: Padding
|
||||
let style = top.getProperty('currentLine') as string;
|
||||
if (style !== top.getProperty('line')) {
|
||||
top.setProperty('currentLine', top.getProperty('line'));
|
||||
}
|
||||
let rule = createRule(
|
||||
parser, table, [conclusion], top.getProperty('left') as MmlNode,
|
||||
top.getProperty('right') as MmlNode, style, rootAtTop);
|
||||
top.setProperty('left', null);
|
||||
top.setProperty('right', null);
|
||||
BussproofsUtil.setProperty(rule, 'inference', childCount);
|
||||
parser.configuration.addNode('inference', rule);
|
||||
top.Push(rule);
|
||||
};
|
||||
|
||||
export default BussproofsMethods;
|
||||
626
node_modules/mathjax-full/ts/input/tex/bussproofs/BussproofsUtil.ts
generated
vendored
Normal file
626
node_modules/mathjax-full/ts/input/tex/bussproofs/BussproofsUtil.ts
generated
vendored
Normal file
@@ -0,0 +1,626 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Postfilter utility for the Bussproofs package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
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';
|
||||
|
||||
|
||||
type MATHITEM = MathItem<any, any, any>;
|
||||
type MATHDOCUMENT = MathDocument<any, any, any>;
|
||||
|
||||
type FilterData = {math: MATHITEM, document: MATHDOCUMENT, data: ParseOptions};
|
||||
|
||||
/**
|
||||
* Global constants local to the module. They instantiate an output jax for
|
||||
* bounding box computation.
|
||||
*/
|
||||
let doc: MATHDOCUMENT = null;
|
||||
let item: MATHITEM = null;
|
||||
|
||||
|
||||
/**
|
||||
* Get the bounding box of a node.
|
||||
* @param {MmlNode} node The target node.
|
||||
*/
|
||||
let getBBox = function(node: MmlNode) {
|
||||
item.root = node;
|
||||
let {w: width} = (doc.outputJax as any).getBBox(item, doc);
|
||||
return width;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the actual table that represents the inference rule, i.e., the rule
|
||||
* without the label. We ignore preceding elements or spaces.
|
||||
*
|
||||
* @param {MmlNode} node The out node representing the inference.
|
||||
* @return {MmlNode} The actual table representing the inference rule.
|
||||
*/
|
||||
let getRule = function(node: MmlNode): MmlNode {
|
||||
let i = 0;
|
||||
while (node && !NodeUtil.isType(node, 'mtable')) {
|
||||
if (NodeUtil.isType(node, 'text')) {
|
||||
return null;
|
||||
}
|
||||
if (NodeUtil.isType(node, 'mrow')) {
|
||||
node = node.childNodes[0] as MmlNode;
|
||||
i = 0;
|
||||
continue;
|
||||
}
|
||||
node = node.parent.childNodes[i] as MmlNode;
|
||||
i++;
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
|
||||
/*******************************
|
||||
* Convenience methods for retrieving bits of the proof tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets premises of an inference rule.
|
||||
* @param {MmlNode} rule The rule.
|
||||
* @param {string} direction Up or down.
|
||||
* @return {MmlNode} The premisses.
|
||||
*/
|
||||
let getPremises = function(rule: MmlNode, direction: string): MmlNode {
|
||||
return rule.childNodes[direction === 'up' ? 1 : 0].childNodes[0].
|
||||
childNodes[0].childNodes[0].childNodes[0] as MmlNode;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets nth premise.
|
||||
* @param {MmlNode} premises The premises.
|
||||
* @param {number} n Number of premise to get.
|
||||
* @return {MmlNode} The nth premise.
|
||||
*/
|
||||
let getPremise = function(premises: MmlNode, n: number): MmlNode {
|
||||
return premises.childNodes[n].childNodes[0].childNodes[0] as MmlNode;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets first premise.
|
||||
* @param {MmlNode} premises The premises.
|
||||
* @return {MmlNode} The first premise.
|
||||
*/
|
||||
let firstPremise = function(premises: MmlNode): MmlNode {
|
||||
return getPremise(premises, 0) as MmlNode;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets last premise.
|
||||
* @param {MmlNode} premises The premises.
|
||||
* @return {MmlNode} The last premise.
|
||||
*/
|
||||
let lastPremise = function(premises: MmlNode): MmlNode {
|
||||
return getPremise(premises, premises.childNodes.length - 1);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get conclusion in an inference rule.
|
||||
* @param {MmlNode} rule The rule.
|
||||
* @param {string} direction Up or down.
|
||||
* @return {MmlNode} The conclusion.
|
||||
*/
|
||||
let getConclusion = function(rule: MmlNode, direction: string): MmlNode {
|
||||
return rule.childNodes[direction === 'up' ? 0 : 1].childNodes[0].childNodes[0].childNodes[0] as MmlNode;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the actual column element in an inference rule. I.e., digs down through
|
||||
* row, padding and space elements.
|
||||
* @param {MmlNode} inf The rule.
|
||||
* @return {MmlNode} The mtd element.
|
||||
*/
|
||||
let getColumn = function(inf: MmlNode): MmlNode {
|
||||
while (inf && !NodeUtil.isType(inf, 'mtd')) {
|
||||
inf = inf.parent as MmlNode;
|
||||
}
|
||||
return inf;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the next sibling of an inference rule.
|
||||
* @param {MmlNode} inf The inference rule.
|
||||
* @return {MmlNode} The next sibling.
|
||||
*/
|
||||
let nextSibling = function(inf: MmlNode): MmlNode {
|
||||
return inf.parent.childNodes[inf.parent.childNodes.indexOf(inf) + 1] as MmlNode;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the previous sibling of an inference rule.
|
||||
* @param {MmlNode} inf The inference rule.
|
||||
* @return {MmlNode} The previous sibling.
|
||||
*/
|
||||
// @ts-ignore
|
||||
let previousSibling = function(inf: MmlNode): MmlNode {
|
||||
return inf.parent.childNodes[inf.parent.childNodes.indexOf(inf) - 1] as MmlNode;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the parent inference rule.
|
||||
* @param {MmlNode} inf The inference rule.
|
||||
* @return {MmlNode} Its parent.
|
||||
*/
|
||||
let getParentInf = function(inf: MmlNode): MmlNode {
|
||||
while (inf && getProperty(inf, 'inference') == null) {
|
||||
inf = inf.parent as MmlNode;
|
||||
}
|
||||
return inf;
|
||||
};
|
||||
|
||||
|
||||
// Computes bbox spaces
|
||||
//
|
||||
//
|
||||
|
||||
/**
|
||||
* Computes spacing left or right of an inference rule. In the case of
|
||||
* right: right space + right label
|
||||
* left: left space + left label
|
||||
* @param {MmlNode} inf The overall proof tree.
|
||||
* @param {MmlNode} rule The particular inference rule.
|
||||
* @param {boolean = false} right True for right, o/w left.
|
||||
* @return {number} The spacing next to the rule.
|
||||
*/
|
||||
let getSpaces = function(inf: MmlNode, rule: MmlNode, right: boolean = false): number {
|
||||
let result = 0;
|
||||
if (inf === rule) {
|
||||
return result;
|
||||
}
|
||||
if (inf !== rule.parent) {
|
||||
let children = inf.childNodes as MmlNode[];
|
||||
let index = right ? children.length - 1 : 0;
|
||||
if (NodeUtil.isType(children[index], 'mspace')) {
|
||||
result += getBBox(children[index]);
|
||||
}
|
||||
inf = rule.parent;
|
||||
}
|
||||
if (inf === rule) {
|
||||
return result;
|
||||
}
|
||||
let children = inf.childNodes as MmlNode[];
|
||||
let index = right ? children.length - 1 : 0;
|
||||
if (children[index] !== rule) {
|
||||
result += getBBox(children[index]);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
// - Get rule T from Wrapper W.
|
||||
// - Get conclusion C in T.
|
||||
// - w: Preceding/following space/label.
|
||||
// - (x - y)/2: Distance from left boundary to middle of C.
|
||||
/**
|
||||
* Computes an space adjustment value to move the inference rule.
|
||||
* @param {MmlNode} inf The inference rule.
|
||||
* @param {boolean = false} right True if adjustments are on the right.
|
||||
* @return {number} The adjustment value.
|
||||
*/
|
||||
let adjustValue = function(inf: MmlNode, right: boolean = false): number {
|
||||
let rule = getRule(inf);
|
||||
let conc = getConclusion(rule, getProperty(rule, 'inferenceRule') as string);
|
||||
// TODO: Here we have to improve sequent adjustment!
|
||||
let w = getSpaces(inf, rule, right);
|
||||
let x = getBBox(rule);
|
||||
let y = getBBox(conc);
|
||||
return w + ((x - y) / 2);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds (positive or negative) space in the column containing the inference rule.
|
||||
* @param {ParseOptions} config The parser configuration.
|
||||
* @param {MmlNode} inf The inference rule to place.
|
||||
* @param {number} space The space to be added.
|
||||
* @param {boolean = false} right True if adjustment is on the right.
|
||||
*/
|
||||
let addSpace = function(config: ParseOptions, inf: MmlNode,
|
||||
space: number, right: boolean = false) {
|
||||
if (getProperty(inf, 'inferenceRule') ||
|
||||
getProperty(inf, 'labelledRule')) {
|
||||
const mrow = config.nodeFactory.create('node', 'mrow');
|
||||
inf.parent.replaceChild(mrow, inf);
|
||||
mrow.setChildren([inf]);
|
||||
moveProperties(inf, mrow);
|
||||
inf = mrow;
|
||||
}
|
||||
// TODO: Simplify below as we now have a definite mrow.
|
||||
const index = right ? inf.childNodes.length - 1 : 0;
|
||||
let mspace = inf.childNodes[index] as MmlNode;
|
||||
if (NodeUtil.isType(mspace, 'mspace')) {
|
||||
NodeUtil.setAttribute(
|
||||
mspace, 'width',
|
||||
ParseUtil.Em(ParseUtil.dimen2em(
|
||||
NodeUtil.getAttribute(mspace, 'width') as string) + space));
|
||||
return;
|
||||
}
|
||||
mspace = config.nodeFactory.create('node', 'mspace', [],
|
||||
{width: ParseUtil.Em(space)});
|
||||
if (right) {
|
||||
inf.appendChild(mspace);
|
||||
return;
|
||||
}
|
||||
mspace.parent = inf;
|
||||
inf.childNodes.unshift(mspace);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Propagates properties up the tree.
|
||||
* @param {MmlNode} src The source node.
|
||||
* @param {MmlNode} dest The destination node.
|
||||
*/
|
||||
let moveProperties = function(src: MmlNode, dest: MmlNode) {
|
||||
let props = ['inference', 'proof', 'maxAdjust', 'labelledRule'];
|
||||
props.forEach(x => {
|
||||
let value = getProperty(src, x);
|
||||
if (value != null) {
|
||||
setProperty(dest, x, value);
|
||||
removeProperty(src, x);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
/********************************
|
||||
* The following methods deal with sequents. There are still issues with the
|
||||
* spatial layout, though.
|
||||
*/
|
||||
// Sequents look like this: table row 3 cells
|
||||
// The table has the 'sequent' property.
|
||||
// The row is the node that is actually saved in the config object.
|
||||
/**
|
||||
* Method to adjust sequent positioning after the tree is computed.
|
||||
* @param {ParseOptions} config Parser configuration options.
|
||||
*/
|
||||
let adjustSequents = function(config: ParseOptions) {
|
||||
let sequents = config.nodeLists['sequent'];
|
||||
if (!sequents) {
|
||||
return;
|
||||
}
|
||||
for (let i = sequents.length - 1, seq; seq = sequents[i]; i--) {
|
||||
if (getProperty(seq, 'sequentProcessed')) {
|
||||
removeProperty(seq, 'sequentProcessed');
|
||||
continue;
|
||||
}
|
||||
let collect = [];
|
||||
let inf = getParentInf(seq);
|
||||
if (getProperty(inf, 'inference') !== 1) {
|
||||
continue;
|
||||
}
|
||||
collect.push(seq);
|
||||
while (getProperty(inf, 'inference') === 1) {
|
||||
// In case we have a table with a label.
|
||||
inf = getRule(inf);
|
||||
let premise = firstPremise(getPremises(inf, getProperty(inf, 'inferenceRule') as string));
|
||||
let sequent = (getProperty(premise, 'inferenceRule')) ?
|
||||
// If the first premise is an inference rule, check the conclusions for a sequent.
|
||||
getConclusion(premise, getProperty(premise, 'inferenceRule') as string) :
|
||||
// Otherwise it is a hyp and we have to check the formula itself.
|
||||
premise;
|
||||
if (getProperty(sequent, 'sequent')) {
|
||||
seq = sequent.childNodes[0] as MmlNode;
|
||||
collect.push(seq);
|
||||
setProperty(seq, 'sequentProcessed', true);
|
||||
}
|
||||
inf = premise;
|
||||
}
|
||||
adjustSequentPairwise(config, collect);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add spaces to the sequents where necessary.
|
||||
* @param {ParseOptions} config Parser configuration options.
|
||||
* @param {MmlNode} sequent The sequent inference rule.
|
||||
* @param {number} position Position of formula to adjust (0 or 2).
|
||||
* @param {string} direction Left or right of the turnstyle.
|
||||
* @param {number} width The space to add to the formulas.
|
||||
*/
|
||||
const addSequentSpace = function(config: ParseOptions, sequent: MmlNode,
|
||||
position: number, direction: string, width: number) {
|
||||
let mspace = config.nodeFactory.create('node', 'mspace', [],
|
||||
{width: ParseUtil.Em(width)});
|
||||
if (direction === 'left') {
|
||||
let row = sequent.childNodes[position].childNodes[0] as MmlNode;
|
||||
mspace.parent = row;
|
||||
row.childNodes.unshift(mspace);
|
||||
} else {
|
||||
sequent.childNodes[position].appendChild(mspace);
|
||||
}
|
||||
setProperty(sequent.parent, 'sequentAdjust_' + direction, width);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adjusts the sequent positioning for a list of inference rules by pairwise
|
||||
* adjusting the width of formulas in sequents. I.e.,
|
||||
* A,B |- C
|
||||
* ------------
|
||||
* A |- B,C
|
||||
*
|
||||
* will be adjusted to
|
||||
*
|
||||
* A, B |- C
|
||||
* ----------------
|
||||
* A |- B,C
|
||||
*
|
||||
* @param {ParseOptions} config Parser configuration options.
|
||||
* @param {MmlNode[]} sequents The list of sequents.
|
||||
*/
|
||||
const adjustSequentPairwise = function(config: ParseOptions, sequents: MmlNode[]) {
|
||||
let top = sequents.pop();
|
||||
while (sequents.length) {
|
||||
let bottom = sequents.pop();
|
||||
let [left, right] = compareSequents(top, bottom);
|
||||
if (getProperty(top.parent, 'axiom')) {
|
||||
addSequentSpace(config, left < 0 ? top : bottom, 0, 'left', Math.abs(left));
|
||||
addSequentSpace(config, right < 0 ? top : bottom, 2, 'right', Math.abs(right));
|
||||
}
|
||||
top = bottom;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares the top and bottom sequent of a inference rule
|
||||
* Top: A |- B
|
||||
* ----------
|
||||
* Bottom: C |- D
|
||||
*
|
||||
* @param {MmlNode} top Top sequent.
|
||||
* @param {MmlNode} bottom Bottom sequent.
|
||||
* @return {[number, number]} The delta for left and right side of the sequents.
|
||||
*/
|
||||
const compareSequents = function(top: MmlNode, bottom: MmlNode): [number, number] {
|
||||
const tr = getBBox(top.childNodes[2] as MmlNode);
|
||||
const br = getBBox(bottom.childNodes[2] as MmlNode);
|
||||
const tl = getBBox(top.childNodes[0] as MmlNode);
|
||||
const bl = getBBox(bottom.childNodes[0] as MmlNode);
|
||||
// Deltas
|
||||
const dl = tl - bl;
|
||||
const dr = tr - br;
|
||||
return [dl, dr];
|
||||
};
|
||||
|
||||
// For every inference rule we adjust the width of ruler by subtracting and
|
||||
// adding suitable spaces around the rule. The algorithm in detail.
|
||||
//
|
||||
// Notions that we need:
|
||||
//
|
||||
//
|
||||
// * Inference: The inference consisting either of an inference rule or a
|
||||
// structure containing the rule plus 0 - 2 labels and spacing
|
||||
// elements. s l{0,1} t r{0,1} s', m,n \in IN_0
|
||||
//
|
||||
// Technically this is realised as nested rows, if the spaces
|
||||
// and/or labels exist:
|
||||
// mr s mr l t r /mr s' /mr
|
||||
//
|
||||
// * InferenceRule: The rule without the labels and spacing.
|
||||
//
|
||||
// * Conclusion: The element forming the conclusion of the rule. In
|
||||
// downwards inferences this is the final row of the table.
|
||||
//
|
||||
// * Premises: The premises of the rule. In downwards inferences this is the
|
||||
// first row of the rule. Note that this is a rule itself,
|
||||
// with one column for each premise and an empty column
|
||||
// inbetween.
|
||||
//
|
||||
// * |x|: Width of bounding box of element x.
|
||||
//
|
||||
// Left adjustment:
|
||||
//
|
||||
// * For the given inference I:
|
||||
// + compute rule R of I
|
||||
// + compute premises P of I
|
||||
// + compute premise P_f, P_l as first and last premise of I
|
||||
//
|
||||
// * If P_f is an inference rule:
|
||||
// + compute adjust value a_f for wrapper W_f of P_f
|
||||
// + add -a_f space to wrapper W_f
|
||||
// + add a_f space to wrapper W
|
||||
//
|
||||
// * If P_l is an inference rule:
|
||||
// + compute adjust value a_l for wrapper W_l of P_l
|
||||
// + if I has (right) label L: a_l = a_l + |L|
|
||||
// + add -a_l space to P_l
|
||||
// + a_l = max(a_l, A_I), where A_I is saved ajust value in the
|
||||
// "maxAdjust" attribute of I.
|
||||
//
|
||||
// + Case I is proof: Add a_l space to inf. (Correct after proof.)
|
||||
// + Case I has sibling: Add a_l space to sibling. (Correct after column.)
|
||||
// + Otherwise: Propagate a_l by
|
||||
// ++ find direct parent infererence rule I'
|
||||
// ++ Set A_{I'} = a_l.
|
||||
//
|
||||
/**
|
||||
* Implements the above algorithm.
|
||||
* @param {FilterData} arg The parser configuration and mathitem to filter.
|
||||
*/
|
||||
export let balanceRules = function(arg: FilterData) {
|
||||
item = new arg.document.options.MathItem('', null, arg.math.display);
|
||||
let config = arg.data;
|
||||
adjustSequents(config);
|
||||
let inferences = config.nodeLists['inference'] || [];
|
||||
for (let inf of inferences) {
|
||||
let isProof = getProperty(inf, 'proof');
|
||||
// This currently only works with downwards rules.
|
||||
let rule = getRule(inf);
|
||||
let premises = getPremises(rule, getProperty(rule, 'inferenceRule') as string);
|
||||
let premiseF = firstPremise(premises);
|
||||
if (getProperty(premiseF, 'inference')) {
|
||||
let adjust = adjustValue(premiseF);
|
||||
if (adjust) {
|
||||
addSpace(config, premiseF, -adjust);
|
||||
let w = getSpaces(inf, rule, false);
|
||||
addSpace(config, inf, adjust - w);
|
||||
}
|
||||
}
|
||||
// Right adjust:
|
||||
let premiseL = lastPremise(premises);
|
||||
if (getProperty(premiseL, 'inference') == null) {
|
||||
continue;
|
||||
}
|
||||
let adjust = adjustValue(premiseL, true);
|
||||
addSpace(config, premiseL, -adjust, true);
|
||||
let w = getSpaces(inf, rule, true);
|
||||
let maxAdjust = getProperty(inf, 'maxAdjust') as number;
|
||||
if (maxAdjust != null) {
|
||||
adjust = Math.max(adjust, maxAdjust);
|
||||
}
|
||||
let column: MmlNode;
|
||||
if (isProof || !(column = getColumn(inf))) {
|
||||
// After the tree we add a space with the accumulated max value.
|
||||
// If the element is not in a column, we know we have some noise and the
|
||||
// proof is an mrow around the final inference.
|
||||
addSpace(config,
|
||||
// in case the rule has been moved into an mrow in Left Adjust.
|
||||
getProperty(inf, 'proof') ? inf : inf.parent, adjust - w, true);
|
||||
continue;
|
||||
}
|
||||
let sibling = nextSibling(column);
|
||||
if (sibling) {
|
||||
// If there is a next column, it is the empty one and we make it wider by
|
||||
// the accumulated max value.
|
||||
const pos = config.nodeFactory.create('node', 'mspace', [],
|
||||
{width: adjust - w + 'em'});
|
||||
sibling.appendChild(pos);
|
||||
inf.removeProperty('maxAdjust');
|
||||
continue;
|
||||
}
|
||||
let parentRule = getParentInf(column);
|
||||
if (!parentRule) {
|
||||
continue;
|
||||
}
|
||||
// We are currently in rightmost inference, so we propagate the max
|
||||
// correction value up in the tree.
|
||||
adjust = getProperty(parentRule, 'maxAdjust') ?
|
||||
Math.max(getProperty(parentRule, 'maxAdjust') as number, adjust) : adjust;
|
||||
setProperty(parentRule, 'maxAdjust', adjust);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Facilities for semantically relevant properties. These are used by SRE and
|
||||
* are always prefixed with bspr_.
|
||||
*/
|
||||
let property_prefix = 'bspr_';
|
||||
let blacklistedProperties = {
|
||||
[property_prefix + 'maxAdjust']: true
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets a bussproofs property used for postprocessing and to convey
|
||||
* semantics. Uses the bspr prefix.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {string} property The property to set.
|
||||
* @param {Property} value Its value.
|
||||
*/
|
||||
export let setProperty = function(node: MmlNode, property: string, value: Property) {
|
||||
NodeUtil.setProperty(node, property_prefix + property, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets a bussproofs property.
|
||||
* @param {MmlNode} node The node.
|
||||
* @param {string} property The property to retrieve.
|
||||
* @return {Property} The property object.
|
||||
*/
|
||||
export let getProperty = function(node: MmlNode, property: string): Property {
|
||||
return NodeUtil.getProperty(node, property_prefix + property);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a bussproofs property.
|
||||
* @param {MmlNode} node
|
||||
* @param {string} property
|
||||
*/
|
||||
export let removeProperty = function(node: MmlNode, property: string) {
|
||||
node.removeProperty(property_prefix + property);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Postprocessor that adds properties as attributes to the nodes, unless they
|
||||
* are blacklisted.
|
||||
* @param {FilterData} arg The object to post-process.
|
||||
*/
|
||||
export let makeBsprAttributes = function(arg: FilterData) {
|
||||
arg.data.root.walkTree((mml: MmlNode, _data?: any) => {
|
||||
let attr: string[] = [];
|
||||
mml.getPropertyNames().forEach(x => {
|
||||
if (!blacklistedProperties[x] && x.match(RegExp('^' + property_prefix))) {
|
||||
attr.push(x + ':' + mml.getProperty(x));
|
||||
}
|
||||
});
|
||||
if (attr.length) {
|
||||
NodeUtil.setAttribute(mml, 'semantics', attr.join(';'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Preprocessor that sets the document and jax for bounding box computations
|
||||
* @param {FilterData} arg The object to pre-process.
|
||||
*/
|
||||
export let saveDocument = function (arg: FilterData) {
|
||||
doc = arg.document;
|
||||
if (!('getBBox' in doc.outputJax)) {
|
||||
throw Error('The bussproofs extension requires an output jax with a getBBox() method');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the document when we are done
|
||||
* @param {FilterData} arg The object to pre-process.
|
||||
*/
|
||||
export let clearDocument = function (_arg: FilterData) {
|
||||
doc = null;
|
||||
};
|
||||
87
node_modules/mathjax-full/ts/input/tex/cancel/CancelConfiguration.ts
generated
vendored
Normal file
87
node_modules/mathjax-full/ts/input/tex/cancel/CancelConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the cancel package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import {ENCLOSE_OPTIONS} from '../enclose/EncloseConfiguration.js';
|
||||
|
||||
|
||||
// Namespace
|
||||
export let CancelMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
|
||||
/**
|
||||
* Parse function for cancel macros of the form \(b|x)?cancel[attributes]{math}
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the calling macro.
|
||||
* @param {string} notation The type of cancel notation to use.
|
||||
*/
|
||||
CancelMethods.Cancel = function(parser: TexParser, name: string, notation: string) {
|
||||
const attr = parser.GetBrackets(name, '');
|
||||
const math = parser.ParseArg(name);
|
||||
const def = ParseUtil.keyvalOptions(attr, ENCLOSE_OPTIONS);
|
||||
def['notation'] = notation;
|
||||
parser.Push(parser.create('node', 'menclose', [math], def));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parse function implementing \cancelto{value}[attributes]{math}
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the calling macro.
|
||||
*/
|
||||
|
||||
CancelMethods.CancelTo = function(parser: TexParser, name: string) {
|
||||
const attr = parser.GetBrackets(name, '');
|
||||
let value = parser.ParseArg(name);
|
||||
const math = parser.ParseArg(name);
|
||||
const def = ParseUtil.keyvalOptions(attr, ENCLOSE_OPTIONS);
|
||||
def ['notation'] = [TexConstant.Notation.UPDIAGONALSTRIKE,
|
||||
TexConstant.Notation.UPDIAGONALARROW,
|
||||
TexConstant.Notation.NORTHEASTARROW].join(' ');
|
||||
value = parser.create('node', 'mpadded', [value],
|
||||
{depth: '-.1em', height: '+.1em', voffset: '.1em'});
|
||||
parser.Push(parser.create('node', 'msup',
|
||||
[parser.create('node', 'menclose', [math], def), value]));
|
||||
};
|
||||
|
||||
|
||||
new CommandMap('cancel', {
|
||||
cancel: ['Cancel', TexConstant.Notation.UPDIAGONALSTRIKE],
|
||||
bcancel: ['Cancel', TexConstant.Notation.DOWNDIAGONALSTRIKE],
|
||||
xcancel: ['Cancel', TexConstant.Notation.UPDIAGONALSTRIKE + ' ' +
|
||||
TexConstant.Notation.DOWNDIAGONALSTRIKE],
|
||||
cancelto: 'CancelTo'
|
||||
}, CancelMethods);
|
||||
|
||||
|
||||
export const CancelConfiguration = Configuration.create(
|
||||
'cancel', {handler: {macro: ['cancel']}}
|
||||
);
|
||||
|
||||
|
||||
212
node_modules/mathjax-full/ts/input/tex/cases/CasesConfiguration.ts
generated
vendored
Normal file
212
node_modules/mathjax-full/ts/input/tex/cases/CasesConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {EnvironmentMap, MacroMap} from '../SymbolMap.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import BaseMethods from '../base/BaseMethods.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import TexError from '../TexError.js';
|
||||
import {BeginItem, EqnArrayItem} from '../base/BaseItems.js';
|
||||
import {AmsTags} from '../ams/AmsConfiguration.js';
|
||||
import {StackItem, CheckType} from '../StackItem.js';
|
||||
import {MmlMtable} from '../../../core/MmlTree/MmlNodes/mtable.js';
|
||||
import {EmpheqUtil} from '../empheq/EmpheqUtil.js';
|
||||
|
||||
/**
|
||||
* The StackItem for the numcases environment.
|
||||
*/
|
||||
export class CasesBeginItem extends BeginItem {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
get kind() {
|
||||
return 'cases-begin';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public checkItem(item: StackItem) {
|
||||
if (item.isKind('end') && item.getName() === this.getName()) {
|
||||
if (this.getProperty('end')) {
|
||||
this.setProperty('end', false);
|
||||
return [[], true] as CheckType;
|
||||
}
|
||||
}
|
||||
return super.checkItem(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A tagging class for the subnumcases environment.
|
||||
*/
|
||||
export class CasesTags extends AmsTags {
|
||||
|
||||
/**
|
||||
* The counter for the subnumber.
|
||||
*/
|
||||
protected subcounter = 0;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public start(env: string, taggable: boolean, defaultTags: boolean) {
|
||||
this.subcounter = 0;
|
||||
super.start(env, taggable, defaultTags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public autoTag() {
|
||||
if (this.currentTag.tag != null) return;
|
||||
if (this.currentTag.env === 'subnumcases') {
|
||||
if (this.subcounter === 0) this.counter++;
|
||||
this.subcounter++;
|
||||
this.tag(this.formatNumber(this.counter, this.subcounter), false);
|
||||
} else {
|
||||
if (this.subcounter === 0 || this.currentTag.env !== 'numcases-left') this.counter++;
|
||||
this.tag(this.formatNumber(this.counter), false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public formatNumber(n: number, m: number = null) {
|
||||
return n.toString() + (m === null ? '' : String.fromCharCode(0x60 + m));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const CasesMethods = {
|
||||
|
||||
/**
|
||||
* Implements the numcases environment.
|
||||
*
|
||||
* @param {TexParser} texparser The active tex parser.
|
||||
* @param {CasesBeginItem} begin The environment begin item.
|
||||
*/
|
||||
NumCases(parser: TexParser, begin: CasesBeginItem) {
|
||||
if (parser.stack.env.closing === begin.getName()) {
|
||||
delete parser.stack.env.closing;
|
||||
parser.Push(parser.itemFactory.create('end').setProperty('name', begin.getName())); // finish eqnarray
|
||||
const cases = parser.stack.Top();
|
||||
const table = cases.Last as MmlMtable;
|
||||
const original = ParseUtil.copyNode(table, parser) as MmlMtable;
|
||||
const left = cases.getProperty('left');
|
||||
EmpheqUtil.left(table, original, left + '\\empheqlbrace\\,', parser, 'numcases-left');
|
||||
parser.Push(parser.itemFactory.create('end').setProperty('name', begin.getName()));
|
||||
return null;
|
||||
} else {
|
||||
const left = parser.GetArgument('\\begin{' + begin.getName() + '}');
|
||||
begin.setProperty('left', left);
|
||||
const array = BaseMethods.EqnArray(parser, begin, true, true, 'll', ) as EqnArrayItem;
|
||||
array.arraydef.displaystyle = false;
|
||||
array.arraydef.rowspacing = '.2em';
|
||||
array.setProperty('numCases', true);
|
||||
parser.Push(begin);
|
||||
return array;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Replacement for & in cases environment.
|
||||
*/
|
||||
Entry(parser: TexParser, name: string) {
|
||||
if (!parser.stack.Top().getProperty('numCases')) {
|
||||
return BaseMethods.Entry(parser, name);
|
||||
}
|
||||
parser.Push(parser.itemFactory.create('cell').setProperties({isEntry: true, name: name}));
|
||||
//
|
||||
// Make second column be in \text{...}
|
||||
//
|
||||
const tex = parser.string;
|
||||
let braces = 0, i = parser.i, m = tex.length;
|
||||
//
|
||||
// Look through the string character by character...
|
||||
//
|
||||
while (i < m) {
|
||||
const c = tex.charAt(i);
|
||||
if (c === '{') {
|
||||
//
|
||||
// Increase the nested brace count and go on
|
||||
//
|
||||
braces++;
|
||||
i++;
|
||||
} else if (c === '}') {
|
||||
//
|
||||
// If there are too many close braces, just end (we will get an
|
||||
// error message later when the rest of the string is parsed)
|
||||
// Otherwise
|
||||
// decrease the nested brace count,
|
||||
// go on to the next character.
|
||||
//
|
||||
if (braces === 0) {
|
||||
break;
|
||||
} else {
|
||||
braces--;
|
||||
i++;
|
||||
}
|
||||
} else if (c === '&' && braces === 0) {
|
||||
//
|
||||
// Extra alignment tabs are not allowed in cases
|
||||
//
|
||||
throw new TexError('ExtraCasesAlignTab', 'Extra alignment tab in text for numcase environment');
|
||||
} else if (c === '\\' && braces === 0) {
|
||||
//
|
||||
// If the macro is \cr or \\, end the search, otherwise skip the macro
|
||||
// (multi-letter names don't matter, as we will skip the rest of the
|
||||
// characters in the main loop)
|
||||
//
|
||||
const cs = (tex.slice(i + 1).match(/^[a-z]+|./i) || [])[0];
|
||||
if (cs === '\\' || cs === 'cr' || cs === 'end' || cs === 'label') {
|
||||
break;
|
||||
} else {
|
||||
i += cs.length;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Go on to the next character
|
||||
//
|
||||
i++;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Process the second column as text and continue parsing from there,
|
||||
//
|
||||
const text = tex.substr(parser.i, i - parser.i).replace(/^\s*/, '');
|
||||
parser.PushAll(ParseUtil.internalMath(parser, text, 0));
|
||||
parser.i = i;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The environments for this package
|
||||
*/
|
||||
new EnvironmentMap('cases-env', EmpheqUtil.environment, {
|
||||
numcases: ['NumCases', 'cases'],
|
||||
subnumcases: ['NumCases', 'cases']
|
||||
}, CasesMethods);
|
||||
|
||||
/**
|
||||
* The macros for this package
|
||||
*/
|
||||
new MacroMap('cases-macros', {
|
||||
'&': 'Entry'
|
||||
}, CasesMethods);
|
||||
|
||||
//
|
||||
// Define the package for our new environment
|
||||
//
|
||||
export const CasesConfiguration = Configuration.create('cases', {
|
||||
handler: {
|
||||
environment: ['cases-env'],
|
||||
character: ['cases-macros']
|
||||
},
|
||||
items: {
|
||||
[CasesBeginItem.prototype.kind]: CasesBeginItem
|
||||
},
|
||||
tags: {'cases': CasesTags}
|
||||
});
|
||||
81
node_modules/mathjax-full/ts/input/tex/centernot/CenternotConfiguration.ts
generated
vendored
Normal file
81
node_modules/mathjax-full/ts/input/tex/centernot/CenternotConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2021-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the centernot package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import ParseOptions from '../ParseOptions.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
import BaseMethods from '../base/BaseMethods.js';
|
||||
|
||||
new CommandMap('centernot', {
|
||||
centerOver: 'CenterOver',
|
||||
centernot: ['Macro', '\\centerOver{#1}{{\u29F8}}', 1]
|
||||
}, {
|
||||
/**
|
||||
* Implements \centerOver{base}{symbol}
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} name The name of the macro being processed.
|
||||
*/
|
||||
CenterOver(parser: TexParser, name: string) {
|
||||
const arg = '{' + parser.GetArgument(name) + '}';
|
||||
const over = parser.ParseArg(name);
|
||||
const base = new TexParser(arg, parser.stack.env, parser.configuration).mml();
|
||||
let mml = parser.create('node', 'TeXAtom', [
|
||||
new TexParser(arg, parser.stack.env, parser.configuration).mml(),
|
||||
parser.create('node', 'mpadded', [
|
||||
parser.create('node', 'mpadded', [over], {width: 0, lspace: '-.5width'}),
|
||||
parser.create('node', 'mphantom', [base])
|
||||
], {width: 0, lspace: '-.5width'})
|
||||
]);
|
||||
parser.configuration.addNode('centerOver', base);
|
||||
parser.Push(mml);
|
||||
},
|
||||
Macro: BaseMethods.Macro
|
||||
});
|
||||
|
||||
/**
|
||||
* Filter to copy texClass to the surrounding TeXAtom so that the negated
|
||||
* item has the same class of the base.
|
||||
*
|
||||
* @param {ParseOptions} data The active tex parser.
|
||||
*/
|
||||
export function filterCenterOver({data}: {data: ParseOptions}) {
|
||||
for (const base of data.getList('centerOver')) {
|
||||
const texClass = NodeUtil.getTexClass(base.childNodes[0].childNodes[0] as MmlNode);
|
||||
if (texClass !== null) {
|
||||
NodeUtil.setProperties(base.parent.parent.parent.parent.parent.parent, {texClass});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const CenternotConfiguration = Configuration.create(
|
||||
'centernot', {
|
||||
handler: {macro: ['centernot']},
|
||||
postprocessors: [filterCenterOver]
|
||||
}
|
||||
);
|
||||
68
node_modules/mathjax-full/ts/input/tex/color/ColorConfiguration.ts
generated
vendored
Normal file
68
node_modules/mathjax-full/ts/input/tex/color/ColorConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 Omar Al-Ithawi and The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the color package.
|
||||
*
|
||||
* @author i@omardo.com (Omar Al-Ithawi)
|
||||
*/
|
||||
|
||||
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {Configuration, ParserConfiguration} from '../Configuration.js';
|
||||
import {ColorMethods} from './ColorMethods.js';
|
||||
import {ColorModel} from './ColorUtil.js';
|
||||
import {TeX} from '../../tex.js';
|
||||
|
||||
/**
|
||||
* The color macros
|
||||
*/
|
||||
new CommandMap('color', {
|
||||
color: 'Color',
|
||||
textcolor: 'TextColor',
|
||||
definecolor: 'DefineColor',
|
||||
colorbox: 'ColorBox',
|
||||
fcolorbox: 'FColorBox'
|
||||
}, ColorMethods);
|
||||
|
||||
/**
|
||||
* Config method for Color package.
|
||||
*
|
||||
* @param {Configuration} config The current configuration.
|
||||
* @param {TeX} jax The TeX jax having that configuration
|
||||
*/
|
||||
const config = function(_config: ParserConfiguration, jax: TeX<any, any, any>) {
|
||||
jax.parseOptions.packageData.set('color', {model: new ColorModel()});
|
||||
};
|
||||
|
||||
/**
|
||||
* The configuration for the color macros
|
||||
*/
|
||||
export const ColorConfiguration = Configuration.create(
|
||||
'color', {
|
||||
handler: {
|
||||
macro: ['color'],
|
||||
},
|
||||
options: {
|
||||
color: {
|
||||
padding: '5px',
|
||||
borderWidth: '2px'
|
||||
}
|
||||
},
|
||||
config: config
|
||||
}
|
||||
);
|
||||
93
node_modules/mathjax-full/ts/input/tex/color/ColorConstants.ts
generated
vendored
Normal file
93
node_modules/mathjax-full/ts/input/tex/color/ColorConstants.ts
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 Omar Al-Ithawi and The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Constants file for the color package.
|
||||
*
|
||||
* @author i@omardo.com (Omar Al-Ithawi)
|
||||
*/
|
||||
|
||||
export const COLORS: Map<string, string> = new Map<string, string>([
|
||||
['Apricot', '#FBB982'],
|
||||
['Aquamarine', '#00B5BE'],
|
||||
['Bittersweet', '#C04F17'],
|
||||
['Black', '#221E1F'],
|
||||
['Blue', '#2D2F92'],
|
||||
['BlueGreen', '#00B3B8'],
|
||||
['BlueViolet', '#473992'],
|
||||
['BrickRed', '#B6321C'],
|
||||
['Brown', '#792500'],
|
||||
['BurntOrange', '#F7921D'],
|
||||
['CadetBlue', '#74729A'],
|
||||
['CarnationPink', '#F282B4'],
|
||||
['Cerulean', '#00A2E3'],
|
||||
['CornflowerBlue', '#41B0E4'],
|
||||
['Cyan', '#00AEEF'],
|
||||
['Dandelion', '#FDBC42'],
|
||||
['DarkOrchid', '#A4538A'],
|
||||
['Emerald', '#00A99D'],
|
||||
['ForestGreen', '#009B55'],
|
||||
['Fuchsia', '#8C368C'],
|
||||
['Goldenrod', '#FFDF42'],
|
||||
['Gray', '#949698'],
|
||||
['Green', '#00A64F'],
|
||||
['GreenYellow', '#DFE674'],
|
||||
['JungleGreen', '#00A99A'],
|
||||
['Lavender', '#F49EC4'],
|
||||
['LimeGreen', '#8DC73E'],
|
||||
['Magenta', '#EC008C'],
|
||||
['Mahogany', '#A9341F'],
|
||||
['Maroon', '#AF3235'],
|
||||
['Melon', '#F89E7B'],
|
||||
['MidnightBlue', '#006795'],
|
||||
['Mulberry', '#A93C93'],
|
||||
['NavyBlue', '#006EB8'],
|
||||
['OliveGreen', '#3C8031'],
|
||||
['Orange', '#F58137'],
|
||||
['OrangeRed', '#ED135A'],
|
||||
['Orchid', '#AF72B0'],
|
||||
['Peach', '#F7965A'],
|
||||
['Periwinkle', '#7977B8'],
|
||||
['PineGreen', '#008B72'],
|
||||
['Plum', '#92268F'],
|
||||
['ProcessBlue', '#00B0F0'],
|
||||
['Purple', '#99479B'],
|
||||
['RawSienna', '#974006'],
|
||||
['Red', '#ED1B23'],
|
||||
['RedOrange', '#F26035'],
|
||||
['RedViolet', '#A1246B'],
|
||||
['Rhodamine', '#EF559F'],
|
||||
['RoyalBlue', '#0071BC'],
|
||||
['RoyalPurple', '#613F99'],
|
||||
['RubineRed', '#ED017D'],
|
||||
['Salmon', '#F69289'],
|
||||
['SeaGreen', '#3FBC9D'],
|
||||
['Sepia', '#671800'],
|
||||
['SkyBlue', '#46C5DD'],
|
||||
['SpringGreen', '#C6DC67'],
|
||||
['Tan', '#DA9D76'],
|
||||
['TealBlue', '#00AEB3'],
|
||||
['Thistle', '#D883B7'],
|
||||
['Turquoise', '#00B4CE'],
|
||||
['Violet', '#58429B'],
|
||||
['VioletRed', '#EF58A0'],
|
||||
['White', '#FFFFFF'],
|
||||
['WildStrawberry', '#EE2967'],
|
||||
['Yellow', '#FFF200'],
|
||||
['YellowGreen', '#98CC70'],
|
||||
['YellowOrange', '#FAA21A'],
|
||||
]);
|
||||
156
node_modules/mathjax-full/ts/input/tex/color/ColorMethods.ts
generated
vendored
Normal file
156
node_modules/mathjax-full/ts/input/tex/color/ColorMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 Omar Al-Ithawi and The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Parse methods and helper functtions for the color package.
|
||||
*
|
||||
* @author i@omardo.com (Omar Al-Ithawi)
|
||||
*/
|
||||
|
||||
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import {PropertyList} from '../../../core/Tree/Node.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
|
||||
import {ColorModel} from './ColorUtil.js';
|
||||
|
||||
|
||||
/**
|
||||
* Build PropertyList from padding value.
|
||||
*
|
||||
* @param {string} colorPadding: Padding for \colorbox and \fcolorbox.
|
||||
* @return {PropertyList} The padding properties.
|
||||
*/
|
||||
function padding(colorPadding: string): PropertyList {
|
||||
const pad = `+${colorPadding}`;
|
||||
const unit = colorPadding.replace(/^.*?([a-z]*)$/, '$1');
|
||||
const pad2 = 2 * parseFloat(pad);
|
||||
return {
|
||||
width: `+${pad2}${unit}`,
|
||||
height: pad,
|
||||
depth: pad,
|
||||
lspace: colorPadding,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export const ColorMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
|
||||
/**
|
||||
* Override \color macro definition.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the control sequence.
|
||||
*/
|
||||
ColorMethods.Color = function (parser: TexParser, name: string) {
|
||||
const model = parser.GetBrackets(name, '');
|
||||
const colorDef = parser.GetArgument(name);
|
||||
const colorModel: ColorModel = parser.configuration.packageData.get('color').model;
|
||||
const color = colorModel.getColor(model, colorDef);
|
||||
|
||||
const style = parser.itemFactory.create('style')
|
||||
.setProperties({styles: { mathcolor: color }});
|
||||
parser.stack.env['color'] = color;
|
||||
|
||||
parser.Push(style);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Define the \textcolor macro.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the control sequence.
|
||||
*/
|
||||
ColorMethods.TextColor = function (parser: TexParser, name: string) {
|
||||
const model = parser.GetBrackets(name, '');
|
||||
const colorDef = parser.GetArgument(name);
|
||||
const colorModel: ColorModel = parser.configuration.packageData.get('color').model;
|
||||
const color = colorModel.getColor(model, colorDef);
|
||||
const old = parser.stack.env['color'];
|
||||
|
||||
parser.stack.env['color'] = color;
|
||||
const math = parser.ParseArg(name);
|
||||
|
||||
if (old) {
|
||||
parser.stack.env['color'] = old;
|
||||
} else {
|
||||
delete parser.stack.env['color'];
|
||||
}
|
||||
|
||||
const node = parser.create('node', 'mstyle', [math], {mathcolor: color});
|
||||
parser.Push(node);
|
||||
};
|
||||
|
||||
/**
|
||||
* Define the \definecolor macro.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the control sequence.
|
||||
*/
|
||||
ColorMethods.DefineColor = function (parser: TexParser, name: string) {
|
||||
const cname = parser.GetArgument(name);
|
||||
const model = parser.GetArgument(name);
|
||||
const def = parser.GetArgument(name);
|
||||
|
||||
const colorModel: ColorModel = parser.configuration.packageData.get('color').model;
|
||||
colorModel.defineColor(model, cname, def);
|
||||
};
|
||||
|
||||
/**
|
||||
* Produce a text box with a colored background: `\colorbox`.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the control sequence.
|
||||
*/
|
||||
ColorMethods.ColorBox = function (parser: TexParser, name: string) {
|
||||
const cname = parser.GetArgument(name);
|
||||
const math = ParseUtil.internalMath(parser, parser.GetArgument(name));
|
||||
const colorModel: ColorModel = parser.configuration.packageData.get('color').model;
|
||||
|
||||
const node = parser.create('node', 'mpadded', math, {
|
||||
mathbackground: colorModel.getColor('named', cname)
|
||||
});
|
||||
|
||||
NodeUtil.setProperties(node, padding(parser.options.color.padding));
|
||||
parser.Push(node);
|
||||
};
|
||||
|
||||
/**
|
||||
* Produce a framed text box with a colored background: `\fcolorbox`.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the control sequence.
|
||||
*/
|
||||
ColorMethods.FColorBox = function (parser: TexParser, name: string) {
|
||||
const fname = parser.GetArgument(name);
|
||||
const cname = parser.GetArgument(name);
|
||||
const math = ParseUtil.internalMath(parser, parser.GetArgument(name));
|
||||
const options = parser.options.color;
|
||||
const colorModel: ColorModel = parser.configuration.packageData.get('color').model;
|
||||
|
||||
const node = parser.create('node', 'mpadded', math, {
|
||||
mathbackground: colorModel.getColor('named', cname),
|
||||
style: `border: ${options.borderWidth} solid ${colorModel.getColor('named', fname)}`
|
||||
});
|
||||
|
||||
NodeUtil.setProperties(node, padding(options.padding));
|
||||
parser.Push(node);
|
||||
};
|
||||
218
node_modules/mathjax-full/ts/input/tex/color/ColorUtil.ts
generated
vendored
Normal file
218
node_modules/mathjax-full/ts/input/tex/color/ColorUtil.ts
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 Omar Al-Ithawi and The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Utility functions and classes for the color package.
|
||||
*
|
||||
* @author i@omardo.com (Omar Al-Ithawi)
|
||||
*/
|
||||
|
||||
|
||||
import TexError from '../TexError.js';
|
||||
import {COLORS} from './ColorConstants.js';
|
||||
|
||||
type ColorModelProcessor = (def: string) => string;
|
||||
const ColorModelProcessors: Map<string, ColorModelProcessor> = new Map<string, ColorModelProcessor>();
|
||||
|
||||
|
||||
export class ColorModel {
|
||||
|
||||
/**
|
||||
* User defined colors.
|
||||
*
|
||||
* This variable is local to the parser, so two parsers in the same
|
||||
* JavaScript thread can have two different sets of user-defined colors.
|
||||
*/
|
||||
private userColors: Map<string, string> = new Map<string, string>();
|
||||
|
||||
/**
|
||||
* Converts a color model from string representation to its CSS format `#44ff00`
|
||||
*
|
||||
* @param {string} model The coloring model type: `rgb` `RGB` or `gray`.
|
||||
* @param {string} def The color definition: `0.5,0,1`, `128,0,255`, `0.5`.
|
||||
* @return {string} The color definition in CSS format e.g. `#44ff00`.
|
||||
*/
|
||||
private normalizeColor(model: string, def: string): string {
|
||||
if (!model || model === 'named') {
|
||||
// Allow to define colors directly by using the CSS format e.g. `#888`
|
||||
return def;
|
||||
}
|
||||
|
||||
if (ColorModelProcessors.has(model)) {
|
||||
const modelProcessor = ColorModelProcessors.get(model);
|
||||
return modelProcessor(def);
|
||||
}
|
||||
|
||||
throw new TexError('UndefinedColorModel', 'Color model \'%1\' not defined', model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a color based on its model and definition.
|
||||
*
|
||||
* @param {string} model The coloring model type: `named`, `rgb` `RGB` or `gray`.
|
||||
* @param {string} def The color definition: `red, `0.5,0,1`, `128,0,255`, `0.5`.
|
||||
* @return {string} The color definition in CSS format e.g. `#44ff00`.
|
||||
*/
|
||||
public getColor(model: string, def: string): string {
|
||||
if (!model || model === 'named') {
|
||||
return this.getColorByName(def);
|
||||
}
|
||||
|
||||
return this.normalizeColor(model, def);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a named color.
|
||||
*
|
||||
* @param {string} name The color name e.g. `darkblue`.
|
||||
* @return {string} The color definition in CSS format e.g. `#44ff00`.
|
||||
*
|
||||
* To retain backward compatilbity with MathJax v2 this method returns
|
||||
* unknown as-is, this is useful for both passing through CSS format colors like `#ff0`,
|
||||
* or even standard CSS color names that this plugin is unaware of.
|
||||
*
|
||||
* In TeX format, this would help to let `\textcolor{#f80}{\text{Orange}}` show an
|
||||
* orange word.
|
||||
*/
|
||||
private getColorByName(name: string): string {
|
||||
if (this.userColors.has(name)) {
|
||||
return this.userColors.get(name);
|
||||
}
|
||||
|
||||
if (COLORS.has(name)) {
|
||||
return COLORS.get(name);
|
||||
}
|
||||
|
||||
// Pass the color name as-is to CSS
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user-defined color.
|
||||
*
|
||||
* This color is local to the parser, so another MathJax parser won't be poluted.
|
||||
*
|
||||
* @param {string} model The coloring model type: e.g. `rgb`, `RGB` or `gray`.
|
||||
* @param {string} name The color name: `darkblue`.
|
||||
* @param {string} def The color definition in the color model format: `128,0,255`.
|
||||
*/
|
||||
public defineColor(model: string, name: string, def: string) {
|
||||
const normalized = this.normalizeColor(model, def);
|
||||
this.userColors.set(name, normalized);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an rgb color.
|
||||
*
|
||||
* @param {OptionList} parserOptions The parser options object.
|
||||
* @param {string} rgb The color definition in rgb: `0.5,0,1`.
|
||||
* @return {string} The color definition in CSS format e.g. `#44ff00`.
|
||||
*/
|
||||
ColorModelProcessors.set('rgb', function (rgb: string): string {
|
||||
const rgbParts: string[] = rgb.trim().split(/\s*,\s*/);
|
||||
let RGB: string = '#';
|
||||
|
||||
if (rgbParts.length !== 3) {
|
||||
throw new TexError('ModelArg1', 'Color values for the %1 model require 3 numbers', 'rgb');
|
||||
}
|
||||
|
||||
for (const rgbPart of rgbParts) {
|
||||
if (!rgbPart.match(/^(\d+(\.\d*)?|\.\d+)$/)) {
|
||||
throw new TexError('InvalidDecimalNumber', 'Invalid decimal number');
|
||||
}
|
||||
|
||||
const n = parseFloat(rgbPart);
|
||||
if (n < 0 || n > 1) {
|
||||
throw new TexError('ModelArg2',
|
||||
'Color values for the %1 model must be between %2 and %3',
|
||||
'rgb', '0', '1');
|
||||
}
|
||||
|
||||
let pn = Math.floor(n * 255).toString(16);
|
||||
if (pn.length < 2) {
|
||||
pn = '0' + pn;
|
||||
}
|
||||
|
||||
RGB += pn;
|
||||
}
|
||||
|
||||
return RGB;
|
||||
});
|
||||
|
||||
/**
|
||||
* Get an RGB color.
|
||||
*
|
||||
* @param {OptionList} parserOptions The parser options object.
|
||||
* @param {string} rgb The color definition in RGB: `128,0,255`.
|
||||
* @return {string} The color definition in CSS format e.g. `#44ff00`.
|
||||
*/
|
||||
ColorModelProcessors.set('RGB', function (rgb: string): string {
|
||||
const rgbParts: string[] = rgb.trim().split(/\s*,\s*/);
|
||||
let RGB = '#';
|
||||
|
||||
if (rgbParts.length !== 3) {
|
||||
throw new TexError('ModelArg1', 'Color values for the %1 model require 3 numbers', 'RGB');
|
||||
}
|
||||
|
||||
for (const rgbPart of rgbParts) {
|
||||
if (!rgbPart.match(/^\d+$/)) {
|
||||
throw new TexError('InvalidNumber', 'Invalid number');
|
||||
}
|
||||
|
||||
const n = parseInt(rgbPart);
|
||||
if (n > 255) {
|
||||
throw new TexError('ModelArg2',
|
||||
'Color values for the %1 model must be between %2 and %3',
|
||||
'RGB', '0', '255');
|
||||
}
|
||||
|
||||
let pn = n.toString(16);
|
||||
if (pn.length < 2) {
|
||||
pn = '0' + pn;
|
||||
}
|
||||
RGB += pn;
|
||||
}
|
||||
return RGB;
|
||||
});
|
||||
|
||||
/**
|
||||
* Get a gray-scale value.
|
||||
*
|
||||
* @param {OptionList} parserOptions The parser options object.
|
||||
* @param {string} gray The color definition in RGB: `0.5`.
|
||||
* @return {string} The color definition in CSS format e.g. `#808080`.
|
||||
*/
|
||||
ColorModelProcessors.set('gray', function (gray: string): string {
|
||||
if (!gray.match(/^\s*(\d+(\.\d*)?|\.\d+)\s*$/)) {
|
||||
throw new TexError('InvalidDecimalNumber', 'Invalid decimal number');
|
||||
}
|
||||
|
||||
const n: number = parseFloat(gray);
|
||||
if (n < 0 || n > 1) {
|
||||
throw new TexError('ModelArg2',
|
||||
'Color values for the %1 model must be between %2 and %3',
|
||||
'gray', '0', '1');
|
||||
}
|
||||
let pn = Math.floor(n * 255).toString(16);
|
||||
if (pn.length < 2) {
|
||||
pn = '0' + pn;
|
||||
}
|
||||
|
||||
return `#${pn}${pn}${pn}`;
|
||||
});
|
||||
177
node_modules/mathjax-full/ts/input/tex/colortbl/ColortblConfiguration.ts
generated
vendored
Normal file
177
node_modules/mathjax-full/ts/input/tex/colortbl/ColortblConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2021-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the colortbl package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {ArrayItem} from '../base/BaseItems.js';
|
||||
import {Configuration, ParserConfiguration, ConfigurationHandler} from '../Configuration.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import TexError from '../TexError.js';
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
|
||||
import {TeX} from '../../tex.js';
|
||||
|
||||
/**
|
||||
* Information about table colors.
|
||||
*/
|
||||
export interface ColorData {
|
||||
cell: string;
|
||||
row: string;
|
||||
col: string[];
|
||||
}
|
||||
|
||||
//
|
||||
// Sublcass the ArrayItem to handle colored entries
|
||||
//
|
||||
export class ColorArrayItem extends ArrayItem {
|
||||
/**
|
||||
* Store current color for cell, row, and columns.
|
||||
*/
|
||||
public color: ColorData = {
|
||||
cell: '',
|
||||
row: '',
|
||||
col: []
|
||||
};
|
||||
|
||||
/**
|
||||
* True if any cell is colored (we will make sure the edge cells are full sized).
|
||||
*/
|
||||
public hasColor: boolean = false;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public EndEntry() {
|
||||
super.EndEntry();
|
||||
const cell = this.row[this.row.length - 1];
|
||||
const color = this.color.cell || this.color.row || this.color.col[this.row.length - 1];
|
||||
if (color) {
|
||||
cell.attributes.set('mathbackground', color);
|
||||
this.color.cell = '';
|
||||
this.hasColor = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public EndRow() {
|
||||
super.EndRow();
|
||||
this.color.row = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public createMml() {
|
||||
//
|
||||
// If there is any color in the array, give it an empty frame,
|
||||
// if there isn't one already. This will make sure the color
|
||||
// in edge cells extends past their contents.
|
||||
//
|
||||
const mml = super.createMml();
|
||||
let table = (mml.isKind('mrow') ? mml.childNodes[1] : mml) as MmlNode;
|
||||
if (table.isKind('menclose')) {
|
||||
table = table.childNodes[0].childNodes[0] as MmlNode;
|
||||
}
|
||||
if (this.hasColor && table.attributes.get('frame') === 'none') {
|
||||
table.attributes.set('frame', '');
|
||||
}
|
||||
return mml;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Define macros for table coloring.
|
||||
//
|
||||
new CommandMap('colortbl', {
|
||||
cellcolor: ['TableColor', 'cell'],
|
||||
rowcolor: ['TableColor', 'row'],
|
||||
columncolor: ['TableColor', 'col']
|
||||
}, {
|
||||
/**
|
||||
* Add color to a column, row, or cell.
|
||||
*
|
||||
* @param {TexParser} parser The active TeX parser
|
||||
* @param {string} name The name of the macro that is being processed
|
||||
* @param {keyof ColorData} type The type (col, row, cell) of color being added
|
||||
*/
|
||||
TableColor(parser: TexParser, name: string, type: keyof ColorData) {
|
||||
const lookup = parser.configuration.packageData.get('color').model; // use the color extension's color model
|
||||
const model = parser.GetBrackets(name, '');
|
||||
const color = lookup.getColor(model, parser.GetArgument(name));
|
||||
//
|
||||
// Check that we are in a colorable array.
|
||||
//
|
||||
const top = parser.stack.Top() as ColorArrayItem;
|
||||
if (!(top instanceof ColorArrayItem)) {
|
||||
throw new TexError('UnsupportedTableColor', 'Unsupported use of %1', parser.currentCS);
|
||||
}
|
||||
//
|
||||
// Check the position of the macro and save the color.
|
||||
//
|
||||
if (type === 'col') {
|
||||
if (top.table.length) {
|
||||
throw new TexError('ColumnColorNotTop', '%1 must be in the top row', name);
|
||||
}
|
||||
top.color.col[top.row.length] = color;
|
||||
//
|
||||
// Ignore the left and right overlap options.
|
||||
//
|
||||
if (parser.GetBrackets(name, '')) {
|
||||
parser.GetBrackets(name, '');
|
||||
}
|
||||
} else {
|
||||
top.color[type] = color;
|
||||
if (type === 'row' && (top.Size() || top.row.length)) {
|
||||
throw new TexError('RowColorNotFirst', '%1 must be at the beginning of a row', name);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The configuration function for colortbl.
|
||||
*
|
||||
* @param {ParserConfiguration} config The configuration being used.
|
||||
* @param {Tex} jax The TeX jax using this configuration.
|
||||
*/
|
||||
const config = function (config: ParserConfiguration, jax: TeX<any, any, any>) {
|
||||
//
|
||||
// Make sure color is configured. (It doesn't have to be included in tex.packages.)
|
||||
//
|
||||
if (!jax.parseOptions.packageData.has('color')) {
|
||||
ConfigurationHandler.get('color').config(config, jax);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Create the color-table configuration.
|
||||
//
|
||||
export const ColortblConfiguration = Configuration.create('colortbl', {
|
||||
handler: {macro: ['colortbl']},
|
||||
items: {'array': ColorArrayItem}, // overrides original array class
|
||||
priority: 10, // make sure we are processed after the base package (to override its array)
|
||||
config: [config, 10] // make sure we configure after the color package, if it is used.
|
||||
});
|
||||
64
node_modules/mathjax-full/ts/input/tex/colorv2/ColorV2Configuration.ts
generated
vendored
Normal file
64
node_modules/mathjax-full/ts/input/tex/colorv2/ColorV2Configuration.ts
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the v2-compatible color package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
|
||||
export const ColorV2Methods: Record<string, ParseMethod> = {
|
||||
|
||||
/**
|
||||
* Implements the v2 color macro
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
Color(parser: TexParser, name: string) {
|
||||
// @test Color Frac
|
||||
const color = parser.GetArgument(name);
|
||||
const old = parser.stack.env['color'];
|
||||
parser.stack.env['color'] = color;
|
||||
const math = parser.ParseArg(name);
|
||||
if (old) {
|
||||
parser.stack.env['color'] = old;
|
||||
} else {
|
||||
delete parser.stack.env['color'];
|
||||
}
|
||||
const node = parser.create('node', 'mstyle', [math], {mathcolor: color});
|
||||
parser.Push(node);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The color macros
|
||||
*/
|
||||
new CommandMap('colorv2', {color: 'Color'}, ColorV2Methods);
|
||||
|
||||
/**
|
||||
* The configuration for the color macros
|
||||
*/
|
||||
export const ColorConfiguration = Configuration.create(
|
||||
'colorv2', {handler: {macro: ['colorv2']}}
|
||||
);
|
||||
119
node_modules/mathjax-full/ts/input/tex/configmacros/ConfigMacrosConfiguration.ts
generated
vendored
Normal file
119
node_modules/mathjax-full/ts/input/tex/configmacros/ConfigMacrosConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the configmacros package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {Configuration, ParserConfiguration} from '../Configuration.js';
|
||||
import {expandable} from '../../../util/Options.js';
|
||||
import {CommandMap, EnvironmentMap} from '../SymbolMap.js';
|
||||
import ParseMethods from '../ParseMethods.js';
|
||||
import {Macro} from '../Symbol.js';
|
||||
import NewcommandMethods from '../newcommand/NewcommandMethods.js';
|
||||
import {BeginEnvItem} from '../newcommand/NewcommandItems.js';
|
||||
import {TeX} from '../../tex.js';
|
||||
|
||||
type TEX = TeX<any, any, any>;
|
||||
|
||||
/**
|
||||
* The name to use for the macros map
|
||||
*/
|
||||
const MACROSMAP = 'configmacros-map';
|
||||
|
||||
/**
|
||||
* The name to use for the environment map
|
||||
*/
|
||||
const ENVIRONMENTMAP = 'configmacros-env-map';
|
||||
|
||||
/**
|
||||
* Create the command map for the macros
|
||||
*
|
||||
* @param {Configuration} config The configuration object for the input jax
|
||||
*/
|
||||
function configmacrosInit(config: ParserConfiguration) {
|
||||
new CommandMap(MACROSMAP, {}, {});
|
||||
new EnvironmentMap(ENVIRONMENTMAP, ParseMethods.environment, {}, {});
|
||||
config.append(Configuration.local({
|
||||
handler: {
|
||||
macro: [MACROSMAP],
|
||||
environment: [ENVIRONMENTMAP]
|
||||
},
|
||||
priority: 3
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the user-defined macros and environments from their options
|
||||
*
|
||||
* @param {Configuration} config The configuration object for the input jax
|
||||
* @param {TeX} jax The TeX input jax
|
||||
*/
|
||||
function configmacrosConfig(_config: ParserConfiguration, jax: TEX) {
|
||||
configMacros(jax);
|
||||
configEnvironments(jax);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create user-defined macros from the macros option
|
||||
*
|
||||
* @param {TeX} jax The TeX input jax
|
||||
*/
|
||||
function configMacros(jax: TEX) {
|
||||
const handler = jax.parseOptions.handlers.retrieve(MACROSMAP) as CommandMap;
|
||||
const macros = jax.parseOptions.options.macros;
|
||||
for (const cs of Object.keys(macros)) {
|
||||
const def = (typeof macros[cs] === 'string' ? [macros[cs]] : macros[cs]);
|
||||
const macro = Array.isArray(def[2]) ?
|
||||
new Macro(cs, NewcommandMethods.MacroWithTemplate, def.slice(0, 2).concat(def[2])) :
|
||||
new Macro(cs, NewcommandMethods.Macro, def);
|
||||
handler.add(cs, macro);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create user-defined environments from the environments option
|
||||
*
|
||||
* @param {TeX} jax The TeX input jax
|
||||
*/
|
||||
function configEnvironments(jax: TEX) {
|
||||
const handler = jax.parseOptions.handlers.retrieve(ENVIRONMENTMAP) as EnvironmentMap;
|
||||
const environments = jax.parseOptions.options.environments;
|
||||
for (const env of Object.keys(environments)) {
|
||||
handler.add(env, new Macro(env, NewcommandMethods.BeginEnv, [true].concat(environments[env])));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The configuration object for configmacros
|
||||
*/
|
||||
export const ConfigMacrosConfiguration = Configuration.create(
|
||||
'configmacros', {
|
||||
init: configmacrosInit,
|
||||
config: configmacrosConfig,
|
||||
items: {
|
||||
[BeginEnvItem.prototype.kind]: BeginEnvItem,
|
||||
},
|
||||
options: {
|
||||
macros: expandable({}),
|
||||
environments: expandable({})
|
||||
}
|
||||
}
|
||||
);
|
||||
180
node_modules/mathjax-full/ts/input/tex/empheq/EmpheqConfiguration.ts
generated
vendored
Normal file
180
node_modules/mathjax-full/ts/input/tex/empheq/EmpheqConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2021-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the empheq package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {CommandMap, EnvironmentMap} from '../SymbolMap.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import TexError from '../TexError.js';
|
||||
import {BeginItem} from '../base/BaseItems.js';
|
||||
import {StackItem} from '../StackItem.js';
|
||||
import {EmpheqUtil} from './EmpheqUtil.js';
|
||||
|
||||
/**
|
||||
* A StackItem for empheq environments.
|
||||
*/
|
||||
export class EmpheqBeginItem extends BeginItem {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public get kind() {
|
||||
return 'empheq-begin';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public checkItem(item: StackItem) {
|
||||
if (item.isKind('end') && item.getName() === this.getName()) {
|
||||
this.setProperty('end', false);
|
||||
}
|
||||
return super.checkItem(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The methods that implement the empheq package.
|
||||
*/
|
||||
export const EmpheqMethods = {
|
||||
|
||||
/**
|
||||
* Handle an empheq environment.
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {EmpheqBeginItem} begin The begin item for this environment.
|
||||
*/
|
||||
Empheq(parser: TexParser, begin: EmpheqBeginItem) {
|
||||
if (parser.stack.env.closing === begin.getName()) {
|
||||
delete parser.stack.env.closing;
|
||||
parser.Push(parser.itemFactory.create('end').setProperty('name', parser.stack.global.empheq));
|
||||
parser.stack.global.empheq = '';
|
||||
const empheq = parser.stack.Top() as EmpheqBeginItem;
|
||||
EmpheqUtil.adjustTable(empheq, parser);
|
||||
parser.Push(parser.itemFactory.create('end').setProperty('name', 'empheq'));
|
||||
} else {
|
||||
ParseUtil.checkEqnEnv(parser);
|
||||
delete parser.stack.global.eqnenv;
|
||||
const opts = parser.GetBrackets('\\begin{' + begin.getName() + '}') || '';
|
||||
const [env, n] = (parser.GetArgument('\\begin{' + begin.getName() + '}') || '').split(/=/);
|
||||
if (!EmpheqUtil.checkEnv(env)) {
|
||||
throw new TexError('UnknownEnv', 'Unknown environment "%1"', env);
|
||||
}
|
||||
if (opts) {
|
||||
begin.setProperties(EmpheqUtil.splitOptions(opts, {left: 1, right: 1}));
|
||||
}
|
||||
parser.stack.global.empheq = env;
|
||||
parser.string = '\\begin{' + env + '}' + (n ? '{' + n + '}' : '') + parser.string.slice(parser.i);
|
||||
parser.i = 0;
|
||||
parser.Push(begin);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Create an <mo> with a given content
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} name The name of the macro being processed.
|
||||
* @param {string} c The character for the <mo>
|
||||
*/
|
||||
EmpheqMO(parser: TexParser, _name: string, c: string) {
|
||||
parser.Push(parser.create('token', 'mo', {}, c));
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a delimiter <mo> with a given character
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} name The name of the macro being processed.
|
||||
*/
|
||||
EmpheqDelim(parser: TexParser, name: string) {
|
||||
const c = parser.GetDelimiter(name);
|
||||
parser.Push(parser.create('token', 'mo', {stretchy: true, symmetric: true}, c));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Define an environment map to add the new empheq environment
|
||||
//
|
||||
new EnvironmentMap('empheq-env', EmpheqUtil.environment, {
|
||||
empheq: ['Empheq', 'empheq'],
|
||||
}, EmpheqMethods);
|
||||
|
||||
//
|
||||
// Define the empheq characters
|
||||
//
|
||||
new CommandMap('empheq-macros', {
|
||||
empheqlbrace: ['EmpheqMO', '{'],
|
||||
empheqrbrace: ['EmpheqMO', '}'],
|
||||
empheqlbrack: ['EmpheqMO', '['],
|
||||
empheqrbrack: ['EmpheqMO', ']'],
|
||||
empheqlangle: ['EmpheqMO', '\u27E8'],
|
||||
empheqrangle: ['EmpheqMO', '\u27E9'],
|
||||
empheqlparen: ['EmpheqMO', '('],
|
||||
empheqrparen: ['EmpheqMO', ')'],
|
||||
empheqlvert: ['EmpheqMO', '|'],
|
||||
empheqrvert: ['EmpheqMO', '|'],
|
||||
empheqlVert: ['EmpheqMO', '\u2016'],
|
||||
empheqrVert: ['EmpheqMO', '\u2016'],
|
||||
empheqlfloor: ['EmpheqMO', '\u230A'],
|
||||
empheqrfloor: ['EmpheqMO', '\u230B'],
|
||||
empheqlceil: ['EmpheqMO', '\u2308'],
|
||||
empheqrceil: ['EmpheqMO', '\u2309'],
|
||||
empheqbiglbrace: ['EmpheqMO', '{'],
|
||||
empheqbigrbrace: ['EmpheqMO', '}'],
|
||||
empheqbiglbrack: ['EmpheqMO', '['],
|
||||
empheqbigrbrack: ['EmpheqMO', ']'],
|
||||
empheqbiglangle: ['EmpheqMO', '\u27E8'],
|
||||
empheqbigrangle: ['EmpheqMO', '\u27E9'],
|
||||
empheqbiglparen: ['EmpheqMO', '('],
|
||||
empheqbigrparen: ['EmpheqMO', ')'],
|
||||
empheqbiglvert: ['EmpheqMO', '|'],
|
||||
empheqbigrvert: ['EmpheqMO', '|'],
|
||||
empheqbiglVert: ['EmpheqMO', '\u2016'],
|
||||
empheqbigrVert: ['EmpheqMO', '\u2016'],
|
||||
empheqbiglfloor: ['EmpheqMO', '\u230A'],
|
||||
empheqbigrfloor: ['EmpheqMO', '\u230B'],
|
||||
empheqbiglceil: ['EmpheqMO', '\u2308'],
|
||||
empheqbigrceil: ['EmpheqMO', '\u2309'],
|
||||
empheql: 'EmpheqDelim',
|
||||
empheqr: 'EmpheqDelim',
|
||||
empheqbigl: 'EmpheqDelim',
|
||||
empheqbigr: 'EmpheqDelim'
|
||||
}, EmpheqMethods);
|
||||
|
||||
//
|
||||
// Define the package for our new environment
|
||||
//
|
||||
export const EmpheqConfiguration = Configuration.create('empheq', {
|
||||
handler: {
|
||||
macro: ['empheq-macros'],
|
||||
environment: ['empheq-env'],
|
||||
},
|
||||
items: {
|
||||
[EmpheqBeginItem.prototype.kind]: EmpheqBeginItem
|
||||
}
|
||||
});
|
||||
228
node_modules/mathjax-full/ts/input/tex/empheq/EmpheqUtil.ts
generated
vendored
Normal file
228
node_modules/mathjax-full/ts/input/tex/empheq/EmpheqUtil.ts
generated
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2021-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities file for the empheq package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {EnvList} from '../StackItem.js';
|
||||
import {AbstractTags} from '../Tags.js';
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
import {MmlMtable} from '../../../core/MmlTree/MmlNodes/mtable.js';
|
||||
import {MmlMtd} from '../../../core/MmlTree/MmlNodes/mtd.js';
|
||||
import {EmpheqBeginItem} from './EmpheqConfiguration.js';
|
||||
|
||||
export const EmpheqUtil = {
|
||||
|
||||
/**
|
||||
* Create the needed envinronment and process it by the give function.
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} env The environment to create.
|
||||
* @param {Function} func A function to process the environment.
|
||||
* @param {any[]} args The arguments for func.
|
||||
*/
|
||||
environment(parser: TexParser, env: string, func: Function, args: any[]) {
|
||||
const name = args[0];
|
||||
const item = parser.itemFactory.create(name + '-begin').setProperties({name: env, end: name});
|
||||
parser.Push(func(parser, item, ...args.slice(1)));
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse an options string.
|
||||
*
|
||||
* @param {string} text The string to parse.
|
||||
* @param {{[key:string]:number} allowed Object containing options to allow
|
||||
* @return {EnvList} The parsed keys
|
||||
*/
|
||||
splitOptions(text: string, allowed: {[key: string]: number} = null): EnvList {
|
||||
return ParseUtil.keyvalOptions(text, allowed, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Find the number of columns in the table.
|
||||
*
|
||||
* @param {MmlMtable} table The table whose columns to count.
|
||||
* @return {number} The number of columns in the table.
|
||||
*/
|
||||
columnCount(table: MmlMtable): number {
|
||||
let m = 0;
|
||||
for (const row of table.childNodes) {
|
||||
const n = row.childNodes.length - (row.isKind('mlabeledtr') ? 1 : 0);
|
||||
if (n > m) m = n;
|
||||
}
|
||||
return m;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create an mpadded element with no height and depth, but whose
|
||||
* content is the given TeX code with a phantom that is the height and
|
||||
* depth of the given table.
|
||||
*
|
||||
* @param {string} tex The TeX code to put in the box.
|
||||
* @param {MmlTable} table The table used to size the box.
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} env The name of the current environment.
|
||||
* @return {MmlNode} The mpadded element.
|
||||
*/
|
||||
cellBlock(tex: string, table: MmlMtable, parser: TexParser, env: string): MmlNode {
|
||||
const mpadded = parser.create('node', 'mpadded', [], {height: 0, depth: 0, voffset: '-1height'});
|
||||
const result = new TexParser(tex, parser.stack.env, parser.configuration);
|
||||
const mml = result.mml();
|
||||
if (env && result.configuration.tags.label) {
|
||||
(result.configuration.tags.currentTag as any).env = env;
|
||||
(result.configuration.tags as AbstractTags).getTag(true);
|
||||
}
|
||||
for (const child of (mml.isInferred ? mml.childNodes : [mml])) {
|
||||
mpadded.appendChild(child);
|
||||
}
|
||||
mpadded.appendChild(parser.create('node', 'mphantom', [
|
||||
parser.create('node', 'mpadded', [table], {width: 0})
|
||||
]));
|
||||
return mpadded;
|
||||
},
|
||||
|
||||
/**
|
||||
* Make a copy of the table with only the first row and create a phantom element
|
||||
* that has its height and depth.
|
||||
*
|
||||
* @param {MmlMtable} original The original table.
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @return {MmlNode} The resulting mphantom element.
|
||||
*/
|
||||
topRowTable(original: MmlMtable, parser: TexParser): MmlNode {
|
||||
const table = ParseUtil.copyNode(original, parser);
|
||||
table.setChildren(table.childNodes.slice(0, 1));
|
||||
table.attributes.set('align', 'baseline 1');
|
||||
return original.factory.create('mphantom', {}, [parser.create('node', 'mpadded', [table], {width: 0})]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add an mpadded element that has zero height and depth but whose content is
|
||||
* the cell block for the given TeX code followed by a struct the size of the top row.
|
||||
*
|
||||
* @param {MmlMtd} mtd The mtd to add content to.
|
||||
* @param {string} tex The TeX string to put into the cell.
|
||||
* @param {MmlMtable} table The reference table used for its various heights.
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {srting} env The current environment.
|
||||
*/
|
||||
rowspanCell(mtd: MmlMtd, tex: string, table: MmlMtable, parser: TexParser, env: string) {
|
||||
mtd.appendChild(
|
||||
parser.create('node', 'mpadded', [
|
||||
this.cellBlock(tex, ParseUtil.copyNode(table, parser), parser, env),
|
||||
this.topRowTable(table, parser)
|
||||
], {height: 0, depth: 0, voffset: 'height'})
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add something on the left of the original table.
|
||||
*
|
||||
* @param {MmlMtable} table The table to modify.
|
||||
* @param {MmlMtable} original The original table.
|
||||
* @param {string} left The TeX code to add to the left.
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} env The current environment.
|
||||
*/
|
||||
left(table: MmlMtable, original: MmlMtable, left: string, parser: TexParser, env: string = '') {
|
||||
table.attributes.set('columnalign', 'right ' + (table.attributes.get('columnalign') || ''));
|
||||
table.attributes.set('columnspacing', '0em ' + (table.attributes.get('columnspacing') || ''));
|
||||
let mtd;
|
||||
for (const row of table.childNodes.slice(0).reverse()) {
|
||||
mtd = parser.create('node', 'mtd');
|
||||
row.childNodes.unshift(mtd);
|
||||
mtd.parent = row;
|
||||
if (row.isKind('mlabeledtr')) {
|
||||
row.childNodes[0] = row.childNodes[1];
|
||||
row.childNodes[1] = mtd;
|
||||
}
|
||||
}
|
||||
this.rowspanCell(mtd, left, original, parser, env);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add something on the right of the original table.
|
||||
*
|
||||
* @param {MmlMtable} table The table to modify.
|
||||
* @param {MmlMtable} original The original table.
|
||||
* @param {string} right The TeX code to add to the right.
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} env The current environment.
|
||||
*/
|
||||
right(table: MmlMtable, original: MmlMtable, right: string, parser: TexParser, env: string = '') {
|
||||
if (table.childNodes.length === 0) {
|
||||
table.appendChild(parser.create('node', 'mtr'));
|
||||
}
|
||||
const m = EmpheqUtil.columnCount(table);
|
||||
const row = table.childNodes[0];
|
||||
while (row.childNodes.length < m) row.appendChild(parser.create('node', 'mtd'));
|
||||
const mtd = row.appendChild(parser.create('node', 'mtd')) as MmlMtd;
|
||||
EmpheqUtil.rowspanCell(mtd, right, original, parser, env);
|
||||
table.attributes.set(
|
||||
'columnalign',
|
||||
(table.attributes.get('columnalign') as string || '').split(/ /).slice(0, m).join(' ') + ' left'
|
||||
);
|
||||
table.attributes.set(
|
||||
'columnspacing',
|
||||
(table.attributes.get('columnspacing') as string || '').split(/ /).slice(0, m - 1).join(' ') + ' 0em'
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add the left- and right-hand material to the table.
|
||||
*/
|
||||
adjustTable(empheq: EmpheqBeginItem, parser: TexParser) {
|
||||
const left = empheq.getProperty('left');
|
||||
const right = empheq.getProperty('right');
|
||||
if (left || right) {
|
||||
const table = empheq.Last;
|
||||
const original = ParseUtil.copyNode(table, parser);
|
||||
if (left) this.left(table, original, left, parser);
|
||||
if (right) this.right(table, original, right, parser);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The environments allowed to be used in the empheq environment.
|
||||
*/
|
||||
allowEnv: {
|
||||
equation: true,
|
||||
align: true,
|
||||
gather: true,
|
||||
flalign: true,
|
||||
alignat: true,
|
||||
multline: true
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks to see if the given environment is one of the allowed ones.
|
||||
*
|
||||
* @param {string} env The environment to check.
|
||||
* @return {boolean} True if the environment is allowed.
|
||||
*/
|
||||
checkEnv(env: string): boolean {
|
||||
return this.allowEnv.hasOwnProperty(env.replace(/\*$/, '')) || false;
|
||||
}
|
||||
|
||||
};
|
||||
74
node_modules/mathjax-full/ts/input/tex/enclose/EncloseConfiguration.ts
generated
vendored
Normal file
74
node_modules/mathjax-full/ts/input/tex/enclose/EncloseConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the enclose package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes allowed in \enclose{notation}[attributes]{math}
|
||||
* @type {{[key: string]: number}}
|
||||
*/
|
||||
export const ENCLOSE_OPTIONS: {[key: string]: number} = {
|
||||
'data-arrowhead': 1,
|
||||
color: 1,
|
||||
mathcolor: 1,
|
||||
background: 1,
|
||||
mathbackground: 1,
|
||||
'data-padding': 1,
|
||||
'data-thickness': 1
|
||||
};
|
||||
|
||||
|
||||
// Namespace
|
||||
export let EncloseMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
|
||||
/**
|
||||
* Implements \enclose{notation}[attr]{math}
|
||||
* (create <menclose notation="notation">math</menclose>)
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the calling macro.
|
||||
*/
|
||||
EncloseMethods.Enclose = function(parser: TexParser, name: string) {
|
||||
let notation = parser.GetArgument(name).replace(/,/g, ' ');
|
||||
const attr = parser.GetBrackets(name, '');
|
||||
const math = parser.ParseArg(name);
|
||||
const def = ParseUtil.keyvalOptions(attr, ENCLOSE_OPTIONS);
|
||||
def.notation = notation;
|
||||
parser.Push(parser.create('node', 'menclose', [math], def));
|
||||
};
|
||||
|
||||
|
||||
new CommandMap('enclose', {enclose: 'Enclose'}, EncloseMethods);
|
||||
|
||||
|
||||
export const EncloseConfiguration = Configuration.create(
|
||||
'enclose', {handler: {macro: ['enclose']}}
|
||||
);
|
||||
|
||||
|
||||
92
node_modules/mathjax-full/ts/input/tex/extpfeil/ExtpfeilConfiguration.ts
generated
vendored
Normal file
92
node_modules/mathjax-full/ts/input/tex/extpfeil/ExtpfeilConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the extpfeil package. Note that this is
|
||||
* based on AMS package and Newcommand utilities.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration, ParserConfiguration} from '../Configuration.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import {AmsMethods} from '../ams/AmsMethods.js';
|
||||
import NewcommandUtil from '../newcommand/NewcommandUtil.js';
|
||||
import {NewcommandConfiguration} from '../newcommand/NewcommandConfiguration.js';
|
||||
import TexError from '../TexError.js';
|
||||
|
||||
|
||||
// Namespace
|
||||
export let ExtpfeilMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
ExtpfeilMethods.xArrow = AmsMethods.xArrow;
|
||||
|
||||
/**
|
||||
* Implements \Newextarrow to define a new arrow.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the calling macro.
|
||||
*/
|
||||
ExtpfeilMethods.NewExtArrow = function(parser: TexParser, name: string) {
|
||||
let cs = parser.GetArgument(name);
|
||||
const space = parser.GetArgument(name);
|
||||
const chr = parser.GetArgument(name);
|
||||
if (!cs.match(/^\\([a-z]+|.)$/i)) {
|
||||
throw new TexError('NewextarrowArg1',
|
||||
'First argument to %1 must be a control sequence name', name);
|
||||
}
|
||||
if (!space.match(/^(\d+),(\d+)$/)) {
|
||||
throw new TexError(
|
||||
'NewextarrowArg2',
|
||||
'Second argument to %1 must be two integers separated by a comma',
|
||||
name);
|
||||
}
|
||||
if (!chr.match(/^(\d+|0x[0-9A-F]+)$/i)) {
|
||||
throw new TexError(
|
||||
'NewextarrowArg3',
|
||||
'Third argument to %1 must be a unicode character number',
|
||||
name);
|
||||
}
|
||||
cs = cs.substr(1);
|
||||
let spaces = space.split(',');
|
||||
NewcommandUtil.addMacro(parser, cs, ExtpfeilMethods.xArrow,
|
||||
[parseInt(chr), parseInt(spaces[0]), parseInt(spaces[1])]);
|
||||
};
|
||||
|
||||
|
||||
new CommandMap('extpfeil', {
|
||||
xtwoheadrightarrow: ['xArrow', 0x21A0, 12, 16],
|
||||
xtwoheadleftarrow: ['xArrow', 0x219E, 17, 13],
|
||||
xmapsto: ['xArrow', 0x21A6, 6, 7],
|
||||
xlongequal: ['xArrow', 0x003D, 7, 7],
|
||||
xtofrom: ['xArrow', 0x21C4, 12, 12],
|
||||
Newextarrow: 'NewExtArrow'
|
||||
}, ExtpfeilMethods);
|
||||
|
||||
|
||||
let init = function(config: ParserConfiguration) {
|
||||
NewcommandConfiguration.init(config);
|
||||
};
|
||||
|
||||
export const ExtpfeilConfiguration = Configuration.create(
|
||||
'extpfeil', {
|
||||
handler: {macro: ['extpfeil']},
|
||||
init: init
|
||||
}
|
||||
);
|
||||
63
node_modules/mathjax-full/ts/input/tex/gensymb/GensymbConfiguration.ts
generated
vendored
Normal file
63
node_modules/mathjax-full/ts/input/tex/gensymb/GensymbConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2021-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the gensymb package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {Symbol} from '../Symbol.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import {CharacterMap} from '../SymbolMap.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
|
||||
|
||||
/**
|
||||
* Handle characters that are known units.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {Symbol} mchar The parsed symbol.
|
||||
*/
|
||||
function mathcharUnit(parser: TexParser, mchar: Symbol) {
|
||||
const def = mchar.attributes || {};
|
||||
def.mathvariant = TexConstant.Variant.NORMAL;
|
||||
def.class = 'MathML-Unit';
|
||||
const node = parser.create('token', 'mi', def, mchar.char);
|
||||
parser.Push(node);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gensymb units.
|
||||
*/
|
||||
new CharacterMap('gensymb-symbols', mathcharUnit, {
|
||||
ohm: '\u2126',
|
||||
degree: '\u00B0',
|
||||
celsius: '\u2103',
|
||||
perthousand: '\u2030',
|
||||
micro: '\u00B5'
|
||||
});
|
||||
|
||||
|
||||
export const GensymbConfiguration = Configuration.create(
|
||||
'gensymb', {
|
||||
handler: {macro: ['gensymb-symbols']},
|
||||
}
|
||||
);
|
||||
|
||||
39
node_modules/mathjax-full/ts/input/tex/html/HtmlConfiguration.ts
generated
vendored
Normal file
39
node_modules/mathjax-full/ts/input/tex/html/HtmlConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the Html package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import HtmlMethods from './HtmlMethods.js';
|
||||
|
||||
|
||||
new CommandMap('html_macros', {
|
||||
href: 'Href',
|
||||
'class': 'Class',
|
||||
style: 'Style',
|
||||
cssId: 'Id'
|
||||
}, HtmlMethods);
|
||||
|
||||
export const HtmlConfiguration = Configuration.create(
|
||||
'html', {handler: { macro: ['html_macros']}}
|
||||
);
|
||||
124
node_modules/mathjax-full/ts/input/tex/html/HtmlMethods.ts
generated
vendored
Normal file
124
node_modules/mathjax-full/ts/input/tex/html/HtmlMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Methods for the Html package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import TexParser from '../TexParser.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
|
||||
|
||||
// Namespace
|
||||
let HtmlMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
|
||||
/**
|
||||
* Implements \href{url}{math}
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
HtmlMethods.Href = function(parser: TexParser, name: string) {
|
||||
const url = parser.GetArgument(name);
|
||||
const arg = GetArgumentMML(parser, name);
|
||||
NodeUtil.setAttribute(arg, 'href', url);
|
||||
parser.Push(arg);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements \class{name}{math}
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
HtmlMethods.Class = function(parser: TexParser, name: string) {
|
||||
let CLASS = parser.GetArgument(name);
|
||||
const arg = GetArgumentMML(parser, name);
|
||||
let oldClass = NodeUtil.getAttribute(arg, 'class');
|
||||
if (oldClass) {
|
||||
CLASS = oldClass + ' ' + CLASS;
|
||||
}
|
||||
NodeUtil.setAttribute(arg, 'class', CLASS);
|
||||
parser.Push(arg);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements \style{style-string}{math}
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
HtmlMethods.Style = function(parser: TexParser, name: string) {
|
||||
let style = parser.GetArgument(name);
|
||||
const arg = GetArgumentMML(parser, name);
|
||||
// check that it looks like a style string
|
||||
let oldStyle = NodeUtil.getAttribute(arg, 'style');
|
||||
if (oldStyle) {
|
||||
if (style.charAt(style.length - 1) !== ';') {
|
||||
style += ';';
|
||||
}
|
||||
style = oldStyle + ' ' + style;
|
||||
}
|
||||
NodeUtil.setAttribute(arg, 'style', style);
|
||||
parser.Push(arg);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements \cssId{id}{math}
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
HtmlMethods.Id = function(parser: TexParser, name: string) {
|
||||
const ID = parser.GetArgument(name);
|
||||
const arg = GetArgumentMML(parser, name);
|
||||
NodeUtil.setAttribute(arg, 'id', ID);
|
||||
parser.Push(arg);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses the math argument of the above commands and returns it as single
|
||||
* node (in an mrow if necessary). The HTML attributes are then
|
||||
* attached to this element.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The calling macro name.
|
||||
* @return {MmlNode} The math node.
|
||||
*/
|
||||
let GetArgumentMML = function(parser: TexParser, name: string): MmlNode {
|
||||
let arg = parser.ParseArg(name);
|
||||
if (!NodeUtil.isInferred(arg)) {
|
||||
return arg;
|
||||
}
|
||||
let children = NodeUtil.getChildren(arg);
|
||||
if (children.length === 1) {
|
||||
return children[0];
|
||||
}
|
||||
const mrow = parser.create('node', 'mrow');
|
||||
NodeUtil.copyChildren(arg, mrow);
|
||||
NodeUtil.copyAttributes(arg, mrow);
|
||||
return mrow;
|
||||
};
|
||||
|
||||
|
||||
export default HtmlMethods;
|
||||
134
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsConfiguration.ts
generated
vendored
Normal file
134
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/*************************************************************
|
||||
* Copyright (c) 2020-2022 MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the mathtools package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import {expandable} from '../../../util/Options.js';
|
||||
import {ParserConfiguration} from '../Configuration.js';
|
||||
import {TeX} from '../../tex.js';
|
||||
import ParseOptions from '../ParseOptions.js';
|
||||
|
||||
import './MathtoolsMappings.js';
|
||||
import {MathtoolsUtil} from './MathtoolsUtil.js';
|
||||
import {MathtoolsTagFormat} from './MathtoolsTags.js';
|
||||
import {MultlinedItem} from './MathtoolsItems.js';
|
||||
|
||||
/**
|
||||
* The name of the paried-delimiters command map.
|
||||
*/
|
||||
export const PAIREDDELIMS = 'mathtools-paired-delims';
|
||||
|
||||
/**
|
||||
* Create the paired-delimiters command map, and link it into the configuration.
|
||||
* @param {ParserConfiguration} config The current configuration.
|
||||
*/
|
||||
function initMathtools(config: ParserConfiguration) {
|
||||
new CommandMap(PAIREDDELIMS, {}, {});
|
||||
config.append(Configuration.local({handler: {macro: [PAIREDDELIMS]}, priority: -5}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any pre-defined paired delimiters, and subclass the configured tag format.
|
||||
* @param {ParserConfiguration} config The current configuration.
|
||||
* @param {TeX} jac The TeX input jax
|
||||
*/
|
||||
function configMathtools(config: ParserConfiguration, jax: TeX<any, any, any>) {
|
||||
const parser = jax.parseOptions;
|
||||
const pairedDelims = parser.options.mathtools.pairedDelimiters;
|
||||
for (const cs of Object.keys(pairedDelims)) {
|
||||
MathtoolsUtil.addPairedDelims(parser, cs, pairedDelims[cs]);
|
||||
}
|
||||
MathtoolsTagFormat(config, jax);
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter to fix up mmultiscripts elements.
|
||||
* @param {ParseOptions} data The parse options.
|
||||
*/
|
||||
export function fixPrescripts({data}: {data: ParseOptions}) {
|
||||
for (const node of data.getList('mmultiscripts')) {
|
||||
if (!node.getProperty('fixPrescript')) continue;
|
||||
const childNodes = NodeUtil.getChildren(node);
|
||||
let n = 0;
|
||||
for (const i of [1, 2]) {
|
||||
if (!childNodes[i]) {
|
||||
NodeUtil.setChild(node, i, data.nodeFactory.create('node', 'none'));
|
||||
n++;
|
||||
}
|
||||
}
|
||||
for (const i of [4, 5]) {
|
||||
if (NodeUtil.isType(childNodes[i], 'mrow') && NodeUtil.getChildren(childNodes[i]).length === 0) {
|
||||
NodeUtil.setChild(node, i, data.nodeFactory.create('node', 'none'));
|
||||
}
|
||||
}
|
||||
if (n === 2) {
|
||||
childNodes.splice(1, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The configuration for the mathtools package
|
||||
*/
|
||||
export const MathtoolsConfiguration = Configuration.create(
|
||||
'mathtools', {
|
||||
handler: {
|
||||
macro: ['mathtools-macros', 'mathtools-delimiters'],
|
||||
environment: ['mathtools-environments'],
|
||||
delimiter: ['mathtools-delimiters'],
|
||||
character: ['mathtools-characters']
|
||||
},
|
||||
items: {
|
||||
[MultlinedItem.prototype.kind]: MultlinedItem
|
||||
},
|
||||
init: initMathtools,
|
||||
config: configMathtools,
|
||||
postprocessors: [[fixPrescripts, -6]],
|
||||
options: {
|
||||
mathtools: {
|
||||
'multlinegap': '1em', // horizontal space for multlined environments
|
||||
'multlined-pos': 'c', // default alignment for multlined environments
|
||||
'firstline-afterskip': '', // space for first line of multlined (overrides multlinegap)
|
||||
'lastline-preskip': '', // space for last line of multlined (overrides multlinegap)
|
||||
'smallmatrix-align': 'c', // default alignment for smallmatrix environments
|
||||
'shortvdotsadjustabove': '.2em', // space to remove above \shortvdots
|
||||
'shortvdotsadjustbelow': '.2em', // space to remove below \shortvdots
|
||||
'centercolon': false, // true to have colon automatically centered
|
||||
'centercolon-offset': '.04em', // vertical adjustment for centered colons
|
||||
'thincolon-dx': '-.04em', // horizontal adjustment for thin colons (e.g., \coloneqq)
|
||||
'thincolon-dw': '-.08em', // width adjustment for thin colons
|
||||
'use-unicode': false, // true to use unicode characters rather than multi-character
|
||||
// version for \coloneqq, etc., when possible
|
||||
'prescript-sub-format': '', // format for \prescript subscript
|
||||
'prescript-sup-format': '', // format for \prescript superscript
|
||||
'prescript-arg-format': '', // format for \prescript base
|
||||
'allow-mathtoolsset': true, // true to allow \mathtoolsset to change settings
|
||||
pairedDelimiters: expandable({}), // predefined paired delimiters
|
||||
// name: [left, right, body, argcount, pre, post]
|
||||
tagforms: expandable({}), // tag form definitions
|
||||
// name: [left, right, format]
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
70
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsItems.ts
generated
vendored
Normal file
70
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsItems.ts
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*************************************************************
|
||||
* Copyright (c) 2020-2022 MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Implementation of items for the mathtools package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {MultlineItem} from '../ams/AmsItems.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
|
||||
|
||||
/**
|
||||
* The StackItem for the multlined environment
|
||||
*/
|
||||
export class MultlinedItem extends MultlineItem {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
get kind() {
|
||||
return 'multlined';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public EndTable() {
|
||||
if (this.Size() || this.row.length) {
|
||||
this.EndEntry();
|
||||
this.EndRow();
|
||||
}
|
||||
if (this.table.length > 1) {
|
||||
const options = this.factory.configuration.options.mathtools;
|
||||
const gap = options.multlinegap;
|
||||
const firstskip = options['firstline-afterskip'] || gap;
|
||||
const lastskip = options['lastline-preskip'] || gap;
|
||||
const first = NodeUtil.getChildren(this.table[0])[0];
|
||||
if (NodeUtil.getAttribute(first, 'columnalign') !== TexConstant.Align.RIGHT) {
|
||||
first.appendChild(this.create('node', 'mspace', [], {width: firstskip}));
|
||||
}
|
||||
const last = NodeUtil.getChildren(this.table[this.table.length - 1])[0];
|
||||
if (NodeUtil.getAttribute(last, 'columnalign') !== TexConstant.Align.LEFT) {
|
||||
const top = NodeUtil.getChildren(last)[0];
|
||||
top.childNodes.unshift(null);
|
||||
const space = this.create('node', 'mspace', [], {width: lastskip});
|
||||
NodeUtil.setChild(top, 0, space);
|
||||
}
|
||||
}
|
||||
super.EndTable.call(this);
|
||||
}
|
||||
|
||||
}
|
||||
206
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsMappings.ts
generated
vendored
Normal file
206
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsMappings.ts
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
/*************************************************************
|
||||
* Copyright (c) 2020-2022 MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Macro and environment mappings for the mathtools package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import ParseMethods from '../ParseMethods.js';
|
||||
import {CommandMap, EnvironmentMap, DelimiterMap} from '../SymbolMap.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
|
||||
import {MathtoolsMethods} from './MathtoolsMethods.js';
|
||||
|
||||
//
|
||||
// Mathtools macros that are not implemented:
|
||||
//
|
||||
// \smashoperator[〈pos〉]{〈operator with limits〉}
|
||||
// \SwapAboveDisplaySkip
|
||||
// \noeqref{〈label,label,. . . 〉}
|
||||
// \intertext{〈text 〉}
|
||||
// \shortintertext{〈text 〉}
|
||||
// \reDeclarePairedDelimiterInnerWrapper{〈macro name〉}{〈star or nostarnonscaled or nostarscaled〉}{〈code〉}
|
||||
// \DeclareMathSizes{〈dimen〉}{〈dimen〉}{〈dimen〉}{〈dimen〉}
|
||||
// \newgathered{〈name〉}{〈pre_line〉}{〈post_line〉}{〈after〉}
|
||||
// \renewgathered{〈name〉}{〈pre_line〉}{〈post_line〉}{〈after〉}
|
||||
//
|
||||
|
||||
/**
|
||||
* The macros for this package.
|
||||
*/
|
||||
new CommandMap('mathtools-macros', {
|
||||
|
||||
shoveleft: ['HandleShove', TexConstant.Align.LEFT], // override AMS version
|
||||
shoveright: ['HandleShove', TexConstant.Align.RIGHT], // override AMS version
|
||||
|
||||
xleftrightarrow: ['xArrow', 0x2194, 10, 10],
|
||||
xLeftarrow: ['xArrow', 0x21D0, 12, 7],
|
||||
xRightarrow: ['xArrow', 0x21D2, 7, 12],
|
||||
xLeftrightarrow: ['xArrow', 0x21D4, 12, 12],
|
||||
xhookleftarrow: ['xArrow', 0x21A9, 10, 5],
|
||||
xhookrightarrow: ['xArrow', 0x21AA, 5, 10],
|
||||
xmapsto: ['xArrow', 0x21A6, 10, 10],
|
||||
xrightharpoondown: ['xArrow', 0x21C1, 5, 10],
|
||||
xleftharpoondown: ['xArrow', 0x21BD, 10, 5],
|
||||
xrightleftharpoons: ['xArrow', 0x21CC, 10, 10],
|
||||
xrightharpoonup: ['xArrow', 0x21C0, 5, 10],
|
||||
xleftharpoonup: ['xArrow', 0x21BC, 10, 5],
|
||||
xleftrightharpoons: ['xArrow', 0x21CB, 10, 10],
|
||||
|
||||
mathllap: ['MathLap', 'l', false],
|
||||
mathrlap: ['MathLap', 'r', false],
|
||||
mathclap: ['MathLap', 'c', false],
|
||||
clap: ['MtLap', 'c'],
|
||||
textllap: ['MtLap', 'l'],
|
||||
textrlap: ['MtLap', 'r'],
|
||||
textclap: ['MtLap', 'c'],
|
||||
|
||||
cramped: 'Cramped',
|
||||
crampedllap: ['MathLap', 'l', true],
|
||||
crampedrlap: ['MathLap', 'r', true],
|
||||
crampedclap: ['MathLap', 'c', true],
|
||||
crampedsubstack: ['Macro', '\\begin{crampedsubarray}{c}#1\\end{crampedsubarray}', 1],
|
||||
|
||||
mathmbox: 'MathMBox',
|
||||
mathmakebox: 'MathMakeBox',
|
||||
|
||||
overbracket: 'UnderOverBracket',
|
||||
underbracket: 'UnderOverBracket',
|
||||
|
||||
refeq: 'HandleRef',
|
||||
|
||||
MoveEqLeft: ['Macro', '\\hspace{#1em}&\\hspace{-#1em}', 1, '2'],
|
||||
Aboxed: 'Aboxed',
|
||||
|
||||
ArrowBetweenLines: 'ArrowBetweenLines',
|
||||
vdotswithin: 'VDotsWithin',
|
||||
shortvdotswithin: 'ShortVDotsWithin',
|
||||
MTFlushSpaceAbove: 'FlushSpaceAbove',
|
||||
MTFlushSpaceBelow: 'FlushSpaceBelow',
|
||||
|
||||
DeclarePairedDelimiter: 'DeclarePairedDelimiter',
|
||||
DeclarePairedDelimiterX: 'DeclarePairedDelimiterX',
|
||||
DeclarePairedDelimiterXPP: 'DeclarePairedDelimiterXPP',
|
||||
|
||||
//
|
||||
// Typos from initial release -- kept for backward compatibility for now
|
||||
//
|
||||
DeclarePairedDelimiters: 'DeclarePairedDelimiter',
|
||||
DeclarePairedDelimitersX: 'DeclarePairedDelimiterX',
|
||||
DeclarePairedDelimitersXPP: 'DeclarePairedDelimiterXPP',
|
||||
|
||||
centercolon: ['CenterColon', true, true],
|
||||
ordinarycolon: ['CenterColon', false],
|
||||
MTThinColon: ['CenterColon', true, true, true],
|
||||
|
||||
coloneqq: ['Relation', ':=', '\u2254'],
|
||||
Coloneqq: ['Relation', '::=', '\u2A74'],
|
||||
coloneq: ['Relation', ':-'],
|
||||
Coloneq: ['Relation', '::-'],
|
||||
eqqcolon: ['Relation', '=:', '\u2255'],
|
||||
Eqqcolon: ['Relation', '=::'],
|
||||
eqcolon: ['Relation', '-:', '\u2239'],
|
||||
Eqcolon: ['Relation', '-::'],
|
||||
colonapprox: ['Relation', ':\\approx'],
|
||||
Colonapprox: ['Relation', '::\\approx'],
|
||||
colonsim: ['Relation', ':\\sim'],
|
||||
Colonsim: ['Relation', '::\\sim'],
|
||||
dblcolon: ['Relation', '::', '\u2237'],
|
||||
|
||||
nuparrow: ['NArrow', '\u2191', '.06em'],
|
||||
ndownarrow: ['NArrow', '\u2193', '.25em'],
|
||||
bigtimes: ['Macro', '\\mathop{\\Large\\kern-.1em\\boldsymbol{\\times}\\kern-.1em}'],
|
||||
|
||||
splitfrac: ['SplitFrac', false],
|
||||
splitdfrac: ['SplitFrac', true],
|
||||
|
||||
xmathstrut: 'XMathStrut',
|
||||
|
||||
prescript: 'Prescript',
|
||||
|
||||
newtagform: ['NewTagForm', false],
|
||||
renewtagform: ['NewTagForm', true],
|
||||
usetagform: 'UseTagForm',
|
||||
|
||||
adjustlimits: [
|
||||
'MacroWithTemplate',
|
||||
'\\mathop{{#1}\\vphantom{{#3}}}_{{#2}\\vphantom{{#4}}}\\mathop{{#3}\\vphantom{{#1}}}_{{#4}\\vphantom{{#2}}}',
|
||||
4, , '_', , '_'
|
||||
],
|
||||
|
||||
mathtoolsset: 'SetOptions'
|
||||
|
||||
}, MathtoolsMethods);
|
||||
|
||||
/**
|
||||
* The environments for this package.
|
||||
*/
|
||||
new EnvironmentMap('mathtools-environments', ParseMethods.environment, {
|
||||
dcases: ['Array', null, '\\{', '', 'll', null, '.2em', 'D'],
|
||||
rcases: ['Array', null, '', '\\}', 'll', null, '.2em'],
|
||||
drcases: ['Array', null, '', '\\}', 'll', null, '.2em', 'D'],
|
||||
'dcases*': ['Cases', null, '{', '', 'D'],
|
||||
'rcases*': ['Cases', null, '', '}'],
|
||||
'drcases*': ['Cases', null, '', '}', 'D'],
|
||||
'cases*': ['Cases', null, '{', ''],
|
||||
|
||||
'matrix*': ['MtMatrix', null, null, null],
|
||||
'pmatrix*': ['MtMatrix', null, '(', ')'],
|
||||
'bmatrix*': ['MtMatrix', null, '[', ']'],
|
||||
'Bmatrix*': ['MtMatrix', null, '\\{', '\\}'],
|
||||
'vmatrix*': ['MtMatrix', null, '\\vert', '\\vert'],
|
||||
'Vmatrix*': ['MtMatrix', null, '\\Vert', '\\Vert'],
|
||||
|
||||
'smallmatrix*': ['MtSmallMatrix', null, null, null],
|
||||
psmallmatrix: ['MtSmallMatrix', null, '(', ')', 'c'],
|
||||
'psmallmatrix*': ['MtSmallMatrix', null, '(', ')'],
|
||||
bsmallmatrix: ['MtSmallMatrix', null, '[', ']', 'c'],
|
||||
'bsmallmatrix*': ['MtSmallMatrix', null, '[', ']'],
|
||||
Bsmallmatrix: ['MtSmallMatrix', null, '\\{', '\\}', 'c'],
|
||||
'Bsmallmatrix*': ['MtSmallMatrix', null, '\\{', '\\}'],
|
||||
vsmallmatrix: ['MtSmallMatrix', null, '\\vert', '\\vert', 'c'],
|
||||
'vsmallmatrix*': ['MtSmallMatrix', null, '\\vert', '\\vert'],
|
||||
Vsmallmatrix: ['MtSmallMatrix', null, '\\Vert', '\\Vert', 'c'],
|
||||
'Vsmallmatrix*': ['MtSmallMatrix', null, '\\Vert', '\\Vert'],
|
||||
|
||||
crampedsubarray: ['Array', null, null, null, null, '0em', '0.1em', 'S\'', 1],
|
||||
|
||||
multlined: 'MtMultlined',
|
||||
|
||||
spreadlines: ['SpreadLines', true],
|
||||
|
||||
lgathered: ['AmsEqnArray', null, null, null, 'l', null, '.5em', 'D'],
|
||||
rgathered: ['AmsEqnArray', null, null, null, 'r', null, '.5em', 'D'],
|
||||
|
||||
}, MathtoolsMethods);
|
||||
|
||||
/**
|
||||
* The delimiters for this package.
|
||||
*/
|
||||
new DelimiterMap('mathtools-delimiters', ParseMethods.delimiter, {
|
||||
'\\lparen': '(',
|
||||
'\\rparen': ')'
|
||||
});
|
||||
|
||||
/**
|
||||
* The special characters for this package.
|
||||
*/
|
||||
new CommandMap('mathtools-characters', {
|
||||
':' : ['CenterColon', true]
|
||||
}, MathtoolsMethods);
|
||||
747
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsMethods.ts
generated
vendored
Normal file
747
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,747 @@
|
||||
/*************************************************************
|
||||
* Copyright (c) 2020-2022 MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Macro and environment implementations for the mathtools package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
|
||||
import {ArrayItem, EqnArrayItem} from '../base/BaseItems.js';
|
||||
import {StackItem} from '../StackItem.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import {ParseMethod, ParseResult} from '../Types.js';
|
||||
import {AmsMethods} from '../ams/AmsMethods.js';
|
||||
import BaseMethods from '../base/BaseMethods.js';
|
||||
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 {lookup} from '../../../util/Options.js';
|
||||
import NewcommandUtil from '../newcommand/NewcommandUtil.js';
|
||||
import NewcommandMethods from '../newcommand/NewcommandMethods.js';
|
||||
|
||||
import {MathtoolsTags} from './MathtoolsTags.js';
|
||||
import {MathtoolsUtil} from './MathtoolsUtil.js';
|
||||
|
||||
/**
|
||||
* The implementations for the macros and environments for the mathtools package.
|
||||
*/
|
||||
export const MathtoolsMethods: Record<string, ParseMethod> = {
|
||||
|
||||
/**
|
||||
* Handle a mathtools matrix environment, with optional alignment.
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {StackItem} begin The BeginItem for the environment.
|
||||
* @param {string} open The open delimiter for the matrix.
|
||||
* @param {string} close The close delimiter for the matrix.
|
||||
* @return {ParserResult} The ArrayItem for the matrix.
|
||||
*/
|
||||
MtMatrix(parser: TexParser, begin: StackItem, open: string, close: string): ParseResult {
|
||||
const align = parser.GetBrackets(`\\begin{${begin.getName()}}`, 'c');
|
||||
return MathtoolsMethods.Array(parser, begin, open, close, align);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a smallmatrix with given delimiters, and with optional alignment (and settable default)
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {StackItem} begin The BeginItem for the environment.
|
||||
* @param {string} open The open delimiter for the matrix.
|
||||
* @param {string} close The close delimiter for the matrix.
|
||||
* @param {string} align The (optional) alignment. If not given, use a bracket argument for it.
|
||||
* @return {ParseResult} The ArrayItem for the matrix.
|
||||
*/
|
||||
MtSmallMatrix(parser: TexParser, begin: StackItem, open: string, close: string, align?: string): ParseResult {
|
||||
if (!align) {
|
||||
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
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create the multlined StackItem.
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {StackItem} begin The BeginItem for the environment.
|
||||
* @return {ParseResult} The MultlinedItem.
|
||||
*/
|
||||
MtMultlined(parser: TexParser, begin: StackItem): ParseResult {
|
||||
const name = `\\begin{${begin.getName()}}`;
|
||||
let pos = parser.GetBrackets(name, parser.options.mathtools['multlined-pos'] || 'c');
|
||||
let width = pos ? parser.GetBrackets(name, '') : '';
|
||||
if (pos && !pos.match(/^[cbt]$/)) {
|
||||
[width, pos] = [pos, width];
|
||||
}
|
||||
parser.Push(begin);
|
||||
const item = parser.itemFactory.create('multlined', parser, begin) as ArrayItem;
|
||||
item.arraydef = {
|
||||
displaystyle: true,
|
||||
rowspacing: '.5em',
|
||||
width: width || 'auto',
|
||||
columnwidth: '100%',
|
||||
};
|
||||
return ParseUtil.setArrayAlign(item as ArrayItem, pos || 'c');
|
||||
},
|
||||
|
||||
/**
|
||||
* Replacement for the AMS HandleShove that includes optional spacing values
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} name The name of the calling macro.
|
||||
* @param {string} shove Which way to shove the result.
|
||||
*/
|
||||
HandleShove(parser: TexParser, name: string, shove: string) {
|
||||
let top = parser.stack.Top();
|
||||
if (top.kind !== 'multline' && top.kind !== 'multlined') {
|
||||
throw new TexError(
|
||||
'CommandInMultlined',
|
||||
'%1 can only appear within the multline or multlined environments',
|
||||
name);
|
||||
}
|
||||
if (top.Size()) {
|
||||
throw new TexError(
|
||||
'CommandAtTheBeginingOfLine',
|
||||
'%1 must come at the beginning of the line',
|
||||
name);
|
||||
}
|
||||
top.setProperty('shove', shove);
|
||||
let shift = parser.GetBrackets(name);
|
||||
let mml = parser.ParseArg(name);
|
||||
if (shift) {
|
||||
let mrow = parser.create('node', 'mrow', []);
|
||||
let mspace = parser.create('node', 'mspace', [], {width: shift});
|
||||
if (shove === 'left') {
|
||||
mrow.appendChild(mspace);
|
||||
mrow.appendChild(mml);
|
||||
} else {
|
||||
mrow.appendChild(mml);
|
||||
mrow.appendChild(mspace);
|
||||
}
|
||||
mml = mrow;
|
||||
}
|
||||
parser.Push(mml);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle the spreadlines environment.
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {StackItem} begin The BeginItem for the environment.
|
||||
*/
|
||||
SpreadLines(parser: TexParser, begin: StackItem) {
|
||||
if (parser.stack.env.closing === begin.getName()) {
|
||||
//
|
||||
// When the environment ends, look through the contents and
|
||||
// adjust the spacing in any tables, then push the results.
|
||||
//
|
||||
delete parser.stack.env.closing;
|
||||
const top = parser.stack.Pop();
|
||||
const mml = top.toMml();
|
||||
const spread = top.getProperty('spread') as string;
|
||||
if (mml.isInferred) {
|
||||
for (const child of NodeUtil.getChildren(mml)) {
|
||||
MathtoolsUtil.spreadLines(child, spread);
|
||||
}
|
||||
} else {
|
||||
MathtoolsUtil.spreadLines(mml, spread);
|
||||
}
|
||||
parser.Push(mml);
|
||||
} else {
|
||||
//
|
||||
// Read the spread dimension and save it, then begin the environment.
|
||||
//
|
||||
const spread = parser.GetDimen(`\\begin{${begin.getName()}}`);
|
||||
begin.setProperty('spread', spread);
|
||||
parser.Push(begin);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements the various cases environments.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {StackItem} begin The BeginItem for the environment.
|
||||
* @param {string} open The open delimiter for the matrix.
|
||||
* @param {string} close The close delimiter for the matrix.
|
||||
* @param {string} style The style (D, T, S, SS) for the contents of the array
|
||||
* @return {ArrayItem} The ArrayItem for the environment
|
||||
*/
|
||||
Cases(parser: TexParser, begin: StackItem, open: string, close: string, style: string): ArrayItem {
|
||||
const array = parser.itemFactory.create('array').setProperty('casesEnv', begin.getName()) as ArrayItem;
|
||||
array.arraydef = {
|
||||
rowspacing: '.2em',
|
||||
columnspacing: '1em',
|
||||
columnalign: 'left'
|
||||
};
|
||||
if (style === 'D') {
|
||||
array.arraydef.displaystyle = true;
|
||||
}
|
||||
array.setProperties({open, close});
|
||||
parser.Push(begin);
|
||||
return array;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle \mathrlap, \mathllap, \mathclap, and their cramped versions.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} pos The position (l, c, r) of the lapped content
|
||||
* @param {boolean} cramped True if the style should be cramped
|
||||
*/
|
||||
MathLap(parser: TexParser, name: string, pos: string, cramped: boolean) {
|
||||
const style = parser.GetBrackets(name, '').trim();
|
||||
let mml = parser.create('node', 'mstyle', [
|
||||
parser.create('node', 'mpadded', [parser.ParseArg(name)], {
|
||||
width: 0, ...(pos === 'r' ? {} : {lspace: (pos === 'l' ? '-1width' : '-.5width')})
|
||||
})
|
||||
], {'data-cramped': cramped});
|
||||
MathtoolsUtil.setDisplayLevel(mml, style);
|
||||
parser.Push(parser.create('node', 'TeXAtom', [mml]));
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \cramped.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
Cramped(parser: TexParser, name: string) {
|
||||
const style = parser.GetBrackets(name, '').trim();
|
||||
const arg = parser.ParseArg(name);
|
||||
const mml = parser.create('node', 'mstyle', [arg], {'data-cramped': true});
|
||||
MathtoolsUtil.setDisplayLevel(mml, style);
|
||||
parser.Push(mml);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \clap (and could do \llap and \rlap, where the contents are text mode).
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} pos The position (l, c, r) of the lapped content
|
||||
*/
|
||||
MtLap(parser: TexParser, name: string, pos: string) {
|
||||
const content = ParseUtil.internalMath(parser, parser.GetArgument(name), 0);
|
||||
let mml = parser.create('node', 'mpadded', content, {width: 0});
|
||||
if (pos !== 'r') {
|
||||
NodeUtil.setAttribute(mml, 'lspace', pos === 'l' ? '-1width' : '-.5width');
|
||||
}
|
||||
parser.Push(mml);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \mathmakebox.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
MathMakeBox(parser: TexParser, name: string) {
|
||||
const width = parser.GetBrackets(name);
|
||||
const pos = parser.GetBrackets(name, 'c');
|
||||
const mml = parser.create('node', 'mpadded', [parser.ParseArg(name)]);
|
||||
if (width) {
|
||||
NodeUtil.setAttribute(mml, 'width', width);
|
||||
}
|
||||
const align = lookup(pos, {c: 'center', r: 'right'}, '');
|
||||
if (align) {
|
||||
NodeUtil.setAttribute(mml, 'data-align', align);
|
||||
}
|
||||
parser.Push(mml);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \mathmbox.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
MathMBox(parser: TexParser, name: string) {
|
||||
parser.Push(parser.create('node', 'mrow', [parser.ParseArg(name)]));
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \underbacket and \overbracket.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
UnderOverBracket(parser: TexParser, name: string) {
|
||||
const thickness = length2em(parser.GetBrackets(name, '.1em'), .1);
|
||||
const height = parser.GetBrackets(name, '.2em');
|
||||
const arg = parser.GetArgument(name);
|
||||
const [pos, accent, border] = (
|
||||
name.charAt(1) === 'o' ?
|
||||
['over', 'accent', 'bottom'] :
|
||||
['under', 'accentunder', 'top']
|
||||
);
|
||||
const t = em(thickness);
|
||||
const base = new TexParser(arg, parser.stack.env, parser.configuration).mml();
|
||||
const copy = new TexParser(arg, parser.stack.env, parser.configuration).mml();
|
||||
const script = parser.create('node', 'mpadded', [
|
||||
parser.create('node', 'mphantom', [copy])
|
||||
], {
|
||||
style: `border: ${t} solid; border-${border}: none`,
|
||||
height: height,
|
||||
depth: 0
|
||||
});
|
||||
const node = ParseUtil.underOver(parser, base, script, pos, true);
|
||||
const munderover = NodeUtil.getChildAt(NodeUtil.getChildAt(node, 0), 0); // TeXAtom.inferredMrow child 0
|
||||
NodeUtil.setAttribute(munderover, accent, true);
|
||||
parser.Push(node);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \Aboxed.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
Aboxed(parser: TexParser, name: string) {
|
||||
//
|
||||
// Check that the top item is an alignment, and that we are on an even number of cells
|
||||
// (othewise add one to make it even).
|
||||
//
|
||||
const top = MathtoolsUtil.checkAlignment(parser, name);
|
||||
if (top.row.length % 2 === 1) {
|
||||
top.row.push(parser.create('node', 'mtd', []));
|
||||
}
|
||||
//
|
||||
// Get the argument and the rest of the TeX string.
|
||||
//
|
||||
const arg = parser.GetArgument(name);
|
||||
const rest = parser.string.substr(parser.i);
|
||||
//
|
||||
// Put the argument back, followed by "&&", and a marker that we look for below.
|
||||
//
|
||||
parser.string = arg + '&&\\endAboxed';
|
||||
parser.i = 0;
|
||||
//
|
||||
// Get the two parts separated by ampersands, and ignore the rest.
|
||||
//
|
||||
const left = parser.GetUpTo(name, '&');
|
||||
const right = parser.GetUpTo(name, '&');
|
||||
parser.GetUpTo(name, '\\endAboxed');
|
||||
//
|
||||
// Insert the TeX needed for the boxed content
|
||||
//
|
||||
const tex = ParseUtil.substituteArgs(
|
||||
parser, [left, right], '\\rlap{\\boxed{#1{}#2}}\\kern.267em\\phantom{#1}&\\phantom{{}#2}\\kern.267em'
|
||||
);
|
||||
parser.string = tex + rest;
|
||||
parser.i = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \ArrowBetweenLines.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
ArrowBetweenLines(parser: TexParser, name: string) {
|
||||
const top = MathtoolsUtil.checkAlignment(parser, name);
|
||||
if (top.Size() || top.row.length) {
|
||||
throw new TexError('BetweenLines', '%1 must be on a row by itself', name);
|
||||
}
|
||||
const star = parser.GetStar();
|
||||
const symbol = parser.GetBrackets(name, '\\Updownarrow');
|
||||
if (star) {
|
||||
top.EndEntry();
|
||||
top.EndEntry();
|
||||
}
|
||||
const tex = (star ? '\\quad' + symbol : symbol + '\\quad');
|
||||
const mml = new TexParser(tex, parser.stack.env, parser.configuration).mml();
|
||||
parser.Push(mml);
|
||||
top.EndEntry();
|
||||
top.EndRow();
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \vdotswithin.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
VDotsWithin(parser: TexParser, name: string) {
|
||||
const top = parser.stack.Top() as EqnArrayItem;
|
||||
const isFlush = (top.getProperty('flushspaceabove') === top.table.length);
|
||||
const arg = '\\mmlToken{mi}{}' + parser.GetArgument(name) + '\\mmlToken{mi}{}';
|
||||
const base = new TexParser(arg, parser.stack.env, parser.configuration).mml();
|
||||
let mml = parser.create('node', 'mpadded', [
|
||||
parser.create('node', 'mpadded', [
|
||||
parser.create('node', 'mo', [
|
||||
parser.create('text', '\u22EE')
|
||||
])
|
||||
], {
|
||||
width: 0,
|
||||
lspace: '-.5width', ...(isFlush ? {height: '-.6em', voffset: '-.18em'} : {})
|
||||
}),
|
||||
parser.create('node', 'mphantom', [base])
|
||||
], {
|
||||
lspace: '.5width'
|
||||
});
|
||||
parser.Push(mml);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \shortvdotswithin.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
ShortVDotsWithin(parser: TexParser, _name: string) {
|
||||
const top = parser.stack.Top() as EqnArrayItem;
|
||||
const star = parser.GetStar();
|
||||
MathtoolsMethods.FlushSpaceAbove(parser, '\\MTFlushSpaceAbove');
|
||||
!star && top.EndEntry();
|
||||
MathtoolsMethods.VDotsWithin(parser, '\\vdotswithin');
|
||||
star && top.EndEntry();
|
||||
MathtoolsMethods.FlushSpaceBelow(parser, '\\MTFlushSpaceBelow');
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \MTFlushSpaceAbove.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
FlushSpaceAbove(parser: TexParser, name: string) {
|
||||
const top = MathtoolsUtil.checkAlignment(parser, name);
|
||||
top.setProperty('flushspaceabove', top.table.length); // marker so \vdotswithin can shorten its height
|
||||
top.addRowSpacing('-' + parser.options.mathtools['shortvdotsadjustabove']);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \MTFlushSpaceBelow.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
FlushSpaceBelow(parser: TexParser, name: string) {
|
||||
const top = MathtoolsUtil.checkAlignment(parser, name);
|
||||
top.Size() && top.EndEntry();
|
||||
top.EndRow();
|
||||
top.addRowSpacing('-' + parser.options.mathtools['shortvdotsadjustbelow']);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements a paired delimiter (e.g., from \DeclarePairedDelimiter).
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} open The open delimiter.
|
||||
* @param {string} close The close delimiter.
|
||||
* @param {string?} body The body betweeen the delimiters.
|
||||
* @param {number?} n The number of arguments to use for the body.
|
||||
* @param {string?} pre The TeX to go before the open delimiter.
|
||||
* @param {string?} post The TeX to go after the close delimiter.
|
||||
*/
|
||||
PairedDelimiters(parser: TexParser, name: string,
|
||||
open: string, close: string,
|
||||
body: string = '#1', n: number = 1,
|
||||
pre: string = '', post: string = '') {
|
||||
const star = parser.GetStar();
|
||||
const size = (star ? '' : parser.GetBrackets(name));
|
||||
const [left, right] = (star ? ['\\left', '\\right'] : size ? [size + 'l' , size + 'r'] : ['', '']);
|
||||
const delim = (star ? '\\middle' : size || '');
|
||||
if (n) {
|
||||
const args: string[] = [];
|
||||
for (let i = args.length; i < n; i++) {
|
||||
args.push(parser.GetArgument(name));
|
||||
}
|
||||
pre = ParseUtil.substituteArgs(parser, args, pre);
|
||||
body = ParseUtil.substituteArgs(parser, args, body);
|
||||
post = ParseUtil.substituteArgs(parser, args, post);
|
||||
}
|
||||
body = body.replace(/\\delimsize/g, delim);
|
||||
parser.string = [pre, left, open, body, right, close, post, parser.string.substr(parser.i)]
|
||||
.reduce((s, part) => ParseUtil.addArgs(parser, s, part), '');
|
||||
parser.i = 0;
|
||||
ParseUtil.checkMaxMacros(parser);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \DeclarePairedDelimiter.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
DeclarePairedDelimiter(parser: TexParser, name: string) {
|
||||
const cs = NewcommandUtil.GetCsNameArgument(parser, name);
|
||||
const open = parser.GetArgument(name);
|
||||
const close = parser.GetArgument(name);
|
||||
MathtoolsUtil.addPairedDelims(parser.configuration, cs, [open, close]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \DeclarePairedDelimiterX.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
DeclarePairedDelimiterX(parser: TexParser, name: string) {
|
||||
const cs = NewcommandUtil.GetCsNameArgument(parser, name);
|
||||
const n = NewcommandUtil.GetArgCount(parser, name);
|
||||
const open = parser.GetArgument(name);
|
||||
const close = parser.GetArgument(name);
|
||||
const body = parser.GetArgument(name);
|
||||
MathtoolsUtil.addPairedDelims(parser.configuration, cs, [open, close, body, n]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \DeclarePairedDelimiterXPP.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
DeclarePairedDelimiterXPP(parser: TexParser, name: string) {
|
||||
const cs = NewcommandUtil.GetCsNameArgument(parser, name);
|
||||
const n = NewcommandUtil.GetArgCount(parser, name);
|
||||
const pre = parser.GetArgument(name);
|
||||
const open = parser.GetArgument(name);
|
||||
const close = parser.GetArgument(name);
|
||||
const post = parser.GetArgument(name);
|
||||
const body = parser.GetArgument(name);
|
||||
MathtoolsUtil.addPairedDelims(parser.configuration, cs, [open, close, body, n, pre, post]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \centeredcolon, \ordinarycolon, \MTThinColon.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {boolean} center True if colon should be centered
|
||||
* @param {boolean} force True menas always center (don't use centercolon option).
|
||||
* @param {boolean} thin True if this is a thin color (for \coloneqq, etc).
|
||||
*/
|
||||
CenterColon(parser: TexParser, _name: string, center: boolean, force: boolean = false, thin: boolean = false) {
|
||||
const options = parser.options.mathtools;
|
||||
let mml = parser.create('token', 'mo', {}, ':');
|
||||
if (center && (options['centercolon'] || force)) {
|
||||
const dy = options['centercolon-offset'];
|
||||
mml = parser.create('node', 'mpadded', [mml], {
|
||||
voffset: dy, height: `+${dy}`, depth: `-${dy}`,
|
||||
...(thin ? {width: options['thincolon-dw'], lspace: options['thincolon-dx']} : {})
|
||||
});
|
||||
}
|
||||
parser.Push(mml);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \coloneqq and related macros.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} tex The tex string to use (if not using unicode versions or if there isn't one).
|
||||
* @param {string} unicode The unicode character (if there is one).
|
||||
*/
|
||||
Relation(parser: TexParser, _name: string, tex: string, unicode?: string) {
|
||||
const options = parser.options.mathtools;
|
||||
if (options['use-unicode'] && unicode) {
|
||||
parser.Push(parser.create('token', 'mo', {texClass: TEXCLASS.REL}, unicode));
|
||||
} else {
|
||||
tex = '\\mathrel{' + tex.replace(/:/g, '\\MTThinColon').replace(/-/g, '\\mathrel{-}') + '}';
|
||||
parser.string = ParseUtil.addArgs(parser, tex, parser.string.substr(parser.i));
|
||||
parser.i = 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \ndownarrow and \nuparrow via a terrible hack (visual only, no chance of this working with SRE).
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} c The base arrow for the slashed version
|
||||
* @param {string} dy A vertical offset for the slash
|
||||
*/
|
||||
NArrow(parser: TexParser, _name: string, c: string, dy: string) {
|
||||
parser.Push(
|
||||
parser.create('node', 'TeXAtom', [
|
||||
parser.create('token', 'mtext', {}, c),
|
||||
parser.create('node', 'mpadded', [
|
||||
parser.create('node', 'mpadded', [
|
||||
parser.create('node', 'menclose', [
|
||||
parser.create('node', 'mspace', [], {height: '.2em', depth: 0, width: '.4em'})
|
||||
], {notation: 'updiagonalstrike', 'data-thickness': '.05em', 'data-padding': 0})
|
||||
], {width: 0, lspace: '-.5width', voffset: dy}),
|
||||
parser.create('node', 'mphantom', [
|
||||
parser.create('token', 'mtext', {}, c)
|
||||
])
|
||||
], {width: 0, lspace: '-.5width'})
|
||||
], {texClass: TEXCLASS.REL})
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \splitfrac and \splitdfrac.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {boolean} display True if \splitdfrac.
|
||||
*/
|
||||
SplitFrac(parser: TexParser, name: string, display: boolean) {
|
||||
const num = parser.ParseArg(name);
|
||||
const den = parser.ParseArg(name);
|
||||
parser.Push(
|
||||
parser.create('node', 'mstyle', [
|
||||
parser.create('node', 'mfrac', [
|
||||
parser.create('node', 'mstyle', [
|
||||
num,
|
||||
parser.create('token', 'mi'),
|
||||
parser.create('token', 'mspace', {width: '1em'}) // no parameter for this in mathtools. Should we add one?
|
||||
], {scriptlevel: 0}),
|
||||
parser.create('node', 'mstyle', [
|
||||
parser.create('token', 'mspace', {width: '1em'}),
|
||||
parser.create('token', 'mi'),
|
||||
den
|
||||
], {scriptlevel: 0})
|
||||
], {linethickness: 0, numalign: 'left', denomalign: 'right'})
|
||||
], {displaystyle: display, scriptlevel: 0})
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \xmathstrut.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
XMathStrut(parser: TexParser, name: string) {
|
||||
let dd = parser.GetBrackets(name);
|
||||
let dh = parser.GetArgument(name);
|
||||
dh = MathtoolsUtil.plusOrMinus(name, dh);
|
||||
dd = MathtoolsUtil.plusOrMinus(name, dd || dh);
|
||||
parser.Push(
|
||||
parser.create('node', 'TeXAtom', [
|
||||
parser.create('node', 'mpadded', [
|
||||
parser.create('node', 'mphantom', [
|
||||
parser.create('token', 'mo', {stretchy: false}, '(')
|
||||
])
|
||||
], {width: 0, height: dh + 'height', depth: dd + 'depth'})
|
||||
], {texClass: TEXCLASS.ORD})
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \prescript.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
Prescript(parser: TexParser, name: string) {
|
||||
const sup = MathtoolsUtil.getScript(parser, name, 'sup');
|
||||
const sub = MathtoolsUtil.getScript(parser, name, 'sub');
|
||||
const base = MathtoolsUtil.getScript(parser, name, 'arg');
|
||||
if (NodeUtil.isType(sup, 'none') && NodeUtil.isType(sub, 'none')) {
|
||||
parser.Push(base);
|
||||
return;
|
||||
}
|
||||
const mml = parser.create('node', 'mmultiscripts', [base]);
|
||||
NodeUtil.getChildren(mml).push(null, null);
|
||||
NodeUtil.appendChildren(mml, [parser.create('node', 'mprescripts'), sub, sup]);
|
||||
mml.setProperty('fixPrescript', true);
|
||||
parser.Push(mml);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \newtagform and \renewtagform.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {boolean=} renew True if \renewtagform.
|
||||
*/
|
||||
NewTagForm(parser: TexParser, name: string, renew: boolean = false) {
|
||||
const tags = parser.tags as MathtoolsTags;
|
||||
if (!('mtFormats' in tags)) {
|
||||
throw new TexError('TagsNotMT', '%1 can only be used with ams or mathtools tags', name);
|
||||
}
|
||||
const id = parser.GetArgument(name).trim();
|
||||
if (!id) {
|
||||
throw new TexError('InvalidTagFormID', 'Tag form name can\'t be empty');
|
||||
}
|
||||
const format = parser.GetBrackets(name, '');
|
||||
const left = parser.GetArgument(name);
|
||||
const right = parser.GetArgument(name);
|
||||
if (!renew && tags.mtFormats.has(id)) {
|
||||
throw new TexError('DuplicateTagForm', 'Duplicate tag form: %1', id);
|
||||
}
|
||||
tags.mtFormats.set(id, [left, right, format]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \usetagform.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
UseTagForm(parser: TexParser, name: string) {
|
||||
const tags = parser.tags as MathtoolsTags;
|
||||
if (!('mtFormats' in tags)) {
|
||||
throw new TexError('TagsNotMT', '%1 can only be used with ams or mathtools tags', name);
|
||||
}
|
||||
const id = parser.GetArgument(name).trim();
|
||||
if (!id) {
|
||||
tags.mtCurrent = null;
|
||||
return;
|
||||
}
|
||||
if (!tags.mtFormats.has(id)) {
|
||||
throw new TexError('UndefinedTagForm', 'Undefined tag form: %1', id);
|
||||
}
|
||||
tags.mtCurrent = tags.mtFormats.get(id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements \mathtoolsset.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
SetOptions(parser: TexParser, name: string) {
|
||||
const options = parser.options.mathtools;
|
||||
if (!options['allow-mathtoolsset']) {
|
||||
throw new TexError('ForbiddenMathtoolsSet', '%1 is disabled', name);
|
||||
}
|
||||
const allowed = {} as {[id: string]: number};
|
||||
Object.keys(options).forEach(id => {
|
||||
if (id !== 'pariedDelimiters' && id !== 'tagforms' && id !== 'allow-mathtoolsset') {
|
||||
allowed[id] = 1;
|
||||
}
|
||||
});
|
||||
const args = parser.GetArgument(name);
|
||||
const keys = ParseUtil.keyvalOptions(args, allowed, true);
|
||||
for (const id of Object.keys(keys)) {
|
||||
options[id] = keys[id];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Use the Base or AMS methods for these
|
||||
*/
|
||||
Array: BaseMethods.Array,
|
||||
Macro: BaseMethods.Macro,
|
||||
xArrow: AmsMethods.xArrow,
|
||||
HandleRef: AmsMethods.HandleRef,
|
||||
AmsEqnArray: AmsMethods.AmsEqnArray,
|
||||
MacroWithTemplate: NewcommandMethods.MacroWithTemplate,
|
||||
|
||||
};
|
||||
116
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsTags.ts
generated
vendored
Normal file
116
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsTags.ts
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
/*************************************************************
|
||||
* Copyright (c) 2021-2022 MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Tags implementation for the mathtools package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import TexError from '../TexError.js';
|
||||
import {ParserConfiguration} from '../Configuration.js';
|
||||
import {TeX} from '../../tex.js';
|
||||
import {AbstractTags, TagsFactory} from '../Tags.js';
|
||||
|
||||
|
||||
/**
|
||||
* The type for the Mathtools tags (including their data).
|
||||
*/
|
||||
export type MathtoolsTags = AbstractTags & {
|
||||
mtFormats: Map<string, [string, string, string]>; // name -> [left, right, format]
|
||||
mtCurrent: [string, string, string]; // [left, right, format]
|
||||
};
|
||||
|
||||
/**
|
||||
* The ID number for the current tag class
|
||||
*/
|
||||
let tagID = 0;
|
||||
|
||||
/**
|
||||
* Creates and registers a subclass of the currently configured tag class
|
||||
* that handles the formats created by the \newtagform macro.
|
||||
*/
|
||||
export function MathtoolsTagFormat(config: ParserConfiguration, jax: TeX<any, any, any>) {
|
||||
/**
|
||||
* If the tag format is being added by one of the other extensions,
|
||||
* as is done for the 'ams' tags, make sure it is defined so we can create it.
|
||||
*/
|
||||
const tags = jax.parseOptions.options.tags;
|
||||
if (tags !== 'base' && config.tags.hasOwnProperty(tags)) {
|
||||
TagsFactory.add(tags, config.tags[tags]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The original tag class to be extended (none, ams, or all)
|
||||
*/
|
||||
const TagClass = TagsFactory.create(jax.parseOptions.options.tags).constructor as typeof AbstractTags;
|
||||
|
||||
/**
|
||||
* A Tags object that uses \newtagform to define the formatting
|
||||
*/
|
||||
class TagFormat extends TagClass {
|
||||
|
||||
/**
|
||||
* The defined tag formats
|
||||
*/
|
||||
public mtFormats: Map<string, [string, string, string]> = new Map();
|
||||
|
||||
/**
|
||||
* The format currently in use ([left, right, format]), or null for using the default
|
||||
*/
|
||||
public mtCurrent: [string, string, string] = null;
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
const forms = jax.parseOptions.options.mathtools.tagforms;
|
||||
for (const form of Object.keys(forms)) {
|
||||
if (!Array.isArray(forms[form]) || forms[form].length !== 3) {
|
||||
throw new TexError('InvalidTagFormDef',
|
||||
'The tag form definition for "%1" should be an array fo three strings', form);
|
||||
}
|
||||
this.mtFormats.set(form, forms[form]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public formatTag(tag: string) {
|
||||
if (this.mtCurrent) {
|
||||
const [left, right, format] = this.mtCurrent;
|
||||
return (format ? `${left}${format}{${tag}}${right}` : `${left}${tag}${right}`);
|
||||
}
|
||||
return super.formatTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Get a unique name for the tag class (since it is tied to the input jax)
|
||||
// Note: These never get freed, so they will accumulate if you create many
|
||||
// TeX input jax instances with this extension.
|
||||
//
|
||||
tagID++;
|
||||
const tagName = 'MathtoolsTags-' + tagID;
|
||||
//
|
||||
// Register the tag class
|
||||
//
|
||||
TagsFactory.add(tagName, TagFormat);
|
||||
jax.parseOptions.options.tags = tagName;
|
||||
}
|
||||
145
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsUtil.ts
generated
vendored
Normal file
145
node_modules/mathjax-full/ts/input/tex/mathtools/MathtoolsUtil.ts
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
/*************************************************************
|
||||
* Copyright (c) 2021-2022 MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Utility functions for the mathtools package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {EqnArrayItem} from '../base/BaseItems.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import TexError from '../TexError.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {Macro} from '../Symbol.js';
|
||||
import ParseOptions from '../ParseOptions.js';
|
||||
import {lookup} from '../../../util/Options.js';
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
|
||||
import {MathtoolsMethods} from './MathtoolsMethods.js';
|
||||
import {PAIREDDELIMS} from './MathtoolsConfiguration.js';
|
||||
|
||||
/**
|
||||
* Utility functions for the Mathtools package.
|
||||
*/
|
||||
export const MathtoolsUtil = {
|
||||
|
||||
/**
|
||||
* Set the displaystyle and scriptlevel attributes of an mstyle element
|
||||
*
|
||||
* @param {MmlNode} mml The mstyle node to modify.
|
||||
* @param {string} style The TeX style macro to apply.
|
||||
*/
|
||||
setDisplayLevel(mml: MmlNode, style: string) {
|
||||
if (!style) return;
|
||||
const [display, script] = lookup(style, {
|
||||
'\\displaystyle': [true, 0],
|
||||
'\\textstyle': [false, 0],
|
||||
'\\scriptstyle': [false, 1],
|
||||
'\\scriptscriptstyle': [false, 2]
|
||||
}, [null, null]);
|
||||
if (display !== null) {
|
||||
mml.attributes.set('displaystyle', display);
|
||||
mml.attributes.set('scriptlevel', script);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check that the top stack item is an alignment table.
|
||||
*
|
||||
* @param {TexParser} parser The current TeX parser.
|
||||
* @param {string} name The name of the macro doing the checking.
|
||||
* @return {EqnArrayItem} The top item (an EqnArrayItem).
|
||||
*/
|
||||
checkAlignment(parser: TexParser, name: string): EqnArrayItem {
|
||||
const top = parser.stack.Top() as EqnArrayItem;
|
||||
if (top.kind !== EqnArrayItem.prototype.kind) {
|
||||
throw new TexError('NotInAlignment', '%1 can only be used in aligment environments', name);
|
||||
}
|
||||
return top;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a paired delimiter to the list of them.
|
||||
*
|
||||
* @param {ParseOptions} config The parse options to modify.
|
||||
* @param {string} cs The control sequence for the paired delimiters.
|
||||
* @param {string[]} args The definition for the paired delimiters. One of:
|
||||
* [left, right]
|
||||
* [left, right, body, argcount]
|
||||
* [left, right, body, argcount, pre, post]
|
||||
*/
|
||||
addPairedDelims(config: ParseOptions, cs: string, args: string[]) {
|
||||
const delims = config.handlers.retrieve(PAIREDDELIMS) as CommandMap;
|
||||
delims.add(cs, new Macro(cs, MathtoolsMethods.PairedDelimiters, args));
|
||||
},
|
||||
|
||||
/**
|
||||
* Adjust the line spacing for a table.
|
||||
*
|
||||
* @param {MmlNode} mtable The mtable node to adjust (if it is a table).
|
||||
* @param {string} spread The dimension to change by (number-with-units).
|
||||
*/
|
||||
spreadLines(mtable: MmlNode, spread: string) {
|
||||
if (!mtable.isKind('mtable')) return;
|
||||
let rowspacing = mtable.attributes.get('rowspacing') as string;
|
||||
if (rowspacing) {
|
||||
const add = ParseUtil.dimen2em(spread);
|
||||
rowspacing = rowspacing
|
||||
.split(/ /)
|
||||
.map(s => ParseUtil.Em(Math.max(0, ParseUtil.dimen2em(s) + add)))
|
||||
.join(' ');
|
||||
} else {
|
||||
rowspacing = spread;
|
||||
}
|
||||
mtable.attributes.set('rowspacing', rowspacing);
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if a string is a number and return it with an explicit plus if there isn't one.
|
||||
*
|
||||
* @param {string} name The name of the macro doing the checking.
|
||||
* @param {string} n The string to test as a number.
|
||||
* @return {srtring} The number with an explicit sign.
|
||||
*/
|
||||
plusOrMinus(name: string, n: string): string {
|
||||
n = n.trim();
|
||||
if (!n.match(/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)$/)) {
|
||||
throw new TexError('NotANumber', 'Argument to %1 is not a number', name);
|
||||
}
|
||||
return (n.match(/^[-+]/) ? n : '+' + n);
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse a \prescript argument, with its associated format, if any.
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} name The name of the calling macro (\prescript).
|
||||
* @param {string} pos The position for the argument (sub, sup, arg).
|
||||
* @return {MmlNode} The parsed MML version of the argument.
|
||||
*/
|
||||
getScript(parser: TexParser, name: string, pos: string): MmlNode {
|
||||
let arg = ParseUtil.trimSpaces(parser.GetArgument(name));
|
||||
if (arg === '') {
|
||||
return parser.create('node', 'none');
|
||||
}
|
||||
const format = parser.options.mathtools[`prescript-${pos}-format`];
|
||||
format && (arg = `${format}{${arg}}`);
|
||||
return new TexParser(arg, parser.stack.env, parser.configuration).mml();
|
||||
}
|
||||
|
||||
};
|
||||
95
node_modules/mathjax-full/ts/input/tex/mhchem/MhchemConfiguration.ts
generated
vendored
Normal file
95
node_modules/mathjax-full/ts/input/tex/mhchem/MhchemConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the mhchem package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import TexError from '../TexError.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import BaseMethods from '../base/BaseMethods.js';
|
||||
import {AmsMethods} from '../ams/AmsMethods.js';
|
||||
import {mhchemParser} from 'mhchemparser/dist/mhchemParser.js';
|
||||
|
||||
// Namespace
|
||||
let MhchemMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
MhchemMethods.Macro = BaseMethods.Macro;
|
||||
MhchemMethods.xArrow = AmsMethods.xArrow;
|
||||
|
||||
/**
|
||||
* @param{TeXParser} parser The parser for this expression
|
||||
* @param{string} name The macro name being called
|
||||
* @param{string} machine The name of the fininte-state machine to use
|
||||
*/
|
||||
MhchemMethods.Machine = function(parser: TexParser, name: string, machine: 'tex' | 'ce' | 'pu') {
|
||||
let arg = parser.GetArgument(name);
|
||||
let tex;
|
||||
try {
|
||||
tex = mhchemParser.toTex(arg, machine);
|
||||
} catch (err) {
|
||||
throw new TexError(err[0], err[1]);
|
||||
}
|
||||
parser.string = tex + parser.string.substr(parser.i);
|
||||
parser.i = 0;
|
||||
};
|
||||
|
||||
new CommandMap(
|
||||
'mhchem', {
|
||||
ce: ['Machine', 'ce'],
|
||||
pu: ['Machine', 'pu'],
|
||||
longrightleftharpoons: [
|
||||
'Macro',
|
||||
'\\stackrel{\\textstyle{-}\\!\\!{\\rightharpoonup}}{\\smash{{\\leftharpoondown}\\!\\!{-}}}'
|
||||
],
|
||||
longRightleftharpoons: [
|
||||
'Macro',
|
||||
'\\stackrel{\\textstyle{-}\\!\\!{\\rightharpoonup}}{\\smash{\\leftharpoondown}}'
|
||||
],
|
||||
longLeftrightharpoons: [
|
||||
'Macro',
|
||||
'\\stackrel{\\textstyle\\vphantom{{-}}{\\rightharpoonup}}{\\smash{{\\leftharpoondown}\\!\\!{-}}}'
|
||||
],
|
||||
longleftrightarrows: [
|
||||
'Macro',
|
||||
'\\stackrel{\\longrightarrow}{\\smash{\\longleftarrow}\\Rule{0px}{.25em}{0px}}'
|
||||
],
|
||||
//
|
||||
// Needed for \bond for the ~ forms
|
||||
//
|
||||
tripledash: [
|
||||
'Macro',
|
||||
'\\vphantom{-}\\raise2mu{\\kern2mu\\tiny\\text{-}\\kern1mu\\text{-}\\kern1mu\\text{-}\\kern2mu}'
|
||||
],
|
||||
xleftrightarrow: ['xArrow', 0x2194, 6, 6],
|
||||
xrightleftharpoons: ['xArrow', 0x21CC, 5, 7], // FIXME: doesn't stretch in HTML-CSS output
|
||||
xRightleftharpoons: ['xArrow', 0x21CC, 5, 7], // FIXME: how should this be handled?
|
||||
xLeftrightharpoons: ['xArrow', 0x21CC, 5, 7]
|
||||
},
|
||||
MhchemMethods
|
||||
);
|
||||
|
||||
|
||||
export const MhchemConfiguration = Configuration.create(
|
||||
'mhchem', {handler: {macro: ['mhchem']}}
|
||||
);
|
||||
67
node_modules/mathjax-full/ts/input/tex/newcommand/NewcommandConfiguration.ts
generated
vendored
Normal file
67
node_modules/mathjax-full/ts/input/tex/newcommand/NewcommandConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the Newcommand package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration, ParserConfiguration} from '../Configuration.js';
|
||||
import {BeginEnvItem} from './NewcommandItems.js';
|
||||
import NewcommandUtil from './NewcommandUtil.js';
|
||||
import './NewcommandMappings.js';
|
||||
import ParseMethods from '../ParseMethods.js';
|
||||
import * as sm from '../SymbolMap.js';
|
||||
|
||||
|
||||
/**
|
||||
* Init method for Newcommand package.
|
||||
* @param {Configuration} config The current configuration.
|
||||
*/
|
||||
let init = function(config: ParserConfiguration) {
|
||||
new sm.DelimiterMap(NewcommandUtil.NEW_DELIMITER,
|
||||
ParseMethods.delimiter, {});
|
||||
new sm.CommandMap(NewcommandUtil.NEW_COMMAND, {}, {});
|
||||
new sm.EnvironmentMap(NewcommandUtil.NEW_ENVIRONMENT,
|
||||
ParseMethods.environment, {}, {});
|
||||
config.append(Configuration.local(
|
||||
{handler: {character: [],
|
||||
delimiter: [NewcommandUtil.NEW_DELIMITER],
|
||||
macro: [NewcommandUtil.NEW_DELIMITER,
|
||||
NewcommandUtil.NEW_COMMAND],
|
||||
environment: [NewcommandUtil.NEW_ENVIRONMENT]
|
||||
},
|
||||
priority: -1}));
|
||||
};
|
||||
|
||||
|
||||
export const NewcommandConfiguration = Configuration.create(
|
||||
'newcommand', {
|
||||
handler: {
|
||||
macro: ['Newcommand-macros']
|
||||
},
|
||||
items: {
|
||||
[BeginEnvItem.prototype.kind]: BeginEnvItem,
|
||||
},
|
||||
options: {maxMacros: 1000},
|
||||
init: init
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
74
node_modules/mathjax-full/ts/input/tex/newcommand/NewcommandItems.ts
generated
vendored
Normal file
74
node_modules/mathjax-full/ts/input/tex/newcommand/NewcommandItems.ts
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Items for TeX parsing of new environments.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import TexError from '../TexError.js';
|
||||
import {CheckType, BaseItem, StackItem} from '../StackItem.js';
|
||||
|
||||
|
||||
/**
|
||||
* Opening Item dealing with definitions of new environments. It's pushed onto
|
||||
* the stack whenever a user defined environment is encountered and remains
|
||||
* until a corresponding \\end collapses the stack.
|
||||
*/
|
||||
export class BeginEnvItem extends BaseItem {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public get kind() {
|
||||
return 'beginEnv';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
get isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public checkItem(item: StackItem): CheckType {
|
||||
if (item.isKind('end')) {
|
||||
// @test Newenvironment Empty, Newenvironment Align
|
||||
if (item.getName() !== this.getName()) {
|
||||
// @test (missing) \newenvironment{env}{aa}{bb}\begin{env}cc\end{equation}
|
||||
throw new TexError('EnvBadEnd', '\\begin{%1} ended with \\end{%2}',
|
||||
this.getName(), item.getName());
|
||||
}
|
||||
return [[this.factory.create('mml', this.toMml())], true];
|
||||
}
|
||||
if (item.isKind('stop')) {
|
||||
// @test (missing) \newenvironment{env}{aa}{bb}\begin{env}cc
|
||||
throw new TexError('EnvMissingEnd', 'Missing \\end{%1}', this.getName());
|
||||
}
|
||||
// @test Newenvironment Empty, Newenvironment Align
|
||||
return super.checkItem(item);
|
||||
}
|
||||
|
||||
}
|
||||
41
node_modules/mathjax-full/ts/input/tex/newcommand/NewcommandMappings.ts
generated
vendored
Normal file
41
node_modules/mathjax-full/ts/input/tex/newcommand/NewcommandMappings.ts
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Mappings for TeX parsing for definitorial commands.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import NewcommandMethods from './NewcommandMethods.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
|
||||
|
||||
/**
|
||||
* Macros for newcommand etc.
|
||||
*/
|
||||
new CommandMap('Newcommand-macros', {
|
||||
newcommand: 'NewCommand',
|
||||
renewcommand: 'NewCommand',
|
||||
newenvironment: 'NewEnvironment',
|
||||
renewenvironment: 'NewEnvironment',
|
||||
def: 'MacroDef',
|
||||
'let': 'Let'
|
||||
}, NewcommandMethods);
|
||||
|
||||
|
||||
244
node_modules/mathjax-full/ts/input/tex/newcommand/NewcommandMethods.ts
generated
vendored
Normal file
244
node_modules/mathjax-full/ts/input/tex/newcommand/NewcommandMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Mappings for TeX parsing for definitorial commands.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import TexError from '../TexError.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import * as sm from '../SymbolMap.js';
|
||||
import {Symbol, Macro} from '../Symbol.js';
|
||||
import BaseMethods from '../base/BaseMethods.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import {StackItem} from '../StackItem.js';
|
||||
import NewcommandUtil from './NewcommandUtil.js';
|
||||
|
||||
|
||||
// Namespace
|
||||
let NewcommandMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
/**
|
||||
* Implements \newcommand{\name}[n][default]{...}
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the calling command.
|
||||
*/
|
||||
NewcommandMethods.NewCommand = function(parser: TexParser, name: string) {
|
||||
// @test Newcommand Simple
|
||||
let cs = NewcommandUtil.GetCsNameArgument(parser, name);
|
||||
let n = NewcommandUtil.GetArgCount(parser, name);
|
||||
let opt = parser.GetBrackets(name);
|
||||
let def = parser.GetArgument(name);
|
||||
NewcommandUtil.addMacro(parser, cs, NewcommandMethods.Macro, [def, n, opt]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements \newenvironment{name}[n][default]{begincmd}{endcmd}
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the calling command.
|
||||
*/
|
||||
NewcommandMethods.NewEnvironment = function(parser: TexParser, name: string) {
|
||||
// @test Newenvironment Empty, Newenvironment Content
|
||||
let env = ParseUtil.trimSpaces(parser.GetArgument(name));
|
||||
let n = NewcommandUtil.GetArgCount(parser, name);
|
||||
let opt = parser.GetBrackets(name);
|
||||
let bdef = parser.GetArgument(name);
|
||||
let edef = parser.GetArgument(name);
|
||||
NewcommandUtil.addEnvironment(parser, env, NewcommandMethods.BeginEnv, [true, bdef, edef, n, opt]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements \def command.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the calling command.
|
||||
*/
|
||||
NewcommandMethods.MacroDef = function(parser: TexParser, name: string) {
|
||||
// @test Def DoubleLet, DefReDef
|
||||
let cs = NewcommandUtil.GetCSname(parser, name);
|
||||
let params = NewcommandUtil.GetTemplate(parser, name, '\\' + cs);
|
||||
let def = parser.GetArgument(name);
|
||||
!(params instanceof Array) ?
|
||||
// @test Def DoubleLet, DefReDef
|
||||
NewcommandUtil.addMacro(parser, cs, NewcommandMethods.Macro, [def, params]) :
|
||||
// @test Def Let
|
||||
NewcommandUtil.addMacro(parser, cs, NewcommandMethods.MacroWithTemplate, [def].concat(params));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements the \let command.
|
||||
*
|
||||
* All \let commands create either new delimiters or macros in the extension
|
||||
* maps. In the latter case if the let binds a symbol we have to generate a
|
||||
* macro with the appropriate parse methods from the SymbolMap. Otherwise we
|
||||
* simply copy the macro under a new name.
|
||||
*
|
||||
* Let does not always work on special characters as TeX does. For example
|
||||
* "\let\car^ a\car b" will yield a superscript, on the otherhand
|
||||
* \let\bgroup={ is possible and will work fine in \bgroup a } but will fail
|
||||
* in \sqrt\bgroup a}.
|
||||
*
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the calling command.
|
||||
*/
|
||||
NewcommandMethods.Let = function(parser: TexParser, name: string) {
|
||||
const cs = NewcommandUtil.GetCSname(parser, name);
|
||||
let c = parser.GetNext();
|
||||
// @test Let Bar, Let Caret
|
||||
if (c === '=') {
|
||||
// @test Let Brace Equal, Let Brace Equal Stretchy
|
||||
parser.i++;
|
||||
c = parser.GetNext();
|
||||
}
|
||||
const handlers = parser.configuration.handlers;
|
||||
if (c === '\\') {
|
||||
// @test Let Bar, Let Brace Equal Stretchy
|
||||
name = NewcommandUtil.GetCSname(parser, name);
|
||||
let macro = handlers.get('delimiter').lookup('\\' + name) as Symbol;
|
||||
if (macro) {
|
||||
// @test Let Bar, Let Brace Equal Stretchy
|
||||
NewcommandUtil.addDelimiter(parser, '\\' + cs, macro.char, macro.attributes);
|
||||
return;
|
||||
}
|
||||
const map = handlers.get('macro').applicable(name);
|
||||
if (!map) {
|
||||
// @test Let Undefined CS
|
||||
return;
|
||||
}
|
||||
if (map instanceof sm.MacroMap) {
|
||||
// @test Def Let, Newcommand Let
|
||||
const macro = (map as sm.CommandMap).lookup(name) as Macro;
|
||||
NewcommandUtil.addMacro(parser, cs, macro.func, macro.args, macro.symbol);
|
||||
return;
|
||||
}
|
||||
macro = (map as sm.CharacterMap).lookup(name) as Symbol;
|
||||
const newArgs = NewcommandUtil.disassembleSymbol(cs, macro);
|
||||
const method = (p: TexParser, _cs: string, ...rest: any[]) => {
|
||||
// @test Let Relet, Let Let, Let Circular Macro
|
||||
const symb = NewcommandUtil.assembleSymbol(rest);
|
||||
return map.parser(p, symb);
|
||||
};
|
||||
NewcommandUtil.addMacro(parser, cs, method, newArgs);
|
||||
return;
|
||||
}
|
||||
// @test Let Brace Equal, Let Caret
|
||||
parser.i++;
|
||||
const macro = handlers.get('delimiter').lookup(c) as Symbol;
|
||||
if (macro) {
|
||||
// @test Let Paren Delim, Let Paren Stretchy
|
||||
NewcommandUtil.addDelimiter(parser, '\\' + cs, macro.char, macro.attributes);
|
||||
return;
|
||||
}
|
||||
// @test Let Brace Equal, Let Caret
|
||||
NewcommandUtil.addMacro(parser, cs, NewcommandMethods.Macro, [c]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Process a macro with a parameter template by replacing parameters in the
|
||||
* parser's string.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the calling command.
|
||||
* @param {string} text The text template of the macro.
|
||||
* @param {string} n The number of parameters.
|
||||
* @param {string[]} ...params The parameter values.
|
||||
*/
|
||||
NewcommandMethods.MacroWithTemplate = function (parser: TexParser, name: string,
|
||||
text: string, n: string,
|
||||
...params: string[]) {
|
||||
const argCount = parseInt(n, 10);
|
||||
// @test Def Let
|
||||
if (argCount) {
|
||||
// @test Def Let
|
||||
let args = [];
|
||||
parser.GetNext();
|
||||
if (params[0] && !NewcommandUtil.MatchParam(parser, params[0])) {
|
||||
// @test Missing Arguments
|
||||
throw new TexError('MismatchUseDef',
|
||||
'Use of %1 doesn\'t match its definition', name);
|
||||
}
|
||||
for (let i = 0; i < argCount; i++) {
|
||||
// @test Def Let
|
||||
args.push(NewcommandUtil.GetParameter(parser, name, params[i + 1]));
|
||||
}
|
||||
text = ParseUtil.substituteArgs(parser, args, text);
|
||||
}
|
||||
parser.string = ParseUtil.addArgs(parser, text,
|
||||
parser.string.slice(parser.i));
|
||||
parser.i = 0;
|
||||
ParseUtil.checkMaxMacros(parser);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Process a user-defined environment.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {StackItem} begin The begin stackitem.
|
||||
* @param {string} bdef The begin definition in the newenvironment macro.
|
||||
* @param {string} edef The end definition in the newenvironment macro.
|
||||
* @param {number} n The number of parameters.
|
||||
* @param {string} def Default for an optional parameter.
|
||||
*/
|
||||
NewcommandMethods.BeginEnv = function(parser: TexParser, begin: StackItem,
|
||||
bdef: string, edef: string, n: number, def: string) {
|
||||
// @test Newenvironment Empty, Newenvironment Content
|
||||
// We have an end item, and we are supposed to close this environment.
|
||||
if (begin.getProperty('end') && parser.stack.env['closing'] === begin.getName()) {
|
||||
// @test Newenvironment Empty, Newenvironment Content
|
||||
delete parser.stack.env['closing'];
|
||||
// Parse the commands in the end environment definition.
|
||||
let rest = parser.string.slice(parser.i);
|
||||
parser.string = edef;
|
||||
parser.i = 0;
|
||||
parser.Parse();
|
||||
// Reset to parsing the remainder of the expression.
|
||||
parser.string = rest;
|
||||
parser.i = 0;
|
||||
// Close this environment.
|
||||
return parser.itemFactory.create('end').setProperty('name', begin.getName());
|
||||
}
|
||||
if (n) {
|
||||
// @test Newenvironment Optional, Newenvironment Arg Optional
|
||||
let args: string[] = [];
|
||||
if (def != null) {
|
||||
// @test Newenvironment Optional, Newenvironment Arg Optional
|
||||
let optional = parser.GetBrackets('\\begin{' + begin.getName() + '}');
|
||||
args.push(optional == null ? def : optional);
|
||||
}
|
||||
for (let i = args.length; i < n; i++) {
|
||||
// @test Newenvironment Arg Optional
|
||||
args.push(parser.GetArgument('\\begin{' + begin.getName() + '}'));
|
||||
}
|
||||
bdef = ParseUtil.substituteArgs(parser, args, bdef);
|
||||
edef = ParseUtil.substituteArgs(parser, [], edef); // no args, but get errors for #n in edef
|
||||
}
|
||||
parser.string = ParseUtil.addArgs(parser, bdef,
|
||||
parser.string.slice(parser.i));
|
||||
parser.i = 0;
|
||||
return parser.itemFactory.create('beginEnv').setProperty('name', begin.getName());
|
||||
};
|
||||
|
||||
NewcommandMethods.Macro = BaseMethods.Macro;
|
||||
|
||||
export default NewcommandMethods;
|
||||
326
node_modules/mathjax-full/ts/input/tex/newcommand/NewcommandUtil.ts
generated
vendored
Normal file
326
node_modules/mathjax-full/ts/input/tex/newcommand/NewcommandUtil.ts
generated
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Utility functions for the newcommand package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import TexError from '../TexError.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {Macro, Symbol} from '../Symbol.js';
|
||||
import {Args, Attributes, ParseMethod} from '../Types.js';
|
||||
import * as sm from '../SymbolMap.js';
|
||||
|
||||
|
||||
namespace NewcommandUtil {
|
||||
|
||||
/**
|
||||
* Transforms the attributes of a symbol into the arguments of a macro. E.g.,
|
||||
* Symbol('ell', 'l', {mathvariant: "italic"}) is turned into Macro arguments:
|
||||
* ['ell', 'l', 'mathvariant', 'italic'].
|
||||
*
|
||||
* @param {string} name The command name for the symbol.
|
||||
* @param {Symbol} symbol The symbol associated with name.
|
||||
* @return {Args[]} Arguments for a macro.
|
||||
*/
|
||||
export function disassembleSymbol(name: string, symbol: Symbol): Args[] {
|
||||
let newArgs = [name, symbol.char] as Args[];
|
||||
// @test Let Relet, Let Let, Let Circular Macro
|
||||
if (symbol.attributes) {
|
||||
// @test Let Relet
|
||||
for (let key in symbol.attributes) {
|
||||
newArgs.push(key);
|
||||
newArgs.push(symbol.attributes[key] as Args);
|
||||
}
|
||||
}
|
||||
return newArgs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assembles a symbol from a list of macro arguments. This is the inverse
|
||||
* method of the one above.
|
||||
*
|
||||
* @param {Args[]} args The arguments of the macro.
|
||||
* @return {Symbol} The Symbol generated from the arguments..
|
||||
*/
|
||||
export function assembleSymbol(args: Args[]): Symbol {
|
||||
// @test Let Relet, Let Let, Let Circular Macro
|
||||
let name = args[0] as string;
|
||||
let char = args[1] as string;
|
||||
let attrs: Attributes = {};
|
||||
for (let i = 2; i < args.length; i = i + 2) {
|
||||
// @test Let Relet
|
||||
attrs[args[i] as string] = args[i + 1];
|
||||
}
|
||||
return new Symbol(name, char, attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next CS name or give an error.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} cmd The string starting with a control sequence.
|
||||
* @return {string} The control sequence.
|
||||
*/
|
||||
export function GetCSname(parser: TexParser, cmd: string): string {
|
||||
// @test Def ReDef, Let Bar, Let Brace Equal
|
||||
let c = parser.GetNext();
|
||||
if (c !== '\\') {
|
||||
// @test No CS
|
||||
throw new TexError('MissingCS',
|
||||
'%1 must be followed by a control sequence', cmd);
|
||||
}
|
||||
let cs = ParseUtil.trimSpaces(parser.GetArgument(cmd));
|
||||
return cs.substr(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a control sequence name as an argument (doesn't require the backslash)
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro that is getting the name.
|
||||
* @return {string} The control sequence.
|
||||
*/
|
||||
export function GetCsNameArgument(parser: TexParser, name: string): string {
|
||||
let cs = ParseUtil.trimSpaces(parser.GetArgument(name));
|
||||
if (cs.charAt(0) === '\\') {
|
||||
// @test Newcommand Simple
|
||||
cs = cs.substr(1);
|
||||
}
|
||||
if (!cs.match(/^(.|[a-z]+)$/i)) {
|
||||
// @test Illegal CS
|
||||
throw new TexError('IllegalControlSequenceName',
|
||||
'Illegal control sequence name for %1', name);
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of arguments for a macro definition
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro that is getting the argument count.
|
||||
* @return {string} The number of arguments (or blank).
|
||||
*/
|
||||
export function GetArgCount(parser: TexParser, name: string): string {
|
||||
let n = parser.GetBrackets(name);
|
||||
if (n) {
|
||||
// @test Newcommand Optional, Newcommand Arg, Newcommand Arg Optional
|
||||
// @test Newenvironment Optional, Newenvironment Arg Optional
|
||||
n = ParseUtil.trimSpaces(n);
|
||||
if (!n.match(/^[0-9]+$/)) {
|
||||
// @test Illegal Argument Number
|
||||
throw new TexError('IllegalParamNumber',
|
||||
'Illegal number of parameters specified in %1', name);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a \def parameter template.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} cmd The string starting with the template.
|
||||
* @param {string} cs The control sequence of the \def.
|
||||
* @return {number | string[]} The number of parameters or a string array if
|
||||
* there is an optional argument.
|
||||
*/
|
||||
export function GetTemplate(parser: TexParser, cmd: string, cs: string): number | string[] {
|
||||
// @test Def Double Let, Def ReDef, Def Let
|
||||
let c = parser.GetNext();
|
||||
let params: string[] = [];
|
||||
let n = 0;
|
||||
let i = parser.i;
|
||||
while (parser.i < parser.string.length) {
|
||||
c = parser.GetNext();
|
||||
if (c === '#') {
|
||||
// @test Def ReDef, Def Let, Def Optional Brace
|
||||
if (i !== parser.i) {
|
||||
// @test Def Let, Def Optional Brace
|
||||
params[n] = parser.string.substr(i, parser.i - i);
|
||||
}
|
||||
c = parser.string.charAt(++parser.i);
|
||||
if (!c.match(/^[1-9]$/)) {
|
||||
// @test Illegal Hash
|
||||
throw new TexError('CantUseHash2',
|
||||
'Illegal use of # in template for %1', cs);
|
||||
}
|
||||
if (parseInt(c) !== ++n) {
|
||||
// @test No Sequence
|
||||
throw new TexError('SequentialParam',
|
||||
'Parameters for %1 must be numbered sequentially', cs);
|
||||
}
|
||||
i = parser.i + 1;
|
||||
} else if (c === '{') {
|
||||
// @test Def Double Let, Def ReDef, Def Let
|
||||
if (i !== parser.i) {
|
||||
// @test Optional Brace Error
|
||||
params[n] = parser.string.substr(i, parser.i - i);
|
||||
}
|
||||
if (params.length > 0) {
|
||||
// @test Def Let, Def Optional Brace
|
||||
return [n.toString()].concat(params);
|
||||
} else {
|
||||
// @test Def Double Let, Def ReDef
|
||||
return n;
|
||||
}
|
||||
}
|
||||
parser.i++;
|
||||
}
|
||||
// @test No Replacement
|
||||
throw new TexError('MissingReplacementString',
|
||||
'Missing replacement string for definition of %1', cmd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find a single parameter delimited by a trailing template.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The name of the calling command.
|
||||
* @param {string} param The parameter for the macro.
|
||||
*/
|
||||
export function GetParameter(parser: TexParser, name: string, param: string) {
|
||||
if (param == null) {
|
||||
// @test Def Let, Def Optional Brace, Def Options CS
|
||||
return parser.GetArgument(name);
|
||||
}
|
||||
let i = parser.i;
|
||||
let j = 0;
|
||||
let hasBraces = 0;
|
||||
while (parser.i < parser.string.length) {
|
||||
let c = parser.string.charAt(parser.i);
|
||||
// @test Def Let, Def Optional Brace, Def Options CS
|
||||
if (c === '{') {
|
||||
// @test Def Optional Brace, Def Options CS
|
||||
if (parser.i === i) {
|
||||
// @test Def Optional Brace
|
||||
hasBraces = 1;
|
||||
}
|
||||
parser.GetArgument(name);
|
||||
j = parser.i - i;
|
||||
} else if (MatchParam(parser, param)) {
|
||||
// @test Def Let, Def Optional Brace, Def Options CS
|
||||
if (hasBraces) {
|
||||
// @test Def Optional Brace
|
||||
i++;
|
||||
j -= 2;
|
||||
}
|
||||
return parser.string.substr(i, j);
|
||||
} else if (c === '\\') {
|
||||
// @test Def Options CS
|
||||
parser.i++;
|
||||
j++;
|
||||
hasBraces = 0;
|
||||
let match = parser.string.substr(parser.i).match(/[a-z]+|./i);
|
||||
if (match) {
|
||||
// @test Def Options CS
|
||||
parser.i += match[0].length;
|
||||
j = parser.i - i;
|
||||
}
|
||||
} else {
|
||||
// @test Def Let
|
||||
parser.i++;
|
||||
j++;
|
||||
hasBraces = 0;
|
||||
}
|
||||
}
|
||||
// @test Runaway Argument
|
||||
throw new TexError('RunawayArgument', 'Runaway argument for %1?', name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a template is at the current location.
|
||||
* (The match must be exact, with no spacing differences. TeX is
|
||||
* a little more forgiving than this about spaces after macro names)
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} param Tries to match an optional parameter.
|
||||
* @return {number} The number of optional parameters, either 0 or 1.
|
||||
*/
|
||||
export function MatchParam(parser: TexParser, param: string): number {
|
||||
// @test Def Let, Def Optional Brace, Def Options CS
|
||||
if (parser.string.substr(parser.i, param.length) !== param) {
|
||||
// @test Def Let, Def Options CS
|
||||
return 0;
|
||||
}
|
||||
if (param.match(/\\[a-z]+$/i) &&
|
||||
parser.string.charAt(parser.i + param.length).match(/[a-z]/i)) {
|
||||
// @test (missing)
|
||||
return 0;
|
||||
}
|
||||
// @test Def Let, Def Optional Brace, Def Options CS
|
||||
parser.i += param.length;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new delimiter as extension to the parser.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} cs The control sequence of the delimiter.
|
||||
* @param {string} char The corresponding character.
|
||||
* @param {Attributes} attr The attributes needed for parsing.
|
||||
*/
|
||||
export function addDelimiter(parser: TexParser, cs: string, char: string, attr: Attributes) {
|
||||
const handlers = parser.configuration.handlers;
|
||||
const handler = handlers.retrieve(NEW_DELIMITER) as sm.DelimiterMap;
|
||||
handler.add(cs, new Symbol(cs, char, attr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new macro as extension to the parser.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} cs The control sequence of the delimiter.
|
||||
* @param {ParseMethod} func The parse method for this macro.
|
||||
* @param {Args[]} attr The attributes needed for parsing.
|
||||
* @param {string=} symbol Optionally original symbol for macro, in case it is
|
||||
* different from the control sequence.
|
||||
*/
|
||||
export function addMacro(parser: TexParser, cs: string, func: ParseMethod, attr: Args[],
|
||||
symbol: string = '') {
|
||||
const handlers = parser.configuration.handlers;
|
||||
const handler = handlers.retrieve(NEW_COMMAND) as sm.CommandMap;
|
||||
handler.add(cs, new Macro(symbol ? symbol : cs, func, attr));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new environment as extension to the parser.
|
||||
* @param {TexParser} parser The current parser.
|
||||
* @param {string} env The environment name.
|
||||
* @param {ParseMethod} func The parse method for this macro.
|
||||
* @param {Args[]} attr The attributes needed for parsing.
|
||||
*/
|
||||
export function addEnvironment(parser: TexParser, env: string, func: ParseMethod, attr: Args[]) {
|
||||
const handlers = parser.configuration.handlers;
|
||||
const handler = handlers.retrieve(NEW_ENVIRONMENT) as sm.EnvironmentMap;
|
||||
handler.add(env, new Macro(env, func, attr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Naming constants for the extension mappings.
|
||||
*/
|
||||
export const NEW_DELIMITER = 'new-Delimiter';
|
||||
export const NEW_COMMAND = 'new-Command';
|
||||
export const NEW_ENVIRONMENT = 'new-Environment';
|
||||
|
||||
}
|
||||
|
||||
export default NewcommandUtil;
|
||||
46
node_modules/mathjax-full/ts/input/tex/noerrors/NoErrorsConfiguration.ts
generated
vendored
Normal file
46
node_modules/mathjax-full/ts/input/tex/noerrors/NoErrorsConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the NoErrors package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {NodeFactory} from '../NodeFactory.js';
|
||||
|
||||
/**
|
||||
* Generates an error node containing the erroneous expression.
|
||||
* @param {TexParser} parser The node factory.
|
||||
* @param {string} message The error message (which is ignored).
|
||||
* @param {string} id The error id (which is ignored).
|
||||
* @param {string} expr The original LaTeX expression.
|
||||
*/
|
||||
function noErrors(factory: NodeFactory,
|
||||
message: string, _id: string, expr: string) {
|
||||
let mtext = factory.create('token', 'mtext', {}, expr.replace(/\n/g, ' '));
|
||||
let error = factory.create('node', 'merror', [mtext], {'data-mjx-error': message, title: message});
|
||||
return error;
|
||||
}
|
||||
|
||||
export const NoErrorsConfiguration = Configuration.create(
|
||||
'noerrors', {nodes: {'error': noErrors}}
|
||||
);
|
||||
|
||||
|
||||
60
node_modules/mathjax-full/ts/input/tex/noundefined/NoUndefinedConfiguration.ts
generated
vendored
Normal file
60
node_modules/mathjax-full/ts/input/tex/noundefined/NoUndefinedConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the AMS package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
|
||||
/**
|
||||
* Generates a red version of the undefined control sequence, instead of
|
||||
* throwing an error.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
function noUndefined(parser: TexParser, name: string) {
|
||||
const textNode = parser.create('text', '\\' + name);
|
||||
const options = parser.options.noundefined || {};
|
||||
const def = {} as {[name: string]: string};
|
||||
for (const id of ['color', 'background', 'size']) {
|
||||
if (options[id]) {
|
||||
def['math' + id] = options[id];
|
||||
}
|
||||
}
|
||||
parser.Push(parser.create('node', 'mtext', [], def, textNode));
|
||||
}
|
||||
|
||||
export const NoUndefinedConfiguration = Configuration.create(
|
||||
'noundefined', {
|
||||
fallback: {macro: noUndefined},
|
||||
options: {
|
||||
noundefined: {
|
||||
color: 'red',
|
||||
background: '',
|
||||
size: ''
|
||||
}
|
||||
},
|
||||
priority: 3
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
57
node_modules/mathjax-full/ts/input/tex/physics/PhysicsConfiguration.ts
generated
vendored
Normal file
57
node_modules/mathjax-full/ts/input/tex/physics/PhysicsConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the Physics package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {AutoOpen} from './PhysicsItems.js';
|
||||
import './PhysicsMappings.js';
|
||||
|
||||
|
||||
export const PhysicsConfiguration = Configuration.create(
|
||||
'physics', {
|
||||
handler: {
|
||||
macro: [
|
||||
'Physics-automatic-bracing-macros',
|
||||
'Physics-vector-macros',
|
||||
'Physics-vector-mo',
|
||||
'Physics-vector-mi',
|
||||
'Physics-derivative-macros',
|
||||
'Physics-expressions-macros',
|
||||
'Physics-quick-quad-macros',
|
||||
'Physics-bra-ket-macros',
|
||||
'Physics-matrix-macros'
|
||||
],
|
||||
character: ['Physics-characters'],
|
||||
environment: ['Physics-aux-envs']
|
||||
},
|
||||
items: {
|
||||
[AutoOpen.prototype.kind]: AutoOpen
|
||||
},
|
||||
options: {
|
||||
physics: {
|
||||
italicdiff: false,
|
||||
arrowdel: false
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
120
node_modules/mathjax-full/ts/input/tex/physics/PhysicsItems.ts
generated
vendored
Normal file
120
node_modules/mathjax-full/ts/input/tex/physics/PhysicsItems.ts
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2009-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Stack items for the physics package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import {CheckType, BaseItem, StackItem} from '../StackItem.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {AbstractMmlTokenNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
|
||||
export class AutoOpen extends BaseItem {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
protected static errors = Object.assign(Object.create(BaseItem.errors), {
|
||||
'stop': ['ExtraOrMissingDelims', 'Extra open or missing close delimiter']
|
||||
});
|
||||
|
||||
/**
|
||||
* The number of unpaired open delimiters that need to be matched before
|
||||
* a close delimiter will close this item. (#2831)
|
||||
*/
|
||||
protected openCount: number = 0;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public get kind() {
|
||||
return 'auto open';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
get isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public toMml() {
|
||||
// Smash and right/left
|
||||
let parser = this.factory.configuration.parser;
|
||||
let right = this.getProperty('right') as string;
|
||||
if (this.getProperty('smash')) {
|
||||
let mml = super.toMml();
|
||||
const smash = parser.create('node', 'mpadded', [mml],
|
||||
{height: 0, depth: 0});
|
||||
this.Clear();
|
||||
this.Push(parser.create('node', 'TeXAtom', [smash]));
|
||||
}
|
||||
if (right) {
|
||||
this.Push(new TexParser(right, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
}
|
||||
let mml = ParseUtil.fenced(
|
||||
this.factory.configuration,
|
||||
this.getProperty('open') as string,
|
||||
super.toMml(),
|
||||
this.getProperty('close') as string,
|
||||
this.getProperty('big') as string
|
||||
);
|
||||
//
|
||||
// Remove fence markers that would cause it to be TeX class INNER,
|
||||
// so it is treated as a regular mrow when setting the tex class (#2760)
|
||||
//
|
||||
NodeUtil.removeProperties(mml, 'open', 'close', 'texClass');
|
||||
return mml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public checkItem(item: StackItem): CheckType {
|
||||
//
|
||||
// Check for nested open delimiters (#2831)
|
||||
//
|
||||
if (item.isKind('mml') && item.Size() === 1) {
|
||||
const mml = item.toMml();
|
||||
if (mml.isKind('mo') && (mml as AbstractMmlTokenNode).getText() === this.getProperty('open')) {
|
||||
this.openCount++;
|
||||
}
|
||||
}
|
||||
let close = item.getProperty('autoclose');
|
||||
if (close && close === this.getProperty('close') && !this.openCount--) {
|
||||
if (this.getProperty('ignore')) {
|
||||
this.Clear();
|
||||
return [[], true];
|
||||
}
|
||||
return [[this.toMml()], true];
|
||||
}
|
||||
return super.checkItem(item);
|
||||
}
|
||||
|
||||
}
|
||||
299
node_modules/mathjax-full/ts/input/tex/physics/PhysicsMappings.ts
generated
vendored
Normal file
299
node_modules/mathjax-full/ts/input/tex/physics/PhysicsMappings.ts
generated
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Mappings for TeX parsing of the physics package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {EnvironmentMap, CommandMap, MacroMap, CharacterMap} from '../SymbolMap.js';
|
||||
import PhysicsMethods from './PhysicsMethods.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import ParseMethods from '../ParseMethods.js';
|
||||
import {TEXCLASS} from '../../../core/MmlTree/MmlNode.js';
|
||||
|
||||
|
||||
/**
|
||||
* Macros for physics package (section 2.1).
|
||||
*/
|
||||
new CommandMap('Physics-automatic-bracing-macros', {
|
||||
'quantity': 'Quantity',
|
||||
'qty': 'Quantity',
|
||||
'pqty': ['Quantity', '(', ')', true],
|
||||
'bqty': ['Quantity', '[', ']', true],
|
||||
'vqty': ['Quantity', '|', '|', true],
|
||||
'Bqty': ['Quantity', '\\{', '\\}', true],
|
||||
'absolutevalue': ['Quantity', '|', '|', true],
|
||||
'abs': ['Quantity', '|', '|', true],
|
||||
'norm': ['Quantity', '\\|', '\\|', true],
|
||||
'evaluated': 'Eval',
|
||||
'eval': 'Eval',
|
||||
'order': ['Quantity', '(', ')', true, 'O',
|
||||
TexConstant.Variant.CALLIGRAPHIC],
|
||||
'commutator': 'Commutator',
|
||||
'comm': 'Commutator',
|
||||
'anticommutator': ['Commutator', '\\{', '\\}'],
|
||||
'acomm': ['Commutator', '\\{', '\\}'],
|
||||
'poissonbracket': ['Commutator', '\\{', '\\}'],
|
||||
'pb': ['Commutator', '\\{', '\\}']
|
||||
}, PhysicsMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Macros for physics package (section 2.2).
|
||||
*/
|
||||
new CharacterMap('Physics-vector-mo', ParseMethods.mathchar0mo, {
|
||||
dotproduct: ['\u22C5', {mathvariant: TexConstant.Variant.BOLD}],
|
||||
vdot: ['\u22C5', {mathvariant: TexConstant.Variant.BOLD}],
|
||||
crossproduct: '\u00D7',
|
||||
cross: '\u00D7',
|
||||
cp: '\u00D7',
|
||||
// This is auxiliary!
|
||||
gradientnabla: ['\u2207', {mathvariant: TexConstant.Variant.BOLD}]
|
||||
});
|
||||
|
||||
new CharacterMap('Physics-vector-mi', ParseMethods.mathchar0mi, {
|
||||
real: ['\u211C', {mathvariant: TexConstant.Variant.NORMAL}],
|
||||
imaginary: ['\u2111', {mathvariant: TexConstant.Variant.NORMAL}]
|
||||
});
|
||||
|
||||
new CommandMap('Physics-vector-macros', {
|
||||
'vnabla': 'Vnabla',
|
||||
'vectorbold': 'VectorBold',
|
||||
'vb': 'VectorBold',
|
||||
'vectorarrow': ['StarMacro', 1, '\\vec{\\vb', '{#1}}'],
|
||||
'va': ['StarMacro', 1, '\\vec{\\vb', '{#1}}'],
|
||||
'vectorunit': ['StarMacro', 1, '\\hat{\\vb', '{#1}}'],
|
||||
'vu': ['StarMacro', 1, '\\hat{\\vb', '{#1}}'],
|
||||
'gradient': ['OperatorApplication', '\\vnabla', '(', '['],
|
||||
'grad': ['OperatorApplication', '\\vnabla', '(', '['],
|
||||
'divergence': ['VectorOperator', '\\vnabla\\vdot', '(', '['],
|
||||
'div': ['VectorOperator', '\\vnabla\\vdot', '(', '['],
|
||||
'curl': ['VectorOperator', '\\vnabla\\crossproduct', '(', '['],
|
||||
'laplacian': ['OperatorApplication', '\\nabla^2', '(', '['],
|
||||
}, PhysicsMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Macros for physics package (section 2.3).
|
||||
*/
|
||||
new CommandMap('Physics-expressions-macros', {
|
||||
'sin': 'Expression',
|
||||
'sinh': 'Expression',
|
||||
'arcsin': 'Expression',
|
||||
'asin': 'Expression',
|
||||
'cos': 'Expression',
|
||||
'cosh': 'Expression',
|
||||
'arccos': 'Expression',
|
||||
'acos': 'Expression',
|
||||
'tan': 'Expression',
|
||||
'tanh': 'Expression',
|
||||
'arctan': 'Expression',
|
||||
'atan': 'Expression',
|
||||
'csc': 'Expression',
|
||||
'csch': 'Expression',
|
||||
'arccsc': 'Expression',
|
||||
'acsc': 'Expression',
|
||||
'sec': 'Expression',
|
||||
'sech': 'Expression',
|
||||
'arcsec': 'Expression',
|
||||
'asec': 'Expression',
|
||||
'cot': 'Expression',
|
||||
'coth': 'Expression',
|
||||
'arccot': 'Expression',
|
||||
'acot': 'Expression',
|
||||
'exp': ['Expression', false],
|
||||
'log': 'Expression',
|
||||
'ln': 'Expression',
|
||||
'det': ['Expression', false],
|
||||
'Pr': ['Expression', false],
|
||||
// New expressions.
|
||||
'tr': ['Expression', false],
|
||||
'trace': ['Expression', false, 'tr'],
|
||||
'Tr': ['Expression', false],
|
||||
'Trace': ['Expression', false, 'Tr'],
|
||||
'rank': 'NamedFn',
|
||||
'erf': ['Expression', false],
|
||||
'Residue': ['Macro', '\\mathrm{Res}'],
|
||||
'Res': ['OperatorApplication', '\\Residue', '(', '[', '{'],
|
||||
'principalvalue': ['OperatorApplication', '{\\cal P}'],
|
||||
'pv': ['OperatorApplication', '{\\cal P}'],
|
||||
'PV': ['OperatorApplication', '{\\rm P.V.}'],
|
||||
'Re': ['OperatorApplication', '\\mathrm{Re}', '{'],
|
||||
'Im': ['OperatorApplication', '\\mathrm{Im}', '{'],
|
||||
// Old named functions.
|
||||
'sine': ['NamedFn', 'sin'],
|
||||
'hypsine': ['NamedFn', 'sinh'],
|
||||
'arcsine': ['NamedFn', 'arcsin'],
|
||||
'asine': ['NamedFn', 'asin'],
|
||||
'cosine': ['NamedFn', 'cos'],
|
||||
'hypcosine': ['NamedFn', 'cosh'],
|
||||
'arccosine': ['NamedFn', 'arccos'],
|
||||
'acosine': ['NamedFn', 'acos'],
|
||||
'tangent': ['NamedFn', 'tan'],
|
||||
'hyptangent': ['NamedFn', 'tanh'],
|
||||
'arctangent': ['NamedFn', 'arctan'],
|
||||
'atangent': ['NamedFn', 'atan'],
|
||||
'cosecant': ['NamedFn', 'csc'],
|
||||
'hypcosecant': ['NamedFn', 'csch'],
|
||||
'arccosecant': ['NamedFn', 'arccsc'],
|
||||
'acosecant': ['NamedFn', 'acsc'],
|
||||
'secant': ['NamedFn', 'sec'],
|
||||
'hypsecant': ['NamedFn', 'sech'],
|
||||
'arcsecant': ['NamedFn', 'arcsec'],
|
||||
'asecant': ['NamedFn', 'asec'],
|
||||
'cotangent': ['NamedFn', 'cot'],
|
||||
'hypcotangent': ['NamedFn', 'coth'],
|
||||
'arccotangent': ['NamedFn', 'arccot'],
|
||||
'acotangent': ['NamedFn', 'acot'],
|
||||
'exponential': ['NamedFn', 'exp'],
|
||||
'logarithm': ['NamedFn', 'log'],
|
||||
'naturallogarithm': ['NamedFn', 'ln'],
|
||||
'determinant': ['NamedFn', 'det'],
|
||||
'Probability': ['NamedFn', 'Pr'],
|
||||
}, PhysicsMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Macros for physics package (section 2.4).
|
||||
*/
|
||||
new CommandMap('Physics-quick-quad-macros', {
|
||||
'qqtext': 'Qqtext',
|
||||
'qq': 'Qqtext',
|
||||
'qcomma': ['Macro', '\\qqtext*{,}'],
|
||||
'qc': ['Macro', '\\qqtext*{,}'],
|
||||
'qcc': ['Qqtext', 'c.c.'],
|
||||
'qif': ['Qqtext', 'if'],
|
||||
'qthen': ['Qqtext', 'then'],
|
||||
'qelse': ['Qqtext', 'else'],
|
||||
'qotherwise': ['Qqtext', 'otherwise'],
|
||||
'qunless': ['Qqtext', 'unless'],
|
||||
'qgiven': ['Qqtext', 'given'],
|
||||
'qusing': ['Qqtext', 'using'],
|
||||
'qassume': ['Qqtext', 'assume'],
|
||||
'qsince': ['Qqtext', 'since'],
|
||||
'qlet': ['Qqtext', 'let'],
|
||||
'qfor': ['Qqtext', 'for'],
|
||||
'qall': ['Qqtext', 'all'],
|
||||
'qeven': ['Qqtext', 'even'],
|
||||
'qodd': ['Qqtext', 'odd'],
|
||||
'qinteger': ['Qqtext', 'integer'],
|
||||
'qand': ['Qqtext', 'and'],
|
||||
'qor': ['Qqtext', 'or'],
|
||||
'qas': ['Qqtext', 'as'],
|
||||
'qin': ['Qqtext', 'in'],
|
||||
}, PhysicsMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Macros for physics package (section 2.5).
|
||||
*/
|
||||
new CommandMap('Physics-derivative-macros', {
|
||||
'diffd': 'DiffD',
|
||||
'flatfrac': ['Macro', '\\left.#1\\middle/#2\\right.', 2],
|
||||
'differential': ['Differential', '\\diffd'],
|
||||
'dd': ['Differential', '\\diffd'],
|
||||
'variation': ['Differential', '\\delta'],
|
||||
'var': ['Differential', '\\delta'],
|
||||
'derivative': ['Derivative', 2, '\\diffd'],
|
||||
'dv': ['Derivative', 2, '\\diffd'],
|
||||
'partialderivative': ['Derivative', 3, '\\partial'],
|
||||
'pderivative': ['Derivative', 3, '\\partial'],
|
||||
'pdv': ['Derivative', 3, '\\partial'],
|
||||
'functionalderivative': ['Derivative', 2, '\\delta'],
|
||||
'fderivative': ['Derivative', 2, '\\delta'],
|
||||
'fdv': ['Derivative', 2, '\\delta'],
|
||||
}, PhysicsMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Macros for physics package (section 2.6).
|
||||
*/
|
||||
new CommandMap('Physics-bra-ket-macros', {
|
||||
'bra': 'Bra',
|
||||
'ket': 'Ket',
|
||||
'innerproduct': 'BraKet',
|
||||
'ip': 'BraKet',
|
||||
'braket': 'BraKet',
|
||||
'outerproduct': 'KetBra',
|
||||
'dyad': 'KetBra',
|
||||
'ketbra': 'KetBra',
|
||||
'op': 'KetBra',
|
||||
'expectationvalue': 'Expectation',
|
||||
'expval': 'Expectation',
|
||||
'ev': 'Expectation',
|
||||
'matrixelement': 'MatrixElement',
|
||||
'matrixel': 'MatrixElement',
|
||||
'mel': 'MatrixElement',
|
||||
}, PhysicsMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Macros for physics package (section 2.7).
|
||||
*/
|
||||
new CommandMap('Physics-matrix-macros', {
|
||||
'matrixquantity': 'MatrixQuantity',
|
||||
'mqty' : 'MatrixQuantity',
|
||||
'pmqty': ['Macro', '\\mqty(#1)', 1],
|
||||
'Pmqty': ['Macro', '\\mqty*(#1)', 1],
|
||||
'bmqty': ['Macro', '\\mqty[#1]', 1],
|
||||
'vmqty': ['Macro', '\\mqty|#1|', 1],
|
||||
// Smallmatrices
|
||||
'smallmatrixquantity': ['MatrixQuantity', true],
|
||||
'smqty': ['MatrixQuantity', true],
|
||||
'spmqty': ['Macro', '\\smqty(#1)', 1],
|
||||
'sPmqty': ['Macro', '\\smqty*(#1)', 1],
|
||||
'sbmqty': ['Macro', '\\smqty[#1]', 1],
|
||||
'svmqty': ['Macro', '\\smqty|#1|', 1],
|
||||
'matrixdeterminant': ['Macro', '\\vmqty{#1}', 1],
|
||||
'mdet': ['Macro', '\\vmqty{#1}', 1],
|
||||
'smdet': ['Macro', '\\svmqty{#1}', 1],
|
||||
'identitymatrix': 'IdentityMatrix',
|
||||
'imat': 'IdentityMatrix',
|
||||
'xmatrix': 'XMatrix',
|
||||
'xmat': 'XMatrix',
|
||||
'zeromatrix': ['Macro', '\\xmat{0}{#1}{#2}', 2],
|
||||
'zmat': ['Macro', '\\xmat{0}{#1}{#2}', 2],
|
||||
'paulimatrix': 'PauliMatrix',
|
||||
'pmat': 'PauliMatrix',
|
||||
'diagonalmatrix': 'DiagonalMatrix',
|
||||
'dmat': 'DiagonalMatrix',
|
||||
'antidiagonalmatrix': ['DiagonalMatrix', true],
|
||||
'admat': ['DiagonalMatrix', true]
|
||||
}, PhysicsMethods);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Auxiliary environment map to define smallmatrix. This makes Physics
|
||||
* independent of AmsMath.
|
||||
*/
|
||||
new EnvironmentMap('Physics-aux-envs', ParseMethods.environment, {
|
||||
smallmatrix: ['Array', null, null, null, 'c', '0.333em', '.2em', 'S', 1]
|
||||
}, PhysicsMethods);
|
||||
|
||||
|
||||
/**
|
||||
* Character map for braket package.
|
||||
*/
|
||||
new MacroMap('Physics-characters', {
|
||||
'|': ['AutoClose', TEXCLASS.ORD], // texClass: TEXCLASS.ORD, // Have to push the closer as mml with special property
|
||||
')': 'AutoClose',
|
||||
']': 'AutoClose'
|
||||
}, PhysicsMethods);
|
||||
971
node_modules/mathjax-full/ts/input/tex/physics/PhysicsMethods.ts
generated
vendored
Normal file
971
node_modules/mathjax-full/ts/input/tex/physics/PhysicsMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,971 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Methods for TeX parsing of the physics package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {ParseMethod} from '../Types.js';
|
||||
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 NodeUtil from '../NodeUtil.js';
|
||||
import {NodeFactory} from '../NodeFactory.js';
|
||||
import {Macro} from '../Symbol.js';
|
||||
|
||||
|
||||
let PhysicsMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
|
||||
/***********************
|
||||
* Physics package section 2.1
|
||||
* Automatic bracing
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pairs open and closed fences.
|
||||
* @type {{[fence: string]: string}}
|
||||
*/
|
||||
const pairs: {[fence: string]: string} = {
|
||||
'(': ')',
|
||||
'[': ']',
|
||||
'{': '}',
|
||||
'|': '|',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for matching big fence arguments.
|
||||
* @type {RegExp}
|
||||
*/
|
||||
const biggs: RegExp = /^(b|B)i(g{1,2})$/;
|
||||
|
||||
|
||||
/**
|
||||
* Automatic sizing of fences, e.g., \\qty(x). Some with content.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string=} open Opening fence.
|
||||
* @param {string=} close Closing fence.
|
||||
* @param {boolean=} arg Fences contain an argument.
|
||||
* @param {string=} named Name operator.
|
||||
* @param {string=} variant A font for the mathvariant.
|
||||
*/
|
||||
PhysicsMethods.Quantity = function(parser: TexParser, name: string,
|
||||
open: string = '(', close: string = ')',
|
||||
arg: boolean = false, named: string = '',
|
||||
variant: string = '') {
|
||||
let star = arg ? parser.GetStar() : false;
|
||||
let next = parser.GetNext();
|
||||
let position = parser.i;
|
||||
let big = null;
|
||||
if (next === '\\') {
|
||||
parser.i++;
|
||||
big = parser.GetCS();
|
||||
if (!big.match(biggs)) {
|
||||
// empty
|
||||
let empty = parser.create('node', 'mrow');
|
||||
parser.Push(ParseUtil.fenced(parser.configuration, open, empty, close));
|
||||
parser.i = position;
|
||||
return;
|
||||
}
|
||||
next = parser.GetNext();
|
||||
}
|
||||
let right = pairs[next];
|
||||
if (arg && next !== '{') {
|
||||
throw new TexError('MissingArgFor', 'Missing argument for %1', parser.currentCS);
|
||||
}
|
||||
if (!right) {
|
||||
let empty = parser.create('node', 'mrow');
|
||||
parser.Push(ParseUtil.fenced(parser.configuration, open, empty, close));
|
||||
parser.i = position;
|
||||
return;
|
||||
}
|
||||
// Get the fences
|
||||
if (named) {
|
||||
const mml = parser.create('token', 'mi', {texClass: TEXCLASS.OP}, named);
|
||||
if (variant) {
|
||||
NodeUtil.setAttribute(mml, 'mathvariant', variant);
|
||||
}
|
||||
parser.Push(parser.itemFactory.create('fn', mml));
|
||||
}
|
||||
if (next === '{') {
|
||||
let argument = parser.GetArgument(name);
|
||||
next = arg ? open : '\\{';
|
||||
right = arg ? close : '\\}';
|
||||
// TODO: Make all these fenced expressions.
|
||||
argument = star ? next + ' ' + argument + ' ' + right :
|
||||
(big ?
|
||||
'\\' + big + 'l' + next + ' ' + argument + ' ' + '\\' + big + 'r' + right :
|
||||
'\\left' + next + ' ' + argument + ' ' + '\\right' + right);
|
||||
parser.Push(new TexParser(argument, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
return;
|
||||
}
|
||||
if (arg) {
|
||||
next = open;
|
||||
right = close;
|
||||
}
|
||||
parser.i++;
|
||||
parser.Push(parser.itemFactory.create('auto open')
|
||||
.setProperties({open: next, close: right, big: big}));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The evaluate macro.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.Eval = function(parser: TexParser, name: string) {
|
||||
let star = parser.GetStar();
|
||||
let next = parser.GetNext();
|
||||
if (next === '{') {
|
||||
let arg = parser.GetArgument(name);
|
||||
let replace = '\\left. ' +
|
||||
(star ? '\\smash{' + arg + '}' : arg) +
|
||||
' ' + '\\vphantom{\\int}\\right|';
|
||||
parser.string = parser.string.slice(0, parser.i) + replace +
|
||||
parser.string.slice(parser.i);
|
||||
return;
|
||||
}
|
||||
if (next === '(' || next === '[') {
|
||||
parser.i++;
|
||||
parser.Push(parser.itemFactory.create('auto open')
|
||||
.setProperties(
|
||||
{open: next, close: '|',
|
||||
smash: star, right: '\\vphantom{\\int}'}));
|
||||
return;
|
||||
}
|
||||
throw new TexError('MissingArgFor', 'Missing argument for %1', parser.currentCS);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The anti/commutator and poisson macros.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string=} open Opening fence.
|
||||
* @param {string=} close Closing fence.
|
||||
*/
|
||||
PhysicsMethods.Commutator = function(parser: TexParser, name: string,
|
||||
open: string = '[', close: string = ']') {
|
||||
let star = parser.GetStar();
|
||||
let next = parser.GetNext();
|
||||
let big = null;
|
||||
if (next === '\\') {
|
||||
parser.i++;
|
||||
big = parser.GetCS();
|
||||
if (!big.match(biggs)) {
|
||||
// Actually a commutator error arg1 error.
|
||||
throw new TexError('MissingArgFor', 'Missing argument for %1', parser.currentCS);
|
||||
}
|
||||
next = parser.GetNext();
|
||||
}
|
||||
if (next !== '{') {
|
||||
throw new TexError('MissingArgFor', 'Missing argument for %1', parser.currentCS);
|
||||
}
|
||||
let arg1 = parser.GetArgument(name);
|
||||
let arg2 = parser.GetArgument(name);
|
||||
let argument = arg1 + ',' + arg2;
|
||||
argument = star ? open + ' ' + argument + ' ' + close :
|
||||
(big ?
|
||||
'\\' + big + 'l' + open + ' ' + argument + ' ' + '\\' + big + 'r' + close :
|
||||
'\\left' + open + ' ' + argument + ' ' + '\\right' + close);
|
||||
parser.Push(new TexParser(argument, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
};
|
||||
|
||||
|
||||
/***********************
|
||||
* Physics package section 2.2
|
||||
* Vector notation
|
||||
*/
|
||||
|
||||
let latinCap: [number, number] = [0x41, 0x5A];
|
||||
let latinSmall: [number, number] = [0x61, 0x7A];
|
||||
let greekCap: [number, number] = [0x391, 0x3A9];
|
||||
let greekSmall: [number, number] = [0x3B1, 0x3C9];
|
||||
let digits: [number, number] = [0x30, 0x39];
|
||||
|
||||
/**
|
||||
* Checks if a value is in a given numerical interval.
|
||||
* @param {number} value The value.
|
||||
* @param {[number, number]} range The closed interval.
|
||||
*/
|
||||
function inRange(value: number, range: [number, number]) {
|
||||
return (value >= range[0] && value <= range[1]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to create a token for the vector commands. It creates a vector token
|
||||
* with the specific vector font (e.g., bold) in case it is a Latin or capital
|
||||
* Greek character, accent or small Greek character if command is starred. This
|
||||
* is a replacement for the original token method in the node factory.
|
||||
* @param {NodeFactory} factory The current node factory.
|
||||
* @param {string} kind The type of token to create.
|
||||
* @param {any} def The attributes for the node.
|
||||
* @param {string} text The text contained in the token node.
|
||||
* @return {MmlNode} The newly create token node.
|
||||
*/
|
||||
function createVectorToken(factory: NodeFactory, kind: string,
|
||||
def: any, text: string): MmlNode {
|
||||
let parser = factory.configuration.parser;
|
||||
let token = NodeFactory.createToken(factory, kind, def, text);
|
||||
let code: number = text.codePointAt(0);
|
||||
if (text.length === 1 && !parser.stack.env.font &&
|
||||
parser.stack.env.vectorFont &&
|
||||
(inRange(code, latinCap) || inRange(code, latinSmall) ||
|
||||
inRange(code, greekCap) || inRange(code, digits) ||
|
||||
(inRange(code, greekSmall) && parser.stack.env.vectorStar) ||
|
||||
NodeUtil.getAttribute(token, 'accent'))) {
|
||||
NodeUtil.setAttribute(token, 'mathvariant', parser.stack.env.vectorFont);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bold vector notation.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.VectorBold = function(parser: TexParser, name: string) {
|
||||
let star = parser.GetStar();
|
||||
let arg = parser.GetArgument(name);
|
||||
let oldToken = parser.configuration.nodeFactory.get('token');
|
||||
let oldFont = parser.stack.env.font;
|
||||
delete parser.stack.env.font;
|
||||
parser.configuration.nodeFactory.set('token', createVectorToken);
|
||||
parser.stack.env.vectorFont = star ? 'bold-italic' : 'bold';
|
||||
parser.stack.env.vectorStar = star;
|
||||
let node = new TexParser(arg, parser.stack.env, parser.configuration).mml();
|
||||
if (oldFont) {
|
||||
parser.stack.env.font = oldFont;
|
||||
}
|
||||
delete parser.stack.env.vectorFont;
|
||||
delete parser.stack.env.vectorStar;
|
||||
parser.configuration.nodeFactory.set('token', oldToken);
|
||||
parser.Push(node);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Macros that can have an optional star which is propagated.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {number} argcount Number of arguments.
|
||||
* @param {string[]} ...parts List of parts from which to assemble the macro.
|
||||
* If the original command is starred, a star will be injected at each part.
|
||||
*/
|
||||
PhysicsMethods.StarMacro = function(parser: TexParser, name: string,
|
||||
argcount: number, ...parts: string[]) {
|
||||
let star = parser.GetStar();
|
||||
const args: string[] = [];
|
||||
if (argcount) {
|
||||
for (let i = args.length; i < argcount; i++) {
|
||||
args.push(parser.GetArgument(name));
|
||||
}
|
||||
}
|
||||
let macro = parts.join(star ? '*' : '');
|
||||
macro = ParseUtil.substituteArgs(parser, args, macro);
|
||||
parser.string = ParseUtil.addArgs(parser, macro, parser.string.slice(parser.i));
|
||||
parser.i = 0;
|
||||
ParseUtil.checkMaxMacros(parser);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Computes the application of a vector operation.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} kind The type of stack item to parse the operator into.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} operator The operator expression.
|
||||
* @param {string[]} ...fences List of opening fences that should be
|
||||
* automatically sized and paired to its corresponding closing fence.
|
||||
*/
|
||||
let vectorApplication = function(
|
||||
parser: TexParser, kind: string, name: string, operator: string,
|
||||
fences: string[]) {
|
||||
let op = new TexParser(operator, parser.stack.env,
|
||||
parser.configuration).mml();
|
||||
parser.Push(parser.itemFactory.create(kind, op));
|
||||
let left = parser.GetNext();
|
||||
let right = pairs[left];
|
||||
if (!right) {
|
||||
return;
|
||||
}
|
||||
let lfence = '', rfence = '', arg = '';
|
||||
let enlarge = fences.indexOf(left) !== -1;
|
||||
if (left === '{') {
|
||||
arg = parser.GetArgument(name);
|
||||
lfence = enlarge ? '\\left\\{' : '';
|
||||
rfence = enlarge ? '\\right\\}' : '';
|
||||
let macro = lfence + ' ' + arg + ' ' + rfence;
|
||||
parser.string = macro + parser.string.slice(parser.i);
|
||||
parser.i = 0;
|
||||
return;
|
||||
}
|
||||
if (!enlarge) {
|
||||
return;
|
||||
}
|
||||
parser.i++;
|
||||
parser.Push(parser.itemFactory.create('auto open')
|
||||
.setProperties({open: left, close: right}));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* An operator that needs to be parsed (e.g., a Greek letter or nabla) and
|
||||
* applied to a possibly fenced expression. By default automatic fences are
|
||||
* parentheses and brakets, with braces being ignored.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} operator The operator expression.
|
||||
* @param {string[]} ...fences List of opening fences that should be
|
||||
* automatically sized and paired to its corresponding closing fence.
|
||||
*/
|
||||
PhysicsMethods.OperatorApplication = function(
|
||||
parser: TexParser, name: string, operator: string,
|
||||
...fences: string[]) {
|
||||
vectorApplication(parser, 'fn', name, operator, fences);
|
||||
};
|
||||
|
||||
/**
|
||||
* A vector operator that needs to be parsed (e.g., a Greek letter or nabla with
|
||||
* a crossproduct) and connected to a possibly fenced expression. By default
|
||||
* automatic fences are parentheses and brakets.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} operator The operator expression.
|
||||
* @param {string[]} ...fences List of opening fences that should be
|
||||
* automatically sized and paired to its corresponding closing fence.
|
||||
*/
|
||||
PhysicsMethods.VectorOperator = function(
|
||||
parser: TexParser, name: string, operator: string,
|
||||
...fences: string[]) {
|
||||
vectorApplication(parser, 'mml', name, operator, fences);
|
||||
};
|
||||
|
||||
|
||||
/***********************
|
||||
* Physics package section 2.3
|
||||
* Operators
|
||||
*/
|
||||
|
||||
/**
|
||||
* Operator expression with automatic fences and optional exponent.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {boolean=} opt Set to false if no optional exponent is allowed.
|
||||
* @param {string=} id The name of the function if different from name.
|
||||
*/
|
||||
PhysicsMethods.Expression = function(parser: TexParser, name: string,
|
||||
opt: boolean = true, id: string = '') {
|
||||
id = id || name.slice(1);
|
||||
const exp = opt ? parser.GetBrackets(name) : null;
|
||||
let mml = parser.create('token', 'mi', {texClass: TEXCLASS.OP}, id);
|
||||
if (exp) {
|
||||
const sup = new TexParser(exp,
|
||||
parser.stack.env, parser.configuration).mml();
|
||||
mml = parser.create('node', 'msup', [mml, sup]);
|
||||
}
|
||||
parser.Push(parser.itemFactory.create('fn', mml));
|
||||
if (parser.GetNext() !== '(') {
|
||||
return;
|
||||
}
|
||||
parser.i++;
|
||||
parser.Push(parser.itemFactory.create('auto open')
|
||||
.setProperties({open: '(', close: ')'}));
|
||||
};
|
||||
|
||||
|
||||
/***********************
|
||||
* Physics package section 2.4
|
||||
* Quick quad text
|
||||
*/
|
||||
|
||||
/**
|
||||
* Quad text macros.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} text The text that is to be padded with quad spaces.
|
||||
*/
|
||||
PhysicsMethods.Qqtext = function(parser: TexParser, name: string,
|
||||
text: string) {
|
||||
let star = parser.GetStar();
|
||||
let arg = text ? text : parser.GetArgument(name);
|
||||
let replace = (star ? '' : '\\quad') + '\\text{' + arg + '}\\quad ';
|
||||
parser.string = parser.string.slice(0, parser.i) + replace +
|
||||
parser.string.slice(parser.i);
|
||||
};
|
||||
|
||||
|
||||
/***********************
|
||||
* Physics package section 2.5
|
||||
* Derivatives
|
||||
*/
|
||||
|
||||
/**
|
||||
* The differential and variation macros.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {string} op The operator. It will be parsed.
|
||||
*/
|
||||
PhysicsMethods.Differential = function(parser: TexParser, name: string,
|
||||
op: string) {
|
||||
const optArg = parser.GetBrackets(name);
|
||||
const power = optArg != null ? '^{' + optArg + '}' : ' ';
|
||||
const parens = parser.GetNext() === '(';
|
||||
const braces = parser.GetNext() === '{';
|
||||
let macro = op + power;
|
||||
if (!(parens || braces)) {
|
||||
macro += parser.GetArgument(name, true) || '';
|
||||
let mml = new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml();
|
||||
parser.Push(mml);
|
||||
return;
|
||||
}
|
||||
if (braces) {
|
||||
macro += parser.GetArgument(name);
|
||||
const mml = new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml();
|
||||
parser.Push(parser.create('node', 'TeXAtom', [mml], {texClass: TEXCLASS.OP}));
|
||||
return;
|
||||
}
|
||||
parser.Push(new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
parser.i++;
|
||||
parser.Push(parser.itemFactory.create('auto open')
|
||||
.setProperties({open: '(', close: ')'}));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The derivative macro. Its behaviour depends on the number of arguments
|
||||
* provided. In case of
|
||||
* 1 argument: will be part of the denominator.
|
||||
* 2 arguments: argument one is numerator, argument two is denominator.
|
||||
* 3+ arguments: arguments above 2 will be part of the denominator and the
|
||||
* exponent of the enumerator will depend on the number of denominator
|
||||
* arguments. In particular, the optional exponent argument will be ignored!
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {number} argMax The maximum number of arguments for the macro.
|
||||
* @param {string} op The derivative operator.
|
||||
*/
|
||||
PhysicsMethods.Derivative = function(parser: TexParser, name: string,
|
||||
argMax: number, op: string) {
|
||||
const star = parser.GetStar();
|
||||
const optArg = parser.GetBrackets(name);
|
||||
let argCounter = 1;
|
||||
const args = [];
|
||||
args.push(parser.GetArgument(name));
|
||||
while (parser.GetNext() === '{' && argCounter < argMax) {
|
||||
args.push(parser.GetArgument(name));
|
||||
argCounter++;
|
||||
}
|
||||
let ignore = false;
|
||||
let power1 = ' ';
|
||||
let power2 = ' ';
|
||||
if (argMax > 2 && args.length > 2) {
|
||||
power1 = '^{' + (args.length - 1) + '}';
|
||||
ignore = true;
|
||||
} else if (optArg != null) {
|
||||
if (argMax > 2 && args.length > 1) {
|
||||
ignore = true;
|
||||
}
|
||||
power1 = '^{' + optArg + '}';
|
||||
power2 = power1;
|
||||
}
|
||||
const frac = star ? '\\flatfrac' : '\\frac';
|
||||
const first = args.length > 1 ? args[0] : '';
|
||||
const second = args.length > 1 ? args[1] : args[0];
|
||||
let rest = '';
|
||||
for (let i = 2, arg; arg = args[i]; i++) {
|
||||
rest += op + ' ' + arg;
|
||||
}
|
||||
const macro = frac + '{' + op + power1 + first + '}' +
|
||||
'{' + op + ' ' + second + power2 + ' ' + rest + '}';
|
||||
parser.Push(new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
if (parser.GetNext() === '(') {
|
||||
parser.i++;
|
||||
parser.Push(parser.itemFactory.create('auto open')
|
||||
.setProperties({open: '(', close: ')', ignore: ignore}));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/***********************
|
||||
* Physics package section 2.6
|
||||
* Dirac bra-ket notation
|
||||
*/
|
||||
|
||||
/**
|
||||
* The bra macro.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.Bra = function(parser: TexParser, name: string) {
|
||||
let starBra = parser.GetStar();
|
||||
let bra = parser.GetArgument(name);
|
||||
let ket = '';
|
||||
let hasKet = false;
|
||||
let starKet = false;
|
||||
if (parser.GetNext() === '\\') {
|
||||
let saveI = parser.i;
|
||||
parser.i++;
|
||||
// This ensures that bra-ket also works if \let bound versions of \ket.
|
||||
let cs = parser.GetCS();
|
||||
let symbol = parser.lookup('macro', cs) as Macro;
|
||||
if (symbol && symbol.symbol === 'ket') {
|
||||
hasKet = true;
|
||||
saveI = parser.i;
|
||||
starKet = parser.GetStar();
|
||||
if (parser.GetNext() === '{') {
|
||||
ket = parser.GetArgument(cs, true);
|
||||
} else {
|
||||
parser.i = saveI;
|
||||
starKet = false;
|
||||
}
|
||||
} else {
|
||||
parser.i = saveI;
|
||||
}
|
||||
}
|
||||
let macro = '';
|
||||
if (hasKet) {
|
||||
macro = (starBra || starKet) ?
|
||||
`\\langle{${bra}}\\vert{${ket}}\\rangle` :
|
||||
`\\left\\langle{${bra}}\\middle\\vert{${ket}}\\right\\rangle`;
|
||||
} else {
|
||||
macro = (starBra || starKet) ?
|
||||
`\\langle{${bra}}\\vert` : `\\left\\langle{${bra}}\\right\\vert{${ket}}`;
|
||||
}
|
||||
parser.Push(new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The ket macro.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.Ket = function(parser: TexParser, name: string) {
|
||||
let star = parser.GetStar();
|
||||
let ket = parser.GetArgument(name);
|
||||
let macro = star ? `\\vert{${ket}}\\rangle` :
|
||||
`\\left\\vert{${ket}}\\right\\rangle`;
|
||||
parser.Push(new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The braket macro.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.BraKet = function(parser: TexParser, name: string) {
|
||||
let star = parser.GetStar();
|
||||
let bra = parser.GetArgument(name);
|
||||
let ket = null;
|
||||
if (parser.GetNext() === '{') {
|
||||
ket = parser.GetArgument(name, true);
|
||||
}
|
||||
let macro = '';
|
||||
if (ket == null) {
|
||||
macro = star ?
|
||||
`\\langle{${bra}}\\vert{${bra}}\\rangle` :
|
||||
`\\left\\langle{${bra}}\\middle\\vert{${bra}}\\right\\rangle`;
|
||||
} else {
|
||||
macro = star ?
|
||||
`\\langle{${bra}}\\vert{${ket}}\\rangle` :
|
||||
`\\left\\langle{${bra}}\\middle\\vert{${ket}}\\right\\rangle`;
|
||||
}
|
||||
parser.Push(new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The ketbra macro.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.KetBra = function(parser: TexParser, name: string) {
|
||||
let star = parser.GetStar();
|
||||
let ket = parser.GetArgument(name);
|
||||
let bra = null;
|
||||
if (parser.GetNext() === '{') {
|
||||
bra = parser.GetArgument(name, true);
|
||||
}
|
||||
let macro = '';
|
||||
if (bra == null) {
|
||||
macro = star ?
|
||||
`\\vert{${ket}}\\rangle\\!\\langle{${ket}}\\vert` :
|
||||
`\\left\\vert{${ket}}\\middle\\rangle\\!\\middle\\langle{${ket}}\\right\\vert`;
|
||||
} else {
|
||||
macro = star ?
|
||||
`\\vert{${ket}}\\rangle\\!\\langle{${bra}}\\vert` :
|
||||
`\\left\\vert{${ket}}\\middle\\rangle\\!\\middle\\langle{${bra}}\\right\\vert`;
|
||||
}
|
||||
parser.Push(new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generates the expanded braket LaTeX code for matrix operations.
|
||||
* @param {[string, string, string]} [arg1, arg2, arg3] The three arguments
|
||||
* <arg1|arg2|arg3>.
|
||||
* @param {boolean} star1 No automatic sizing of fences.
|
||||
* @param {boolean} star2 Automatic sizing of fences wrt. to arg1 & arg3 only.
|
||||
*/
|
||||
function outputBraket([arg1, arg2, arg3]: [string, string, string],
|
||||
star1: boolean, star2: boolean) {
|
||||
return (star1 && star2) ?
|
||||
`\\left\\langle{${arg1}}\\middle\\vert{${arg2}}\\middle\\vert{${arg3}}\\right\\rangle` :
|
||||
(star1 ? `\\langle{${arg1}}\\vert{${arg2}}\\vert{${arg3}}\\rangle` :
|
||||
`\\left\\langle{${arg1}}\\right\\vert{${arg2}}\\left\\vert{${arg3}}\\right\\rangle`);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The expectation value macro.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.Expectation = function(parser: TexParser, name: string) {
|
||||
let star1 = parser.GetStar();
|
||||
let star2 = star1 && parser.GetStar();
|
||||
let arg1 = parser.GetArgument(name);
|
||||
let arg2 = null;
|
||||
if (parser.GetNext() === '{') {
|
||||
arg2 = parser.GetArgument(name, true);
|
||||
}
|
||||
let macro = (arg1 && arg2) ?
|
||||
outputBraket([arg2, arg1, arg2], star1, star2) :
|
||||
// Braces for semantics, similar to braket package.
|
||||
(star1 ? `\\langle {${arg1}} \\rangle` :
|
||||
`\\left\\langle {${arg1}} \\right\\rangle`);
|
||||
parser.Push(new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The matrix element macro.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.MatrixElement = function(parser: TexParser, name: string) {
|
||||
const star1 = parser.GetStar();
|
||||
const star2 = star1 && parser.GetStar();
|
||||
const arg1 = parser.GetArgument(name);
|
||||
const arg2 = parser.GetArgument(name);
|
||||
const arg3 = parser.GetArgument(name);
|
||||
const macro = outputBraket([arg1, arg2, arg3], star1, star2);
|
||||
parser.Push(new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
};
|
||||
|
||||
|
||||
|
||||
/********************
|
||||
* Physics package Section 2.7
|
||||
* Matrix macros
|
||||
*/
|
||||
/**
|
||||
* The matrix quantity macro.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {boolean=} small Use small matrix.
|
||||
*/
|
||||
PhysicsMethods.MatrixQuantity = function(parser: TexParser, name: string, small?: boolean) {
|
||||
const star = parser.GetStar();
|
||||
const next = parser.GetNext();
|
||||
const array = small ? 'smallmatrix' : 'array';
|
||||
let arg = '';
|
||||
let open = '';
|
||||
let close = '';
|
||||
switch (next) {
|
||||
case '{':
|
||||
arg = parser.GetArgument(name);
|
||||
break;
|
||||
case '(':
|
||||
parser.i++;
|
||||
open = star ? '\\lgroup' : '(';
|
||||
close = star ? '\\rgroup' : ')';
|
||||
arg = parser.GetUpTo(name, ')');
|
||||
break;
|
||||
case '[':
|
||||
parser.i++;
|
||||
open = '[';
|
||||
close = ']';
|
||||
arg = parser.GetUpTo(name, ']');
|
||||
break;
|
||||
case '|':
|
||||
parser.i++;
|
||||
open = '|';
|
||||
close = '|';
|
||||
arg = parser.GetUpTo(name, '|');
|
||||
break;
|
||||
default:
|
||||
open = '(';
|
||||
close = ')';
|
||||
break;
|
||||
}
|
||||
const macro = (open ? '\\left' : '') + open +
|
||||
'\\begin{' + array + '}{} ' + arg + '\\end{' + array + '}' +
|
||||
(open ? '\\right' : '') + close;
|
||||
parser.Push(new TexParser(macro, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generation of identity matrices.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.IdentityMatrix = function(parser: TexParser, name: string) {
|
||||
const arg = parser.GetArgument(name);
|
||||
const size = parseInt(arg, 10);
|
||||
if (isNaN(size)) {
|
||||
throw new TexError('InvalidNumber', 'Invalid number');
|
||||
}
|
||||
if (size <= 1) {
|
||||
parser.string = '1' + parser.string.slice(parser.i);
|
||||
parser.i = 0;
|
||||
return;
|
||||
}
|
||||
let zeros = Array(size).fill('0');
|
||||
let columns = [];
|
||||
for (let i = 0; i < size; i++) {
|
||||
let row = zeros.slice();
|
||||
row[i] = '1';
|
||||
columns.push(row.join(' & '));
|
||||
}
|
||||
parser.string = columns.join('\\\\ ') + parser.string.slice(parser.i);
|
||||
parser.i = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generation of matrices with fixed value.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.XMatrix = function(parser: TexParser, name: string) {
|
||||
const star = parser.GetStar();
|
||||
const arg1 = parser.GetArgument(name);
|
||||
const arg2 = parser.GetArgument(name);
|
||||
const arg3 = parser.GetArgument(name);
|
||||
let n = parseInt(arg2, 10);
|
||||
let m = parseInt(arg3, 10);
|
||||
if (isNaN(n) || isNaN(m) || m.toString() !== arg3 || n.toString() !== arg2) {
|
||||
throw new TexError('InvalidNumber', 'Invalid number');
|
||||
}
|
||||
n = n < 1 ? 1 : n;
|
||||
m = m < 1 ? 1 : m;
|
||||
// Elements
|
||||
if (!star) {
|
||||
const row = Array(m).fill(arg1).join(' & ');
|
||||
const matrix = Array(n).fill(row).join('\\\\ ');
|
||||
parser.string = matrix + parser.string.slice(parser.i);
|
||||
parser.i = 0;
|
||||
return;
|
||||
}
|
||||
let matrix = '';
|
||||
if (n === 1 && m === 1) {
|
||||
// Case 1: n=m=1, no index.
|
||||
matrix = arg1;
|
||||
} else if (n === 1) {
|
||||
// Case 2: n=1, row vector, single index.
|
||||
let row = [];
|
||||
for (let i = 1; i <= m; i++) {
|
||||
row.push(`${arg1}_{${i}}`);
|
||||
}
|
||||
matrix = row.join(' & ');
|
||||
} else if (m === 1) {
|
||||
// Case 3: m=1, column vector, single index.
|
||||
let row = [];
|
||||
for (let i = 1; i <= n; i++) {
|
||||
row.push(`${arg1}_{${i}}`);
|
||||
}
|
||||
matrix = row.join('\\\\ ');
|
||||
} else {
|
||||
// Case 4: matrix, double index. Note the extra mrows for indices.
|
||||
let rows = [];
|
||||
for (let i = 1; i <= n; i++) {
|
||||
let row = [];
|
||||
for (let j = 1; j <= m; j++) {
|
||||
row.push(`${arg1}_{{${i}}{${j}}}`);
|
||||
}
|
||||
rows.push(row.join(' & '));
|
||||
}
|
||||
matrix = rows.join('\\\\ ');
|
||||
}
|
||||
parser.string = matrix + parser.string.slice(parser.i);
|
||||
parser.i = 0;
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generation of Pauli matrices. Matrix 0 is the 2x2 identity.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.PauliMatrix = function(parser: TexParser, name: string) {
|
||||
const arg = parser.GetArgument(name);
|
||||
let matrix = arg.slice(1);
|
||||
switch (arg[0]) {
|
||||
case '0':
|
||||
matrix += ' 1 & 0\\\\ 0 & 1';
|
||||
break;
|
||||
case '1':
|
||||
case 'x':
|
||||
matrix += ' 0 & 1\\\\ 1 & 0';
|
||||
break;
|
||||
case '2':
|
||||
case 'y':
|
||||
matrix += ' 0 & -i\\\\ i & 0';
|
||||
break;
|
||||
case '3':
|
||||
case 'z':
|
||||
matrix += ' 1 & 0\\\\ 0 & -1';
|
||||
break;
|
||||
default:
|
||||
}
|
||||
parser.string = matrix + parser.string.slice(parser.i);
|
||||
parser.i = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generation of anti/diagonal matrices.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
* @param {boolean=} anti True if constructing anti-diagonal matrix.
|
||||
*/
|
||||
PhysicsMethods.DiagonalMatrix = function(parser: TexParser, name: string,
|
||||
anti?: boolean) {
|
||||
if (parser.GetNext() !== '{') {
|
||||
return;
|
||||
}
|
||||
let startI = parser.i;
|
||||
/* let arg =*/ parser.GetArgument(name);
|
||||
let endI = parser.i;
|
||||
parser.i = startI + 1;
|
||||
let elements = [];
|
||||
let element = '';
|
||||
let currentI = parser.i;
|
||||
while (currentI < endI) {
|
||||
try {
|
||||
element = parser.GetUpTo(name, ',');
|
||||
} catch (e) {
|
||||
parser.i = endI;
|
||||
elements.push(parser.string.slice(currentI, endI - 1));
|
||||
break;
|
||||
}
|
||||
if (parser.i >= endI) {
|
||||
elements.push(parser.string.slice(currentI, endI));
|
||||
break;
|
||||
}
|
||||
currentI = parser.i;
|
||||
elements.push(element);
|
||||
}
|
||||
parser.string = makeDiagMatrix(elements, anti) + parser.string.slice(endI);
|
||||
parser.i = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the a (anti)diagonal matrix string.
|
||||
* @param {string[]} elements The elements on the diagonal.
|
||||
* @param {boolean} anti True if constructing anti-diagonal matrix.
|
||||
*/
|
||||
function makeDiagMatrix(elements: string[], anti: boolean) {
|
||||
let length = elements.length;
|
||||
let matrix = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
matrix.push(Array(anti ? length - i : i + 1).join('&') +
|
||||
'\\mqty{' + elements[i] + '}');
|
||||
}
|
||||
return matrix.join('\\\\ ');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes an automatic fence if one was opened.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} fence The fence.
|
||||
* @param {number} texclass The TeX class.
|
||||
*/
|
||||
PhysicsMethods.AutoClose = function(parser: TexParser, fence: string, _texclass: number) {
|
||||
const mo = parser.create('token', 'mo', {stretchy: false}, fence);
|
||||
const item = parser.itemFactory.create('mml', mo).
|
||||
setProperties({autoclose: fence});
|
||||
parser.Push(item);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generates the vector nabla depending on the arrowdel option.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.Vnabla = function(parser: TexParser, _name: string) {
|
||||
let argument = parser.options.physics.arrowdel ?
|
||||
'\\vec{\\gradientnabla}' : '{\\gradientnabla}';
|
||||
return parser.Push(new TexParser(argument, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generates the differential d depending on the italicdiff option.
|
||||
* @param {TexParser} parser The calling parser.
|
||||
* @param {string} name The macro name.
|
||||
*/
|
||||
PhysicsMethods.DiffD = function(parser: TexParser, _name: string) {
|
||||
let argument = parser.options.physics.italicdiff ? 'd' : '{\\rm d}';
|
||||
return parser.Push(new TexParser(argument, parser.stack.env,
|
||||
parser.configuration).mml());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Methods taken from Base package.
|
||||
*/
|
||||
PhysicsMethods.Macro = BaseMethods.Macro;
|
||||
|
||||
PhysicsMethods.NamedFn = BaseMethods.NamedFn;
|
||||
|
||||
PhysicsMethods.Array = BaseMethods.Array;
|
||||
|
||||
|
||||
export default PhysicsMethods;
|
||||
209
node_modules/mathjax-full/ts/input/tex/require/RequireConfiguration.ts
generated
vendored
Normal file
209
node_modules/mathjax-full/ts/input/tex/require/RequireConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the require package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {Configuration, ParserConfiguration, ConfigurationHandler} from '../Configuration.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import TexError from '../TexError.js';
|
||||
import {TeX} from '../../tex.js';
|
||||
|
||||
import {MathJax} from '../../../components/global.js';
|
||||
import {Package} from '../../../components/package.js';
|
||||
import {Loader, CONFIG as LOADERCONFIG} from '../../../components/loader.js';
|
||||
import {mathjax} from '../../../mathjax.js';
|
||||
import {expandable} from '../../../util/Options.js';
|
||||
|
||||
/**
|
||||
* The MathJax configuration block (for looking up user-defined package options)
|
||||
*/
|
||||
const MJCONFIG = MathJax.config;
|
||||
|
||||
/**
|
||||
* Add an extension to the configuration, and configure its user options
|
||||
*
|
||||
* @param {TeX} jax The TeX jax whose configuration is to be modified
|
||||
* @param {string} name The name of the extension being added (e.g., '[tex]/amscd')
|
||||
*/
|
||||
function RegisterExtension(jax: TeX<any, any, any>, name: string) {
|
||||
const require = jax.parseOptions.options.require;
|
||||
const required = jax.parseOptions.packageData.get('require').required as string[];
|
||||
const extension = name.substr(require.prefix.length);
|
||||
if (required.indexOf(extension) < 0) {
|
||||
required.push(extension);
|
||||
//
|
||||
// Register any dependencies that were loaded to handle this one
|
||||
//
|
||||
RegisterDependencies(jax, LOADERCONFIG.dependencies[name]);
|
||||
//
|
||||
// If the required file loaded an extension...
|
||||
//
|
||||
const handler = ConfigurationHandler.get(extension);
|
||||
if (handler) {
|
||||
//
|
||||
// Check if there are user-supplied options
|
||||
// (place them in a block for the extension, if needed)
|
||||
//
|
||||
let options = MJCONFIG[name] || {};
|
||||
if (handler.options && Object.keys(handler.options).length === 1 && handler.options[extension]) {
|
||||
options = {[extension]: options};
|
||||
}
|
||||
//
|
||||
// Register the extension with the jax's configuration
|
||||
//
|
||||
(jax as any).configuration.add(extension, jax, options);
|
||||
//
|
||||
// If there are preprocessors, restart so that they run
|
||||
// (we don't have access to the document or MathItem needed to call
|
||||
// the preprocessors from here)
|
||||
//
|
||||
const configured = jax.parseOptions.packageData.get('require').configured;
|
||||
if (handler.preprocessors.length && !configured.has(extension)) {
|
||||
configured.set(extension, true);
|
||||
mathjax.retryAfter(Promise.resolve());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any dependencies for the loaded extension
|
||||
*
|
||||
* @param {TeX} jax The jax whose configuration is being modified
|
||||
* @param {string[]} names The names of the dependencies to register
|
||||
*/
|
||||
function RegisterDependencies(jax: TeX<any, any, any>, names: string[] = []) {
|
||||
const prefix = jax.parseOptions.options.require.prefix;
|
||||
for (const name of names) {
|
||||
if (name.substr(0, prefix.length) === prefix) {
|
||||
RegisterExtension(jax, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a required package
|
||||
*
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the package to load.
|
||||
*/
|
||||
export function RequireLoad(parser: TexParser, name: string) {
|
||||
const options = parser.options.require;
|
||||
const allow = options.allow;
|
||||
const extension = (name.substr(0, 1) === '[' ? '' : options.prefix) + name;
|
||||
const allowed = (allow.hasOwnProperty(extension) ? allow[extension] :
|
||||
allow.hasOwnProperty(name) ? allow[name] : options.defaultAllow);
|
||||
if (!allowed) {
|
||||
throw new TexError('BadRequire', 'Extension "%1" is not allowed to be loaded', extension);
|
||||
}
|
||||
if (Package.packages.has(extension)) {
|
||||
RegisterExtension(parser.configuration.packageData.get('require').jax, extension);
|
||||
} else {
|
||||
mathjax.retryAfter(Loader.load(extension));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the jax so that it can be used when \require{} is processed.
|
||||
*/
|
||||
function config(_config: ParserConfiguration, jax: TeX<any, any, any>) {
|
||||
jax.parseOptions.packageData.set('require', {
|
||||
jax: jax, // \require needs access to this
|
||||
required: [...jax.options.packages], // stores the names of the packages that have been added
|
||||
configured: new Map() // stores the packages that have been configured
|
||||
});
|
||||
const options = jax.parseOptions.options.require;
|
||||
const prefix = options.prefix;
|
||||
if (prefix.match(/[^_a-zA-Z0-9]/)) {
|
||||
throw Error('Illegal characters used in \\require prefix');
|
||||
}
|
||||
if (!LOADERCONFIG.paths[prefix]) {
|
||||
LOADERCONFIG.paths[prefix] = '[mathjax]/input/tex/extensions';
|
||||
}
|
||||
options.prefix = '[' + prefix + ']/';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for \require methods
|
||||
*/
|
||||
export const RequireMethods: Record<string, ParseMethod> = {
|
||||
|
||||
/**
|
||||
* Implements \require macro to load TeX extensions
|
||||
*
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the calling macro.
|
||||
*/
|
||||
Require(parser: TexParser, name: string) {
|
||||
const required = parser.GetArgument(name);
|
||||
if (required.match(/[^_a-zA-Z0-9]/) || required === '') {
|
||||
throw new TexError('BadPackageName', 'Argument for %1 is not a valid package name', name);
|
||||
}
|
||||
RequireLoad(parser, required);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The options for the require extension
|
||||
*/
|
||||
export const options = {
|
||||
require: {
|
||||
//
|
||||
// Specifies which extensions can/can't be required.
|
||||
// The keys are the names of extensions, and the value is true
|
||||
// if the extension can be required, and false if it can't
|
||||
//
|
||||
allow: expandable({
|
||||
base: false,
|
||||
'all-packages': false,
|
||||
autoload: false,
|
||||
configmacros: false,
|
||||
tagformat: false,
|
||||
setoptions: false
|
||||
}),
|
||||
//
|
||||
// The default allow value if the extension isn't in the list above
|
||||
//
|
||||
defaultAllow: true,
|
||||
//
|
||||
// The path prefix to use for exensions: 'tex' means use '[tex]/'
|
||||
// before the extension name.
|
||||
//
|
||||
prefix: 'tex'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The command map for the \require macro
|
||||
*/
|
||||
new CommandMap('require', {require: 'Require'}, RequireMethods);
|
||||
|
||||
/**
|
||||
* The configuration for the \require macro
|
||||
*/
|
||||
export const RequireConfiguration = Configuration.create(
|
||||
'require', {handler: {macro: ['require']}, config, options}
|
||||
);
|
||||
176
node_modules/mathjax-full/ts/input/tex/setoptions/SetOptionsConfiguration.ts
generated
vendored
Normal file
176
node_modules/mathjax-full/ts/input/tex/setoptions/SetOptionsConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2021-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the setoptions package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {Configuration, ConfigurationHandler, ParserConfiguration} from '../Configuration.js';
|
||||
import {TeX} from '../../tex.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import TexError from '../TexError.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import {Macro} from '../Symbol.js';
|
||||
import BaseMethods from '../base/BaseMethods.js';
|
||||
import {expandable, isObject} from '../../../util/Options.js';
|
||||
|
||||
export const SetOptionsUtil = {
|
||||
|
||||
/**
|
||||
* Check if options can be set for a given pacakge, and error otherwise.
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} extension The name of the package whose option is being set.
|
||||
* @return {boolean} True when options can be set for this package.
|
||||
*/
|
||||
filterPackage(parser: TexParser, extension: string): boolean {
|
||||
if (extension !== 'tex' && !ConfigurationHandler.get(extension)) {
|
||||
throw new TexError('NotAPackage', 'Not a defined package: %1', extension);
|
||||
}
|
||||
const config = parser.options.setoptions;
|
||||
const options = config.allowOptions[extension];
|
||||
if ((options === undefined && !config.allowPackageDefault) || options === false) {
|
||||
throw new TexError('PackageNotSettable', 'Options can\'t be set for package "%1"', extension);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if an option can be set and error otherwise.
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} extension The name of the package whose option is being set.
|
||||
* @param {string} option The name of the option being set.
|
||||
* @return {boolean} True when the option can be set.
|
||||
*/
|
||||
filterOption(parser: TexParser, extension: string, option: string): boolean {
|
||||
const config = parser.options.setoptions;
|
||||
const options = config.allowOptions[extension] || {};
|
||||
const allow = (options.hasOwnProperty(option) && !isObject(options[option]) ? options[option] : null);
|
||||
if (allow === false || (allow === null && !config.allowOptionsDefault)) {
|
||||
throw new TexError('OptionNotSettable', 'Option "%1" is not allowed to be set', option);
|
||||
}
|
||||
if (!(extension === 'tex' ? parser.options : parser.options[extension])?.hasOwnProperty(option)) {
|
||||
if (extension === 'tex') {
|
||||
throw new TexError('InvalidTexOption', 'Invalid TeX option "%1"', option);
|
||||
} else {
|
||||
throw new TexError('InvalidOptionKey', 'Invalid option "%1" for package "%2"', option, extension);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Verify an option's value before setting it.
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} extension The name of the package whose option this is.
|
||||
* @param {string} option The name of the option being set.
|
||||
* @param {string} value The value to give to the option.
|
||||
* @return {string} The (possibly modified) value for the option
|
||||
*/
|
||||
filterValue(_parser: TexParser, _extension: string, _option: string, value: string): string {
|
||||
return value;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const setOptionsMap = new CommandMap('setoptions', {
|
||||
setOptions: 'SetOptions'
|
||||
}, {
|
||||
/**
|
||||
* Implements \setOptions[package]{option-values}
|
||||
*
|
||||
* @param {TexParser} parser The active tex parser.
|
||||
* @param {string} name The name of the macro being processed.
|
||||
*/
|
||||
SetOptions(parser: TexParser, name: string) {
|
||||
const extension = parser.GetBrackets(name) || 'tex';
|
||||
const options = ParseUtil.keyvalOptions(parser.GetArgument(name));
|
||||
const config = parser.options.setoptions;
|
||||
if (!config.filterPackage(parser, extension)) return;
|
||||
for (const key of Object.keys(options)) {
|
||||
if (config.filterOption(parser, extension, key)) {
|
||||
(extension === 'tex' ? parser.options : parser.options[extension])[key] =
|
||||
config.filterValue(parser, extension, key, options[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* If the require package is available, save the original require,
|
||||
* and define a macro that loads the extension and sets
|
||||
* its options, if any.
|
||||
*
|
||||
* @param {ParserConfiguration} config The current configuration.
|
||||
* @param {TeX} jax The active tex input jax.
|
||||
*/
|
||||
function setoptionsConfig(_config: ParserConfiguration, jax: TeX<any, any, any>) {
|
||||
const require = jax.parseOptions.handlers.get('macro').lookup('require') as any;
|
||||
if (require) {
|
||||
setOptionsMap.add('Require', new Macro('Require', require._func));
|
||||
setOptionsMap.add('require', new Macro('require', BaseMethods.Macro,
|
||||
['\\Require{#2}\\setOptions[#2]{#1}', 2, '']));
|
||||
}
|
||||
}
|
||||
|
||||
export const SetOptionsConfiguration = Configuration.create(
|
||||
'setoptions', {
|
||||
handler: {macro: ['setoptions']},
|
||||
config: setoptionsConfig,
|
||||
priority: 3, // must be less than the priority of the require package (which is 5).
|
||||
options: {
|
||||
setoptions: {
|
||||
filterPackage: SetOptionsUtil.filterPackage, // filter for whether a package can be configured
|
||||
filterOption: SetOptionsUtil.filterOption, // filter for whether an option can be set
|
||||
filterValue: SetOptionsUtil.filterValue, // filter for the value to assign to an option
|
||||
allowPackageDefault: true, // default for allowing packages when not explicitly set in allowOptions
|
||||
allowOptionsDefault: true, // default for allowing option that isn't explicitly set in allowOptions
|
||||
allowOptions: expandable({ // list of packages to allow/disallow, and their options to allow/disallow
|
||||
//
|
||||
// top-level tex items can be set, but not these
|
||||
// (that leaves digits and the tagging options)
|
||||
//
|
||||
tex: {
|
||||
FindTeX: false,
|
||||
formatError: false,
|
||||
package: false,
|
||||
baseURL: false,
|
||||
tags: false,
|
||||
maxBuffer: false,
|
||||
maxMaxros: false,
|
||||
macros: false,
|
||||
environments: false
|
||||
},
|
||||
//
|
||||
// These packages can't be configured at all
|
||||
//
|
||||
setoptions: false,
|
||||
autoload: false,
|
||||
require: false,
|
||||
configmacros: false,
|
||||
tagformat: false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
124
node_modules/mathjax-full/ts/input/tex/tagformat/TagFormatConfiguration.ts
generated
vendored
Normal file
124
node_modules/mathjax-full/ts/input/tex/tagformat/TagFormatConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the tagformat package.
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {Configuration, ParserConfiguration} from '../Configuration.js';
|
||||
import {TeX} from '../../tex.js';
|
||||
import {AbstractTags, TagsFactory} from '../Tags.js';
|
||||
|
||||
/**
|
||||
* Number used to make tag class unique (each TeX input has to have its own because
|
||||
* it needs access to the parse options)
|
||||
*/
|
||||
let tagID = 0;
|
||||
|
||||
/**
|
||||
* Configure a class to use for the tag handler that uses the input jax's options
|
||||
* to control the formatting of the tags
|
||||
* @param {Configuration} config The configuration for the input jax
|
||||
* @param {TeX} jax The TeX input jax
|
||||
*/
|
||||
export function tagformatConfig(config: ParserConfiguration, jax: TeX<any, any, any>) {
|
||||
|
||||
/**
|
||||
* If the tag format is being added by one of the other extensions,
|
||||
* as is done for the 'ams' tags, make sure it is defined so we can create it.
|
||||
*/
|
||||
const tags = jax.parseOptions.options.tags;
|
||||
if (tags !== 'base' && config.tags.hasOwnProperty(tags)) {
|
||||
TagsFactory.add(tags, config.tags[tags]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The original tag class to be extended (none, ams, or all)
|
||||
*/
|
||||
const TagClass = TagsFactory.create(jax.parseOptions.options.tags).constructor as typeof AbstractTags;
|
||||
|
||||
/**
|
||||
* A Tags object that uses the input jax options to perform the formatting
|
||||
*
|
||||
* Note: We have to make a new class for each input jax since the format
|
||||
* methods don't have access to the input jax, and hence to its options.
|
||||
* If they did, we would use a common configTags class instead.
|
||||
*/
|
||||
class TagFormat extends TagClass {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public formatNumber(n: number) {
|
||||
return jax.parseOptions.options.tagformat.number(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public formatTag(tag: string) {
|
||||
return jax.parseOptions.options.tagformat.tag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public formatId(id: string) {
|
||||
return jax.parseOptions.options.tagformat.id(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public formatUrl(id: string, base: string) {
|
||||
return jax.parseOptions.options.tagformat.url(id, base);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Get a unique name for the tag class (since it is tied to the input jax)
|
||||
// Note: These never get freed, so they will accumulate if you create many
|
||||
// TeX input jax instances with this extension.
|
||||
//
|
||||
tagID++;
|
||||
const tagName = 'configTags-' + tagID;
|
||||
//
|
||||
// Register the tag class
|
||||
//
|
||||
TagsFactory.add(tagName, TagFormat);
|
||||
jax.parseOptions.options.tags = tagName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The configuration object for configTags
|
||||
*/
|
||||
export const TagFormatConfiguration = Configuration.create(
|
||||
'tagformat', {
|
||||
config: [tagformatConfig, 10],
|
||||
options: {
|
||||
tagformat: {
|
||||
number: (n: number) => n.toString(),
|
||||
tag: (tag: string) => '(' + tag + ')',
|
||||
id: (id: string) => 'mjx-eqn:' + id.replace(/\s/g, '_'),
|
||||
url: (id: string, base: string) => base + '#' + encodeURIComponent(id),
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
34
node_modules/mathjax-full/ts/input/tex/textcomp/TextcompConfiguration.ts
generated
vendored
Normal file
34
node_modules/mathjax-full/ts/input/tex/textcomp/TextcompConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2021-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the textcomp package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import './TextcompMappings.js';
|
||||
|
||||
|
||||
export const TextcompConfiguration = Configuration.create(
|
||||
'textcomp', {
|
||||
handler: {macro: ['textcomp-macros']}
|
||||
}
|
||||
);
|
||||
|
||||
191
node_modules/mathjax-full/ts/input/tex/textcomp/TextcompMappings.ts
generated
vendored
Normal file
191
node_modules/mathjax-full/ts/input/tex/textcomp/TextcompMappings.ts
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2021-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Mappings for the textcomp package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import {TextMacrosMethods} from '../textmacros/TextMacrosMethods.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import {TextParser} from '../textmacros/TextParser.js';
|
||||
|
||||
|
||||
/**
|
||||
* Identifiers from the Textcomp package.
|
||||
*/
|
||||
new CommandMap('textcomp-macros', {
|
||||
|
||||
// Table 3: Predefined LATEX 2ε Text-Mode Commands
|
||||
'textasciicircum': ['Insert', '\u005E'],
|
||||
'textasciitilde': ['Insert', '\u007E'],
|
||||
'textasteriskcentered': ['Insert', '\u002A'],
|
||||
'textbackslash': ['Insert', '\u005C'],
|
||||
'textbar': ['Insert', '\u007C'],
|
||||
'textbraceleft': ['Insert', '\u007B'],
|
||||
'textbraceright': ['Insert', '\u007D'],
|
||||
'textbullet': ['Insert', '\u2022'],
|
||||
'textdagger': ['Insert', '\u2020'],
|
||||
'textdaggerdbl': ['Insert', '\u2021'],
|
||||
'textellipsis': ['Insert', '\u2026'],
|
||||
'textemdash': ['Insert', '\u2014'],
|
||||
'textendash': ['Insert', '\u2013'],
|
||||
'textexclamdown': ['Insert', '\u00A1'],
|
||||
'textgreater': ['Insert', '\u003E'],
|
||||
'textless': ['Insert', '\u003C'],
|
||||
'textordfeminine': ['Insert', '\u00AA'],
|
||||
'textordmasculine': ['Insert', '\u00BA'],
|
||||
'textparagraph': ['Insert', '\u00B6'],
|
||||
'textperiodcentered': ['Insert', '\u00B7'],
|
||||
'textquestiondown': ['Insert', '\u00BF'],
|
||||
'textquotedblleft': ['Insert', '\u201C'],
|
||||
'textquotedblright': ['Insert', '\u201D'],
|
||||
'textquoteleft': ['Insert', '\u2018'],
|
||||
'textquoteright': ['Insert', '\u2019'],
|
||||
'textsection': ['Insert', '\u00A7'],
|
||||
'textunderscore': ['Insert', '\u005F'],
|
||||
'textvisiblespace': ['Insert', '\u2423'],
|
||||
|
||||
// Table 12: textcomp Diacritics
|
||||
'textacutedbl': ['Insert', '\u02DD'],
|
||||
'textasciiacute': ['Insert', '\u00B4'],
|
||||
'textasciibreve': ['Insert', '\u02D8'],
|
||||
'textasciicaron': ['Insert', '\u02C7'],
|
||||
'textasciidieresis': ['Insert', '\u00A8'],
|
||||
'textasciimacron': ['Insert', '\u00AF'],
|
||||
'textgravedbl': ['Insert', '\u02F5'],
|
||||
'texttildelow': ['Insert', '\u02F7'],
|
||||
|
||||
// Table 13: textcomp Currency Symbols
|
||||
'textbaht': ['Insert', '\u0E3F'],
|
||||
'textcent': ['Insert', '\u00A2'],
|
||||
'textcolonmonetary': ['Insert', '\u20A1'],
|
||||
'textcurrency': ['Insert', '\u00A4'],
|
||||
'textdollar': ['Insert', '\u0024'],
|
||||
'textdong': ['Insert', '\u20AB'],
|
||||
'texteuro': ['Insert', '\u20AC'],
|
||||
'textflorin': ['Insert', '\u0192'],
|
||||
'textguarani': ['Insert', '\u20B2'],
|
||||
'textlira': ['Insert', '\u20A4'],
|
||||
'textnaira': ['Insert', '\u20A6'],
|
||||
'textpeso': ['Insert', '\u20B1'],
|
||||
'textsterling': ['Insert', '\u00A3'],
|
||||
'textwon': ['Insert', '\u20A9'],
|
||||
'textyen': ['Insert', '\u00A5'],
|
||||
|
||||
// Table 15: textcomp Legal Symbols
|
||||
'textcircledP': ['Insert', '\u2117'],
|
||||
'textcompwordmark': ['Insert', '\u200C'],
|
||||
'textcopyleft': ['Insert', '\u{1F12F}'],
|
||||
'textcopyright': ['Insert', '\u00A9'],
|
||||
'textregistered': ['Insert', '\u00AE'],
|
||||
'textservicemark': ['Insert', '\u2120'],
|
||||
'texttrademark': ['Insert', '\u2122'],
|
||||
|
||||
// Table 20: Miscellaneous textcomp Symbol
|
||||
'textbardbl': ['Insert', '\u2016'],
|
||||
'textbigcircle': ['Insert', '\u25EF'],
|
||||
'textblank': ['Insert', '\u2422'],
|
||||
'textbrokenbar': ['Insert', '\u00A6'],
|
||||
'textdiscount': ['Insert', '\u2052'],
|
||||
'textestimated': ['Insert', '\u212E'],
|
||||
'textinterrobang': ['Insert', '\u203D'],
|
||||
'textinterrobangdown': ['Insert', '\u2E18'],
|
||||
'textmusicalnote': ['Insert', '\u266A'],
|
||||
'textnumero': ['Insert', '\u2116'],
|
||||
'textopenbullet': ['Insert', '\u25E6'],
|
||||
'textpertenthousand': ['Insert', '\u2031'],
|
||||
'textperthousand': ['Insert', '\u2030'],
|
||||
'textrecipe': ['Insert', '\u211E'],
|
||||
'textreferencemark': ['Insert', '\u203B'],
|
||||
// 'textthreequartersemdash'
|
||||
// 'texttwelveudash'
|
||||
|
||||
// Table 51: textcomp Text-Mode Delimiters
|
||||
'textlangle': ['Insert', '\u2329'],
|
||||
'textrangle': ['Insert', '\u232A'],
|
||||
'textlbrackdbl': ['Insert', '\u27E6'],
|
||||
'textrbrackdbl': ['Insert', '\u27E7'],
|
||||
'textlquill': ['Insert', '\u2045'],
|
||||
'textrquill': ['Insert', '\u2046'],
|
||||
|
||||
// Table 62: textcomp Text-Mode Math and Science Symbols
|
||||
'textcelsius': ['Insert', '\u2103'],
|
||||
'textdegree': ['Insert', '\u00B0'],
|
||||
'textdiv': ['Insert', '\u00F7'],
|
||||
'textdownarrow': ['Insert', '\u2193'],
|
||||
'textfractionsolidus': ['Insert', '\u2044'],
|
||||
'textleftarrow': ['Insert', '\u2190'],
|
||||
'textlnot': ['Insert', '\u00AC'],
|
||||
'textmho': ['Insert', '\u2127'],
|
||||
'textminus': ['Insert', '\u2212'],
|
||||
'textmu': ['Insert', '\u00B5'],
|
||||
'textohm': ['Insert', '\u2126'],
|
||||
'textonehalf': ['Insert', '\u00BD'],
|
||||
'textonequarter': ['Insert', '\u00BC'],
|
||||
'textonesuperior': ['Insert', '\u00B9'],
|
||||
'textpm': ['Insert', '\u00B1'],
|
||||
'textrightarrow': ['Insert', '\u2192'],
|
||||
'textsurd': ['Insert', '\u221A'],
|
||||
'textthreequarters': ['Insert', '\u00BE'],
|
||||
'textthreesuperior': ['Insert', '\u00B3'],
|
||||
'texttimes': ['Insert', '\u00D7'],
|
||||
'texttwosuperior': ['Insert', '\u00B2'],
|
||||
'textuparrow': ['Insert', '\u2191'],
|
||||
|
||||
// Table 110: textcomp Genealogical Symbols
|
||||
'textborn': ['Insert', '\u002A'],
|
||||
'textdied': ['Insert', '\u2020'],
|
||||
'textdivorced': ['Insert', '\u26AE'],
|
||||
// 'textleaf'
|
||||
'textmarried': ['Insert', '\u26AD'],
|
||||
|
||||
// This is not the correct glyph
|
||||
'textcentoldstyle': ['Insert', '\u00A2', TexConstant.Variant.OLDSTYLE],
|
||||
// This is not the correct glyph
|
||||
'textdollaroldstyle': ['Insert', '\u0024', TexConstant.Variant.OLDSTYLE],
|
||||
|
||||
// Table 16: textcomp Old-Style Numerals
|
||||
'textzerooldstyle': ['Insert', '0', TexConstant.Variant.OLDSTYLE],
|
||||
'textoneoldstyle': ['Insert', '1', TexConstant.Variant.OLDSTYLE],
|
||||
'texttwooldstyle': ['Insert', '2', TexConstant.Variant.OLDSTYLE],
|
||||
'textthreeoldstyle': ['Insert', '3', TexConstant.Variant.OLDSTYLE],
|
||||
'textfouroldstyle': ['Insert', '4', TexConstant.Variant.OLDSTYLE],
|
||||
'textfiveoldstyle': ['Insert', '5', TexConstant.Variant.OLDSTYLE],
|
||||
'textsixoldstyle': ['Insert', '6', TexConstant.Variant.OLDSTYLE],
|
||||
'textsevenoldstyle': ['Insert', '7', TexConstant.Variant.OLDSTYLE],
|
||||
'texteightoldstyle': ['Insert', '8', TexConstant.Variant.OLDSTYLE],
|
||||
'textnineoldstyle': ['Insert', '9', TexConstant.Variant.OLDSTYLE]
|
||||
}, {
|
||||
Insert: function(parser: TexParser, name: string, c: string, font: string) {
|
||||
if (parser instanceof TextParser) {
|
||||
if (!font) {
|
||||
TextMacrosMethods.Insert(parser, name, c);
|
||||
return;
|
||||
}
|
||||
parser.saveText();
|
||||
}
|
||||
parser.Push(ParseUtil.internalText(
|
||||
parser, c, font ? {mathvariant: font} : {}));
|
||||
}
|
||||
});
|
||||
138
node_modules/mathjax-full/ts/input/tex/textmacros/TextMacrosConfiguration.ts
generated
vendored
Normal file
138
node_modules/mathjax-full/ts/input/tex/textmacros/TextMacrosConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the textmacros package
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {TeX} from '../../tex.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {Configuration, ParserConfiguration} from '../Configuration.js';
|
||||
import ParseOptions from '../ParseOptions.js';
|
||||
import {TagsFactory} from '../Tags.js';
|
||||
import {StartItem, StopItem, MmlItem, StyleItem} from '../base/BaseItems.js';
|
||||
import {TextParser} from './TextParser.js';
|
||||
import {TextMacrosMethods} from './TextMacrosMethods.js';
|
||||
import {MmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
|
||||
import './TextMacrosMappings.js';
|
||||
|
||||
/**
|
||||
* The base text macro configuration (used in the TextParser)
|
||||
*/
|
||||
export const TextBaseConfiguration = Configuration.create('text-base', {
|
||||
parser: 'text',
|
||||
handler: {
|
||||
character: ['command', 'text-special'],
|
||||
macro: ['text-macros']
|
||||
},
|
||||
fallback: {
|
||||
//
|
||||
// Unknown characters are added to the text verbatim
|
||||
//
|
||||
character: (parser: TextParser, c: string) => {
|
||||
parser.text += c;
|
||||
},
|
||||
//
|
||||
// For unknown macros, if they are defined in the main TeX parser
|
||||
// and not string-replacement macros, give an error, otherwise
|
||||
// run the macro (this either does the string replacement or
|
||||
// produces the error as configured in the main TeX parser, so
|
||||
// this will respect the noundefined package, if loaded).
|
||||
//
|
||||
macro: (parser: TextParser, name: string) => {
|
||||
const texParser = parser.texParser;
|
||||
const macro = texParser.lookup('macro', name);
|
||||
if (macro && macro._func !== TextMacrosMethods.Macro) {
|
||||
parser.Error('MathMacro', '%1 is only supported in math mode', '\\' + name);
|
||||
}
|
||||
texParser.parse('macro', [parser, name]);
|
||||
}
|
||||
},
|
||||
items: {
|
||||
[StartItem.prototype.kind]: StartItem,
|
||||
[StopItem.prototype.kind]: StopItem,
|
||||
[MmlItem.prototype.kind]: MmlItem,
|
||||
[StyleItem.prototype.kind]: StyleItem // needed for \color
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Replacement for ParseUtil.internalMath that handles text-mode macros.
|
||||
*
|
||||
* @param {TexParser} parser The TexParser calling this function
|
||||
* @param {string} text The text-mode string to be processed
|
||||
* @param {number|string} level The scriptlevel of the text
|
||||
* @param {string} mathvariant The mathvariant for the text
|
||||
* @return {MmlNode[]} The final MmlNode generated for the text
|
||||
*/
|
||||
function internalMath(parser: TexParser, text: string, level?: number | string, mathvariant?: string): MmlNode[] {
|
||||
const config = parser.configuration.packageData.get('textmacros');
|
||||
if (!(parser instanceof TextParser)) {
|
||||
config.texParser = parser;
|
||||
}
|
||||
return [(new TextParser(text, mathvariant ? {mathvariant} : {}, config.parseOptions, level)).mml()];
|
||||
}
|
||||
|
||||
//
|
||||
// The textmacros package configuration
|
||||
//
|
||||
export const TextMacrosConfiguration = Configuration.create('textmacros', {
|
||||
/**
|
||||
* @param {ParserConfiguration} config The configuration object we are being configured within
|
||||
* @param {TeX<any,any,any>} jax The TeX input jax in which we are running
|
||||
*/
|
||||
config(_config: ParserConfiguration, jax: TeX<any, any, any>) {
|
||||
//
|
||||
// Create the configuration and parseOptions objects for the
|
||||
// internal TextParser and add the textBase configuration.
|
||||
//
|
||||
const textConf = new ParserConfiguration(jax.parseOptions.options.textmacros.packages, ['tex', 'text']);
|
||||
textConf.init();
|
||||
const parseOptions = new ParseOptions(textConf, []);
|
||||
parseOptions.options = jax.parseOptions.options; // share the TeX options
|
||||
textConf.config(jax);
|
||||
TagsFactory.addTags(textConf.tags);
|
||||
parseOptions.tags = TagsFactory.getDefault();
|
||||
parseOptions.tags.configuration = parseOptions;
|
||||
//
|
||||
// Share the TeX input jax's parseOptions packageData object
|
||||
// so that require and other packages will work in both parsers,
|
||||
// set the textmacros data (texParser will be filled in later),
|
||||
// and replace the internalMath function with our own.
|
||||
//
|
||||
parseOptions.packageData = jax.parseOptions.packageData;
|
||||
parseOptions.packageData.set('textmacros', {parseOptions, jax, texParser: null});
|
||||
parseOptions.options.internalMath = internalMath;
|
||||
},
|
||||
preprocessors: [(data: {data: ParseOptions}) => {
|
||||
//
|
||||
// Set the MmlFactory for the nodeFactory, since it was not available
|
||||
// durring configuration above.
|
||||
//
|
||||
const config = data.data.packageData.get('textmacros');
|
||||
config.parseOptions.nodeFactory.setMmlFactory(config.jax.mmlFactory);
|
||||
}],
|
||||
options: {
|
||||
textmacros: {
|
||||
packages: ['text-base'] // textmacro packages to load
|
||||
}
|
||||
}
|
||||
});
|
||||
151
node_modules/mathjax-full/ts/input/tex/textmacros/TextMacrosMappings.ts
generated
vendored
Normal file
151
node_modules/mathjax-full/ts/input/tex/textmacros/TextMacrosMappings.ts
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Character and Macro mappings for the textmacros package
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import {MacroMap, CommandMap} from '../SymbolMap.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import {TextMacrosMethods} from './TextMacrosMethods.js';
|
||||
import {MATHSPACE} from '../../../util/lengths.js';
|
||||
|
||||
//
|
||||
// The special characters in text-mode
|
||||
//
|
||||
new MacroMap('text-special', {
|
||||
'$': 'Math',
|
||||
'%': 'Comment',
|
||||
'^': 'MathModeOnly',
|
||||
'_': 'MathModeOnly',
|
||||
'&': 'Misplaced',
|
||||
'#': 'Misplaced',
|
||||
'~': 'Tilde',
|
||||
' ': 'Space',
|
||||
'\t': 'Space',
|
||||
'\r': 'Space',
|
||||
'\n': 'Space',
|
||||
'\u00A0': 'Tilde',
|
||||
'{': 'OpenBrace',
|
||||
'}': 'CloseBrace',
|
||||
'`': 'OpenQuote',
|
||||
'\'': 'CloseQuote'
|
||||
}, TextMacrosMethods);
|
||||
|
||||
//
|
||||
// The text-mode macro mappings
|
||||
//
|
||||
new CommandMap('text-macros', {
|
||||
'(': 'Math',
|
||||
|
||||
'$': 'SelfQuote',
|
||||
'_': 'SelfQuote',
|
||||
'%': 'SelfQuote',
|
||||
'{': 'SelfQuote',
|
||||
'}': 'SelfQuote',
|
||||
' ': 'SelfQuote',
|
||||
'&': 'SelfQuote',
|
||||
'#': 'SelfQuote',
|
||||
'\\': 'SelfQuote',
|
||||
|
||||
'\'': ['Accent', '\u00B4'],
|
||||
'\u2019': ['Accent', '\u00B4'],
|
||||
'`': ['Accent', '\u0060'],
|
||||
'\u2018': ['Accent', '\u0060'],
|
||||
'^': ['Accent', '^'],
|
||||
'\"': ['Accent', '\u00A8'],
|
||||
'~': ['Accent', '~'],
|
||||
'=': ['Accent', '\u00AF'],
|
||||
'.': ['Accent', '\u02D9'],
|
||||
'u': ['Accent', '\u02D8'],
|
||||
'v': ['Accent', '\u02C7'],
|
||||
|
||||
emph: 'Emph',
|
||||
rm: ['SetFont', TexConstant.Variant.NORMAL],
|
||||
mit: ['SetFont', TexConstant.Variant.ITALIC],
|
||||
oldstyle: ['SetFont', TexConstant.Variant.OLDSTYLE],
|
||||
cal: ['SetFont', TexConstant.Variant.CALLIGRAPHIC],
|
||||
it: ['SetFont', '-tex-mathit'], // needs special handling
|
||||
bf: ['SetFont', TexConstant.Variant.BOLD],
|
||||
bbFont: ['SetFont', TexConstant.Variant.DOUBLESTRUCK],
|
||||
scr: ['SetFont', TexConstant.Variant.SCRIPT],
|
||||
frak: ['SetFont', TexConstant.Variant.FRAKTUR],
|
||||
sf: ['SetFont', TexConstant.Variant.SANSSERIF],
|
||||
tt: ['SetFont', TexConstant.Variant.MONOSPACE],
|
||||
|
||||
tiny: ['SetSize', 0.5],
|
||||
Tiny: ['SetSize', 0.6], // non-standard
|
||||
scriptsize: ['SetSize', 0.7],
|
||||
small: ['SetSize', 0.85],
|
||||
normalsize: ['SetSize', 1.0],
|
||||
large: ['SetSize', 1.2],
|
||||
Large: ['SetSize', 1.44],
|
||||
LARGE: ['SetSize', 1.73],
|
||||
huge: ['SetSize', 2.07],
|
||||
Huge: ['SetSize', 2.49],
|
||||
|
||||
Bbb: ['Macro', '{\\bbFont #1}', 1],
|
||||
textnormal: ['Macro', '{\\rm #1}', 1],
|
||||
textup: ['Macro', '{\\rm #1}', 1],
|
||||
textrm: ['Macro', '{\\rm #1}', 1],
|
||||
textit: ['Macro', '{\\it #1}', 1],
|
||||
textbf: ['Macro', '{\\bf #1}', 1],
|
||||
textsf: ['Macro', '{\\sf #1}', 1],
|
||||
texttt: ['Macro', '{\\tt #1}', 1],
|
||||
|
||||
dagger: ['Insert', '\u2020'],
|
||||
ddagger: ['Insert', '\u2021'],
|
||||
S: ['Insert', '\u00A7'],
|
||||
|
||||
',': ['Spacer', MATHSPACE.thinmathspace],
|
||||
':': ['Spacer', MATHSPACE.mediummathspace],
|
||||
'>': ['Spacer', MATHSPACE.mediummathspace],
|
||||
';': ['Spacer', MATHSPACE.thickmathspace],
|
||||
'!': ['Spacer', MATHSPACE.negativethinmathspace],
|
||||
enspace: ['Spacer', .5],
|
||||
quad: ['Spacer', 1],
|
||||
qquad: ['Spacer', 2],
|
||||
thinspace: ['Spacer', MATHSPACE.thinmathspace],
|
||||
negthinspace: ['Spacer', MATHSPACE.negativethinmathspace],
|
||||
|
||||
hskip: 'Hskip',
|
||||
hspace: 'Hskip',
|
||||
kern: 'Hskip',
|
||||
mskip: 'Hskip',
|
||||
mspace: 'Hskip',
|
||||
mkern: 'Hskip',
|
||||
rule: 'rule',
|
||||
Rule: ['Rule'],
|
||||
Space: ['Rule', 'blank'],
|
||||
|
||||
color: 'CheckAutoload',
|
||||
textcolor: 'CheckAutoload',
|
||||
colorbox: 'CheckAutoload',
|
||||
fcolorbox: 'CheckAutoload',
|
||||
href: 'CheckAutoload',
|
||||
style: 'CheckAutoload',
|
||||
class: 'CheckAutoload',
|
||||
cssId: 'CheckAutoload',
|
||||
unicode: 'CheckAutoload',
|
||||
|
||||
ref: ['HandleRef', false],
|
||||
eqref: ['HandleRef', true],
|
||||
|
||||
}, TextMacrosMethods);
|
||||
287
node_modules/mathjax-full/ts/input/tex/textmacros/TextMacrosMethods.ts
generated
vendored
Normal file
287
node_modules/mathjax-full/ts/input/tex/textmacros/TextMacrosMethods.ts
generated
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Method definitions for the textmacros package
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import TexParser from '../TexParser.js';
|
||||
import {retryAfter} from '../../../util/Retries.js';
|
||||
import {TextParser} from './TextParser.js';
|
||||
import BaseMethods from '../base/BaseMethods.js';
|
||||
|
||||
/**
|
||||
* The methods used to implement the text-mode macros
|
||||
*/
|
||||
export const TextMacrosMethods = {
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} c The character that called this function
|
||||
*/
|
||||
Comment(parser: TextParser, _c: string) {
|
||||
while (parser.i < parser.string.length && parser.string.charAt(parser.i) !== '\n') {
|
||||
parser.i++;
|
||||
}
|
||||
parser.i++;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} open The delimiter used to open math-mode in text-mode
|
||||
*/
|
||||
Math(parser: TextParser, open: string) {
|
||||
parser.saveText();
|
||||
let i = parser.i;
|
||||
let j, c;
|
||||
let braces = 0;
|
||||
//
|
||||
// Loop through the string looking for the closing delimiter, while matching braces
|
||||
//
|
||||
while ((c = parser.GetNext())) {
|
||||
j = parser.i++;
|
||||
switch (c) {
|
||||
|
||||
case '\\':
|
||||
const cs = parser.GetCS();
|
||||
if (cs === ')') c = '\\('; // \( is the opening delimiter for \)
|
||||
case '$':
|
||||
//
|
||||
// If there are no unbalanced braces and we have found the close delimiter,
|
||||
// process the contents of the delimiters in math mode (using the original TeX parser)
|
||||
//
|
||||
if (braces === 0 && open === c) {
|
||||
const config = parser.texParser.configuration;
|
||||
const mml = (new TexParser(parser.string.substr(i, j - i), parser.stack.env, config)).mml();
|
||||
parser.PushMath(mml);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case '{':
|
||||
braces++;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
if (braces === 0) {
|
||||
parser.Error('ExtraCloseMissingOpen', 'Extra close brace or missing open brace');
|
||||
}
|
||||
braces--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
parser.Error('MathNotTerminated', 'Math-mode is not properly terminated');
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} c The character that called this function
|
||||
*/
|
||||
MathModeOnly(parser: TextParser, c: string) {
|
||||
parser.Error('MathModeOnly', '\'%1\' allowed only in math mode', c);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} c The character that called this function
|
||||
*/
|
||||
Misplaced(parser: TextParser, c: string) {
|
||||
parser.Error('Misplaced', '\'%1\' can not be used here', c);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} c The character that called this function
|
||||
*/
|
||||
OpenBrace(parser: TextParser, _c: string) {
|
||||
//
|
||||
// Save the current stack environment and make a copy of it for
|
||||
// use within the braced group.
|
||||
//
|
||||
const env = parser.stack.env;
|
||||
parser.envStack.push(env);
|
||||
parser.stack.env = Object.assign({}, env);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} c The character that called this function
|
||||
*/
|
||||
CloseBrace(parser: TextParser, _c: string) {
|
||||
//
|
||||
// Restore the saved stack environment, if there was one
|
||||
//
|
||||
if (parser.envStack.length) {
|
||||
parser.saveText();
|
||||
parser.stack.env = parser.envStack.pop();
|
||||
} else {
|
||||
parser.Error('ExtraCloseMissingOpen', 'Extra close brace or missing open brace');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} c The character that called this function
|
||||
*/
|
||||
OpenQuote(parser: TextParser, c: string) {
|
||||
//
|
||||
// Handle smart open quotes
|
||||
//
|
||||
if (parser.string.charAt(parser.i) === c) {
|
||||
parser.text += '\u201C';
|
||||
parser.i++;
|
||||
} else {
|
||||
parser.text += '\u2018';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} c The character that called this function
|
||||
*/
|
||||
CloseQuote(parser: TextParser, c: string) {
|
||||
//
|
||||
// Handle smart close quotes
|
||||
//
|
||||
if (parser.string.charAt(parser.i) === c) {
|
||||
parser.text += '\u201D';
|
||||
parser.i++;
|
||||
} else {
|
||||
parser.text += '\u2019';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} c The character that called this function
|
||||
*/
|
||||
Tilde(parser: TextParser, _c: string) {
|
||||
parser.text += '\u00A0'; // non-breaking space
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} c The character that called this function
|
||||
*/
|
||||
Space(parser: TextParser, _c: string) {
|
||||
parser.text += ' '; // regular space, but skipping multiple spaces
|
||||
while (parser.GetNext().match(/\s/)) parser.i++;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} name The control sequence that called this function
|
||||
*/
|
||||
SelfQuote(parser: TextParser, name: string) {
|
||||
parser.text += name.substr(1); // add in the quoted character
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} name The control sequence that called this function
|
||||
* @param {string} c The character to insert into the string
|
||||
*/
|
||||
Insert(parser: TextParser, _name: string, c: string) {
|
||||
parser.text += c;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} name The control sequence that called this function
|
||||
* @param {string} c The character to insert into the string
|
||||
*/
|
||||
Accent(parser: TextParser, name: string, c: string) {
|
||||
//
|
||||
// Create an accented character using mover
|
||||
//
|
||||
const base = parser.ParseArg(name);
|
||||
const accent = parser.create('token', 'mo', {}, c);
|
||||
parser.addAttributes(accent);
|
||||
parser.Push(parser.create('node', 'mover', [base, accent]));
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} name The control sequence that called this function
|
||||
*/
|
||||
Emph(parser: TextParser, name: string) {
|
||||
//
|
||||
// Switch to/from italics
|
||||
//
|
||||
const variant = (parser.stack.env.mathvariant === '-tex-mathit' ? 'normal' : '-tex-mathit');
|
||||
parser.Push(parser.ParseTextArg(name, {mathvariant: variant}));
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} name The control sequence that called this function
|
||||
* @param {string} variant The font variant to use from now on
|
||||
*/
|
||||
SetFont(parser: TextParser, _name: string, variant: string) {
|
||||
parser.saveText();
|
||||
parser.stack.env.mathvariant = variant;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} name The control sequence that called this function
|
||||
* @param {number} size The font size to use from now on
|
||||
*/
|
||||
SetSize(parser: TextParser, _name: string, size: number) {
|
||||
parser.saveText();
|
||||
parser.stack.env.mathsize = size;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {TextParser} parser The text-mode parser
|
||||
* @param {string} name The control sequence that called this function
|
||||
*/
|
||||
CheckAutoload(parser: TextParser, name: string) {
|
||||
const autoload = parser.configuration.packageData.get('autoload');
|
||||
const texParser = parser.texParser;
|
||||
name = name.slice(1);
|
||||
//
|
||||
// Check if a macro is undefined, or currently set to autoload an extension.
|
||||
// If so, process the macro in the original TexParser:
|
||||
// This will handle the undefined macro using the TeX parser's configuration, then return,
|
||||
// or will cause the autoloaded extension to load or be processed and restart the expression.
|
||||
// Otherwise, process the macro in text mode.
|
||||
//
|
||||
const macro = texParser.lookup('macro', name);
|
||||
if (!macro || (autoload && macro._func === autoload.Autoload)) {
|
||||
texParser.parse('macro', [texParser, name]);
|
||||
if (!macro) return;
|
||||
retryAfter(Promise.resolve());
|
||||
}
|
||||
texParser.parse('macro', [parser, name]);
|
||||
},
|
||||
|
||||
//
|
||||
// Copy some methods from the base package
|
||||
//
|
||||
Macro: BaseMethods.Macro,
|
||||
Spacer: BaseMethods.Spacer,
|
||||
Hskip: BaseMethods.Hskip,
|
||||
rule: BaseMethods.rule,
|
||||
Rule: BaseMethods.Rule,
|
||||
HandleRef: BaseMethods.HandleRef
|
||||
|
||||
};
|
||||
|
||||
209
node_modules/mathjax-full/ts/input/tex/textmacros/TextParser.ts
generated
vendored
Normal file
209
node_modules/mathjax-full/ts/input/tex/textmacros/TextParser.ts
generated
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2020-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview The TextParser class for the textmacros package
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide P. Cervone)
|
||||
*/
|
||||
|
||||
import TexParser from '../TexParser.js';
|
||||
import TexError from '../TexError.js';
|
||||
import ParseOptions from '../ParseOptions.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import {StackItem} from '../StackItem.js';
|
||||
import {MmlNode, AbstractMmlNode} from '../../../core/MmlTree/MmlNode.js';
|
||||
import {EnvList} from '../StackItem.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import {StopItem, StyleItem} from '../base/BaseItems.js';
|
||||
|
||||
/**
|
||||
* Subclass of the TexParser but for handling text-mode material
|
||||
*/
|
||||
export class TextParser extends TexParser {
|
||||
|
||||
/**
|
||||
* The accumulated text material to go into an mtext element
|
||||
*/
|
||||
public text: string;
|
||||
|
||||
/**
|
||||
* Saved stack environments for processing braces
|
||||
*/
|
||||
public envStack: EnvList[];
|
||||
|
||||
/**
|
||||
* The scriptlevel of this text-mode material
|
||||
*/
|
||||
public level: number | string | undefined;
|
||||
|
||||
/**
|
||||
* The accumulated MmlNodes generated by parsing the text-mode material
|
||||
*/
|
||||
protected nodes: MmlNode[];
|
||||
|
||||
/**
|
||||
* Short-hand for obtaining the saved TexParser
|
||||
*/
|
||||
public get texParser() {
|
||||
return this.configuration.packageData.get('textmacros').texParser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public get tags() {
|
||||
return this.texParser.tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @constructor
|
||||
*/
|
||||
constructor(text: string, env: EnvList, configuration: ParseOptions, level?: number | string) {
|
||||
super(text, env, configuration);
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure we only return one element (wrap multiple ones in an mrow or mstyle, as needed).
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public mml() {
|
||||
return (this.level != null ?
|
||||
this.create('node', 'mstyle', this.nodes, {displaystyle: false, scriptlevel: this.level}) :
|
||||
this.nodes.length === 1 ? this.nodes[0] : this.create('node', 'mrow', this.nodes));
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public Parse() {
|
||||
this.text = '';
|
||||
this.nodes = [];
|
||||
this.envStack = [];
|
||||
super.Parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an mtext element for the saved text and pushes that onto the node list
|
||||
*/
|
||||
public saveText() {
|
||||
if (this.text) {
|
||||
const mathvariant = this.stack.env.mathvariant;
|
||||
const text = ParseUtil.internalText(this, this.text, mathvariant ? {mathvariant} : {});
|
||||
this.text = '';
|
||||
this.Push(text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public Push(mml: MmlNode | StackItem) {
|
||||
if (this.text) {
|
||||
this.saveText();
|
||||
}
|
||||
if (mml instanceof StopItem) {
|
||||
return super.Push(mml);
|
||||
}
|
||||
if (mml instanceof StyleItem) {
|
||||
this.stack.env.mathcolor = this.stack.env.color;
|
||||
return;
|
||||
}
|
||||
if (mml instanceof AbstractMmlNode) {
|
||||
this.addAttributes(mml);
|
||||
this.nodes.push(mml);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push some math into the node list, adding mathsize and mathcolor
|
||||
* if specified in the environment.
|
||||
*
|
||||
* @param {MmlNode} mml The math nodes to push
|
||||
*/
|
||||
public PushMath(mml: MmlNode) {
|
||||
const env = this.stack.env;
|
||||
if (!mml.isKind('TeXAtom')) {
|
||||
mml = this.create('node', 'TeXAtom', [mml]); // make sure the math is an ORD
|
||||
}
|
||||
for (const name of ['mathsize', 'mathcolor']) {
|
||||
if (env[name] && !mml.attributes.getExplicit(name)) {
|
||||
if (!mml.isToken && !mml.isKind('mstyle')) {
|
||||
mml = this.create('node', 'mstyle', [mml]);
|
||||
}
|
||||
NodeUtil.setAttribute(mml, name, env[name]);
|
||||
}
|
||||
}
|
||||
if (mml.isInferred) {
|
||||
mml = this.create('node', 'mrow', mml.childNodes);
|
||||
}
|
||||
this.nodes.push(mml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add mathsize, mathcolor, and mathvariant to token nodes,
|
||||
* if they are specified in the environment
|
||||
*
|
||||
* @param {MmlNode} mml The node to adjust
|
||||
*/
|
||||
public addAttributes(mml: MmlNode) {
|
||||
const env = this.stack.env;
|
||||
if (!mml.isToken) return;
|
||||
for (const name of ['mathsize', 'mathcolor', 'mathvariant']) {
|
||||
if (env[name] && !mml.attributes.getExplicit(name)) {
|
||||
NodeUtil.setAttribute(mml, name, env[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the argument as text with the given environment settings
|
||||
*
|
||||
* @param {string} name The macro that is calling for a parameter
|
||||
* @param {EnvList} env The environment to use
|
||||
*/
|
||||
public ParseTextArg(name: string, env: EnvList) {
|
||||
const text = this.GetArgument(name);
|
||||
env = Object.assign(Object.assign({}, this.stack.env), env);
|
||||
return (new TextParser(text, env, this.configuration)).mml();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an argument as text rather than math
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public ParseArg(name: string) {
|
||||
return (new TextParser(this.GetArgument(name), this.stack.env, this.configuration)).mml();
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw an error
|
||||
*
|
||||
* @param {string} id The id for the message string
|
||||
* @param {string} message The English version of the message
|
||||
* @param {string[]} args Any substitution args for the message
|
||||
*/
|
||||
public Error(id: string, message: string, ...args: string[]) {
|
||||
throw new TexError(id, message, ...args);
|
||||
}
|
||||
|
||||
}
|
||||
98
node_modules/mathjax-full/ts/input/tex/unicode/UnicodeConfiguration.ts
generated
vendored
Normal file
98
node_modules/mathjax-full/ts/input/tex/unicode/UnicodeConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the unicode package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {EnvList} from '../StackItem.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import TexError from '../TexError.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import ParseUtil from '../ParseUtil.js';
|
||||
import NodeUtil from '../NodeUtil.js';
|
||||
import {numeric} from '../../../util/Entities.js';
|
||||
|
||||
// Namespace
|
||||
export let UnicodeMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
let UnicodeCache: {[key: number]: [number, number, string, number]} = {};
|
||||
|
||||
/**
|
||||
* Parse function for unicode macro.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the macro.
|
||||
*/
|
||||
UnicodeMethods.Unicode = function(parser: TexParser, name: string) {
|
||||
let HD = parser.GetBrackets(name);
|
||||
let HDsplit = null;
|
||||
let font = null;
|
||||
if (HD) {
|
||||
if (HD.replace(/ /g, '').
|
||||
match(/^(\d+(\.\d*)?|\.\d+),(\d+(\.\d*)?|\.\d+)$/)) {
|
||||
HDsplit = HD.replace(/ /g, '').split(/,/);
|
||||
font = parser.GetBrackets(name);
|
||||
} else {
|
||||
font = HD;
|
||||
}
|
||||
}
|
||||
let n = ParseUtil.trimSpaces(parser.GetArgument(name)).replace(/^0x/, 'x');
|
||||
if (!n.match(/^(x[0-9A-Fa-f]+|[0-9]+)$/)) {
|
||||
throw new TexError('BadUnicode', 'Argument to \\unicode must be a number');
|
||||
}
|
||||
let N = parseInt(n.match(/^x/) ? '0' + n : n);
|
||||
if (!UnicodeCache[N]) {
|
||||
UnicodeCache[N] = [800, 200, font, N];
|
||||
} else if (!font) {
|
||||
font = UnicodeCache[N][2];
|
||||
}
|
||||
if (HDsplit) {
|
||||
UnicodeCache[N][0] = Math.floor(parseFloat(HDsplit[0]) * 1000);
|
||||
UnicodeCache[N][1] = Math.floor(parseFloat(HDsplit[1]) * 1000);
|
||||
}
|
||||
let variant = parser.stack.env.font as string;
|
||||
let def: EnvList = {};
|
||||
if (font) {
|
||||
UnicodeCache[N][2] = def.fontfamily = font.replace(/'/g, '\'');
|
||||
if (variant) {
|
||||
if (variant.match(/bold/)) {
|
||||
def.fontweight = 'bold';
|
||||
}
|
||||
if (variant.match(/italic|-mathit/)) {
|
||||
def.fontstyle = 'italic';
|
||||
}
|
||||
}
|
||||
} else if (variant) {
|
||||
def.mathvariant = variant;
|
||||
}
|
||||
let node = parser.create('token', 'mtext', def, numeric(n));
|
||||
NodeUtil.setProperty(node, 'unicode', true);
|
||||
parser.Push(node);
|
||||
};
|
||||
|
||||
|
||||
new CommandMap('unicode', {unicode: 'Unicode'}, UnicodeMethods);
|
||||
|
||||
|
||||
export const UnicodeConfiguration = Configuration.create(
|
||||
'unicode', {handler: {macro: ['unicode']}}
|
||||
);
|
||||
98
node_modules/mathjax-full/ts/input/tex/upgreek/UpgreekConfiguration.ts
generated
vendored
Normal file
98
node_modules/mathjax-full/ts/input/tex/upgreek/UpgreekConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2021-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the upgreek package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {Symbol} from '../Symbol.js';
|
||||
import {CharacterMap} from '../SymbolMap.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
|
||||
|
||||
/**
|
||||
* Handle greek mathchar as mi in normal variant.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {Symbol} mchar The parsed symbol.
|
||||
*/
|
||||
function mathchar0miNormal(parser: TexParser, mchar: Symbol) {
|
||||
const def = mchar.attributes || {};
|
||||
def.mathvariant = TexConstant.Variant.NORMAL;
|
||||
const node = parser.create('token', 'mi', def, mchar.char);
|
||||
parser.Push(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upright Greek characters.
|
||||
*/
|
||||
new CharacterMap('upgreek', mathchar0miNormal, {
|
||||
upalpha: '\u03B1',
|
||||
upbeta: '\u03B2',
|
||||
upgamma: '\u03B3',
|
||||
updelta: '\u03B4',
|
||||
upepsilon: '\u03F5',
|
||||
upzeta: '\u03B6',
|
||||
upeta: '\u03B7',
|
||||
uptheta: '\u03B8',
|
||||
upiota: '\u03B9',
|
||||
upkappa: '\u03BA',
|
||||
uplambda: '\u03BB',
|
||||
upmu: '\u03BC',
|
||||
upnu: '\u03BD',
|
||||
upxi: '\u03BE',
|
||||
upomicron: '\u03BF',
|
||||
uppi: '\u03C0',
|
||||
uprho: '\u03C1',
|
||||
upsigma: '\u03C3',
|
||||
uptau: '\u03C4',
|
||||
upupsilon: '\u03C5',
|
||||
upphi: '\u03D5',
|
||||
upchi: '\u03C7',
|
||||
uppsi: '\u03C8',
|
||||
upomega: '\u03C9',
|
||||
upvarepsilon: '\u03B5',
|
||||
upvartheta: '\u03D1',
|
||||
upvarpi: '\u03D6',
|
||||
upvarrho: '\u03F1',
|
||||
upvarsigma: '\u03C2',
|
||||
upvarphi: '\u03C6',
|
||||
|
||||
Upgamma: '\u0393',
|
||||
Updelta: '\u0394',
|
||||
Uptheta: '\u0398',
|
||||
Uplambda: '\u039B',
|
||||
Upxi: '\u039E',
|
||||
Uppi: '\u03A0',
|
||||
Upsigma: '\u03A3',
|
||||
Upupsilon: '\u03A5',
|
||||
Upphi: '\u03A6',
|
||||
Uppsi: '\u03A8',
|
||||
Upomega: '\u03A9'
|
||||
});
|
||||
|
||||
|
||||
export const UpgreekConfiguration = Configuration.create(
|
||||
'upgreek', {
|
||||
handler: {macro: ['upgreek']},
|
||||
}
|
||||
);
|
||||
|
||||
70
node_modules/mathjax-full/ts/input/tex/verb/VerbConfiguration.ts
generated
vendored
Normal file
70
node_modules/mathjax-full/ts/input/tex/verb/VerbConfiguration.ts
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Configuration file for the verb package.
|
||||
*
|
||||
* @author v.sorge@mathjax.org (Volker Sorge)
|
||||
*/
|
||||
|
||||
import {Configuration} from '../Configuration.js';
|
||||
import {TexConstant} from '../TexConstants.js';
|
||||
import TexParser from '../TexParser.js';
|
||||
import {CommandMap} from '../SymbolMap.js';
|
||||
import {ParseMethod} from '../Types.js';
|
||||
import TexError from '../TexError.js';
|
||||
|
||||
|
||||
// Namespace
|
||||
export let VerbMethods: Record<string, ParseMethod> = {};
|
||||
|
||||
|
||||
/**
|
||||
* Implements the verbatim notation \verb|...|.
|
||||
* @param {TexParser} parser The current tex parser.
|
||||
* @param {string} name The name of the calling macro.
|
||||
*/
|
||||
VerbMethods.Verb = function(parser: TexParser, name: string) {
|
||||
const c = parser.GetNext();
|
||||
const start = ++parser.i;
|
||||
if (c === '' ) {
|
||||
throw new TexError('MissingArgFor', 'Missing argument for %1', name);
|
||||
}
|
||||
while (parser.i < parser.string.length &&
|
||||
parser.string.charAt(parser.i) !== c) {
|
||||
parser.i++;
|
||||
}
|
||||
if (parser.i === parser.string.length) {
|
||||
throw new TexError('NoClosingDelim',
|
||||
'Can\'t find closing delimiter for %1',
|
||||
parser.currentCS);
|
||||
}
|
||||
const text = parser.string.slice(start, parser.i).replace(/ /g, '\u00A0');
|
||||
parser.i++;
|
||||
parser.Push(parser.create('token', 'mtext',
|
||||
{mathvariant: TexConstant.Variant.MONOSPACE},
|
||||
text));
|
||||
};
|
||||
|
||||
|
||||
new CommandMap('verb', {verb: 'Verb'}, VerbMethods);
|
||||
|
||||
|
||||
export const VerbConfiguration = Configuration.create(
|
||||
'verb', {handler: {macro: ['verb']}}
|
||||
);
|
||||
Reference in New Issue
Block a user