使用 Remark.js 自定义渲染 MD
Warning本文发布于 2024/03/14,内容可能已过时。
Astro.js yes
迁移到 Astro 的原因之一是,尽管 vuepress 有许多插件可以扩展 Markdown 的功能,但自定义程度仍然太低。虽然也可以编写相应的插件,但既然选择了 Astro 并手动编写主题样式,那也少不了自定义解析 Markdown。
Astro.js 使用 remark.js 进行 Markdown 解析并转换为 HTML,然后使用 remark-rehype 修改编译后的 HTML,在配置文件中体现在 [config:markdown.remarkPlugins] 中。
本次打算实现以下内容:
- 为外部链接添加对应网站图标,类似前面几个链接;
- 统一图片格式,将
![alt](src)
的 Markdown 语法转换为用<figcaption>
包裹的 img 标签,并将 alt 属性作为图片注释; - 对图片设置懒加载:将所有 src 替换为占位符,在滚动到视图时再替换回原始 src;
- 解决引用本地文件和在 Astro 构建时表现不一致的问题;
- 计算大约阅读时间和字数。
所有源码实现可见于 plugins。
注意的点
图标方案使用 Unocss 提供的图标库,在匹配到对应 hostname 后会添加相应的 <i class={icon-class}/>
。由于这是动态生成的内容,在构建时 Unocss 不会输出相关图标 CSS。
需要预先准备好一个包含图标信息的数组,并将其添加到 unocss safelist 中。(同时要注意在导入至 unocss.config.ts
时,在配置阶段不能导入与 Astro 相关无关包,需要单独处理:constant/hostIcons.ts)。
此外,在 remark 阶段似乎没有直接访问 Astro 上下文信息。因此无法使用任何 Astro 函数;但可以导入类型。