Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update KaTeX to the latest version #24

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
334 changes: 161 additions & 173 deletions assets/contrib/auto-render.js
100755 → 100644

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/contrib/auto-render.min.js
100755 → 100644

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

203 changes: 105 additions & 98 deletions assets/contrib/auto-render.mjs
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import katex from '../katex.mjs';

/* eslint no-constant-condition:0 */
const findEndOfMath = function findEndOfMath(delimiter, text, startIndex) {
var findEndOfMath = function findEndOfMath(delimiter, text, startIndex) {
// Adapted from
// https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx
let index = startIndex;
let braceLevel = 0;
const delimLength = delimiter.length;
var index = startIndex;
var braceLevel = 0;
var delimLength = delimiter.length;

while (index < text.length) {
const character = text[index];
var character = text[index];

if (braceLevel <= 0 && text.slice(index, index + delimLength) === delimiter) {
return index;
Expand All @@ -27,100 +27,84 @@ const findEndOfMath = function findEndOfMath(delimiter, text, startIndex) {
return -1;
};

const splitAtDelimiters = function splitAtDelimiters(startData, leftDelim, rightDelim, display) {
const finalData = [];

for (let i = 0; i < startData.length; i++) {
if (startData[i].type === "text") {
const text = startData[i].data;
let lookingForLeft = true;
let currIndex = 0;
let nextIndex;
nextIndex = text.indexOf(leftDelim);

if (nextIndex !== -1) {
currIndex = nextIndex;
finalData.push({
type: "text",
data: text.slice(0, currIndex)
});
lookingForLeft = false;
}
var escapeRegex = function escapeRegex(string) {
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
};

while (true) {
if (lookingForLeft) {
nextIndex = text.indexOf(leftDelim, currIndex);

if (nextIndex === -1) {
break;
}

finalData.push({
type: "text",
data: text.slice(currIndex, nextIndex)
});
currIndex = nextIndex;
} else {
nextIndex = findEndOfMath(rightDelim, text, currIndex + leftDelim.length);

if (nextIndex === -1) {
break;
}

finalData.push({
type: "math",
data: text.slice(currIndex + leftDelim.length, nextIndex),
rawData: text.slice(currIndex, nextIndex + rightDelim.length),
display: display
});
currIndex = nextIndex + rightDelim.length;
}
var amsRegex = /^\\begin{/;

lookingForLeft = !lookingForLeft;
}
var splitAtDelimiters = function splitAtDelimiters(text, delimiters) {
var index;
var data = [];
var regexLeft = new RegExp("(" + delimiters.map(x => escapeRegex(x.left)).join("|") + ")");

while (true) {
index = text.search(regexLeft);

finalData.push({
if (index === -1) {
break;
}

if (index > 0) {
data.push({
type: "text",
data: text.slice(currIndex)
data: text.slice(0, index)
});
} else {
finalData.push(startData[i]);
}
}
text = text.slice(index); // now text starts with delimiter
} // ... so this always succeeds:

return finalData;
};

/* eslint no-console:0 */
var i = delimiters.findIndex(delim => text.startsWith(delim.left));
index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length);

const splitWithDelimiters = function splitWithDelimiters(text, delimiters) {
let data = [{
type: "text",
data: text
}];
if (index === -1) {
break;
}

var rawData = text.slice(0, index + delimiters[i].right.length);
var math = amsRegex.test(rawData) ? rawData : text.slice(delimiters[i].left.length, index);
data.push({
type: "math",
data: math,
rawData,
display: delimiters[i].display
});
text = text.slice(index + delimiters[i].right.length);
}

for (let i = 0; i < delimiters.length; i++) {
const delimiter = delimiters[i];
data = splitAtDelimiters(data, delimiter.left, delimiter.right, delimiter.display || false);
if (text !== "") {
data.push({
type: "text",
data: text
});
}

return data;
};

/* eslint no-console:0 */
/* Note: optionsCopy is mutated by this method. If it is ever exposed in the
* API, we should copy it before mutating.
*/

var renderMathInText = function renderMathInText(text, optionsCopy) {
var data = splitAtDelimiters(text, optionsCopy.delimiters);

if (data.length === 1 && data[0].type === 'text') {
// There is no formula in the text.
// Let's return null which means there is no need to replace
// the current text node with a new one.
return null;
}

const renderMathInText = function renderMathInText(text, optionsCopy) {
const data = splitWithDelimiters(text, optionsCopy.delimiters);
const fragment = document.createDocumentFragment();
var fragment = document.createDocumentFragment();

for (let i = 0; i < data.length; i++) {
for (var i = 0; i < data.length; i++) {
if (data[i].type === "text") {
fragment.appendChild(document.createTextNode(data[i].data));
} else {
const span = document.createElement("span");
let math = data[i].data; // Override any display mode defined in the settings with that
var span = document.createElement("span");
var math = data[i].data; // Override any display mode defined in the settings with that
// defined by the text itself

optionsCopy.displayMode = data[i].display;
Expand Down Expand Up @@ -148,36 +132,41 @@ const renderMathInText = function renderMathInText(text, optionsCopy) {
return fragment;
};

const renderElem = function renderElem(elem, optionsCopy) {
for (let i = 0; i < elem.childNodes.length; i++) {
const childNode = elem.childNodes[i];
var renderElem = function renderElem(elem, optionsCopy) {
for (var i = 0; i < elem.childNodes.length; i++) {
var childNode = elem.childNodes[i];

if (childNode.nodeType === 3) {
// Text node
const frag = renderMathInText(childNode.textContent, optionsCopy);
i += frag.childNodes.length - 1;
elem.replaceChild(frag, childNode);
} else if (childNode.nodeType === 1) {
// Element node
const className = ' ' + childNode.className + ' ';
const shouldRender = optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) === -1 && optionsCopy.ignoredClasses.every(x => className.indexOf(' ' + x + ' ') === -1);
var frag = renderMathInText(childNode.textContent, optionsCopy);

if (shouldRender) {
renderElem(childNode, optionsCopy);
if (frag) {
i += frag.childNodes.length - 1;
elem.replaceChild(frag, childNode);
}
} else if (childNode.nodeType === 1) {
(function () {
// Element node
var className = ' ' + childNode.className + ' ';
var shouldRender = optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) === -1 && optionsCopy.ignoredClasses.every(x => className.indexOf(' ' + x + ' ') === -1);

if (shouldRender) {
renderElem(childNode, optionsCopy);
}
})();
} // Otherwise, it's something else, and ignore it.

}
};

const renderMathInElement = function renderMathInElement(elem, options) {
var renderMathInElement = function renderMathInElement(elem, options) {
if (!elem) {
throw new Error("No element provided to render");
}

const optionsCopy = {}; // Object.assign(optionsCopy, option)
var optionsCopy = {}; // Object.assign(optionsCopy, option)

for (const option in options) {
for (var option in options) {
if (options.hasOwnProperty(option)) {
optionsCopy[option] = options[option];
}
Expand All @@ -194,16 +183,34 @@ const renderMathInElement = function renderMathInElement(elem, options) {
display: false
}, // LaTeX uses $…$, but it ruins the display of normal `$` in text:
// {left: "$", right: "$", display: false},
// \[…\] must come last in this array. Otherwise, renderMathInElement
// will search for \[ before it searches for $$ or \(
// That makes it susceptible to finding a \\[0.3em] row delimiter and
// treating it as if it were the start of a KaTeX math zone.
// $ must come after $$
// Render AMS environments even if outside $$…$$ delimiters.
{
left: "\\begin{equation}",
right: "\\end{equation}",
display: true
}, {
left: "\\begin{align}",
right: "\\end{align}",
display: true
}, {
left: "\\begin{alignat}",
right: "\\end{alignat}",
display: true
}, {
left: "\\begin{gather}",
right: "\\end{gather}",
display: true
}, {
left: "\\begin{CD}",
right: "\\end{CD}",
display: true
}, {
left: "\\[",
right: "\\]",
display: true
}];
optionsCopy.ignoredTags = optionsCopy.ignoredTags || ["script", "noscript", "style", "textarea", "pre", "code"];
optionsCopy.ignoredTags = optionsCopy.ignoredTags || ["script", "noscript", "style", "textarea", "pre", "code", "option"];
optionsCopy.ignoredClasses = optionsCopy.ignoredClasses || [];
optionsCopy.errorCallback = optionsCopy.errorCallback || console.error; // Enable sharing of global macros defined via `\gdef` between different
// math elements within a single call to `renderMathInElement`.
Expand All @@ -212,4 +219,4 @@ const renderMathInElement = function renderMathInElement(elem, options) {
renderElem(elem, optionsCopy);
};

export default renderMathInElement;
export { renderMathInElement as default };
6 changes: 3 additions & 3 deletions assets/contrib/copy-tex.css
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
*/
.katex,
.katex-display {
user-select: all;
-moz-user-select: all;
-webkit-user-select: all;
-ms-user-select: all;
-moz-user-select: all;
-ms-user-select: all;
user-select: all;
}

Loading