在 remark transformer 函数中,修改 file.value(raw Markdown 字符串)不会影响输出,因为 AST 已在 parser 阶段建立完毕。
原因
unified 的处理流水线分三个阶段:
parse(raw text → AST)→ transform(AST 操作)→ stringify(AST → 输出)
transformer 函数在 transform 阶段运行,此时 AST 已经从 file.value 解析完成。修改 file.value 不会触发重新解析,stringify 阶段直接从 AST 生成输出,file.value 的改动完全被忽略。
错误示例
// ❌ 这是 no-op:transformer 阶段修改 file.value 无效
export function remarkObsidianComments() {
return (tree: any, file: any) => {
// 这行不会影响任何输出
file.value = file.value.replace(/%%[\s\S]*?%%/g, "");
// 需要操作 AST,而不是 raw text
};
}
正确做法
在 transformer 中直接操作 AST 节点:
// ✅ 操作 AST text 节点
import { visit } from "unist-util-visit";
export function remarkObsidianComments() {
return (tree: any) => {
visit(tree, "text", (node: any) => {
node.value = node.value.replace(/%%[\s\S]*?%%/g, "");
});
// 清除变为空的 paragraph 节点
visit(tree, "paragraph", (node: any, index, parent) => {
if (!parent || index == null) return;
const hasContent = node.children.some(
(c: any) => c.type !== "text" || c.value.trim() !== ""
);
if (!hasContent) { parent.children.splice(index, 1); return index; }
});
};
}
参见
- astro-content-layer-remark-only
参考
- HAT-217 实现
remarkObsidianComments插件时发现,code quality review 指出并修正