Skip to content

Commit

Permalink
feat(auto-render): add option to ignore escaped special characters ou…
Browse files Browse the repository at this point in the history
…tside of LaTeX math mode (KaTeX#437)
  • Loading branch information
lnasrc committed Jun 26, 2023
1 parent ad03d1e commit de8d0e1
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 43 deletions.
19 changes: 17 additions & 2 deletions contrib/auto-render/auto-render.js
Expand Up @@ -7,18 +7,30 @@ import splitAtDelimiters from "./splitAtDelimiters";
* API, we should copy it before mutating.
*/
const renderMathInText = function(text, optionsCopy) {
const data = splitAtDelimiters(text, optionsCopy.delimiters);
const data = splitAtDelimiters(text, optionsCopy.delimiters,
optionsCopy.supportEscapedSpecialCharsInText);
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;
if (!optionsCopy.supportEscapedSpecialCharsInText) {
return null;
}
}

const fragment = document.createDocumentFragment();

for (let i = 0; i < data.length; i++) {
if (data[i].type === "text") {
if (optionsCopy.supportEscapedSpecialCharsInText) {
data[i].data = data[i].data.replace(/\\\$/g, '$');
data[i].data = data[i].data.replace(/\\%/g, '%');
data[i].data = data[i].data.replace(/\\_/g, '_');
data[i].data = data[i].data.replace(/\\&/g, '&');
data[i].data = data[i].data.replace(/\\#/g, '#');
data[i].data = data[i].data.replace(/\\{/g, '{');
data[i].data = data[i].data.replace(/\\}/g, '}');
}
fragment.appendChild(document.createTextNode(data[i].data));
} else {
const span = document.createElement("span");
Expand Down Expand Up @@ -136,6 +148,9 @@ const renderMathInElement = function(elem, options) {
// math elements within a single call to `renderMathInElement`.
optionsCopy.macros = optionsCopy.macros || {};

optionsCopy.supportEscapedSpecialCharsInText =
optionsCopy.supportEscapedSpecialCharsInText || false;

renderElem(elem, optionsCopy);
};

Expand Down
31 changes: 25 additions & 6 deletions contrib/auto-render/splitAtDelimiters.js
Expand Up @@ -27,19 +27,38 @@ const findEndOfMath = function(delimiter, text, startIndex) {
return -1;
};

const escapeRegex = function(string) {
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
const escapeRegex = function(string, supportEscapedSpecialCharsInText) {
if (supportEscapedSpecialCharsInText) {
if (string === "$") {
/* negative lookbehind to find any dollar not preceded by a
backslash */
return "(?<!\\\\)\\$";
} else if (string === "(") {
/* negative lookbehind to find any parenthesis not preceded by a
backslash */
return "(?<!\\\\)\\(";
} else if (string === "\\(") {
return "\\\\\\(";
} else if (string === "\\$") {
return "\\\\\\$";
} else {
return string.replace(/[-/\\^$*+?.)|[\]{}]/g, "\\$&");
}
} else {
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
}
};

const amsRegex = /^\\begin{/;

const splitAtDelimiters = function(text, delimiters) {
const splitAtDelimiters = function(text, delimiters,
supportEscapedSpecialCharsInText) {
let index;
const data = [];

const regexLeft = new RegExp(
"(" + delimiters.map((x) => escapeRegex(x.left)).join("|") + ")"
);
const regexLeft = new RegExp("(" + delimiters.map((x) =>
escapeRegex(x.left, supportEscapedSpecialCharsInText),
).join("|") + ")");

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

0 comments on commit de8d0e1

Please sign in to comment.