feat(frontend): Markdown 支持 GFM、代码高亮与图片灯箱
统一 SSR/客户端渲染路径,评论与预览共用增强组件。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
45
frontend/components/markdown/renderMarkdown.tsx
Normal file
45
frontend/components/markdown/renderMarkdown.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import type { Components } from "react-markdown";
|
||||
import type { ReactElement } from "react";
|
||||
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
||||
import { toJsxRuntime } from "hast-util-to-jsx-runtime";
|
||||
import { unified } from "unified";
|
||||
import remarkParse from "remark-parse";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import remarkRehype from "remark-rehype";
|
||||
import rehypePrettyCode from "rehype-pretty-code";
|
||||
import type { Root } from "hast";
|
||||
import { mergeMarkdownComponents } from "./mergeComponents";
|
||||
|
||||
export const prettyCodeOptions = {
|
||||
theme: {
|
||||
light: "github-light",
|
||||
dark: "github-dark-dimmed",
|
||||
},
|
||||
keepBackground: false,
|
||||
defaultLang: "plaintext",
|
||||
} as const;
|
||||
|
||||
/** 服务端异步管线:GFM + Shiki 双主题高亮 → React 树 */
|
||||
export async function renderMarkdownToReact(
|
||||
content: string,
|
||||
overrides?: Components
|
||||
): Promise<ReactElement> {
|
||||
const processor = unified()
|
||||
.use(remarkParse)
|
||||
.use(remarkGfm)
|
||||
.use(remarkRehype)
|
||||
.use(rehypePrettyCode, { ...prettyCodeOptions });
|
||||
|
||||
const mdast = processor.parse(content || "");
|
||||
const hast = (await processor.run(mdast)) as Root;
|
||||
|
||||
return toJsxRuntime(hast, {
|
||||
Fragment,
|
||||
jsx,
|
||||
jsxs,
|
||||
components: mergeMarkdownComponents(overrides) as Record<
|
||||
string,
|
||||
React.ElementType
|
||||
>,
|
||||
}) as ReactElement;
|
||||
}
|
||||
Reference in New Issue
Block a user