From 61baf0f6c3d95f09077378ca10705294ef24e0f3 Mon Sep 17 00:00:00 2001 From: Glen Huang Date: Wed, 8 Oct 2025 10:50:34 +0800 Subject: [PATCH] site: parse markdown only once --- site/package-lock.json | 4 ++- site/package.json | 4 ++- site/vitePlugins/markdown.ts | 50 ++++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/site/package-lock.json b/site/package-lock.json index 2b33f80a6..27ae825be 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -14,8 +14,11 @@ "@sveltejs/adapter-static": "^3.0.10", "@sveltejs/kit": "^2.43.2", "@sveltejs/vite-plugin-svelte": "^6.2.0", + "hast-util-to-html": "^9.0.5", "hastscript": "^9.0.1", "mdast": "^2.3.2", + "mdast-util-from-markdown": "^2.0.2", + "mdast-util-to-hast": "^13.2.0", "mdast-util-toc": "^7.1.0", "mdsvex": "^0.12.6", "prettier": "^3.6.2", @@ -27,7 +30,6 @@ "remark-directive": "^4.0.0", "remark-frontmatter": "^5.0.0", "remark-gfm": "^4.0.1", - "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-stringify": "^11.0.0", "remark-toc": "^9.0.0", diff --git a/site/package.json b/site/package.json index a3659425b..011b2b15f 100644 --- a/site/package.json +++ b/site/package.json @@ -20,8 +20,11 @@ "@sveltejs/adapter-static": "^3.0.10", "@sveltejs/kit": "^2.43.2", "@sveltejs/vite-plugin-svelte": "^6.2.0", + "hast-util-to-html": "^9.0.5", "hastscript": "^9.0.1", "mdast": "^2.3.2", + "mdast-util-from-markdown": "^2.0.2", + "mdast-util-to-hast": "^13.2.0", "mdast-util-toc": "^7.1.0", "mdsvex": "^0.12.6", "prettier": "^3.6.2", @@ -33,7 +36,6 @@ "remark-directive": "^4.0.0", "remark-frontmatter": "^5.0.0", "remark-gfm": "^4.0.1", - "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-stringify": "^11.0.0", "remark-toc": "^9.0.0", diff --git a/site/vitePlugins/markdown.ts b/site/vitePlugins/markdown.ts index bc2573a8f..a8f5148e5 100644 --- a/site/vitePlugins/markdown.ts +++ b/site/vitePlugins/markdown.ts @@ -1,7 +1,9 @@ import { matter } from "vfile-matter"; -import { unified } from "unified"; +import { unified, type Processor } from "unified"; import { VFile } from "vfile"; -import remarkParse from "remark-parse"; +import { fromMarkdown } from "mdast-util-from-markdown"; +import { toHast } from "mdast-util-to-hast"; +import { toHtml } from "hast-util-to-html"; import remarkRehype from "remark-rehype"; import rehypeStringify from "rehype-stringify"; import rehypeShiki from "@shikijs/rehype"; @@ -28,11 +30,9 @@ export default function (): PluginOption { async transform(code, id) { if (id.slice(-3) !== ".md") return; - // TODO: move VFile into unified - const file = new VFile(code); - matter(file, { strip: true }); - const html = await unified() + const file = await unified() .use(remarkParse) + .use(remarkToc) .use(link_migration) .use(remarkGfm) .use(remarkDirective) @@ -55,26 +55,38 @@ export default function (): PluginOption { .use(rehypeStringify) .use(rehypeSlug) .use(rehypeAutolinkHeadings) - .process(String(file)); - - const parsed = await unified() - .use(remarkParse) - .use(() => (tree) => { - const result = toc(tree as Nodes); - return result.map; - }) - .use(remarkRehype) - .use(rehypeStringify) - .process(String(file)); + .process(code); return ` -export const content = ${JSON.stringify(String(html))}; +export const content = ${JSON.stringify(String(file))}; export const frontmatter = ${JSON.stringify(file.data.matter)}; -export const toc = ${JSON.stringify(String(parsed))};`; +export const toc = ${JSON.stringify(file.data.toc)};`; }, }; } +function remarkParse(this: Processor) { + this.parser = (document, file) => { + matter(file, { strip: true }); + return fromMarkdown(String(file)); + }; +} +function remarkToc() { + return (tree: Nodes, file: VFile) => { + const { map } = toc(tree); + if (!map) { + file.data.toc = ""; + return; + } + // Remove the extranuous p element in each toc entry + map.spread = false; + map.children.forEach((child) => { + child.spread = false; + }); + file.data.toc = toHtml(toHast(map)); + }; +} + // Needed according to: // https://github.com/remarkjs/remark-directive function styleDirectives() {