Add style changing functions
Summary: Add \displaystyle, \textstyle, \scriptstyle, and \scriptscriptstyle commands. Added tests and huxley screenshots for everything that looks different in displaystyle vs normal style. Fixes #24. Test Plan: - See new tests work, and old tests still work - See no huxley screenshots changed, and new screenshot looks good Reviewers: alpert Reviewed By: alpert Differential Revision: http://phabricator.khanacademy.org/D13079
This commit is contained in:
parent
a76f6eb985
commit
0be77d4e6f
26
Parser.js
26
Parser.js
|
@ -242,6 +242,11 @@ var sizeFuncs = [
|
|||
"\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge"
|
||||
];
|
||||
|
||||
// A list of the style-changing functions, for use in parseImplicitGroup
|
||||
var styleFuncs = [
|
||||
"\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle"
|
||||
];
|
||||
|
||||
// Parses an implicit group, which is a group that starts at the end of a
|
||||
// specified, and ends right before a higher explicit group ends, or at EOL. It
|
||||
// is used for functions that appear to affect the current style, like \Large or
|
||||
|
@ -259,7 +264,9 @@ Parser.prototype.parseImplicitGroup = function(pos, mode) {
|
|||
return this.parseFunction(pos, mode);
|
||||
}
|
||||
|
||||
if (start.result.result === "\\left") {
|
||||
var func = start.result.result;
|
||||
|
||||
if (func === "\\left") {
|
||||
// If we see a left:
|
||||
// Parse the entire left function (including the delimiter)
|
||||
var left = this.parseFunction(pos, mode);
|
||||
|
@ -282,17 +289,28 @@ Parser.prototype.parseImplicitGroup = function(pos, mode) {
|
|||
} else {
|
||||
throw new ParseError("Missing \\right", this.lexer, body.position);
|
||||
}
|
||||
} else if (start.result.result === "\\right") {
|
||||
} else if (func === "\\right") {
|
||||
// If we see a right, explicitly fail the parsing here so the \left
|
||||
// handling ends the group
|
||||
return null;
|
||||
} else if (utils.contains(sizeFuncs, start.result.result)) {
|
||||
} else if (utils.contains(sizeFuncs, func)) {
|
||||
// If we see a sizing function, parse out the implict body
|
||||
var body = this.handleExpressionBody(start.result.position, mode);
|
||||
return new ParseResult(
|
||||
new ParseNode("sizing", {
|
||||
// Figure out what size to use based on the list of functions above
|
||||
size: "size" + (utils.indexOf(sizeFuncs, start.result.result) + 1),
|
||||
size: "size" + (utils.indexOf(sizeFuncs, func) + 1),
|
||||
value: body.body
|
||||
}, mode),
|
||||
body.position);
|
||||
} else if (utils.contains(styleFuncs, func)) {
|
||||
// If we see a styling function, parse out the implict body
|
||||
var body = this.handleExpressionBody(start.result.position, mode);
|
||||
return new ParseResult(
|
||||
new ParseNode("styling", {
|
||||
// Figure out what style to use by pulling out the style from
|
||||
// the function name
|
||||
style: func.slice(1, func.length - 5),
|
||||
value: body.body
|
||||
}, mode),
|
||||
body.position);
|
||||
|
|
18
buildTree.js
18
buildTree.js
|
@ -54,6 +54,8 @@ var getTypeOfGroup = function(group) {
|
|||
return getTypeOfGroup(group.value.value);
|
||||
} else if (group.type === "sizing") {
|
||||
return getTypeOfGroup(group.value.value);
|
||||
} else if (group.type === "styling") {
|
||||
return getTypeOfGroup(group.value.value);
|
||||
} else if (group.type === "delimsizing") {
|
||||
return groupToType[group.value.delimType];
|
||||
} else {
|
||||
|
@ -547,6 +549,22 @@ var groupTypes = {
|
|||
return span;
|
||||
},
|
||||
|
||||
styling: function(group, options, prev) {
|
||||
var style = {
|
||||
"display": Style.DISPLAY,
|
||||
"text": Style.TEXT,
|
||||
"script": Style.SCRIPT,
|
||||
"scriptscript": Style.SCRIPTSCRIPT
|
||||
};
|
||||
|
||||
var newStyle = style[group.value.style];
|
||||
|
||||
var inner = buildExpression(
|
||||
group.value.value, options.withStyle(newStyle), prev);
|
||||
|
||||
return makeSpan([options.style.reset(), newStyle.cls()], inner);
|
||||
},
|
||||
|
||||
delimsizing: function(group, options, prev) {
|
||||
var delim = group.value.value;
|
||||
|
||||
|
|
14
functions.js
14
functions.js
|
@ -310,7 +310,7 @@ var duplicatedFunctions = [
|
|||
}
|
||||
},
|
||||
|
||||
// Sizing functions
|
||||
// Sizing functions (handled in Parser.js explicitly, hence no handler)
|
||||
{
|
||||
funcs: [
|
||||
"\\tiny", "\\scriptsize", "\\footnotesize", "\\small",
|
||||
|
@ -319,6 +319,18 @@ var duplicatedFunctions = [
|
|||
data: {
|
||||
numArgs: 0
|
||||
}
|
||||
},
|
||||
|
||||
// Style changing functions (handled in Parser.js explicitly, hence no
|
||||
// handler)
|
||||
{
|
||||
funcs: [
|
||||
"\\displaystyle", "\\textstyle", "\\scriptstyle",
|
||||
"\\scriptscriptstyle"
|
||||
],
|
||||
data: {
|
||||
numArgs: 0
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
|
BIN
test/huxley/DisplayStyle.hux/firefox-1.png
Normal file
BIN
test/huxley/DisplayStyle.hux/firefox-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
5
test/huxley/DisplayStyle.hux/record.json
Normal file
5
test/huxley/DisplayStyle.hux/record.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
{
|
||||
"action": "screenshot"
|
||||
}
|
||||
]
|
|
@ -159,5 +159,11 @@
|
|||
"name": "Sqrt",
|
||||
"screenSize": [1024, 768],
|
||||
"url": "http://localhost:7936/test/huxley/test.html?m=\\sqrt{\\sqrt{\\sqrt{x}}}_{\\sqrt{\\sqrt{x}}}^{\\sqrt{\\sqrt{\\sqrt{x}}}^{\\sqrt{\\sqrt{\\sqrt{x}}}}}"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "DisplayStyle",
|
||||
"screenSize": [1024, 768],
|
||||
"url": "http://localhost:7936/test/huxley/test.html?m={\\displaystyle\\sqrt{x}}{\\sqrt{x}}{\\displaystyle \\frac12}{\\frac12}{\\displaystyle x^1_2}{x^1_2}"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -916,3 +916,36 @@ describe("A TeX-compliant parser", function() {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("A style change parser", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\displaystyle x").toParse();
|
||||
expect("\\textstyle x").toParse();
|
||||
expect("\\scriptstyle x").toParse();
|
||||
expect("\\scriptscriptstyle x").toParse();
|
||||
});
|
||||
|
||||
it("should produce the correct style", function() {
|
||||
var displayParse = parseTree("\\displaystyle x")[0];
|
||||
expect(displayParse.value.style).toMatch("display");
|
||||
|
||||
var scriptscriptParse = parseTree("\\scriptscriptstyle x")[0];
|
||||
expect(scriptscriptParse.value.style).toMatch("scriptscript");
|
||||
});
|
||||
|
||||
it("should only change the style within its group", function() {
|
||||
var text = "a b { c d \\displaystyle e f } g h";
|
||||
expect(text).toParse();
|
||||
|
||||
var parse = parseTree(text);
|
||||
|
||||
var displayNode = parse[2].value[2];
|
||||
|
||||
expect(displayNode.type).toMatch("styling");
|
||||
|
||||
var displayBody = displayNode.value.value;
|
||||
|
||||
expect(displayBody.length).toEqual(2);
|
||||
expect(displayBody[0].value).toMatch("e");
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user