Parse single superscripts and subscripts
Summary: Add the ability to parse lone `^x` and `_y`, etc. This basically just involves more checking of cases in the increasingly ugly `parseAtom` function. Also, now we manually check for the cases of double superscripts and subscripts. Test Plan: Make sure the tests pass. Make sure things like `^x` and `_y` parse. Reviewers: emily Reviewed By: emily Differential Revision: http://phabricator.khanacademy.org/D3095
This commit is contained in:
parent
bcd6e8687f
commit
c08fadfaa9
77
Parser.js
77
Parser.js
|
@ -110,42 +110,55 @@ Parser.prototype.parseSubscript = function(pos) {
|
|||
Parser.prototype.parseAtom = function(pos) {
|
||||
// Parse the nucleus
|
||||
var nucleus = this.parseGroup(pos);
|
||||
var nextPos = pos;
|
||||
var nucleusNode;
|
||||
|
||||
if (nucleus) {
|
||||
// Now, we try to parse a subscript or a superscript. If one of those
|
||||
// succeeds, we then try to parse the opposite one, and depending on
|
||||
// whether that succeeds, we return the correct type.
|
||||
var sup, sub;
|
||||
if (sup = this.parseSuperscript(nucleus.position)) {
|
||||
if (sub = this.parseSubscript(sup.position)) {
|
||||
return new ParseResult(
|
||||
new ParseNode("supsub",
|
||||
{base: nucleus.result, sup: sup.result,
|
||||
sub: sub.result}),
|
||||
sub.position);
|
||||
} else {
|
||||
return new ParseResult(
|
||||
new ParseNode("sup",
|
||||
{base: nucleus.result, sup: sup.result}),
|
||||
sup.position);
|
||||
nextPos = nucleus.position;
|
||||
nucleusNode = nucleus.result;
|
||||
}
|
||||
|
||||
var sup;
|
||||
var sub;
|
||||
|
||||
// Now, we try to parse a subscript or a superscript (or both!), and
|
||||
// depending on whether those succeed, we return the correct type.
|
||||
while (true) {
|
||||
var node;
|
||||
if ((node = this.parseSuperscript(nextPos))) {
|
||||
if (sup) {
|
||||
throw "Parse error: Double superscript";
|
||||
}
|
||||
} else if (sub = this.parseSubscript(nucleus.position)) {
|
||||
if (sup = this.parseSuperscript(sub.position)) {
|
||||
return new ParseResult(
|
||||
new ParseNode("supsub",
|
||||
{base: nucleus.result, sup: sup.result,
|
||||
sub: sub.result}),
|
||||
sup.position);
|
||||
} else {
|
||||
return new ParseResult(
|
||||
new ParseNode("sub",
|
||||
{base: nucleus.result, sub: sub.result}),
|
||||
sub.position);
|
||||
}
|
||||
} else {
|
||||
return nucleus;
|
||||
nextPos = node.position;
|
||||
sup = node.result;
|
||||
continue;
|
||||
}
|
||||
if ((node = this.parseSubscript(nextPos))) {
|
||||
if (sub) {
|
||||
throw "Parse error: Double subscript";
|
||||
}
|
||||
nextPos = node.position;
|
||||
sub = node.result;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (sup && sub) {
|
||||
return new ParseResult(
|
||||
new ParseNode("supsub", {base: nucleusNode, sup: sup,
|
||||
sub: sub}),
|
||||
nextPos);
|
||||
} else if (sup) {
|
||||
return new ParseResult(
|
||||
new ParseNode("sup", {base: nucleusNode, sup: sup}),
|
||||
nextPos);
|
||||
} else if (sub) {
|
||||
return new ParseResult(
|
||||
new ParseNode("sub", {base: nucleusNode, sub: sub}),
|
||||
nextPos);
|
||||
} else {
|
||||
return null;
|
||||
return nucleus;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
4
katex.js
4
katex.js
|
@ -27,6 +27,10 @@ var makeSpan = function(className, children) {
|
|||
};
|
||||
|
||||
var buildGroup = function(style, color, group, prev) {
|
||||
if (!group) {
|
||||
return makeSpan();
|
||||
}
|
||||
|
||||
if (group.type === "mathord") {
|
||||
return makeSpan("mord" + color, [mathit(group.value)]);
|
||||
} else if (group.type === "textord") {
|
||||
|
|
|
@ -164,6 +164,24 @@ describe("A subscript and superscript parser", function() {
|
|||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it("should not fail when there is no nucleus", function() {
|
||||
expect(function() {
|
||||
parseTree("^3");
|
||||
}).not.toThrow();
|
||||
|
||||
expect(function() {
|
||||
parseTree("_2");
|
||||
}).not.toThrow();
|
||||
|
||||
expect(function() {
|
||||
parseTree("^3_2");
|
||||
}).not.toThrow();
|
||||
|
||||
expect(function() {
|
||||
parseTree("_2^3");
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it("should produce sups for superscript", function() {
|
||||
var parse = parseTree("x^2")[0];
|
||||
|
||||
|
@ -207,16 +225,30 @@ describe("A subscript and superscript parser", function() {
|
|||
expect(parseA).toEqual(parseB);
|
||||
});
|
||||
|
||||
it("should not parse x^x^x", function() {
|
||||
it("should not parse double subscripts or superscripts", function() {
|
||||
expect(function() {
|
||||
parseTree("x^x^x");
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("should not parse x_x_x", function() {
|
||||
expect(function() {
|
||||
parseTree("x_x_x");
|
||||
}).toThrow();
|
||||
|
||||
expect(function() {
|
||||
parseTree("x_x^x_x");
|
||||
}).toThrow();
|
||||
|
||||
expect(function() {
|
||||
parseTree("x_x^x^x");
|
||||
}).toThrow();
|
||||
|
||||
expect(function() {
|
||||
parseTree("x^x_x_x");
|
||||
}).toThrow();
|
||||
|
||||
expect(function() {
|
||||
parseTree("x^x_x^x");
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("should work correctly with {}s", function() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user