Strict setting controls \newline display-mode behavior; fix MacroExpander space handling (#1314)

* Strict setting controls \newline display-mode behavior

* Bug-fix space handling in macros

Whitespace after a \controlWord is now handled within the lexer, not by the
MacroExpander.  This way, \\ expanding to \newline doesn't accidentally
cause spaces to get consumed.

* Rename nonstrict -> reportNonstrict; strictBehavior -> useStrictBehavior

* Second category of errorCodes
This commit is contained in:
Erik Demaine
2018-05-16 09:37:41 -04:00
committed by GitHub
parent 7ab4f76e16
commit 1ed99d9ff3
14 changed files with 155 additions and 55 deletions

View File

@@ -60,12 +60,12 @@ describe("Parser:", function() {
it("rejects repeated infix operators", function() {
expect("1\\over 2\\over 3").toFailWithParseError(
"only one infix operator per group at position 9: " +
"1\\over 2\\̲o̲v̲e̲r̲ 3");
"1\\over 2\\̲o̲v̲e̲r̲ ̲3");
});
it("rejects conflicting infix operators", function() {
expect("1\\over 2\\choose 3").toFailWithParseError(
"only one infix operator per group at position 9: " +
"1\\over 2\\̲c̲h̲o̲o̲s̲e̲ 3");
"1\\over 2\\̲c̲h̲o̲o̲s̲e̲ ̲3");
});
});

View File

@@ -181,7 +181,7 @@ beforeEach(function() {
expect(actual).toParse(usedSettings);
try {
_getBuilt(actual, settings);
_getBuilt(actual, usedSettings);
} catch (e) {
result.pass = false;
if (e instanceof ParseError) {
@@ -196,6 +196,31 @@ beforeEach(function() {
return result;
},
toNotBuild: function(actual, settings) {
const usedSettings = settings ? settings : defaultSettings;
const result = {
pass: false,
message: () => "Expected '" + actual + "' to fail " +
"building, but it succeeded",
};
try {
_getBuilt(actual, usedSettings);
} catch (e) {
if (e instanceof ParseError) {
result.pass = true;
result.message = () => "'" + actual + "' correctly " +
"didn't build with error: " + e.message;
} else {
result.message = () => "'" + actual + "' failed " +
"building with unknown error: " + e.message;
}
}
return result;
},
toParseLike: function(actual, expected, settings) {
const usedSettings = settings ? settings : defaultSettings;
@@ -2719,6 +2744,10 @@ describe("A macro expander", function() {
compareParseTree("\\text{\\foo }", "\\text{}", {"\\foo": "\\relax"});
});
it("should not consume spaces after control-word expansion", function() {
compareParseTree("\\text{\\\\ }", "\\text{ }", {"\\\\": "\\relax"});
});
it("should consume spaces after \\relax", function() {
compareParseTree("\\text{\\relax }", "\\text{}");
});
@@ -3133,7 +3162,7 @@ describe("Newlines via \\\\ and \\newline", function() {
});
it("should not allow \\cr at top level", () => {
expect("hello \\cr world").toNotParse();
expect("hello \\cr world").toNotBuild();
});
});
@@ -3186,6 +3215,11 @@ describe("strict setting", function() {
expect("\\text{é試}").toParse(new Settings({strict: true}));
expect("\\text{é試}").toParse();
});
it("should warn about top-level \\newline in display mode", () => {
expect("x\\\\y").toWarn(new Settings({displayMode: true}));
expect("x\\\\y").toParse(new Settings({displayMode: false}));
});
});
describe("Internal __* interface", function() {