diff --git a/src/delimiter.js b/src/delimiter.js index 3e46e9dd..7dcc0ade 100644 --- a/src/delimiter.js +++ b/src/delimiter.js @@ -431,9 +431,9 @@ const sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0]; */ const makeSizedDelim = function(delim, size, options, mode, classes) { // < and > turn into \langle and \rangle in delimiters - if (delim === "<" || delim === "\\lt") { + if (delim === "<" || delim === "\\lt" || delim === "\u27e8") { delim = "\\langle"; - } else if (delim === ">" || delim === "\\gt") { + } else if (delim === ">" || delim === "\\gt" || delim === "\u27e9") { delim = "\\rangle"; } @@ -549,9 +549,9 @@ const traverseSequence = function(delim, height, sequence, options) { */ const makeCustomSizedDelim = function(delim, height, center, options, mode, classes) { - if (delim === "<" || delim === "\\lt") { + if (delim === "<" || delim === "\\lt" || delim === "\u27e8") { delim = "\\langle"; - } else if (delim === ">" || delim === "\\gt") { + } else if (delim === ">" || delim === "\\gt" || delim === "\u27e9") { delim = "\\rangle"; } diff --git a/src/functions/delimsizing.js b/src/functions/delimsizing.js index dc24d67b..1d2ae561 100644 --- a/src/functions/delimsizing.js +++ b/src/functions/delimsizing.js @@ -38,7 +38,7 @@ const delimiters = [ "(", ")", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\\lceil", "\\rceil", - "<", ">", "\\langle", "\\rangle", "\\lt", "\\gt", + "<", ">", "\\langle", "\u27e8", "\\rangle", "\u27e9", "\\lt", "\\gt", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\\lmoustache", "\\rmoustache", "/", "\\backslash", diff --git a/src/symbols.js b/src/symbols.js index 3d82fe63..e001b867 100644 --- a/src/symbols.js +++ b/src/symbols.js @@ -513,14 +513,14 @@ defineSymbol(math, main, bin, "\u2228", "\\vee", true); defineSymbol(math, main, textord, "\u221a", "\\surd"); defineSymbol(math, main, open, "(", "("); defineSymbol(math, main, open, "[", "["); -defineSymbol(math, main, open, "\u27e8", "\\langle"); +defineSymbol(math, main, open, "\u27e8", "\\langle", true); defineSymbol(math, main, open, "\u2223", "\\lvert"); defineSymbol(math, main, open, "\u2225", "\\lVert"); defineSymbol(math, main, close, ")", ")"); defineSymbol(math, main, close, "]", "]"); defineSymbol(math, main, close, "?", "?"); defineSymbol(math, main, close, "!", "!"); -defineSymbol(math, main, close, "\u27e9", "\\rangle"); +defineSymbol(math, main, close, "\u27e9", "\\rangle", true); defineSymbol(math, main, close, "\u2223", "\\rvert"); defineSymbol(math, main, close, "\u2225", "\\rVert"); defineSymbol(math, main, rel, "=", "="); diff --git a/test/errors-spec.js b/test/errors-spec.js index 97e859ca..864b0d84 100644 --- a/test/errors-spec.js +++ b/test/errors-spec.js @@ -17,13 +17,13 @@ beforeEach(function() { parseTree(actual, defaultSettings); return { pass: false, - message: "'" + actual + "' parsed without error", + message: () => "'" + actual + "' parsed without error", }; } catch (e) { if (expected === undefined) { return { pass: true, - message: "'" + actual + "' parsed with error", + message: () => "'" + actual + "' parsed with error", }; } const msg = e.message; @@ -31,20 +31,20 @@ beforeEach(function() { if (msg === exp) { return { pass: true, - message: "'" + actual + "'" + + message: () => "'" + actual + "'" + " parsed with error '" + expected + "'", }; } else if (msg.slice(0, 19) === prefix) { return { pass: false, - message: "'" + actual + "'" + + message: () => "'" + actual + "'" + " parsed with error '" + msg.slice(19) + "' but expected '" + expected + "'", }; } else { return { pass: false, - message: "'" + actual + "'" + + message: () => "'" + actual + "'" + " caused error '" + msg + "' but expected '" + exp + "'", }; diff --git a/test/katex-spec.js b/test/katex-spec.js index f279bcda..b9a55dfa 100644 --- a/test/katex-spec.js +++ b/test/katex-spec.js @@ -107,6 +107,21 @@ const parseAndSetResult = function(expr, result, settings) { } }; +const buildAndSetResult = function(expr, result, settings) { + try { + return _getBuilt(expr, settings || defaultSettings); + } catch (e) { + result.pass = false; + if (e instanceof ParseError) { + result.message = "'" + expr + "' failed " + + "parsing with error: " + e.message; + } else { + result.message = "'" + expr + "' failed " + + "parsing with unknown error: " + e.message; + } + } +}; + beforeEach(function() { expect.extend({ toParse: function(actual, settings) { @@ -114,7 +129,7 @@ beforeEach(function() { const result = { pass: true, - message: "'" + actual + "' succeeded parsing", + message: () => "'" + actual + "' succeeded parsing", }; parseAndSetResult(actual, result, usedSettings); return result; @@ -125,7 +140,7 @@ beforeEach(function() { const result = { pass: false, - message: "Expected '" + actual + "' to fail " + + message: () => "Expected '" + actual + "' to fail " + "parsing, but it succeeded", }; @@ -150,7 +165,7 @@ beforeEach(function() { const result = { pass: true, - message: "'" + actual + "' succeeded in building", + message: () => "'" + actual + "' succeeded in building", }; expect(actual).toParse(usedSettings); @@ -176,7 +191,7 @@ beforeEach(function() { const result = { pass: true, - message: "Parse trees of '" + actual + + message: () => "Parse trees of '" + actual + "' and '" + expected + "' are equivalent", }; @@ -196,7 +211,38 @@ beforeEach(function() { if (JSON.stringify(actualTree) !== JSON.stringify(expectedTree)) { result.pass = false; - result.message = "Parse trees of '" + actual + + result.message = () => "Parse trees of '" + actual + + "' and '" + expected + "' are not equivalent"; + } + return result; + }, + + toBuildLike: function(actual, expected, settings) { + const usedSettings = settings ? settings : defaultSettings; + + const result = { + pass: true, + message: () => "Build trees of '" + actual + + "' and '" + expected + "' are equivalent", + }; + + const actualTree = buildAndSetResult(actual, result, + usedSettings); + if (!actualTree) { + return result; + } + const expectedTree = buildAndSetResult(expected, result, + usedSettings); + if (!expectedTree) { + return result; + } + + stripPositions(actualTree); + stripPositions(expectedTree); + + if (JSON.stringify(actualTree) !== JSON.stringify(expectedTree)) { + result.pass = false; + result.message = () => "Parse trees of '" + actual + "' and '" + expected + "' are not equivalent"; } return result; @@ -1212,6 +1258,19 @@ describe("A left/right parser", function() { }); }); +describe("left/right builder", () => { + const cases = [ + ['\\left\\langle \\right\\rangle', '\\left< \\right>'], + ['\\left\\langle \\right\\rangle', '\\left\u27e8 \\right\u27e9'], + ]; + + for (const [actual, expected] of cases) { + it(`should build "${actual}" like "${expected}"`, () => { + expect(actual).toBuildLike(expected); + }); + } +}); + describe("A begin/end parser", function() { it("should parse a simple environment", function() { diff --git a/test/unicode-spec.js b/test/unicode-spec.js index d1a9ba32..ec048c6a 100644 --- a/test/unicode-spec.js +++ b/test/unicode-spec.js @@ -16,10 +16,10 @@ const parseAndSetResult = function(expr, result, settings) { } catch (e) { result.pass = false; if (e instanceof ParseError) { - result.message = "'" + expr + "' failed " + + result.message = () => "'" + expr + "' failed " + "parsing with error: " + e.message; } else { - result.message = "'" + expr + "' failed " + + result.message = () => "'" + expr + "' failed " + "parsing with unknown error: " + e.message; } } @@ -34,7 +34,7 @@ describe("unicode", function() { const result = { pass: true, - message: "'" + actual + "' succeeded parsing", + message: () => "'" + actual + "' succeeded parsing", }; parseAndSetResult(actual, result, usedSettings); return result; @@ -45,7 +45,7 @@ describe("unicode", function() { const result = { pass: false, - message: "Expected '" + actual + "' to fail " + + message: () => "Expected '" + actual + "' to fail " + "parsing, but it succeeded", }; @@ -54,10 +54,10 @@ describe("unicode", function() { } catch (e) { if (e instanceof ParseError) { result.pass = true; - result.message = "'" + actual + "' correctly " + + result.message = () => "'" + actual + "' correctly " + "didn't parse with error: " + e.message; } else { - result.message = "'" + actual + "' failed " + + result.message = () => "'" + actual + "' failed " + "parsing with unknown error: " + e.message; } }