feat(frontend): Shiki 白名单语言高亮并支持 aardio

显式加载常用语言;修复 pretty-code 去 shiki class 导致不上色,以及 aardio 循环别名。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-16 06:09:25 +08:00
parent 3f88b38610
commit 8d5e00a112
7 changed files with 290 additions and 23 deletions

View File

@@ -6,24 +6,45 @@ 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 rehypePrettyCode, { type Options as PrettyCodeOptions } from "rehype-pretty-code";
import type { Root } from "hast";
import type { Root as MdastRoot } from "mdast";
import { visit } from "unist-util-visit";
import { mergeMarkdownComponents } from "./mergeComponents";
import {
getPrettyCodeHighlighter,
resolveShikiLang,
SHIKI_THEMES,
} from "./shikiHighlighter";
export const prettyCodeOptions = {
/**
* 将代码围栏语言归一到白名单(未知 → plaintext),
* 避免 rehype-pretty-code 对未装载语言 loadLanguage 失败。
*/
function remarkNormalizeCodeLang() {
return (tree: MdastRoot) => {
visit(tree, "code", (node) => {
node.lang = resolveShikiLang(node.lang);
});
};
}
export const prettyCodeOptions: PrettyCodeOptions = {
theme: {
light: "github-light",
dark: "github-dark-dimmed",
light: SHIKI_THEMES.light,
dark: SHIKI_THEMES.dark,
},
keepBackground: false,
defaultLang: "plaintext",
// HighlighterCore 与 pretty-code 期望的 Highlighter 在运行时兼容
getHighlighter: getPrettyCodeHighlighter as unknown as PrettyCodeOptions["getHighlighter"],
// 空行在 display:grid 下会塌缩成 0 高,补一个空格撑住行高
onVisitLine(element: { children: unknown[] }) {
onVisitLine(element) {
if (element.children.length === 0) {
element.children = [{ type: "text", value: " " }];
}
},
} as const;
};
/** 服务端异步管线:GFM + Shiki 双主题高亮 → React 树 */
export async function renderMarkdownToReact(
@@ -33,6 +54,7 @@ export async function renderMarkdownToReact(
const processor = unified()
.use(remarkParse)
.use(remarkGfm)
.use(remarkNormalizeCodeLang)
.use(remarkRehype)
.use(rehypePrettyCode, { ...prettyCodeOptions });