Commit node_modules
This commit is contained in:
129
paige/node_modules/katex/src/Namespace.js
generated
vendored
Normal file
129
paige/node_modules/katex/src/Namespace.js
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
// @flow
|
||||
|
||||
/**
|
||||
* A `Namespace` refers to a space of nameable things like macros or lengths,
|
||||
* which can be `set` either globally or local to a nested group, using an
|
||||
* undo stack similar to how TeX implements this functionality.
|
||||
* Performance-wise, `get` and local `set` take constant time, while global
|
||||
* `set` takes time proportional to the depth of group nesting.
|
||||
*/
|
||||
|
||||
import ParseError from "./ParseError";
|
||||
|
||||
export type Mapping<Value> = {[string]: Value};
|
||||
|
||||
export default class Namespace<Value> {
|
||||
current: Mapping<Value>;
|
||||
builtins: Mapping<Value>;
|
||||
undefStack: Mapping<?Value>[];
|
||||
|
||||
/**
|
||||
* Both arguments are optional. The first argument is an object of
|
||||
* built-in mappings which never change. The second argument is an object
|
||||
* of initial (global-level) mappings, which will constantly change
|
||||
* according to any global/top-level `set`s done.
|
||||
*/
|
||||
constructor(builtins: Mapping<Value> = {},
|
||||
globalMacros: Mapping<Value> = {}) {
|
||||
this.current = globalMacros;
|
||||
this.builtins = builtins;
|
||||
this.undefStack = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new nested group, affecting future local `set`s.
|
||||
*/
|
||||
beginGroup() {
|
||||
this.undefStack.push({});
|
||||
}
|
||||
|
||||
/**
|
||||
* End current nested group, restoring values before the group began.
|
||||
*/
|
||||
endGroup() {
|
||||
if (this.undefStack.length === 0) {
|
||||
throw new ParseError("Unbalanced namespace destruction: attempt " +
|
||||
"to pop global namespace; please report this as a bug");
|
||||
}
|
||||
const undefs = this.undefStack.pop();
|
||||
for (const undef in undefs) {
|
||||
if (undefs.hasOwnProperty(undef)) {
|
||||
if (undefs[undef] == null) {
|
||||
delete this.current[undef];
|
||||
} else {
|
||||
this.current[undef] = undefs[undef];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends all currently nested groups (if any), restoring values before the
|
||||
* groups began. Useful in case of an error in the middle of parsing.
|
||||
*/
|
||||
endGroups() {
|
||||
while (this.undefStack.length > 0) {
|
||||
this.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether `name` has a definition. Equivalent to
|
||||
* `get(name) != null`.
|
||||
*/
|
||||
has(name: string): boolean {
|
||||
return this.current.hasOwnProperty(name) ||
|
||||
this.builtins.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current value of a name, or `undefined` if there is no value.
|
||||
*
|
||||
* Note: Do not use `if (namespace.get(...))` to detect whether a macro
|
||||
* is defined, as the definition may be the empty string which evaluates
|
||||
* to `false` in JavaScript. Use `if (namespace.get(...) != null)` or
|
||||
* `if (namespace.has(...))`.
|
||||
*/
|
||||
get(name: string): ?Value {
|
||||
if (this.current.hasOwnProperty(name)) {
|
||||
return this.current[name];
|
||||
} else {
|
||||
return this.builtins[name];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current value of a name, and optionally set it globally too.
|
||||
* Local set() sets the current value and (when appropriate) adds an undo
|
||||
* operation to the undo stack. Global set() may change the undo
|
||||
* operation at every level, so takes time linear in their number.
|
||||
* A value of undefined means to delete existing definitions.
|
||||
*/
|
||||
set(name: string, value: ?Value, global: boolean = false) {
|
||||
if (global) {
|
||||
// Global set is equivalent to setting in all groups. Simulate this
|
||||
// by destroying any undos currently scheduled for this name,
|
||||
// and adding an undo with the *new* value (in case it later gets
|
||||
// locally reset within this environment).
|
||||
for (let i = 0; i < this.undefStack.length; i++) {
|
||||
delete this.undefStack[i][name];
|
||||
}
|
||||
if (this.undefStack.length > 0) {
|
||||
this.undefStack[this.undefStack.length - 1][name] = value;
|
||||
}
|
||||
} else {
|
||||
// Undo this set at end of this group (possibly to `undefined`),
|
||||
// unless an undo is already in place, in which case that older
|
||||
// value is the correct one.
|
||||
const top = this.undefStack[this.undefStack.length - 1];
|
||||
if (top && !top.hasOwnProperty(name)) {
|
||||
top[name] = this.current[name];
|
||||
}
|
||||
}
|
||||
if (value == null) {
|
||||
delete this.current[name];
|
||||
} else {
|
||||
this.current[name] = value;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user