[auto-render] Don't stop parsing when one expression fails

Summary: Fixes #223.

Test Plan: Opened http://127.0.0.1:7936/contrib/auto-render/, saw `$\unsupported$` in page and error in console, but other expressions rendered. Made test.

Reviewers: emily

Reviewed By: emily

Differential Revision: https://phabricator.khanacademy.org/D17543
This commit is contained in:
Ben Alpert 2015-04-26 17:04:11 -07:00
parent af8c1307f7
commit b29b8c40ea
4 changed files with 55 additions and 23 deletions

View File

@ -91,7 +91,8 @@ describe("A delimiter splitter", function() {
"(", ")", "(", ")",
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world ", display: false}, {type: "math", data: " world ",
rawData: "( world )", display: false},
{type: "text", data: " boo"} {type: "text", data: " boo"}
]); ]);
}); });
@ -101,7 +102,8 @@ describe("A delimiter splitter", function() {
"[[", "]]", "[[", "]]",
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world ", display: false}, {type: "math", data: " world ",
rawData: "[[ world ]]", display: false},
{type: "text", data: " boo"} {type: "text", data: " boo"}
]); ]);
}); });
@ -111,9 +113,11 @@ describe("A delimiter splitter", function() {
"(", ")", "(", ")",
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world ", display: false}, {type: "math", data: " world ",
rawData: "( world )", display: false},
{type: "text", data: " boo "}, {type: "text", data: " boo "},
{type: "math", data: " more ", display: false}, {type: "math", data: " more ",
rawData: "( more )", display: false},
{type: "text", data: " stuff"} {type: "text", data: " stuff"}
]); ]);
}); });
@ -123,7 +127,8 @@ describe("A delimiter splitter", function() {
"(", ")", "(", ")",
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world ", display: false}, {type: "math", data: " world ",
rawData: "( world )", display: false},
{type: "text", data: " boo "}, {type: "text", data: " boo "},
{type: "text", data: "( left"} {type: "text", data: "( left"}
]); ]);
@ -134,7 +139,8 @@ describe("A delimiter splitter", function() {
"(", ")", "(", ")",
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world { ) } ", display: false}, {type: "math", data: " world { ) } ",
rawData: "( world { ) } )", display: false},
{type: "text", data: " boo"} {type: "text", data: " boo"}
]); ]);
@ -142,7 +148,8 @@ describe("A delimiter splitter", function() {
"(", ")", "(", ")",
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world { { } ) } ", display: false}, {type: "math", data: " world { { } ) } ",
rawData: "( world { { } ) } )", display: false},
{type: "text", data: " boo"} {type: "text", data: " boo"}
]); ]);
}); });
@ -152,7 +159,8 @@ describe("A delimiter splitter", function() {
"(", ")", "(", ")",
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world \\) ", display: false}, {type: "math", data: " world \\) ",
rawData: "( world \\) )", display: false},
{type: "text", data: " boo"} {type: "text", data: " boo"}
]); ]);
@ -161,7 +169,8 @@ describe("A delimiter splitter", function() {
"(", ")", "(", ")",
[ [
{type: "text", data: "hello \\( "}, {type: "text", data: "hello \\( "},
{type: "math", data: " world ", display: false}, {type: "math", data: " world ",
rawData: "( world )", display: false},
{type: "text", data: " boo"} {type: "text", data: " boo"}
]); ]);
*/ */
@ -172,7 +181,8 @@ describe("A delimiter splitter", function() {
"$", "$", "$", "$",
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world ", display: false}, {type: "math", data: " world ",
rawData: "$ world $", display: false},
{type: "text", data: " boo"} {type: "text", data: " boo"}
]); ]);
}); });
@ -183,7 +193,8 @@ describe("A delimiter splitter", function() {
expect(splitAtDelimiters(startData, "(", ")", true)).toEqual( expect(splitAtDelimiters(startData, "(", ")", true)).toEqual(
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world ", display: true}, {type: "math", data: " world ",
rawData: "( world )", display: true},
{type: "text", data: " boo"} {type: "text", data: " boo"}
]); ]);
}); });
@ -191,18 +202,20 @@ describe("A delimiter splitter", function() {
it("works with more than one start datum", function() { it("works with more than one start datum", function() {
var startData = [ var startData = [
{type: "text", data: "hello ( world ) boo"}, {type: "text", data: "hello ( world ) boo"},
{type: "math", data: "math", display: true}, {type: "math", data: "math", rawData: "(math)", display: true},
{type: "text", data: "hello ( world ) boo"} {type: "text", data: "hello ( world ) boo"}
]; ];
expect(splitAtDelimiters(startData, "(", ")", false)).toEqual( expect(splitAtDelimiters(startData, "(", ")", false)).toEqual(
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world ", display: false}, {type: "math", data: " world ",
rawData: "( world )", display: false},
{type: "text", data: " boo"}, {type: "text", data: " boo"},
{type: "math", data: "math", display: true}, {type: "math", data: "math", rawData: "(math)", display: true},
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world ", display: false}, {type: "math", data: " world ",
rawData: "( world )", display: false},
{type: "text", data: " boo"} {type: "text", data: " boo"}
]); ]);
}); });
@ -210,15 +223,18 @@ describe("A delimiter splitter", function() {
it("doesn't do splitting inside of math nodes", function() { it("doesn't do splitting inside of math nodes", function() {
var startData = [ var startData = [
{type: "text", data: "hello ( world ) boo"}, {type: "text", data: "hello ( world ) boo"},
{type: "math", data: "hello ( world ) boo", display: true} {type: "math", data: "hello ( world ) boo",
rawData: "(hello ( world ) boo)", display: true}
]; ];
expect(splitAtDelimiters(startData, "(", ")", false)).toEqual( expect(splitAtDelimiters(startData, "(", ")", false)).toEqual(
[ [
{type: "text", data: "hello "}, {type: "text", data: "hello "},
{type: "math", data: " world ", display: false}, {type: "math", data: " world ",
rawData: "( world )", display: false},
{type: "text", data: " boo"}, {type: "text", data: " boo"},
{type: "math", data: "hello ( world ) boo", display: true} {type: "math", data: "hello ( world ) boo",
rawData: "(hello ( world ) boo)", display: true}
]); ]);
}); });
}); });

View File

@ -24,9 +24,22 @@ var renderMathInText = function(text, delimiters) {
} else { } else {
var span = document.createElement("span"); var span = document.createElement("span");
var math = data[i].data; var math = data[i].data;
katex.render(math, span, { try {
displayMode: data[i].display katex.render(math, span, {
}); displayMode: data[i].display
});
} catch (e) {
if (!(e instanceof katex.ParseError)) {
throw e;
}
console.error(
"KaTeX auto-render: Failed to parse `" + data[i].data +
"` with ",
e
);
fragment.appendChild(document.createTextNode(data[i].rawData));
continue;
}
fragment.appendChild(span); fragment.appendChild(span);
} }
} }

View File

@ -10,7 +10,7 @@
body { body {
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
font-size: 72px; font-size: 36px;
} }
#test > .blue { #test > .blue {
@ -20,7 +20,7 @@
</head> </head>
<body> <body>
<div id="test"> <div id="test">
This is some text $math \frac12$ other text This is some text $math \frac12$ other text $\unsupported$
<span class="blue"> <span class="blue">
Other node \[ displaymath \frac{1}{2} \] blah $$ \int_2^3 $$ Other node \[ displaymath \frac{1}{2} \] blah $$ \int_2^3 $$
</span> </span>

View File

@ -74,6 +74,9 @@ var splitAtDelimiters = function(startData, leftDelim, rightDelim, display) {
data: text.slice( data: text.slice(
currIndex + leftDelim.length, currIndex + leftDelim.length,
nextIndex), nextIndex),
rawData: text.slice(
currIndex,
nextIndex + rightDelim.length),
display: display display: display
}); });