import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import remarkMath from "remark-math"; import rehypeHighlight from "rehype-highlight"; import rehypeKatex from "rehype-katex"; import "katex/dist/katex.min.css"; import Mermaid from "./Mermaid"; function preprocessContent(text) { if (!text) return ""; let processedText = text; const imageBlockRegex = /((?:!\[.*?\]\(.*?\)(?:\s| )*){2,})/g; processedText = processedText.replace(imageBlockRegex, (match) => { return `\n\`\`\`slider\n${match.trim()}\n\`\`\`\n`; }); const parts = processedText.split(/(```[\s\S]*?```|`[^`\n]+`|!\[[\s\S]*?\]\([\s\S]*?\))/g); const processedParts = parts.map(part => { if (part.startsWith("```") || part.startsWith("`") || part.startsWith("![")) return part; let processed = part; const mermaidRegex = /^(?:graph|flowchart|classDiagram|stateDiagram|erDiagram|sequenceDiagram|gantt|pie|quadrantChart|xychart|mindmap|timeline)[\s\S]+?(?=\n\n|\n$|$)/gm; processed = processed.replace(mermaidRegex, (match) => { if (match.trim().split("\n").length > 1) { return `\n\`\`\`mermaid\n${match.trim()}\n\`\`\`\n`; } return match; }); const treeRegex = /((?:^[ \t]*[│├└┌┐┘┤┼|].*$\n?)+)/gm; processed = processed.replace(treeRegex, (match) => { const lines = match.trim().split("\n"); const hasStrongTreeChars = /[│├└┌┐┘┤┼├─]/.test(match); if (lines.length > 1 || hasStrongTreeChars) { return `\n\`\`\`tree\n${match.trim()}\n\`\`\`\n`; } return match; }); processed = processed.replace(/^[ \t\u00a0]*[•●○·][ \t\u00a0]*/gm, "- "); processed = processed.replace(/\\\[([\s\S]*?)\\\]/g, "$$$$1$$"); processed = processed.replace(/\\\(([\s\S]*?)\\\)/g, "$$1$"); processed = processed.replace(/(\((.+?)\)|\[(.+?)\])/g, (match, full, p1, p2) => { const content = (p1 || p2 || "").trim(); if (!content) return match; const hasMathOperator = /[\\_^={}+\-*/]/.test(content); const isSingleVar = /^[a-z]$/i.test(content); const isExpression = /^[a-z0-9] *[+\-*/=] *[a-z0-9]/i.test(content); if (hasMathOperator || isSingleVar || isExpression) { const delim = (match.startsWith("[") || content.length > 50) ? "$$" : "$"; return `${delim}${match}${delim}`; } return match; }); const lines = processed.split("\n"); const resultLines = lines.map(line => { const trimmed = line.trim(); if ( (trimmed.includes("\\") || /[_^]/.test(trimmed) || /^[a-z] *=/i.test(trimmed)) && !trimmed.includes("$") && !trimmed.startsWith("#") && !trimmed.startsWith("-") && !trimmed.startsWith("*") && trimmed.length > 0 ) { if (/^[a-zA-Z0-9] *=/.test(trimmed) || /^\\[a-zA-Z]+/.test(trimmed)) { return `$$${trimmed}$$`; } } return line; }); return resultLines.join("\n"); }); let finalProcessed = processedParts.join(""); finalProcessed = finalProcessed.replace(/([^\n])\n- /g, "$1\n\n- "); return finalProcessed; } export function AnswerRenderer({ answer }) { const processedAnswer = preprocessContent(answer); return (
{children}
{children}
) : (
{children}
);
},
}}
>
{processedAnswer}