import type { Plugin } from 'unified'; import { visit } from 'unist-util-visit'; import type { Element, Root, ElementData } from 'hast'; interface ExtendElementData extends ElementData { isVisited?: boolean; } export const rehypePluginPreWrapper: Plugin<[], Root> = () => { return (tree) => { visit(tree, 'element', (node) => { //
...
// 1. 找到 pre 元素 if ( node.tagName === 'pre' && node.children[0]?.type === 'element' && node.children[0].tagName === 'code' && (node.data as ExtendElementData)?.isVisited !== true ) { // console.log(node.tagName); const codeNode = node.children[0]; const codeClassName = codeNode.properties?.className?.toString() || ''; // language-xxx const lang = codeClassName.split('-')[1]; // codeNode.properties.className = ''; const clonedNode: Element = { type: 'element', tagName: 'pre', children: node.children, properties: null, data: { isVisited: true } as ExtendElementData }; // 修改原来的 pre 标签 -> div 标签 node.tagName = 'div'; node.properties = node.properties || {}; node.properties.className = codeClassName; node.children = [ { type: 'element', tagName: 'button', properties: { className: 'copy-code' }, children: [ { type: 'text', value: '' } ] }, { type: 'element', tagName: 'span', properties: { className: 'lang' }, children: [ { type: 'text', value: lang } ] }, clonedNode ]; } }); }; };