mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-05 11:18:39 +00:00
* Nested environments of macro definitions * Rename environment -> namespace * \def support * Clean up \df@tag at beginning * \global\def support * Fix \global via new setMacro helper * Fix caching behavior and build array on top of it Also avoid double lookup of macros * Add tests * Add argument tests * Remove global pointer * Note about macros object being modified * add __defineMacro * Add \global\def test * More \global tests * Constant-time lookup Rewrite to use an "undo" stack similar to TeX, so get and set are constant-time operations. get() still has to check two objects: one with all current settings, and then the built-ins. Local set() sets the current value and (when appropriate) adds an undo operation to the undo stack. Global set() still takes time linear in the number of groups, possibly changing the undo operation at every level. `Namespace` now refers to a space of things like macros or lengths. * Add \def to-dos * Put optional arguments in their own group * Rename `pushNamespace` -> `beginGroup` * Wrap each expression in a group namespace * Add comments
106 lines
3.0 KiB
JavaScript
106 lines
3.0 KiB
JavaScript
/* global expect: false */
|
|
|
|
import katex from "../katex";
|
|
import ParseError from "../src/ParseError";
|
|
import parseTree from "../src/parseTree";
|
|
import Settings from "../src/Settings";
|
|
|
|
export const defaultSettings = new Settings({
|
|
strict: false, // deal with warnings only when desired
|
|
});
|
|
export const strictSettings = new Settings({strict: true});
|
|
|
|
export const _getBuilt = function(expr, settings = defaultSettings) {
|
|
if (settings === defaultSettings) {
|
|
settings.macros = {};
|
|
}
|
|
let rootNode = katex.__renderToDomTree(expr, settings);
|
|
|
|
if (rootNode.classes.indexOf('katex-error') >= 0) {
|
|
return rootNode;
|
|
}
|
|
|
|
if (rootNode.classes.indexOf('katex-display') >= 0) {
|
|
rootNode = rootNode.children[0];
|
|
}
|
|
|
|
// grab the root node of the HTML rendering
|
|
// rootNode.children[0] is the MathML rendering
|
|
const builtHTML = rootNode.children[1];
|
|
|
|
// combine the non-strut children of all base spans
|
|
const children = [];
|
|
for (let i = 0; i < builtHTML.children.length; i++) {
|
|
children.push(...builtHTML.children[i].children.filter(
|
|
(node) => node.classes.indexOf("strut") < 0));
|
|
}
|
|
return children;
|
|
};
|
|
|
|
/**
|
|
* Return the root node of the rendered HTML.
|
|
* @param expr
|
|
* @param settings
|
|
* @returns {Object}
|
|
*/
|
|
export const getBuilt = function(expr, settings = defaultSettings) {
|
|
expect(expr).toBuild(settings);
|
|
return _getBuilt(expr, settings);
|
|
};
|
|
|
|
/**
|
|
* Return the root node of the parse tree.
|
|
* @param expr
|
|
* @param settings
|
|
* @returns {Object}
|
|
*/
|
|
export const getParsed = function(expr, settings = defaultSettings) {
|
|
expect(expr).toParse(settings);
|
|
return parseTree(expr, settings);
|
|
};
|
|
|
|
export const stripPositions = function(expr) {
|
|
if (typeof expr !== "object" || expr === null) {
|
|
return expr;
|
|
}
|
|
if (expr.loc && expr.loc.lexer && typeof expr.loc.start === "number") {
|
|
delete expr.loc;
|
|
}
|
|
Object.keys(expr).forEach(function(key) {
|
|
stripPositions(expr[key]);
|
|
});
|
|
return expr;
|
|
};
|
|
|
|
export const parseAndSetResult = function(expr, result,
|
|
settings = defaultSettings) {
|
|
try {
|
|
return parseTree(expr, settings);
|
|
} catch (e) {
|
|
result.pass = false;
|
|
if (e instanceof ParseError) {
|
|
result.message = () =>
|
|
`'${expr}' failed parsing with error: ${e.message}`;
|
|
} else {
|
|
result.message = () =>
|
|
`'${expr}' failed parsing with unknown error: ${e.message}`;
|
|
}
|
|
}
|
|
};
|
|
|
|
export const buildAndSetResult = function(expr, result,
|
|
settings = defaultSettings) {
|
|
try {
|
|
return _getBuilt(expr, settings);
|
|
} catch (e) {
|
|
result.pass = false;
|
|
if (e instanceof ParseError) {
|
|
result.message = () =>
|
|
`'${expr}' failed building with error: ${e.message}`;
|
|
} else {
|
|
result.message = () =>
|
|
`'${expr}' failed building with unknown error: ${e.message}`;
|
|
}
|
|
}
|
|
};
|