// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: MIT import { Check, Copy } from "lucide-react"; import { useMemo, useState } from "react"; import ReactMarkdown, { type Options as ReactMarkdownOptions, } from "react-markdown"; import rehypeKatex from "rehype-katex"; import remarkGfm from "remark-gfm"; import remarkMath from "remark-math"; import "katex/dist/katex.min.css"; import { Button } from "~/components/ui/button"; import { rehypeSplitWordsIntoSpans } from "~/core/rehype"; import { cn } from "~/lib/utils"; import Image from "./image"; import { Tooltip } from "./tooltip"; export function Markdown({ className, children, style, enableCopy, animate = false, ...props }: ReactMarkdownOptions & { className?: string; enableCopy?: boolean; style?: React.CSSProperties; animate?: boolean; }) { const rehypePlugins = useMemo(() => { if (animate) { return [rehypeKatex, rehypeSplitWordsIntoSpans]; } return [rehypeKatex]; }, [animate]); return (
( {children} ), img: ({ src, alt }) => ( {alt ), }} {...props} > {dropMarkdownQuote(processKatexInMarkdown(children))} {enableCopy && typeof children === "string" && (
)}
); } function CopyButton({ content }: { content: string }) { const [copied, setCopied] = useState(false); return ( ); } function processKatexInMarkdown(markdown?: string | null) { if (!markdown) return markdown; const markdownWithKatexSyntax = markdown .replace(/\\\\\[/g, "$$$$") // Replace '\\[' with '$$' .replace(/\\\\\]/g, "$$$$") // Replace '\\]' with '$$' .replace(/\\\\\(/g, "$$$$") // Replace '\\(' with '$$' .replace(/\\\\\)/g, "$$$$") // Replace '\\)' with '$$' .replace(/\\\[/g, "$$$$") // Replace '\[' with '$$' .replace(/\\\]/g, "$$$$") // Replace '\]' with '$$' .replace(/\\\(/g, "$$$$") // Replace '\(' with '$$' .replace(/\\\)/g, "$$$$"); // Replace '\)' with '$$'; return markdownWithKatexSyntax; } function dropMarkdownQuote(markdown?: string | null) { if (!markdown) return markdown; return markdown .replace(/^```markdown\n/gm, "") .replace(/^```text\n/gm, "") .replace(/^```\n/gm, "") .replace(/\n```$/gm, ""); }