String with Formula Translated to HTML
将带有$$、$分隔符的字符串转化为Html。
原问题链接:https://github.com/KaTeX/KaTeX/issues/604。
参考代码:
- Katex官方Auto-Render代码。
- https://github.com/hmzlam/katexWithDelimiters/blob/master/katexDel.js
最终实现代码:
// strngRender.js
import katex from 'katex';
const findEndOfMath = function(delimiter, text, startIndex) {
let index = startIndex;
let braceLevel = 0;
const delimLength = delimiter.length;
while (index < text.length) {
const character = text[index];
if (braceLevel <= 0 &&
text.slice(index, index + delimLength) === delimiter) {
return index;
} else if (character === "\\") {
index++;
} else if (character === "{") {
braceLevel++;
} else if (character === "}") {
braceLevel--;
}
index++;
}
return -1;
};
const escapeRegex = function(string) {
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
};
const amsRegex = /^\\begin{/;
const splitAtDelimiters = function(text, delimiters) {
let index;
const data = [];
const regexLeft = new RegExp(
"(" + delimiters.map((x) => escapeRegex(x.left)).join("|") + ")"
);
while (true) {
index = text.search(regexLeft);
if (index === -1) {
break;
}
if (index > 0) {
data.push({
type: "text",
data: text.slice(0, index),
});
text = text.slice(index);
}
const i = delimiters.findIndex((delim) => text.startsWith(delim.left));
index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length);
if (index === -1) {
break;
}
const rawData = text.slice(0, index + delimiters[i].right.length);
const math = amsRegex.test(rawData)
? rawData
: text.slice(delimiters[i].left.length, index);
data.push({
type: "math",
data: math,
rawData,
display: delimiters[i].display,
delimiter: delimiters[i].right
});
text = text.slice(index + delimiters[i].right.length);
}
if (text !== "") {
data.push({
type: "text",
data: text,
});
}
return data;
};
const strngRender = function(text) {
let data = splitAtDelimiters(text,
[
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false},
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true}
],
)
let res = ''
for (let i = 0; i < data.length; i++) {
if (data[i].type === "text") {
res += data[i].data.replace("\n\n","<br/>");
} else {
let html = katex.renderToString(data[i].data, {
throwOnError: false
});
if(data[i].delimiter == '$$'){
html = "<br/><p style='width:100%;text-align:center;'>"+html+"</p>"
}
res += html;
}
}
return res;
}
export default strngRender;
// 使用方式
import strngRender from 'stringRender.js'
let strings = strngRender("hhh$c = \\pm\\sqrt{a^2 + b^2}$\n\n$$\na=b\n$$")