mirror of
https://github.com/versia-pub/docs.git
synced 2026-03-13 02:49:16 +01:00
feat: ✨ Initialize rewrite
This commit is contained in:
parent
47ce9bd9f8
commit
f39d34b769
143 changed files with 7257 additions and 4032 deletions
129
mdx/rehype.mjs
Normal file
129
mdx/rehype.mjs
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
import { slugifyWithCounter } from "@sindresorhus/slugify";
|
||||
import * as acorn from "acorn";
|
||||
import { toString as mdastToString } from "mdast-util-to-string";
|
||||
import { mdxAnnotations } from "mdx-annotations";
|
||||
import shiki from "shiki";
|
||||
import { visit } from "unist-util-visit";
|
||||
|
||||
function rehypeParseCodeBlocks() {
|
||||
return (tree) => {
|
||||
// biome-ignore lint/style/useNamingConvention: <explanation>
|
||||
visit(tree, "element", (node, _, parentNode) => {
|
||||
if (node.tagName === "code" && node.properties.className) {
|
||||
parentNode.properties.language =
|
||||
node.properties.className[0]?.replace(/^language-/, "");
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
let highlighter;
|
||||
|
||||
function rehypeShiki() {
|
||||
return async (tree) => {
|
||||
highlighter =
|
||||
highlighter ??
|
||||
(await shiki.getHighlighter({ theme: "css-variables" }));
|
||||
|
||||
visit(tree, "element", (node) => {
|
||||
if (
|
||||
node.tagName === "pre" &&
|
||||
node.children[0]?.tagName === "code"
|
||||
) {
|
||||
const codeNode = node.children[0];
|
||||
const textNode = codeNode.children[0];
|
||||
|
||||
node.properties.code = textNode.value;
|
||||
|
||||
if (node.properties.language) {
|
||||
const tokens = highlighter.codeToThemedTokens(
|
||||
textNode.value,
|
||||
node.properties.language,
|
||||
);
|
||||
|
||||
textNode.value = shiki.renderToHtml(tokens, {
|
||||
elements: {
|
||||
pre: ({ children }) => children,
|
||||
code: ({ children }) => children,
|
||||
line: ({ children }) => `<span>${children}</span>`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function rehypeSlugify() {
|
||||
return (tree) => {
|
||||
const slugify = slugifyWithCounter();
|
||||
visit(tree, "element", (node) => {
|
||||
if (node.tagName === "h2" && !node.properties.id) {
|
||||
node.properties.id = slugify(mdastToString(node));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function rehypeAddMDXExports(getExports) {
|
||||
return (tree) => {
|
||||
const exports = Object.entries(getExports(tree));
|
||||
|
||||
for (const [name, value] of exports) {
|
||||
for (const node of tree.children) {
|
||||
if (
|
||||
node.type === "mdxjsEsm" &&
|
||||
new RegExp(`export\\s+const\\s+${name}\\s*=`).test(
|
||||
node.value,
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const exportStr = `export const ${name} = ${value}`;
|
||||
|
||||
tree.children.push({
|
||||
type: "mdxjsEsm",
|
||||
value: exportStr,
|
||||
data: {
|
||||
estree: acorn.parse(exportStr, {
|
||||
sourceType: "module",
|
||||
ecmaVersion: "latest",
|
||||
}),
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getSections(node) {
|
||||
const sections = [];
|
||||
|
||||
for (const child of node.children ?? []) {
|
||||
if (child.type === "element" && child.tagName === "h2") {
|
||||
sections.push(`{
|
||||
title: ${JSON.stringify(mdastToString(child))},
|
||||
id: ${JSON.stringify(child.properties.id)},
|
||||
...${child.properties.annotation}
|
||||
}`);
|
||||
} else if (child.children) {
|
||||
sections.push(...getSections(child));
|
||||
}
|
||||
}
|
||||
|
||||
return sections;
|
||||
}
|
||||
|
||||
export const rehypePlugins = [
|
||||
mdxAnnotations.rehype,
|
||||
rehypeParseCodeBlocks,
|
||||
rehypeShiki,
|
||||
rehypeSlugify,
|
||||
[
|
||||
rehypeAddMDXExports,
|
||||
(tree) => ({
|
||||
sections: `[${getSections(tree).join()}]`,
|
||||
}),
|
||||
],
|
||||
];
|
||||
Loading…
Add table
Add a link
Reference in a new issue