387 字
2 分钟
Halo 代码块支持
背景
在其他博客平台(如 Halo)使用 tips:xxx 语法编写提示块,复制到 Astro 博客时需要手动改格式。为了实现跨平台无缝迁移,决定在 Astro 博客中添加 ```halo 代码块支持。
实现方案
1. 添加 Rehype 插件
创建 src/plugins/rehype-halo-code-block.mjs:
import {visit} from 'unist-util-visit';import { h } from 'hastscript';
const TIPS_TO_ADMONITION = { 'info': 'note', 'warn': 'warning', 'danger': 'caution', 'success': 'tip', 'tip': 'tip', 'note': 'note', 'important': 'important',};
export function rehypeHaloCodeBlock() { return (tree) => { const toReplace = [];
visit(tree, (node, index, parent) => { if (node.tagName !== 'pre') return; if (!node.children || !node.children[0]) return; const codeEl = node.children[0]; if (codeEl.tagName !== 'code') return; if (codeEl.properties?.className?.[0] !== 'language-halo') return;
const textContent = codeEl.children?.[0]?.value || ''; const lines = textContent.trim().split('\n'); if (lines.length === 0) return;
const firstLine = lines[0]; if (!firstLine.startsWith('tips:')) return;
const tipsType = firstLine.replace('tips:', '').trim(); const admonitionType = TIPS_TO_ADMONITION[tipsType] || 'note'; const body = lines.slice(1).join('\n').trim();
const title = admonitionType.toUpperCase(); const admonitionEl = h(`blockquote.admonition.bdm-${admonitionType}`, [ h('span.bdm-title', title), h('div', body.split('\n').map(line => h('p', line))) ]);
if (parent && typeof index === 'number') { toReplace.push({ parent, index, newNode: admonitionEl }); } });
for (const { parent, index, newNode } of toReplace) { parent.children.splice(index, 1, newNode); } };}2. 配置 Astro
在 astro.config.mjs 中:
- 引入插件
- 配置 expressive-code 忽略
halo语言 - 添加 rehype 插件
import { rehypeHaloCodeBlock } from "./src/plugins/rehype-halo-code-block.mjs";
// expressive-code 配置中添加ignoreLang: ["halo"],
// rehypePlugins 中添加rehypeHaloCodeBlock,3. 修复样式冲突
src/styles/markdown.css 中原有一规则会让所有 blockquote 显示灰色左边条,需要排除 admonition:
/* 原来 */blockquote { ... }
/* 修改后 */blockquote:not(.admonition) { ... }使用方式
NOTE这是一条信息提示
TIP这是一条提示
TIP这是一条成功提示
WARNING这是一条警告
CAUTION这是一条危险警告
映射规则
| tips 语法 | admonition 类型 |
|---|---|
tips:info | note |
tips:success | tip |
tips:warn | warning |
tips:danger | caution |
tips:tip | tip |
tips:note | note |
tips:important | important |
文件变更
- 新增:
src/plugins/rehype-halo-code-block.mjs - 修改:
astro.config.mjs - 修改:
src/styles/markdown.css