9.2 KiB
Mermaid 渲染问题修复
修复时间
2026-01-27
问题描述
用户报告了以下 Mermaid 相关问题:
- 代码块转换功能被禁用:
convertMermaidCodeblocks()函数第一行有return;,导致 ```mermaid 代码块无法转换 - 检测选择器不完整:
detectMermaidBlocks()只检测div.mermaid-shortcode,缺少其他格式的检测 - 首页预览显示原始代码:点击首页文章预览时,显示无格式化的纯文字 Mermaid 代码
根本原因
1. 代码块转换被禁用
在 argontheme.js 第 4345 行,convertMermaidCodeblocks() 函数开头有一个 return; 语句,导致整个函数被跳过:
function convertMermaidCodeblocks(){
return; // ← 这行导致函数直接返回
// ... 后面的代码都不会执行
}
2. 检测选择器不完整
在 MermaidRenderer.detectMermaidBlocks() 中,选择器数组只包含一个元素:
const selectors = [
'div.mermaid-shortcode' // 只检测 shortcode 格式
];
缺少对以下格式的检测:
div.mermaid-from-codeblock- 代码块魔改格式div.mermaid- 标准格式pre code.language-mermaid- Markdown 格式pre[data-lang="mermaid"]- 自定义属性格式code.mermaid- 简化格式
3. 首页预览问题
在三个文章预览模板中,使用 wp_trim_words() 直接处理包含 [mermaid]...[/mermaid] shortcode 的内容:
$preview = wp_trim_words(get_the_content('...'), $trim_words_count);
wp_trim_words() 会破坏 shortcode 结构,导致显示原始的 Mermaid 代码文本。
修复方案
1. 启用代码块转换功能
文件:argontheme.js
修改:移除 convertMermaidCodeblocks() 函数开头的 return; 语句
// 修改前
function convertMermaidCodeblocks(){
return;
// ...
}
// 修改后
function convertMermaidCodeblocks(){
// 支持多种代码块格式
// ...
}
效果:
- ✅ ```mermaid 代码块可以正常转换为
<div class="mermaid-from-codeblock"> - ✅ 避免代码高亮干扰 Mermaid 渲染
- ✅ 支持标准 Markdown 格式
2. 添加完整的检测选择器
文件:argontheme.js
修改:在 detectMermaidBlocks() 中添加完整的选择器列表
// 修改前
const selectors = [
'div.mermaid-shortcode'
];
// 修改后
const selectors = [
'div.mermaid-shortcode', // Shortcode 格式(推荐)
'div.mermaid-from-codeblock', // 代码块魔改格式
'div.mermaid', // 标准格式
'pre code.language-mermaid', // Markdown 格式(降级)
'pre[data-lang="mermaid"]', // 自定义属性格式
'code.mermaid' // 简化格式
];
效果:
- ✅ 支持多种 Mermaid 代码块格式
- ✅ 兼容不同的编辑器和插件
- ✅ 提供降级支持
3. 修复首页预览问题
文件:
functions.phptemplate-parts/content-preview-1.phptemplate-parts/content-preview-2.phptemplate-parts/content-preview-3.php
修改 1:在 functions.php 中添加辅助函数
/**
* 从内容中移除 Mermaid shortcode,用于文章预览
* 避免在预览中显示原始 Mermaid 代码
*
* @param string $content 文章内容
* @return string 移除 Mermaid shortcode 后的内容
*/
function argon_remove_mermaid_from_preview($content) {
// 移除 [mermaid]...[/mermaid] shortcode
$content = preg_replace('/\[mermaid[^\]]*\].*?\[\/mermaid\]/is', '[Mermaid 图表]', $content);
return $content;
}
修改 2:在三个预览模板中使用辅助函数
// 修改前
if (get_option("argon_hide_shortcode_in_preview") == 'true'){
$preview = wp_trim_words(do_shortcode(get_the_content('...')), $trim_words_count);
}else{
$preview = wp_trim_words(get_the_content('...'), $trim_words_count);
}
// 修改后
$content_for_preview = get_the_content('...');
// 移除 Mermaid shortcode,避免在预览中显示原始代码
$content_for_preview = argon_remove_mermaid_from_preview($content_for_preview);
if (get_option("argon_hide_shortcode_in_preview") == 'true'){
$preview = wp_trim_words(do_shortcode($content_for_preview), $trim_words_count);
}else{
$preview = wp_trim_words($content_for_preview, $trim_words_count);
}
效果:
- ✅ 首页预览中不再显示原始 Mermaid 代码
- ✅ 用
[Mermaid 图表]占位符替代 - ✅ 保持预览内容的可读性
技术细节
代码块转换流程
页面加载/PJAX切换
↓
highlightJsRender() 调用
↓
convertMermaidCodeblocks() 执行 ← 【拦截阶段】
↓
查找 <pre><code class="language-mermaid">
↓
提取纯文本代码
↓
创建 <div class="mermaid-from-codeblock">
↓
替换原始代码块
↓
代码高亮处理其他代码块
↓
MermaidRenderer.detectMermaidBlocks() ← 【检测阶段】
↓
MermaidRenderer.renderChart() ← 【渲染阶段】
支持的 Mermaid 格式
1. Shortcode 格式(推荐)
[mermaid]
flowchart TD
A --> B
[/mermaid]
优势:
- 最稳定的方式
- 不受代码高亮影响
- 支持参数配置
2. Markdown 代码块格式
```mermaid
flowchart TD
A --> B
```
优势:
- 标准 Markdown 语法
- 编辑器支持好
- 可以拉起代码高亮
注意:需要代码块转换功能支持
3. HTML 容器格式
<div class="mermaid">
flowchart TD
A --> B
</div>
优势:
- 直接渲染
- 兼容性好
测试验证
测试场景 1:Shortcode 格式
测试步骤:
- 创建新文章
- 使用
[mermaid]...[/mermaid]格式插入图表 - 发布文章
- 查看文章页面
- 查看首页预览
预期结果:
- ✅ 文章页面正确渲染 Mermaid 图表
- ✅ 首页预览显示
[Mermaid 图表]占位符
测试场景 2:Markdown 代码块格式
测试步骤:
- 创建新文章
- 使用
```mermaid格式插入图表 - 发布文章
- 查看文章页面
预期结果:
- ✅ 代码块被转换为
<div class="mermaid-from-codeblock"> - ✅ 图表正确渲染
- ✅ 不显示代码高亮的行号和复制按钮
测试场景 3:PJAX 切换
测试步骤:
- 在首页点击文章链接(PJAX 加载)
- 查看 Mermaid 图表是否渲染
- 返回首页(PJAX 加载)
- 再次点击文章
预期结果:
- ✅ PJAX 切换后图表正常渲染
- ✅ 不会重复渲染
- ✅ 主题切换正常工作
相关文件
修改的文件
argontheme.js- 启用代码块转换,添加完整选择器functions.php- 添加argon_remove_mermaid_from_preview()函数template-parts/content-preview-1.php- 修复预览显示template-parts/content-preview-2.php- 修复预览显示template-parts/content-preview-3.php- 修复预览显示
相关文档
docs/mermaid-user-guide.md- 用户使用指南docs/mermaid-developer-guide.md- 开发者文档docs/mermaid-troubleshooting.md- 故障排查指南
Git 提交
git commit -m "fix: 修复 Mermaid 渲染问题
- 启用代码块转换功能(移除 convertMermaidCodeblocks 中的 return 语句)
- 添加完整的 Mermaid 代码块检测选择器
- 修复首页预览中显示原始 Mermaid 代码的问题
- 添加 argon_remove_mermaid_from_preview 函数过滤预览内容
- 更新三个文章预览模板,在预览中用 [Mermaid 图表] 替代原始代码"
提交哈希:135c226
后续建议
1. 功能增强
- 添加预览中的 Mermaid 图表缩略图
- 支持更多 Mermaid 图表类型
- 添加图表导出功能
2. 性能优化
- 延迟加载 Mermaid 库
- 缓存渲染结果
- 优化大型图表的渲染
3. 用户体验
- 添加图表编辑器
- 提供图表模板
- 改进错误提示
常见问题
Q1: 为什么代码块转换被禁用了?
A: 可能是在之前的某次修复中,为了临时解决某个问题而添加了 return; 语句,但忘记移除。
Q2: 如何确保 PJAX 兼容性?
A: 代码块转换在 highlightJsRender() 中调用,该函数已在 PJAX 回调中注册,因此自动支持 PJAX。
Q3: 为什么不在预览中渲染 Mermaid 图表?
A: 因为:
- 预览内容会被
wp_trim_words()截断,可能破坏图表代码 - 在列表页渲染大量图表会影响性能
- 使用占位符更简洁明了
Q4: 如何添加新的 Mermaid 格式支持?
A: 在 detectMermaidBlocks() 的 selectors 数组中添加新的选择器,并在 extractMermaidCode() 中添加对应的提取逻辑。
总结
本次修复解决了 Mermaid 渲染的三个主要问题:
- ✅ 启用代码块转换:移除了阻止转换的
return;语句 - ✅ 完善检测机制:添加了完整的选择器列表,支持多种格式
- ✅ 修复预览显示:在预览中用占位符替代原始代码
用户现在可以:
- 使用
[mermaid]...[/mermaid]shortcode 格式(推荐) - 使用
```mermaidMarkdown 代码块格式 - 在首页预览中看到友好的占位符而不是原始代码
- 享受完整的 Mermaid 图表渲染功能
所有修改都遵循了 Argon 主题的代码规范,并保持了向后兼容性。