
Summary We'd like contributors to use the same linter and lint rules that we use internally. This diff swaps out eslint for jshint and fixes all lint failures except for the max-len failures in the test suites. Test Plan: - ka-lint src - make lint - make test Reviewers: emily
112 lines
3.3 KiB
JavaScript
112 lines
3.3 KiB
JavaScript
/* eslint no-console:0 */
|
|
/* global katex */
|
|
|
|
var splitAtDelimiters = require("./splitAtDelimiters");
|
|
|
|
var splitWithDelimiters = function(text, delimiters) {
|
|
var data = [{type: "text", data: text}];
|
|
for (var i = 0; i < delimiters.length; i++) {
|
|
var delimiter = delimiters[i];
|
|
data = splitAtDelimiters(
|
|
data, delimiter.left, delimiter.right,
|
|
delimiter.display || false);
|
|
}
|
|
return data;
|
|
};
|
|
|
|
var renderMathInText = function(text, delimiters) {
|
|
var data = splitWithDelimiters(text, delimiters);
|
|
|
|
var fragment = document.createDocumentFragment();
|
|
|
|
for (var i = 0; i < data.length; i++) {
|
|
if (data[i].type === "text") {
|
|
fragment.appendChild(document.createTextNode(data[i].data));
|
|
} else {
|
|
var span = document.createElement("span");
|
|
var math = data[i].data;
|
|
try {
|
|
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);
|
|
}
|
|
}
|
|
|
|
return fragment;
|
|
};
|
|
|
|
var renderElem = function(elem, delimiters, ignoredTags) {
|
|
for (var i = 0; i < elem.childNodes.length; i++) {
|
|
var childNode = elem.childNodes[i];
|
|
if (childNode.nodeType === 3) {
|
|
// Text node
|
|
var frag = renderMathInText(childNode.textContent, delimiters);
|
|
i += frag.childNodes.length - 1;
|
|
elem.replaceChild(frag, childNode);
|
|
} else if (childNode.nodeType === 1) {
|
|
// Element node
|
|
var shouldRender = ignoredTags.indexOf(
|
|
childNode.nodeName.toLowerCase()) === -1;
|
|
|
|
if (shouldRender) {
|
|
renderElem(childNode, delimiters, ignoredTags);
|
|
}
|
|
}
|
|
// Otherwise, it's something else, and ignore it.
|
|
}
|
|
};
|
|
|
|
var defaultOptions = {
|
|
delimiters: [
|
|
{left: "$$", right: "$$", display: true},
|
|
{left: "\\[", right: "\\]", display: true},
|
|
{left: "\\(", right: "\\)", display: false},
|
|
// LaTeX uses this, but it ruins the display of normal `$` in text:
|
|
// {left: "$", right: "$", display: false},
|
|
],
|
|
|
|
ignoredTags: [
|
|
"script", "noscript", "style", "textarea", "pre", "code",
|
|
],
|
|
};
|
|
|
|
var extend = function(obj) {
|
|
// Adapted from underscore.js' `_.extend`. See LICENSE.txt for license.
|
|
var source;
|
|
var prop;
|
|
for (var i = 1, length = arguments.length; i < length; i++) {
|
|
source = arguments[i];
|
|
for (prop in source) {
|
|
if (Object.prototype.hasOwnProperty.call(source, prop)) {
|
|
obj[prop] = source[prop];
|
|
}
|
|
}
|
|
}
|
|
return obj;
|
|
};
|
|
|
|
var renderMathInElement = function(elem, options) {
|
|
if (!elem) {
|
|
throw new Error("No element provided to render");
|
|
}
|
|
|
|
options = extend({}, defaultOptions, options);
|
|
|
|
renderElem(elem, options.delimiters, options.ignoredTags);
|
|
};
|
|
|
|
module.exports = renderMathInElement;
|