前言
在前两个小节中,我分别介绍了mdx的实时编译与预编译的案例及用法,这一小节就来具体讲讲如何实现代码高亮、以及如何生成 toc 目录等功能。
其实说到这里,那就不得不提一下 unified 大家族了,可以说它提供的功能是非常全的了,它能够处理 Markdown、HTML、自然语言等,提供了非常多的插件,其提供的插件生态主要包含如下:
虽然有这么多插件,但是我们平时常用的就两个 remark 和 rehype,我们以react-markdown 解析编译 markdown 文件为例来看看它们俩分别在什么时候发生作用的。
有了上面知识的铺垫,对于后面我们要实现的功能相信你能更好的理解,接着我们就来完成我们上面说的两个功能。
如何生成toc目录(remark)
export const compileMDX = async (source: any) => {
const toc: Toc = [];
const { code, frontmatter } = await bundleMDX({
source,
cwd: path.join(root, 'components'),
mdxOptions(options, frontmatter) {
options.remarkPlugins = [
...(options.remarkPlugins ?? []),
remarkGfm,
remarkFrontmatter,
[remarkTocHeadings, { exportRef: toc }],
];
options.rehypePlugins = [
...(options.rehypePlugins ?? []),
rehypeSlug,
rehypeExternalLinks,
rehypeAutolinkHeadings,
[rehypePrismPlus, { ignoreMissing: true }],
];
return options;
},
esbuildOptions: (options) => {
options.loader = {
...options.loader,
'.js': 'jsx',
};
return options;
},
});
return {
mdxSource: code,
toc,
frontMatter: frontmatter,
};
};
上面的代码在前面的章节也提到过,不过这里要注意代码中的 remarkPlugins 中的 [remarkTocHeadings, { exportRef: toc }],它是实现生成toc目录的关键,以下是 remarkTocHeadings 的代码
import { Parent } from 'unist';
import { visit } from 'unist-util-visit';
import { slug } from 'github-slugger';
import { toString } from 'mdast-util-to-string';
export default function remarkTocHeadings(options: any) {
return (tree: Parent) =>
visit(tree, 'heading', (node: any) => {
const textContent = toString(node);
options.exportRef.push({
text: textContent,
url: '#' + slug(textContent),
depth: node.depth,
});
});
}
如何实现代码高亮(rehype)
还是上面的第一段代码,我就不重复粘贴了,这里要注意的是 rehypePlugins 中的 [rehypePrismPlus, { ignoreMissing: true }],它是实现代码高亮的关键,当然该插件也支持我们自定义代码高亮的颜色,以下为代码片段
.token.tag,
.token.operator,
.token.keyword {
color: rgb(127, 219, 202);
}
.token.boolean {
color: rgb(255, 88, 116);
}
.token.number {
color: rgb(247, 140, 108);
}
.token.constant,
.token.function,
.token.builtin,
.token.char {
color: rgb(130, 170, 255);
}
最后
- 欢迎访问我的个人网站:openbytecode.com/
- 本周四(23/06/22)我会在 b 站直播手把手教你搭建 chatgpt,欢迎围观,space.bilibili.com/383654866