analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
168 lines (166 loc) • 5.22 kB
JavaScript
import {
KatexMath
} from "./chunk-QVP5SCGQ.mjs";
import {
cn
} from "./chunk-53ICLDGS.mjs";
// src/components/LatexRenderer/LatexRenderer.tsx
import "katex/dist/katex.min.css";
import DOMPurify from "dompurify";
import parse, {
Element
} from "html-react-parser";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var sanitizeHtml = (value) => {
return DOMPurify.sanitize(value, {
ADD_ATTR: ["data-latex", "data-display-mode", "data-math", "data-math-id"]
});
};
var decodeHtmlEntities = (str) => {
const textarea = document.createElement("textarea");
textarea.innerHTML = str;
return textarea.value;
};
var cleanLatex = (str) => {
return str.replaceAll(/[\u200B-\u200D\uFEFF]/g, "").trim();
};
var createMathReplacer = (mathParts, errorRenderer) => {
return (domNode) => {
if (domNode instanceof Element && domNode.name === "span" && domNode.attribs["data-math-id"]) {
const mathId = Number.parseInt(domNode.attribs["data-math-id"], 10);
const mathPart = mathParts[mathId];
if (!mathPart) return domNode;
if (mathPart.type === "inline") {
return /* @__PURE__ */ jsx(
KatexMath,
{
math: mathPart.latex,
renderError: () => errorRenderer(mathPart.latex)
},
`math-${mathId}`
);
} else {
return /* @__PURE__ */ jsx("div", { className: "my-2.5 text-center", children: /* @__PURE__ */ jsx(
KatexMath,
{
math: mathPart.latex,
displayMode: true,
renderError: () => errorRenderer(mathPart.latex)
}
) }, `math-${mathId}`);
}
}
return domNode;
};
};
var LatexRenderer = ({
content,
className,
style,
onError
}) => {
const renderContentWithMath = (htmlContent) => {
if (!htmlContent) return null;
let processedContent = htmlContent;
const mathParts = [];
const mathFormulaPattern = /<span[^>]*class="math-formula"[^>]*data-latex="([^"]*)"[^>]*>[\s\S]*?<\/span>/g;
processedContent = processedContent.replaceAll(
mathFormulaPattern,
(match, latex) => {
const isDisplayMode = match.includes('data-display-mode="true"');
const id = mathParts.length;
mathParts.push({
id,
type: isDisplayMode ? "block" : "inline",
latex: cleanLatex(decodeHtmlEntities(latex))
});
return `<span data-math-id="${id}"></span>`;
}
);
const wrappedMathPattern = /<span[^>]*class="math-expression"[^>]*data-math="([^"]*)"[^>]*>.*?<\/span>/g;
processedContent = processedContent.replaceAll(
wrappedMathPattern,
(match, latex) => {
const id = mathParts.length;
mathParts.push({
id,
type: "inline",
latex: cleanLatex(decodeHtmlEntities(latex))
});
return `<span data-math-id="${id}"></span>`;
}
);
const doubleDollarPattern = /(?<!\\)\$\$([\s\S]+?)\$\$/g;
processedContent = processedContent.replaceAll(
doubleDollarPattern,
(match, latex) => {
const id = mathParts.length;
mathParts.push({
id,
type: "block",
latex: cleanLatex(latex)
});
return `<span data-math-id="${id}"></span>`;
}
);
const singleDollarPattern = /(?<!\\)\$([\s\S]+?)\$/g;
processedContent = processedContent.replaceAll(
singleDollarPattern,
(match, latex) => {
const id = mathParts.length;
mathParts.push({
id,
type: "inline",
latex: cleanLatex(latex)
});
return `<span data-math-id="${id}"></span>`;
}
);
const latexTagPattern = /(?:<latex>|<latex>)([\s\S]*?)(?:<\/latex>|<\/latex>)/g;
processedContent = processedContent.replaceAll(
latexTagPattern,
(match, latex) => {
const id = mathParts.length;
mathParts.push({
id,
type: "inline",
latex: cleanLatex(latex)
});
return `<span data-math-id="${id}"></span>`;
}
);
const latexEnvPattern = /\\begin\{([^}]+)\}([\s\S]*?)\\end\{\1\}/g;
processedContent = processedContent.replaceAll(latexEnvPattern, (match) => {
const id = mathParts.length;
mathParts.push({
id,
type: "block",
latex: cleanLatex(match)
});
return `<span data-math-id="${id}"></span>`;
});
const sanitizedContent = sanitizeHtml(processedContent);
const defaultErrorRenderer = (latex) => /* @__PURE__ */ jsxs("span", { className: "text-red-600", children: [
"Math Error: ",
latex
] });
const errorRenderer = onError || defaultErrorRenderer;
const options = {
replace: createMathReplacer(mathParts, errorRenderer)
};
return /* @__PURE__ */ jsx(Fragment, { children: parse(sanitizedContent, options) });
};
return /* @__PURE__ */ jsx(
"div",
{
className: cn("whitespace-pre-wrap leading-relaxed", className),
style,
children: renderContentWithMath(content)
}
);
};
var LatexRenderer_default = LatexRenderer;
export {
LatexRenderer_default
};
//# sourceMappingURL=chunk-NNUCT5IL.mjs.map