summaryrefslogtreecommitdiffstats
path: root/webapp/non_npm_dependencies/katex/src/buildMathML.js
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/non_npm_dependencies/katex/src/buildMathML.js')
-rw-r--r--webapp/non_npm_dependencies/katex/src/buildMathML.js519
1 files changed, 0 insertions, 519 deletions
diff --git a/webapp/non_npm_dependencies/katex/src/buildMathML.js b/webapp/non_npm_dependencies/katex/src/buildMathML.js
deleted file mode 100644
index f3c7c5e1c..000000000
--- a/webapp/non_npm_dependencies/katex/src/buildMathML.js
+++ /dev/null
@@ -1,519 +0,0 @@
-/**
- * This file converts a parse tree into a cooresponding MathML tree. The main
- * entry point is the `buildMathML` function, which takes a parse tree from the
- * parser.
- */
-
-var buildCommon = require("./buildCommon");
-var fontMetrics = require("./fontMetrics");
-var mathMLTree = require("./mathMLTree");
-var ParseError = require("./ParseError");
-var symbols = require("./symbols");
-var utils = require("./utils");
-
-var makeSpan = buildCommon.makeSpan;
-var fontMap = buildCommon.fontMap;
-
-/**
- * Takes a symbol and converts it into a MathML text node after performing
- * optional replacement from symbols.js.
- */
-var makeText = function(text, mode) {
- if (symbols[mode][text] && symbols[mode][text].replace) {
- text = symbols[mode][text].replace;
- }
-
- return new mathMLTree.TextNode(text);
-};
-
-/**
- * Returns the math variant as a string or null if none is required.
- */
-var getVariant = function(group, options) {
- var font = options.font;
- if (!font) {
- return null;
- }
-
- var mode = group.mode;
- if (font === "mathit") {
- return "italic";
- }
-
- var value = group.value;
- if (utils.contains(["\\imath", "\\jmath"], value)) {
- return null;
- }
-
- if (symbols[mode][value] && symbols[mode][value].replace) {
- value = symbols[mode][value].replace;
- }
-
- var fontName = fontMap[font].fontName;
- if (fontMetrics.getCharacterMetrics(value, fontName)) {
- return fontMap[options.font].variant;
- }
-
- return null;
-};
-
-/**
- * Functions for handling the different types of groups found in the parse
- * tree. Each function should take a parse group and return a MathML node.
- */
-var groupTypes = {};
-
-groupTypes.mathord = function(group, options) {
- var node = new mathMLTree.MathNode(
- "mi",
- [makeText(group.value, group.mode)]);
-
- var variant = getVariant(group, options);
- if (variant) {
- node.setAttribute("mathvariant", variant);
- }
- return node;
-};
-
-groupTypes.textord = function(group, options) {
- var text = makeText(group.value, group.mode);
-
- var variant = getVariant(group, options) || "normal";
-
- var node;
- if (/[0-9]/.test(group.value)) {
- // TODO(kevinb) merge adjacent <mn> nodes
- // do it as a post processing step
- node = new mathMLTree.MathNode("mn", [text]);
- if (options.font) {
- node.setAttribute("mathvariant", variant);
- }
- } else {
- node = new mathMLTree.MathNode("mi", [text]);
- node.setAttribute("mathvariant", variant);
- }
-
- return node;
-};
-
-groupTypes.bin = function(group) {
- var node = new mathMLTree.MathNode(
- "mo", [makeText(group.value, group.mode)]);
-
- return node;
-};
-
-groupTypes.rel = function(group) {
- var node = new mathMLTree.MathNode(
- "mo", [makeText(group.value, group.mode)]);
-
- return node;
-};
-
-groupTypes.open = function(group) {
- var node = new mathMLTree.MathNode(
- "mo", [makeText(group.value, group.mode)]);
-
- return node;
-};
-
-groupTypes.close = function(group) {
- var node = new mathMLTree.MathNode(
- "mo", [makeText(group.value, group.mode)]);
-
- return node;
-};
-
-groupTypes.inner = function(group) {
- var node = new mathMLTree.MathNode(
- "mo", [makeText(group.value, group.mode)]);
-
- return node;
-};
-
-groupTypes.punct = function(group) {
- var node = new mathMLTree.MathNode(
- "mo", [makeText(group.value, group.mode)]);
-
- node.setAttribute("separator", "true");
-
- return node;
-};
-
-groupTypes.ordgroup = function(group, options) {
- var inner = buildExpression(group.value, options);
-
- var node = new mathMLTree.MathNode("mrow", inner);
-
- return node;
-};
-
-groupTypes.text = function(group, options) {
- var inner = buildExpression(group.value.body, options);
-
- var node = new mathMLTree.MathNode("mtext", inner);
-
- return node;
-};
-
-groupTypes.color = function(group, options) {
- var inner = buildExpression(group.value.value, options);
-
- var node = new mathMLTree.MathNode("mstyle", inner);
-
- node.setAttribute("mathcolor", group.value.color);
-
- return node;
-};
-
-groupTypes.supsub = function(group, options) {
- var children = [buildGroup(group.value.base, options)];
-
- if (group.value.sub) {
- children.push(buildGroup(group.value.sub, options));
- }
-
- if (group.value.sup) {
- children.push(buildGroup(group.value.sup, options));
- }
-
- var nodeType;
- if (!group.value.sub) {
- nodeType = "msup";
- } else if (!group.value.sup) {
- nodeType = "msub";
- } else {
- nodeType = "msubsup";
- }
-
- var node = new mathMLTree.MathNode(nodeType, children);
-
- return node;
-};
-
-groupTypes.genfrac = function(group, options) {
- var node = new mathMLTree.MathNode(
- "mfrac",
- [buildGroup(group.value.numer, options),
- buildGroup(group.value.denom, options)]);
-
- if (!group.value.hasBarLine) {
- node.setAttribute("linethickness", "0px");
- }
-
- if (group.value.leftDelim != null || group.value.rightDelim != null) {
- var withDelims = [];
-
- if (group.value.leftDelim != null) {
- var leftOp = new mathMLTree.MathNode(
- "mo", [new mathMLTree.TextNode(group.value.leftDelim)]);
-
- leftOp.setAttribute("fence", "true");
-
- withDelims.push(leftOp);
- }
-
- withDelims.push(node);
-
- if (group.value.rightDelim != null) {
- var rightOp = new mathMLTree.MathNode(
- "mo", [new mathMLTree.TextNode(group.value.rightDelim)]);
-
- rightOp.setAttribute("fence", "true");
-
- withDelims.push(rightOp);
- }
-
- var outerNode = new mathMLTree.MathNode("mrow", withDelims);
-
- return outerNode;
- }
-
- return node;
-};
-
-groupTypes.array = function(group, options) {
- return new mathMLTree.MathNode(
- "mtable", group.value.body.map(function(row) {
- return new mathMLTree.MathNode(
- "mtr", row.map(function(cell) {
- return new mathMLTree.MathNode(
- "mtd", [buildGroup(cell, options)]);
- }));
- }));
-};
-
-groupTypes.sqrt = function(group, options) {
- var node;
- if (group.value.index) {
- node = new mathMLTree.MathNode(
- "mroot", [
- buildGroup(group.value.body, options),
- buildGroup(group.value.index, options),
- ]);
- } else {
- node = new mathMLTree.MathNode(
- "msqrt", [buildGroup(group.value.body, options)]);
- }
-
- return node;
-};
-
-groupTypes.leftright = function(group, options) {
- var inner = buildExpression(group.value.body, options);
-
- if (group.value.left !== ".") {
- var leftNode = new mathMLTree.MathNode(
- "mo", [makeText(group.value.left, group.mode)]);
-
- leftNode.setAttribute("fence", "true");
-
- inner.unshift(leftNode);
- }
-
- if (group.value.right !== ".") {
- var rightNode = new mathMLTree.MathNode(
- "mo", [makeText(group.value.right, group.mode)]);
-
- rightNode.setAttribute("fence", "true");
-
- inner.push(rightNode);
- }
-
- var outerNode = new mathMLTree.MathNode("mrow", inner);
-
- return outerNode;
-};
-
-groupTypes.accent = function(group, options) {
- var accentNode = new mathMLTree.MathNode(
- "mo", [makeText(group.value.accent, group.mode)]);
-
- var node = new mathMLTree.MathNode(
- "mover",
- [buildGroup(group.value.base, options),
- accentNode]);
-
- node.setAttribute("accent", "true");
-
- return node;
-};
-
-groupTypes.spacing = function(group) {
- var node;
-
- if (group.value === "\\ " || group.value === "\\space" ||
- group.value === " " || group.value === "~") {
- node = new mathMLTree.MathNode(
- "mtext", [new mathMLTree.TextNode("\u00a0")]);
- } else {
- node = new mathMLTree.MathNode("mspace");
-
- node.setAttribute(
- "width", buildCommon.spacingFunctions[group.value].size);
- }
-
- return node;
-};
-
-groupTypes.op = function(group) {
- var node;
-
- // TODO(emily): handle big operators using the `largeop` attribute
-
- if (group.value.symbol) {
- // This is a symbol. Just add the symbol.
- node = new mathMLTree.MathNode(
- "mo", [makeText(group.value.body, group.mode)]);
- } else {
- // This is a text operator. Add all of the characters from the
- // operator's name.
- // TODO(emily): Add a space in the middle of some of these
- // operators, like \limsup.
- node = new mathMLTree.MathNode(
- "mi", [new mathMLTree.TextNode(group.value.body.slice(1))]);
- }
-
- return node;
-};
-
-groupTypes.katex = function(group) {
- var node = new mathMLTree.MathNode(
- "mtext", [new mathMLTree.TextNode("KaTeX")]);
-
- return node;
-};
-
-groupTypes.font = function(group, options) {
- var font = group.value.font;
- return buildGroup(group.value.body, options.withFont(font));
-};
-
-groupTypes.delimsizing = function(group) {
- var children = [];
-
- if (group.value.value !== ".") {
- children.push(makeText(group.value.value, group.mode));
- }
-
- var node = new mathMLTree.MathNode("mo", children);
-
- if (group.value.delimType === "open" ||
- group.value.delimType === "close") {
- // Only some of the delimsizing functions act as fences, and they
- // return "open" or "close" delimTypes.
- node.setAttribute("fence", "true");
- } else {
- // Explicitly disable fencing if it's not a fence, to override the
- // defaults.
- node.setAttribute("fence", "false");
- }
-
- return node;
-};
-
-groupTypes.styling = function(group, options) {
- var inner = buildExpression(group.value.value, options);
-
- var node = new mathMLTree.MathNode("mstyle", inner);
-
- var styleAttributes = {
- "display": ["0", "true"],
- "text": ["0", "false"],
- "script": ["1", "false"],
- "scriptscript": ["2", "false"],
- };
-
- var attr = styleAttributes[group.value.style];
-
- node.setAttribute("scriptlevel", attr[0]);
- node.setAttribute("displaystyle", attr[1]);
-
- return node;
-};
-
-groupTypes.sizing = function(group, options) {
- var inner = buildExpression(group.value.value, options);
-
- var node = new mathMLTree.MathNode("mstyle", inner);
-
- // TODO(emily): This doesn't produce the correct size for nested size
- // changes, because we don't keep state of what style we're currently
- // in, so we can't reset the size to normal before changing it. Now
- // that we're passing an options parameter we should be able to fix
- // this.
- node.setAttribute(
- "mathsize", buildCommon.sizingMultiplier[group.value.size] + "em");
-
- return node;
-};
-
-groupTypes.overline = function(group, options) {
- var operator = new mathMLTree.MathNode(
- "mo", [new mathMLTree.TextNode("\u203e")]);
- operator.setAttribute("stretchy", "true");
-
- var node = new mathMLTree.MathNode(
- "mover",
- [buildGroup(group.value.body, options),
- operator]);
- node.setAttribute("accent", "true");
-
- return node;
-};
-
-groupTypes.rule = function(group) {
- // TODO(emily): Figure out if there's an actual way to draw black boxes
- // in MathML.
- var node = new mathMLTree.MathNode("mrow");
-
- return node;
-};
-
-groupTypes.llap = function(group, options) {
- var node = new mathMLTree.MathNode(
- "mpadded", [buildGroup(group.value.body, options)]);
-
- node.setAttribute("lspace", "-1width");
- node.setAttribute("width", "0px");
-
- return node;
-};
-
-groupTypes.rlap = function(group, options) {
- var node = new mathMLTree.MathNode(
- "mpadded", [buildGroup(group.value.body, options)]);
-
- node.setAttribute("width", "0px");
-
- return node;
-};
-
-groupTypes.phantom = function(group, options, prev) {
- var inner = buildExpression(group.value.value, options);
- return new mathMLTree.MathNode("mphantom", inner);
-};
-
-/**
- * Takes a list of nodes, builds them, and returns a list of the generated
- * MathML nodes. A little simpler than the HTML version because we don't do any
- * previous-node handling.
- */
-var buildExpression = function(expression, options) {
- var groups = [];
- for (var i = 0; i < expression.length; i++) {
- var group = expression[i];
- groups.push(buildGroup(group, options));
- }
- return groups;
-};
-
-/**
- * Takes a group from the parser and calls the appropriate groupTypes function
- * on it to produce a MathML node.
- */
-var buildGroup = function(group, options) {
- if (!group) {
- return new mathMLTree.MathNode("mrow");
- }
-
- if (groupTypes[group.type]) {
- // Call the groupTypes function
- return groupTypes[group.type](group, options);
- } else {
- throw new ParseError(
- "Got group of unknown type: '" + group.type + "'");
- }
-};
-
-/**
- * Takes a full parse tree and settings and builds a MathML representation of
- * it. In particular, we put the elements from building the parse tree into a
- * <semantics> tag so we can also include that TeX source as an annotation.
- *
- * Note that we actually return a domTree element with a `<math>` inside it so
- * we can do appropriate styling.
- */
-var buildMathML = function(tree, texExpression, options) {
- var expression = buildExpression(tree, options);
-
- // Wrap up the expression in an mrow so it is presented in the semantics
- // tag correctly.
- var wrapper = new mathMLTree.MathNode("mrow", expression);
-
- // Build a TeX annotation of the source
- var annotation = new mathMLTree.MathNode(
- "annotation", [new mathMLTree.TextNode(texExpression)]);
-
- annotation.setAttribute("encoding", "application/x-tex");
-
- var semantics = new mathMLTree.MathNode(
- "semantics", [wrapper, annotation]);
-
- var math = new mathMLTree.MathNode("math", [semantics]);
-
- // You can't style <math> nodes, so we wrap the node in a span.
- return makeSpan(["katex-mathml"], [math]);
-};
-
-module.exports = buildMathML;