import "server-only"; import { compileMDX } from "next-mdx-remote/rsc"; import rehypePrettyCode, { type Options as PrettyCodeOptions, } from "rehype-pretty-code"; import rehypeSlug from "rehype-slug"; import rehypeAutolinkHeadings from "rehype-autolink-headings"; import remarkGfm from "remark-gfm"; import { mdxComponents } from "@/components/mdx/mdx-components"; /** * MDX 编译管线。 * * 插件顺序(rehype 在 remark 之后执行): * 1. remark-gfm → 表格、任务列表、删除线 * 2. rehype-slug → 为标题生成 id(TOC 锚点依赖它) * 3. rehype-autolink-headings → 标题旁生成可点击的 # 锚点 * 4. rehype-pretty-code → 基于 Shiki 的语法高亮 + 行号/高亮行 * * Shiki 在构建期完成高亮,输出静态 HTML,运行时零 JS 开销。 */ /** 代码高亮主题:深色 surface-code (#1c1c1e) 上对比度良好 */ const CODE_THEME = "github-dark-default"; const prettyCodeOptions: PrettyCodeOptions = { theme: CODE_THEME, // 保留默认的 pre/code 结构,样式由 globals.css 的 .prose-blog 控制 keepBackground: true, defaultLang: "plaintext", }; export interface CompiledMdx { content: React.ReactElement; } /** 编译 MDX 正文为可渲染的 React 元素树 */ export async function compilePostMdx(source: string): Promise { const { content } = await compileMDX({ source, components: mdxComponents, options: { parseFrontmatter: false, mdxOptions: { remarkPlugins: [remarkGfm], rehypePlugins: [ rehypeSlug, [ rehypeAutolinkHeadings, { behavior: "append", properties: { className: "heading-anchor", ariaLabel: "锚点链接", tabIndex: -1, }, content: { type: "text", value: "#", }, }, ], [rehypePrettyCode, prettyCodeOptions], ], }, }, }); return { content }; }