From 28b65d7a9336864d549d55f3d18f27a508de46b4 Mon Sep 17 00:00:00 2001 From: Henry Li Date: Sun, 11 May 2025 00:06:07 +0800 Subject: [PATCH] feat: Enhance markdown's anti-shake --- web/src/components/deer-flow/markdown.tsx | 5 +- web/src/core/utils/markdown.ts | 57 +++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 web/src/core/utils/markdown.ts diff --git a/web/src/components/deer-flow/markdown.tsx b/web/src/components/deer-flow/markdown.tsx index e36319b..1e70474 100644 --- a/web/src/components/deer-flow/markdown.tsx +++ b/web/src/components/deer-flow/markdown.tsx @@ -13,6 +13,7 @@ import "katex/dist/katex.min.css"; import { Button } from "~/components/ui/button"; import { rehypeSplitWordsIntoSpans } from "~/core/rehype"; +import { autoFixMarkdown } from "~/core/utils/markdown"; import { cn } from "~/lib/utils"; import Image from "./image"; @@ -62,7 +63,9 @@ export function Markdown({ }} {...props} > - {dropMarkdownQuote(processKatexInMarkdown(children))} + {autoFixMarkdown( + dropMarkdownQuote(processKatexInMarkdown(children ?? "")) ?? "", + )} {enableCopy && typeof children === "string" && (
diff --git a/web/src/core/utils/markdown.ts b/web/src/core/utils/markdown.ts new file mode 100644 index 0000000..8b4a70f --- /dev/null +++ b/web/src/core/utils/markdown.ts @@ -0,0 +1,57 @@ +export function autoFixMarkdown(markdown: string): string { + return autoCloseTrailingLink(markdown); +} + +function autoCloseTrailingLink(markdown: string): string { + // Fix unclosed Markdown links or images + let fixedMarkdown: string = markdown; + + // Fix unclosed image syntax ![...](...) + fixedMarkdown = fixedMarkdown.replace( + /!\[([^\]]*)\]\(([^)]*)$/g, + (match: string, altText: string, url: string): string => { + return `![${altText}](${url})`; + }, + ); + + // Fix unclosed link syntax [...](...) + fixedMarkdown = fixedMarkdown.replace( + /\[([^\]]*)\]\(([^)]*)$/g, + (match: string, linkText: string, url: string): string => { + return `[${linkText}](${url})`; + }, + ); + + // Fix unclosed image syntax ![...] + fixedMarkdown = fixedMarkdown.replace( + /!\[([^\]]*)$/g, + (match: string, altText: string): string => { + return `![${altText}]`; + }, + ); + + // Fix unclosed link syntax [...] + fixedMarkdown = fixedMarkdown.replace( + /\[([^\]]*)$/g, + (match: string, linkText: string): string => { + return `[${linkText}]`; + }, + ); + + // Fix unclosed images or links missing ")" + fixedMarkdown = fixedMarkdown.replace( + /!\[([^\]]*)\]\(([^)]*)$/g, + (match: string, altText: string, url: string): string => { + return `![${altText}](${url})`; + }, + ); + + fixedMarkdown = fixedMarkdown.replace( + /\[([^\]]*)\]\(([^)]*)$/g, + (match: string, linkText: string, url: string): string => { + return `[${linkText}](${url})`; + }, + ); + + return fixedMarkdown; +}