From 84db798353b88acc3c95cb43b112d02c3d5a8e93 Mon Sep 17 00:00:00 2001 From: Thuc Pham <51660321+thucpn@users.noreply.github.com> Date: Thu, 16 May 2024 15:25:53 +0700 Subject: [PATCH] feat: support display latex in chat markdown (#88) --- .changeset/silent-tomatoes-relax.md | 5 +++++ .../app/components/ui/chat/markdown.tsx | 20 ++++++++++++++++++- templates/types/streaming/nextjs/package.json | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 .changeset/silent-tomatoes-relax.md diff --git a/.changeset/silent-tomatoes-relax.md b/.changeset/silent-tomatoes-relax.md new file mode 100644 index 00000000..71df852c --- /dev/null +++ b/.changeset/silent-tomatoes-relax.md @@ -0,0 +1,5 @@ +--- +"create-llama": patch +--- + +feat: support display latex in chat markdown diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/markdown.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/markdown.tsx index fab4cc57..21ab81dd 100644 --- a/templates/types/streaming/nextjs/app/components/ui/chat/markdown.tsx +++ b/templates/types/streaming/nextjs/app/components/ui/chat/markdown.tsx @@ -1,5 +1,7 @@ +import "katex/dist/katex.min.css"; import { FC, memo } from "react"; import ReactMarkdown, { Options } from "react-markdown"; +import rehypeKatex from "rehype-katex"; import remarkGfm from "remark-gfm"; import remarkMath from "remark-math"; @@ -12,11 +14,27 @@ const MemoizedReactMarkdown: FC<Options> = memo( prevProps.className === nextProps.className, ); +const preprocessLaTeX = (content: string) => { + // Replace block-level LaTeX delimiters \[ \] with $$ $$ + const blockProcessedContent = content.replace( + /\\\[(.*?)\\\]/gs, + (_, equation) => `$$${equation}$$`, + ); + // Replace inline LaTeX delimiters \( \) with $ $ + const inlineProcessedContent = blockProcessedContent.replace( + /\\\((.*?)\\\)/gs, + (_, equation) => `$${equation}$`, + ); + return inlineProcessedContent; +}; + export default function Markdown({ content }: { content: string }) { + const processedContent = preprocessLaTeX(content); return ( <MemoizedReactMarkdown className="prose dark:prose-invert prose-p:leading-relaxed prose-pre:p-0 break-words custom-markdown" remarkPlugins={[remarkGfm, remarkMath]} + rehypePlugins={[rehypeKatex as any]} components={{ p({ children }) { return <p className="mb-2 last:mb-0">{children}</p>; @@ -53,7 +71,7 @@ export default function Markdown({ content }: { content: string }) { }, }} > - {content} + {processedContent} </MemoizedReactMarkdown> ); } diff --git a/templates/types/streaming/nextjs/package.json b/templates/types/streaming/nextjs/package.json index 3bcaf0cd..182828a4 100644 --- a/templates/types/streaming/nextjs/package.json +++ b/templates/types/streaming/nextjs/package.json @@ -30,6 +30,7 @@ "remark-code-import": "^1.2.0", "remark-gfm": "^3.0.1", "remark-math": "^5.1.1", + "rehype-katex": "^7.0.0", "supports-color": "^8.1.1", "tailwind-merge": "^2.1.0" }, -- GitLab