Commit node_modules
This commit is contained in:
1118
paige/node_modules/katex/src/environments/array.js
generated
vendored
Normal file
1118
paige/node_modules/katex/src/environments/array.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
313
paige/node_modules/katex/src/environments/cd.js
generated
vendored
Normal file
313
paige/node_modules/katex/src/environments/cd.js
generated
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
// @flow
|
||||
import buildCommon from "../buildCommon";
|
||||
import defineFunction from "../defineFunction";
|
||||
import mathMLTree from "../mathMLTree";
|
||||
import * as html from "../buildHTML";
|
||||
import * as mml from "../buildMathML";
|
||||
import {assertSymbolNodeType} from "../parseNode";
|
||||
import ParseError from "../ParseError";
|
||||
import {makeEm} from "../units";
|
||||
|
||||
import type Parser from "../Parser";
|
||||
import type {ParseNode, AnyParseNode} from "../parseNode";
|
||||
|
||||
const cdArrowFunctionName = {
|
||||
">": "\\\\cdrightarrow",
|
||||
"<": "\\\\cdleftarrow",
|
||||
"=": "\\\\cdlongequal",
|
||||
"A": "\\uparrow",
|
||||
"V": "\\downarrow",
|
||||
"|": "\\Vert",
|
||||
".": "no arrow",
|
||||
};
|
||||
|
||||
const newCell = () => {
|
||||
// Create an empty cell, to be filled below with parse nodes.
|
||||
// The parseTree from this module must be constructed like the
|
||||
// one created by parseArray(), so an empty CD cell must
|
||||
// be a ParseNode<"styling">. And CD is always displaystyle.
|
||||
// So these values are fixed and flow can do implicit typing.
|
||||
return {type: "styling", body: [], mode: "math", style: "display"};
|
||||
};
|
||||
|
||||
const isStartOfArrow = (node: AnyParseNode) => {
|
||||
return (node.type === "textord" && node.text === "@");
|
||||
};
|
||||
|
||||
const isLabelEnd = (node: AnyParseNode, endChar: string): boolean => {
|
||||
return ((node.type === "mathord" || node.type === "atom") &&
|
||||
node.text === endChar);
|
||||
};
|
||||
|
||||
function cdArrow(
|
||||
arrowChar: string,
|
||||
labels: ParseNode<"ordgroup">[],
|
||||
parser: Parser
|
||||
): AnyParseNode {
|
||||
// Return a parse tree of an arrow and its labels.
|
||||
// This acts in a way similar to a macro expansion.
|
||||
const funcName = cdArrowFunctionName[arrowChar];
|
||||
switch (funcName) {
|
||||
case "\\\\cdrightarrow":
|
||||
case "\\\\cdleftarrow":
|
||||
return parser.callFunction(
|
||||
funcName, [labels[0]], [labels[1]]
|
||||
);
|
||||
case "\\uparrow":
|
||||
case "\\downarrow": {
|
||||
const leftLabel = parser.callFunction(
|
||||
"\\\\cdleft", [labels[0]], []
|
||||
);
|
||||
const bareArrow = {
|
||||
type: "atom",
|
||||
text: funcName,
|
||||
mode: "math",
|
||||
family: "rel",
|
||||
};
|
||||
const sizedArrow = parser.callFunction("\\Big", [bareArrow], []);
|
||||
const rightLabel = parser.callFunction(
|
||||
"\\\\cdright", [labels[1]], []
|
||||
);
|
||||
const arrowGroup = {
|
||||
type: "ordgroup",
|
||||
mode: "math",
|
||||
body: [leftLabel, sizedArrow, rightLabel],
|
||||
};
|
||||
return parser.callFunction("\\\\cdparent", [arrowGroup], []);
|
||||
}
|
||||
case "\\\\cdlongequal":
|
||||
return parser.callFunction("\\\\cdlongequal", [], []);
|
||||
case "\\Vert": {
|
||||
const arrow = {type: "textord", text: "\\Vert", mode: "math"};
|
||||
return parser.callFunction("\\Big", [arrow], []);
|
||||
}
|
||||
default:
|
||||
return {type: "textord", text: " ", mode: "math"};
|
||||
}
|
||||
}
|
||||
|
||||
export function parseCD(parser: Parser): ParseNode<"array"> {
|
||||
// Get the array's parse nodes with \\ temporarily mapped to \cr.
|
||||
const parsedRows: AnyParseNode[][] = [];
|
||||
parser.gullet.beginGroup();
|
||||
parser.gullet.macros.set("\\cr", "\\\\\\relax");
|
||||
parser.gullet.beginGroup();
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
// Get the parse nodes for the next row.
|
||||
parsedRows.push(parser.parseExpression(false, "\\\\"));
|
||||
parser.gullet.endGroup();
|
||||
parser.gullet.beginGroup();
|
||||
const next = parser.fetch().text;
|
||||
if (next === "&" || next === "\\\\") {
|
||||
parser.consume();
|
||||
} else if (next === "\\end") {
|
||||
if (parsedRows[parsedRows.length - 1].length === 0) {
|
||||
parsedRows.pop(); // final row ended in \\
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
throw new ParseError("Expected \\\\ or \\cr or \\end",
|
||||
parser.nextToken);
|
||||
}
|
||||
}
|
||||
|
||||
let row = [];
|
||||
const body = [row];
|
||||
|
||||
// Loop thru the parse nodes. Collect them into cells and arrows.
|
||||
for (let i = 0; i < parsedRows.length; i++) {
|
||||
// Start a new row.
|
||||
const rowNodes = parsedRows[i];
|
||||
// Create the first cell.
|
||||
let cell = newCell();
|
||||
|
||||
for (let j = 0; j < rowNodes.length; j++) {
|
||||
if (!isStartOfArrow(rowNodes[j])) {
|
||||
// If a parseNode is not an arrow, it goes into a cell.
|
||||
cell.body.push(rowNodes[j]);
|
||||
} else {
|
||||
// Parse node j is an "@", the start of an arrow.
|
||||
// Before starting on the arrow, push the cell into `row`.
|
||||
row.push(cell);
|
||||
|
||||
// Now collect parseNodes into an arrow.
|
||||
// The character after "@" defines the arrow type.
|
||||
j += 1;
|
||||
const arrowChar = assertSymbolNodeType(rowNodes[j]).text;
|
||||
|
||||
// Create two empty label nodes. We may or may not use them.
|
||||
const labels: ParseNode<"ordgroup">[] = new Array(2);
|
||||
labels[0] = {type: "ordgroup", mode: "math", body: []};
|
||||
labels[1] = {type: "ordgroup", mode: "math", body: []};
|
||||
|
||||
// Process the arrow.
|
||||
if ("=|.".indexOf(arrowChar) > -1) {
|
||||
// Three "arrows", ``@=`, `@|`, and `@.`, do not take labels.
|
||||
// Do nothing here.
|
||||
} else if ("<>AV".indexOf(arrowChar) > -1) {
|
||||
// Four arrows, `@>>>`, `@<<<`, `@AAA`, and `@VVV`, each take
|
||||
// two optional labels. E.g. the right-point arrow syntax is
|
||||
// really: @>{optional label}>{optional label}>
|
||||
// Collect parseNodes into labels.
|
||||
for (let labelNum = 0; labelNum < 2; labelNum++) {
|
||||
let inLabel = true;
|
||||
for (let k = j + 1; k < rowNodes.length; k++) {
|
||||
if (isLabelEnd(rowNodes[k], arrowChar)) {
|
||||
inLabel = false;
|
||||
j = k;
|
||||
break;
|
||||
}
|
||||
if (isStartOfArrow(rowNodes[k])) {
|
||||
throw new ParseError("Missing a " + arrowChar +
|
||||
" character to complete a CD arrow.", rowNodes[k]);
|
||||
}
|
||||
|
||||
labels[labelNum].body.push(rowNodes[k]);
|
||||
}
|
||||
if (inLabel) {
|
||||
// isLabelEnd never returned a true.
|
||||
throw new ParseError("Missing a " + arrowChar +
|
||||
" character to complete a CD arrow.", rowNodes[j]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new ParseError(`Expected one of "<>AV=|." after @`,
|
||||
rowNodes[j]);
|
||||
}
|
||||
|
||||
// Now join the arrow to its labels.
|
||||
const arrow: AnyParseNode = cdArrow(arrowChar, labels, parser);
|
||||
|
||||
// Wrap the arrow in ParseNode<"styling">.
|
||||
// This is done to match parseArray() behavior.
|
||||
const wrappedArrow = {
|
||||
type: "styling",
|
||||
body: [arrow],
|
||||
mode: "math",
|
||||
style: "display", // CD is always displaystyle.
|
||||
};
|
||||
row.push(wrappedArrow);
|
||||
// In CD's syntax, cells are implicit. That is, everything that
|
||||
// is not an arrow gets collected into a cell. So create an empty
|
||||
// cell now. It will collect upcoming parseNodes.
|
||||
cell = newCell();
|
||||
}
|
||||
}
|
||||
if (i % 2 === 0) {
|
||||
// Even-numbered rows consist of: cell, arrow, cell, arrow, ... cell
|
||||
// The last cell is not yet pushed into `row`, so:
|
||||
row.push(cell);
|
||||
} else {
|
||||
// Odd-numbered rows consist of: vert arrow, empty cell, ... vert arrow
|
||||
// Remove the empty cell that was placed at the beginning of `row`.
|
||||
row.shift();
|
||||
}
|
||||
row = [];
|
||||
body.push(row);
|
||||
}
|
||||
|
||||
// End row group
|
||||
parser.gullet.endGroup();
|
||||
// End array group defining \\
|
||||
parser.gullet.endGroup();
|
||||
|
||||
// define column separation.
|
||||
const cols = new Array(body[0].length).fill({
|
||||
type: "align",
|
||||
align: "c",
|
||||
pregap: 0.25, // CD package sets \enskip between columns.
|
||||
postgap: 0.25, // So pre and post each get half an \enskip, i.e. 0.25em.
|
||||
});
|
||||
|
||||
return {
|
||||
type: "array",
|
||||
mode: "math",
|
||||
body,
|
||||
arraystretch: 1,
|
||||
addJot: true,
|
||||
rowGaps: [null],
|
||||
cols,
|
||||
colSeparationType: "CD",
|
||||
hLinesBeforeRow: new Array(body.length + 1).fill([]),
|
||||
};
|
||||
}
|
||||
|
||||
// The functions below are not available for general use.
|
||||
// They are here only for internal use by the {CD} environment in placing labels
|
||||
// next to vertical arrows.
|
||||
|
||||
// We don't need any such functions for horizontal arrows because we can reuse
|
||||
// the functionality that already exists for extensible arrows.
|
||||
|
||||
defineFunction({
|
||||
type: "cdlabel",
|
||||
names: ["\\\\cdleft", "\\\\cdright"],
|
||||
props: {
|
||||
numArgs: 1,
|
||||
},
|
||||
handler({parser, funcName}, args) {
|
||||
return {
|
||||
type: "cdlabel",
|
||||
mode: parser.mode,
|
||||
side: funcName.slice(4),
|
||||
label: args[0],
|
||||
};
|
||||
},
|
||||
htmlBuilder(group, options) {
|
||||
const newOptions = options.havingStyle(options.style.sup());
|
||||
const label = buildCommon.wrapFragment(
|
||||
html.buildGroup(group.label, newOptions, options), options);
|
||||
label.classes.push("cd-label-" + group.side);
|
||||
label.style.bottom = makeEm(0.8 - label.depth);
|
||||
// Zero out label height & depth, so vertical align of arrow is set
|
||||
// by the arrow height, not by the label.
|
||||
label.height = 0;
|
||||
label.depth = 0;
|
||||
return label;
|
||||
},
|
||||
mathmlBuilder(group, options) {
|
||||
let label = new mathMLTree.MathNode("mrow",
|
||||
[mml.buildGroup(group.label, options)]);
|
||||
label = new mathMLTree.MathNode("mpadded", [label]);
|
||||
label.setAttribute("width", "0");
|
||||
if (group.side === "left") {
|
||||
label.setAttribute("lspace", "-1width");
|
||||
}
|
||||
// We have to guess at vertical alignment. We know the arrow is 1.8em tall,
|
||||
// But we don't know the height or depth of the label.
|
||||
label.setAttribute("voffset", "0.7em");
|
||||
label = new mathMLTree.MathNode("mstyle", [label]);
|
||||
label.setAttribute("displaystyle", "false");
|
||||
label.setAttribute("scriptlevel", "1");
|
||||
return label;
|
||||
},
|
||||
});
|
||||
|
||||
defineFunction({
|
||||
type: "cdlabelparent",
|
||||
names: ["\\\\cdparent"],
|
||||
props: {
|
||||
numArgs: 1,
|
||||
},
|
||||
handler({parser}, args) {
|
||||
return {
|
||||
type: "cdlabelparent",
|
||||
mode: parser.mode,
|
||||
fragment: args[0],
|
||||
};
|
||||
},
|
||||
htmlBuilder(group, options) {
|
||||
// Wrap the vertical arrow and its labels.
|
||||
// The parent gets position: relative. The child gets position: absolute.
|
||||
// So CSS can locate the label correctly.
|
||||
const parent = buildCommon.wrapFragment(
|
||||
html.buildGroup(group.fragment, options), options
|
||||
);
|
||||
parent.classes.push("cd-vert-arrow");
|
||||
return parent;
|
||||
},
|
||||
mathmlBuilder(group, options) {
|
||||
return new mathMLTree.MathNode("mrow",
|
||||
[mml.buildGroup(group.fragment, options)]);
|
||||
},
|
||||
});
|
Reference in New Issue
Block a user