commit 383ca01434a85d6bdf0ecbf6013fcc12e5a608f9
parent b101582aac464fc2e705ebe6ce4f6d894172e4e6
Author: Emily Eisenberg <emily@khanacademy.org>
Date: Wed, 17 Jul 2013 15:43:55 -0700
Sync with Khan-exercises
Summary:
Add some things in to make this more useful to khan-exercises.
Notably, make KaTeX.process create and clean up its own .katex node, and rename
.mathmathmath -> .katex.
Test Plan: Make test, make sure the main page still renders stuff
Reviewers: alpert
Reviewed By: alpert
Differential Revision: http://phabricator.khanacademy.org/D3061
Diffstat:
6 files changed, 104 insertions(+), 92 deletions(-)
diff --git a/Lexer.js b/Lexer.js
@@ -1,3 +1,5 @@
+var ParseError = require("./ParseError");
+
// The main lexer class
function Lexer(input) {
this._input = input;
@@ -62,7 +64,8 @@ Lexer.prototype.lex = function(pos) {
}
// We didn't match any of the tokens, so throw an error.
- throw "Unexpected character: '" + input[0] + "' at position " + pos;
+ throw new ParseError("Unexpected character: '" + input[0] +
+ "' at position " + pos);
};
module.exports = Lexer;
diff --git a/ParseError.js b/ParseError.js
@@ -0,0 +1,7 @@
+function ParseError(message) {
+ this.message = "TeX parse error: " + message;
+}
+
+ParseError.prototype = Error.prototype;
+
+module.exports = ParseError;
diff --git a/Parser.js b/Parser.js
@@ -1,6 +1,8 @@
var Lexer = require("./Lexer");
var utils = require("./utils");
+var ParseError = require("./ParseError");
+
// Main Parser class
function Parser() {
};
@@ -22,7 +24,8 @@ function ParseNode(type, value) {
// appropriate error otherwise.
var expect = function(result, type) {
if (result.type !== type) {
- throw "Failed parsing: Expected '" + type + "', got '" + result.type + "'";
+ throw new ParseError(
+ "Expected '" + type + "', got '" + result.type + "'");
}
};
@@ -76,7 +79,7 @@ Parser.prototype.parseSuperscript = function(pos) {
return group;
} else {
// Throw an error if we didn't find a group
- throw "Parse error: Couldn't find group after '^'";
+ throw new ParseError("Couldn't find group after '^'");
}
} else if (sup.type === "'") {
var pos = sup.position;
@@ -98,7 +101,7 @@ Parser.prototype.parseSubscript = function(pos) {
return group;
} else {
// Throw an error if we didn't find a group
- throw "Parse error: Couldn't find group after '_'";
+ throw new ParseError("Couldn't find group after '_'");
}
} else {
return null;
@@ -343,7 +346,8 @@ Parser.prototype.parseNucleus = function(pos) {
{color: nucleus.type.slice(1), value: atoms}),
group.position);
} else {
- throw "Parse error: Expected group after '" + nucleus.text + "'";
+ throw new ParseError(
+ "Expected group after '" + nucleus.text + "'");
}
} else if (nucleus.type === "\\llap" || nucleus.type === "\\rlap") {
// If this is an llap or rlap, parse its argument and return
@@ -353,7 +357,8 @@ Parser.prototype.parseNucleus = function(pos) {
new ParseNode(nucleus.type.slice(1), group.result),
group.position);
} else {
- throw "Parse error: Expected group after '" + nucleus.text + "'";
+ throw new ParseError(
+ "Expected group after '" + nucleus.text + "'");
}
} else if (nucleus.type === "\\dfrac" || nucleus.type === "\\frac" ||
nucleus.type === "\\tfrac") {
@@ -370,12 +375,12 @@ Parser.prototype.parseNucleus = function(pos) {
}),
denom.position);
} else {
- throw "Parse error: Expected denominator after '" +
- nucleus.type + "'";
+ throw new ParseError("Expected denominator after '" +
+ nucleus.type + "'");
}
} else {
- throw "Parse error: Expected numerator after '" + nucleus.type +
- "'";
+ throw new ParseError("Parse error: Expected numerator after '" +
+ nucleus.type + "'");
}
} else if (funcToType[nucleus.type]) {
// Otherwise if this is a no-argument function, find the type it
diff --git a/katex.js b/katex.js
@@ -1,4 +1,5 @@
var Style = require("./Style");
+var ParseError = require("./ParseError");
var parseTree = require("./parseTree");
var utils = require("./utils");
@@ -240,23 +241,19 @@ var clearNode = function(node) {
}
};
-var process = function(toParse, baseElem) {
- try {
- var tree = parseTree(toParse);
- } catch (e) {
- console.error(e);
- return false;
- }
+var process = function(toParse, baseNode) {
+ var tree = parseTree(toParse);
var style = Style.TEXT;
var expression = buildExpression(style, /* color: */ "", tree);
var span = makeSpan(style.cls(), expression);
+ var katexNode = makeSpan("katex", [span]);
- clearNode(baseElem);
- baseElem.appendChild(span);
- return true;
+ clearNode(baseNode);
+ baseNode.appendChild(katexNode);
};
module.exports = {
- process: process
+ process: process,
+ ParseError: ParseError
};
diff --git a/static/index.html b/static/index.html
@@ -9,6 +9,6 @@
</head>
<body>
<input type="text" value="\blue\dfrac{2(y-z)}{3} \div \orange{\arctan x^{4/3}}" id="input" />
- <div id="math" class="mathmathmath"></div>
+ <div id="math"></div>
</body>
</html>
diff --git a/static/katex.css b/static/katex.css
@@ -14,98 +14,98 @@ things to do:
big parens
*/
-.mathmathmath {
+.katex {
font: normal 1.21em katex_main;
line-height: 1.2;
}
-.mathit {
+.katex .mathit {
font-family: katex_math;
font-style: italic;
}
-.textstyle > .mbin + .minner { margin-left: 0.22222em; }
-.textstyle > .mbin + .mop { margin-left: 0.22222em; }
-.textstyle > .mbin + .mopen { margin-left: 0.22222em; }
-.textstyle > .mbin + .mord { margin-left: 0.22222em; }
-.textstyle > .mclose + .mbin { margin-left: 0.22222em; }
-.textstyle > .mclose + .minner { margin-left: 0.16667em; }
- .mclose + .mop { margin-left: 0.16667em; }
-.textstyle > .mclose + .mrel { margin-left: 0.27778em; }
-.textstyle > .minner + .mbin { margin-left: 0.22222em; }
-.textstyle > .minner + .minner { margin-left: 0.16667em; }
- .minner + .mop { margin-left: 0.16667em; }
-.textstyle > .minner + .mopen { margin-left: 0.16667em; }
-.textstyle > .minner + .mord { margin-left: 0.16667em; }
-.textstyle > .minner + .mpunct { margin-left: 0.16667em; }
-.textstyle > .minner + .mrel { margin-left: 0.27778em; }
-.textstyle > .mop + .minner { margin-left: 0.16667em; }
- .mop + .mop { margin-left: 0.16667em; }
- .mop + .mord { margin-left: 0.16667em; }
-.textstyle > .mop + .mrel { margin-left: 0.27778em; }
-.textstyle > .mord + .mbin { margin-left: 0.22222em; }
-.textstyle > .mord + .minner { margin-left: 0.16667em; }
- .mord + .mop { margin-left: 0.16667em; }
-.textstyle > .mord + .mrel { margin-left: 0.27778em; }
-.textstyle > .mpunct + .mbin { margin-left: 0.16667em; }
-.textstyle > .mpunct + .mclose { margin-left: 0.16667em; }
-.textstyle > .mpunct + .minner { margin-left: 0.16667em; }
-.textstyle > .mpunct + .mop { margin-left: 0.16667em; }
-.textstyle > .mpunct + .mopen { margin-left: 0.16667em; }
-.textstyle > .mpunct + .mord { margin-left: 0.16667em; }
-.textstyle > .mpunct + .mpunct { margin-left: 0.16667em; }
-.textstyle > .mpunct + .mrel { margin-left: 0.16667em; }
-.textstyle > .mrel + .minner { margin-left: 0.27778em; }
-.textstyle > .mrel + .mop { margin-left: 0.27778em; }
-.textstyle > .mrel + .mopen { margin-left: 0.27778em; }
-.textstyle > .mrel + .mord { margin-left: 0.27778em; }
-
-.textstyle > .scriptstyle { font-size: 0.66667em; }
-.scriptstyle > .scriptscriptstyle { font-size: 0.75em; }
-
-.msub {
+.katex .textstyle > .mbin + .minner { margin-left: 0.22222em; }
+.katex .textstyle > .mbin + .mop { margin-left: 0.22222em; }
+.katex .textstyle > .mbin + .mopen { margin-left: 0.22222em; }
+.katex .textstyle > .mbin + .mord { margin-left: 0.22222em; }
+.katex .textstyle > .mclose + .mbin { margin-left: 0.22222em; }
+.katex .textstyle > .mclose + .minner { margin-left: 0.16667em; }
+.katex .mclose + .mop { margin-left: 0.16667em; }
+.katex .textstyle > .mclose + .mrel { margin-left: 0.27778em; }
+.katex .textstyle > .minner + .mbin { margin-left: 0.22222em; }
+.katex .textstyle > .minner + .minner { margin-left: 0.16667em; }
+.katex .minner + .mop { margin-left: 0.16667em; }
+.katex .textstyle > .minner + .mopen { margin-left: 0.16667em; }
+.katex .textstyle > .minner + .mord { margin-left: 0.16667em; }
+.katex .textstyle > .minner + .mpunct { margin-left: 0.16667em; }
+.katex .textstyle > .minner + .mrel { margin-left: 0.27778em; }
+.katex .textstyle > .mop + .minner { margin-left: 0.16667em; }
+.katex .mop + .mop { margin-left: 0.16667em; }
+.katex .mop + .mord { margin-left: 0.16667em; }
+.katex .textstyle > .mop + .mrel { margin-left: 0.27778em; }
+.katex .textstyle > .mord + .mbin { margin-left: 0.22222em; }
+.katex .textstyle > .mord + .minner { margin-left: 0.16667em; }
+.katex .mord + .mop { margin-left: 0.16667em; }
+.katex .textstyle > .mord + .mrel { margin-left: 0.27778em; }
+.katex .textstyle > .mpunct + .mbin { margin-left: 0.16667em; }
+.katex .textstyle > .mpunct + .mclose { margin-left: 0.16667em; }
+.katex .textstyle > .mpunct + .minner { margin-left: 0.16667em; }
+.katex .textstyle > .mpunct + .mop { margin-left: 0.16667em; }
+.katex .textstyle > .mpunct + .mopen { margin-left: 0.16667em; }
+.katex .textstyle > .mpunct + .mord { margin-left: 0.16667em; }
+.katex .textstyle > .mpunct + .mpunct { margin-left: 0.16667em; }
+.katex .textstyle > .mpunct + .mrel { margin-left: 0.16667em; }
+.katex .textstyle > .mrel + .minner { margin-left: 0.27778em; }
+.katex .textstyle > .mrel + .mop { margin-left: 0.27778em; }
+.katex .textstyle > .mrel + .mopen { margin-left: 0.27778em; }
+.katex .textstyle > .mrel + .mord { margin-left: 0.27778em; }
+
+.katex .textstyle > .scriptstyle { font-size: 0.66667em; }
+.katex .scriptstyle > .scriptscriptstyle { font-size: 0.75em; }
+
+.katex .msub {
vertical-align: bottom;
position: relative;
top: 0.2em;
}
-.msup {
+.katex .msup {
position: relative;
top: -0.5em;
}
-.msupsub {
+.katex .msupsub {
display: inline-table;
table-layout: fixed;
vertical-align: middle;
}
-.msupsub > .msup, .msupsub > .msub {
+.katex .msupsub > .msup, .katex .msupsub > .msub {
display: table-row;
vertical-align: baseline;
}
-.mfrac { display: inline-table; }
+.katex .mfrac { display: inline-table; }
/* TODO(alpert): Where do these numbers come from? */
-.mfrac.textstyle.displaystyle { vertical-align: 0.58em; }
-.mfrac.textstyle { vertical-align: 0.50em; }
-.mfrac.scriptstyle { vertical-align: 0.50em; }
-.mfrac.scriptscriptstyle { vertical-align: 0.6em; }
+.katex .mfrac.textstyle.displaystyle { vertical-align: 0.58em; }
+.katex .mfrac.textstyle { vertical-align: 0.50em; }
+.katex .mfrac.scriptstyle { vertical-align: 0.50em; }
+.katex .mfrac.scriptscriptstyle { vertical-align: 0.6em; }
-.mfracnum, .mfracmid, .mfracden {
+.katex .mfracnum, .katex .mfracmid, .katex .mfracden {
display: table-row;
text-align: center;
}
-.mfracmid:before {
+.katex .mfracmid:before {
border-bottom-style: solid;
border-bottom-width: 1px;
content: "";
display: block;
}
-.mfracmid:after {
+.katex .mfracmid:after {
border-bottom-style: solid;
border-bottom-width: 0.05em;
content: "";
@@ -113,54 +113,54 @@ big parens
margin-top: -1px;
}
-.mfracnum > span {
+.katex .mfracnum > span {
display: inline-block;
vertical-align: bottom;
}
-.mspace {
+.katex .mspace {
display: inline-block;
}
-.mspace.thinspace {
+.katex .mspace.thinspace {
width: 0.16667em;
}
-.mspace.mediumspace {
+.katex .mspace.mediumspace {
width: 0.22222em;
}
-.mspace.thickspace {
+.katex .mspace.thickspace {
width: 0.27778em;
}
-.mspace.quad {
+.katex .mspace.quad {
width: 1em;
}
-.mspace.qquad {
+.katex .mspace.qquad {
width: 2em;
}
-.llap, .rlap {
+.katex .llap, .katex .rlap {
width: 0;
position: relative;
}
-.llap > span {
+.katex .llap > span {
position: absolute;
right: 0;
}
-.rlap > span {
+.katex .rlap > span {
position: absolute;
left: 0;
}
-.blue { color: #6495ed; }
-.orange { color: #ffa500; }
-.pink { color: #ff00af; }
-.red { color: #df0030; }
-.green { color: #28ae7b; }
-.gray { color: gray; }
-.purple { color: #9d38bd; }
+.katex .blue { color: #6495ed; }
+.katex .orange { color: #ffa500; }
+.katex .pink { color: #ff00af; }
+.katex .red { color: #df0030; }
+.katex .green { color: #28ae7b; }
+.katex .gray { color: gray; }
+.katex .purple { color: #9d38bd; }