feat(markdown): 添加GitHub风格警告支持

实现GitHub风格警告块([!NOTE], [!TIP]等)到标准容器指令的转换
更新astro配置使用自定义插件
This commit is contained in:
二叉树树
2026-01-09 19:39:17 +08:00
parent cd0baf41ed
commit 0a59253074
2 changed files with 50 additions and 2 deletions

View File

@@ -14,7 +14,7 @@ import rehypeExternalLinks from "rehype-external-links";
import rehypeKatex from "rehype-katex";
import rehypeSlug from "rehype-slug";
import remarkDirective from "remark-directive"; /* Handle directives */
import remarkGithubAdmonitionsToDirectives from "remark-github-admonitions-to-directives";
import { remarkGithubAdmonitions } from "./src/plugins/remark-github-admonitions.js";
import remarkMath from "remark-math";
import remarkSectionize from "remark-sectionize";
import { imageFallbackConfig, siteConfig } from "./src/config.ts";
@@ -122,7 +122,7 @@ export default defineConfig({
remarkMath,
remarkReadingTime,
remarkExcerpt,
remarkGithubAdmonitionsToDirectives,
remarkGithubAdmonitions,
remarkDirective,
remarkSectionize,
parseDirectiveNode,

View File

@@ -0,0 +1,48 @@
import { visit } from 'unist-util-visit';
export function remarkGithubAdmonitions() {
return (tree) => {
visit(tree, 'blockquote', (node, index, parent) => {
const children = node.children;
if (!children || children.length === 0) return;
const firstChild = children[0];
if (firstChild.type !== 'paragraph') return;
const firstTextNode = firstChild.children[0];
if (!firstTextNode || firstTextNode.type !== 'text') return;
const text = firstTextNode.value;
// Match [!TYPE] at the start of the text, allowing for optional whitespace
const match = text.match(/^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]/i);
if (match) {
const type = match[1].toLowerCase();
// Remove the [!TYPE] text
let newFirstTextValue = text.slice(match[0].length);
// If there's a newline or space immediately after, trim it
if (newFirstTextValue.startsWith('\n') || newFirstTextValue.startsWith(' ')) {
newFirstTextValue = newFirstTextValue.slice(1);
}
// Update the text node
firstTextNode.value = newFirstTextValue;
// If the first paragraph becomes empty (just whitespace), remove it
if (newFirstTextValue.trim() === '' && firstChild.children.length === 1) {
node.children.shift();
}
// Transform the node to containerDirective
node.type = 'containerDirective';
node.name = type;
node.attributes = {};
// Ensure data exists
node.data = node.data || {};
}
});
};
}