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
This commit is contained in:
parent
b101582aac
commit
383ca01434
5
Lexer.js
5
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;
|
||||
|
|
7
ParseError.js
Normal file
7
ParseError.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
function ParseError(message) {
|
||||
this.message = "TeX parse error: " + message;
|
||||
}
|
||||
|
||||
ParseError.prototype = Error.prototype;
|
||||
|
||||
module.exports = ParseError;
|
23
Parser.js
23
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
|
||||
|
|
19
katex.js
19
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
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
136
static/katex.css
136
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; }
|
||||
.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; }
|
||||
|
||||
.textstyle > .scriptstyle { font-size: 0.66667em; }
|
||||
.scriptstyle > .scriptscriptstyle { font-size: 0.75em; }
|
||||
.katex .textstyle > .scriptstyle { font-size: 0.66667em; }
|
||||
.katex .scriptstyle > .scriptscriptstyle { font-size: 0.75em; }
|
||||
|
||||
.msub {
|
||||
.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; }
|
||||
|
|
Loading…
Reference in New Issue
Block a user