Support all render options in auto-render.

Closes #690.
This commit is contained in:
Alex Pearce
2017-02-10 20:07:50 +01:00
committed by Erik Demaine
parent 25dde7f841
commit 60b1969a01
2 changed files with 23 additions and 29 deletions

View File

@@ -55,7 +55,9 @@ function renderMathInElement(elem, options)
`elem` is an HTML DOM element. The function will recursively search for text `elem` is an HTML DOM element. The function will recursively search for text
nodes inside this element and render the math in them. nodes inside this element and render the math in them.
`options` is an optional object argument with the following keys: `options` is an optional object argument that can have the same keys as [the
object passed to `katex.render`](https://github.com/Khan/KaTeX/#rendering-options),
in addition to two auto-render-specific keys:
- `delimiters`: This is a list of delimiters to look for math. Each delimiter - `delimiters`: This is a list of delimiters to look for math. Each delimiter
has three properties: has three properties:
@@ -78,3 +80,7 @@ nodes inside this element and render the math in them.
- `ignoredTags`: This is a list of DOM node types to ignore when recursing - `ignoredTags`: This is a list of DOM node types to ignore when recursing
through. The default value is through. The default value is
`["script", "noscript", "style", "textarea", "pre", "code"]`. `["script", "noscript", "style", "textarea", "pre", "code"]`.
Note that the `displayMode` property of the options object is ignored, and is
instead taken from the `display` key of the corresponding entry in the
`delimiters` key.

View File

@@ -14,8 +14,11 @@ const splitWithDelimiters = function(text, delimiters) {
return data; return data;
}; };
const renderMathInText = function(text, delimiters) { /* Note: optionsCopy is mutated by this method. If it is ever exposed in the
const data = splitWithDelimiters(text, delimiters); * API, we should copy it before mutating.
*/
const renderMathInText = function(text, optionsCopy) {
const data = splitWithDelimiters(text, optionsCopy.delimiters);
const fragment = document.createDocumentFragment(); const fragment = document.createDocumentFragment();
@@ -25,10 +28,11 @@ const renderMathInText = function(text, delimiters) {
} else { } else {
const span = document.createElement("span"); const span = document.createElement("span");
const math = data[i].data; const math = data[i].data;
// Override any display mode defined in the settings with that
// defined by the text itself
optionsCopy.displayMode = data[i].display;
try { try {
katex.render(math, span, { katex.render(math, span, optionsCopy);
displayMode: data[i].display,
});
} catch (e) { } catch (e) {
if (!(e instanceof katex.ParseError)) { if (!(e instanceof katex.ParseError)) {
throw e; throw e;
@@ -48,28 +52,28 @@ const renderMathInText = function(text, delimiters) {
return fragment; return fragment;
}; };
const renderElem = function(elem, delimiters, ignoredTags) { const renderElem = function(elem, optionsCopy) {
for (let i = 0; i < elem.childNodes.length; i++) { for (let i = 0; i < elem.childNodes.length; i++) {
const childNode = elem.childNodes[i]; const childNode = elem.childNodes[i];
if (childNode.nodeType === 3) { if (childNode.nodeType === 3) {
// Text node // Text node
const frag = renderMathInText(childNode.textContent, delimiters); const frag = renderMathInText(childNode.textContent, optionsCopy);
i += frag.childNodes.length - 1; i += frag.childNodes.length - 1;
elem.replaceChild(frag, childNode); elem.replaceChild(frag, childNode);
} else if (childNode.nodeType === 1) { } else if (childNode.nodeType === 1) {
// Element node // Element node
const shouldRender = ignoredTags.indexOf( const shouldRender = optionsCopy.ignoredTags.indexOf(
childNode.nodeName.toLowerCase()) === -1; childNode.nodeName.toLowerCase()) === -1;
if (shouldRender) { if (shouldRender) {
renderElem(childNode, delimiters, ignoredTags); renderElem(childNode, optionsCopy);
} }
} }
// Otherwise, it's something else, and ignore it. // Otherwise, it's something else, and ignore it.
} }
}; };
const defaultOptions = { const defaultAutoRenderOptions = {
delimiters: [ delimiters: [
{left: "$$", right: "$$", display: true}, {left: "$$", right: "$$", display: true},
{left: "\\[", right: "\\]", display: true}, {left: "\\[", right: "\\]", display: true},
@@ -83,30 +87,14 @@ const defaultOptions = {
], ],
}; };
const extend = function(obj) {
// Adapted from underscore.js' `_.extend`. See LICENSE.txt for license.
let source;
let prop;
const length = arguments.length;
for (let i = 1; i < length; i++) {
source = arguments[i];
for (prop in source) {
if (Object.prototype.hasOwnProperty.call(source, prop)) {
obj[prop] = source[prop];
}
}
}
return obj;
};
const renderMathInElement = function(elem, options) { const renderMathInElement = function(elem, options) {
if (!elem) { if (!elem) {
throw new Error("No element provided to render"); throw new Error("No element provided to render");
} }
options = extend({}, defaultOptions, options); const optionsCopy = Object.assign({}, defaultAutoRenderOptions, options);
renderElem(elem, options.delimiters, options.ignoredTags); renderElem(elem, optionsCopy);
}; };
module.exports = renderMathInElement; module.exports = renderMathInElement;