Files
KaTeX/katex.js
Ben Alpert 09311de814 Add Greek letters
Summary: Fixes T1190.

Test Plan: `\alpha \beta \gamma \delta \epsilon \varepsilon \zeta \eta \theta \vartheta \iota \kappa \lambda \mu \nu \xi \omicron \pi \varpi \rho \varrho \sigma \varsigma \tau \upsilon \phi \varphi \chi \psi \omega \Gamma \Delta \Theta \Lambda \Xi \Pi \Sigma \Upsilon \Phi \Psi \Omega`

Reviewers: emily

Reviewed By: emily

Maniphest Tasks: T1190

Differential Revision: http://phabricator.khanacademy.org/D3054
2013-07-14 22:54:01 -07:00

259 lines
7.6 KiB
JavaScript

var Style = require("./Style");
var parseTree = require("./parseTree");
var utils = require("./utils");
var buildExpression = function(style, color, expression, prev) {
var groups = [];
for (var i = 0; i < expression.length; i++) {
var group = expression[i];
groups.push(buildGroup(style, color, group, prev));
prev = group;
};
return groups;
};
var makeSpan = function(className, children) {
var span = document.createElement("span");
span.className = className || "";
if (children) {
for (var i = 0; i < children.length; i++) {
span.appendChild(children[i]);
}
}
return span;
};
var buildGroup = function(style, color, group, prev) {
if (group.type === "mathord") {
return makeSpan("mord" + color, [mathit(group.value)]);
} else if (group.type === "textord") {
return makeSpan("mord" + color, [textit(group.value)]);
} else if (group.type === "bin") {
var className = "mbin";
var prevAtom = prev;
while (prevAtom && prevAtom.type == "color") {
var atoms = prevAtom.value.value;
prevAtom = atoms[atoms.length - 1];
}
if (!prev || utils.contains(["bin", "open", "rel"], prevAtom.type)) {
group.type = "ord";
className = "mord";
}
return makeSpan(className + color, [textit(group.value)]);
} else if (group.type === "rel") {
return makeSpan("mrel" + color, [textit(group.value)]);
} else if (group.type === "sup") {
var sup = makeSpan("msup " + style.cls(), [
makeSpan(style.sup().cls(), [
buildGroup(style.sup(), color, group.value.sup)
])
]);
return makeSpan("mord", [
buildGroup(style, color, group.value.base), sup
]);
} else if (group.type === "sub") {
var sub = makeSpan("msub " + style.cls(), [
makeSpan(style.sub().cls(), [
buildGroup(style.sub(), color, group.value.sub)
])
]);
return makeSpan("mord", [
buildGroup(style, color, group.value.base), sub
]);
} else if (group.type === "supsub") {
var sup = makeSpan("msup " + style.sup().cls(), [
buildGroup(style.sup(), color, group.value.sup)
]);
var sub = makeSpan("msub " + style.sub().cls(), [
buildGroup(style.sub(), color, group.value.sub)
]);
var supsub = makeSpan("msupsub " + style.cls(), [sup, sub]);
return makeSpan("mord", [
buildGroup(style, color, group.value.base), supsub
]);
} else if (group.type === "open") {
return makeSpan("mopen" + color, [textit(group.value)]);
} else if (group.type === "close") {
return makeSpan("mclose" + color, [textit(group.value)]);
} else if (group.type === "frac") {
var fstyle = style;
if (group.value.size === "dfrac") {
fstyle = Style.DISPLAY;
} else if (group.value.size === "tfrac") {
fstyle = Style.TEXT;
}
var nstyle = fstyle.fracNum();
var dstyle = fstyle.fracDen();
var numer = makeSpan("mfracnum " + nstyle.cls(), [
makeSpan("", [buildGroup(nstyle, color, group.value.numer)])
]);
var mid = makeSpan("mfracmid");
var denom = makeSpan("mfracden " + dstyle.cls(), [
makeSpan("", [buildGroup(dstyle, color, group.value.denom)])
]);
return makeSpan("minner mfrac " + fstyle.cls() + color, [
numer, mid, denom
]);
} else if (group.type === "color") {
var frag = document.createDocumentFragment();
var els = buildExpression(
style,
" " + group.value.color,
group.value.value,
prev
);
for (var i = 0; i < els.length; i++) {
frag.appendChild(els[i]);
}
return frag;
} else if (group.type === "spacing") {
if (group.value === "\\ " || group.value === "\\space") {
return makeSpan("mord mspace", [textit(group.value)]);
} else {
var spacingClassMap = {
"\\qquad": "qquad",
"\\quad": "quad",
"\\;": "thickspace",
"\\:": "mediumspace",
"\\,": "thinspace"
};
return makeSpan("mord mspace " + spacingClassMap[group.value]);
}
} else if (group.type === "llap") {
var inner = makeSpan("", buildExpression(style, color, group.value));
return makeSpan("llap " + style.cls(), [inner]);
} else if (group.type === "rlap") {
var inner = makeSpan("", buildExpression(style, color, group.value));
return makeSpan("rlap " + style.cls(), [inner]);
} else if (group.type === "punct") {
return makeSpan("mpunct" + color, [textit(group.value)]);
} else if (group.type === "ordgroup") {
return makeSpan("mord " + style.cls(),
buildExpression(style, color, group.value)
);
} else if (group.type === "namedfn") {
return makeSpan("mop" + color, [textit(group.value.slice(1))]);
} else {
throw "Lex error: Got group of unknown type: '" + group.type + "'";
}
};
var charLookup = {
"*": "\u2217",
"-": "\u2212",
"`": "\u2018",
"\\ ": "\u00a0",
"\\angle": "\u2220",
"\\cdot": "\u22c5",
"\\circ": "\u2218",
"\\colon": ":",
"\\div": "\u00f7",
"\\geq": "\u2265",
"\\gets": "\u2190",
"\\infty": "\u221e",
"\\leftarrow": "\u2190",
"\\leq": "\u2264",
"\\lvert": "|",
"\\neq": "\u2260",
"\\ngeq": "\u2271",
"\\nleq": "\u2270",
"\\pm": "\u00b1",
"\\prime": "\u2032",
"\\rightarrow": "\u2192",
"\\rvert": "|",
"\\space": "\u00a0",
"\\times": "\u00d7",
"\\to": "\u2192",
"\\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",
"\\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",
"\\Gamma": "\u0393",
"\\Delta": "\u0394",
"\\Theta": "\u0398",
"\\Lambda": "\u039b",
"\\Xi": "\u039e",
"\\Pi": "\u03a0",
"\\Sigma": "\u03a3",
"\\Upsilon": "\u03a5",
"\\Phi": "\u03a6",
"\\Psi": "\u03a8",
"\\Omega": "\u03a9"
};
var textit = function(value) {
if (value in charLookup) {
value = charLookup[value];
}
return document.createTextNode(value);
};
var mathit = function(value) {
return makeSpan("mathit", [textit(value)]);
};
var clearNode = function(node) {
if ("textContent" in node) {
node.textContent = "";
} else {
node.innerText = "";
}
};
var process = function(toParse, baseElem) {
try {
var tree = parseTree(toParse);
} catch (e) {
console.error(e);
return false;
}
var style = Style.TEXT;
var expression = buildExpression(style, /* color: */ "", tree);
var span = makeSpan(style.cls(), expression);
clearNode(baseElem);
baseElem.appendChild(span);
return true;
};
module.exports = {
process: process
};