import { visit } from 'unist-util-visit'; import type { Plugin } from 'unified'; import type { Text, Root } from 'hast'; import { fromHtml } from 'hast-util-from-html'; import shiki from 'shiki'; interface Options { highlighter: shiki.Highlighter; } export const rehypePluginShiki: Plugin<[Options], Root> = ({ highlighter }) => { return (tree) => { visit(tree, 'element', (node, index, parent) => { //
...
if (
node.tagName === 'pre' &&
node.children[0]?.type === 'element' &&
node.children[0].tagName === 'code'
) {
const codeNode = node.children[0];
// console.log(codeNode);
const codeContent = (codeNode.children[0] as Text).value;
const codeClassName = codeNode.properties?.className?.toString() || '';
const lang = codeClassName.split('-')[1];
if (!lang) {
return;
}
const highlightedCode = highlighter.codeToHtml(codeContent, {
lang,
theme: 'material-theme-palenight'
});
const fragmentAst = fromHtml(highlightedCode, { fragment: true });
parent.children.splice(index, 1, ...fragmentAst.children);
}
});
};
};