Files
argon-theme/.kiro/steering/mermaid-fix-2026-01-27.md

9.2 KiB
Raw Blame History

Mermaid 渲染问题修复

修复时间

2026-01-27

问题描述

用户报告了以下 Mermaid 相关问题:

  1. 代码块转换功能被禁用convertMermaidCodeblocks() 函数第一行有 return;,导致 ```mermaid 代码块无法转换
  2. 检测选择器不完整detectMermaidBlocks() 只检测 div.mermaid-shortcode,缺少其他格式的检测
  3. 首页预览显示原始代码:点击首页文章预览时,显示无格式化的纯文字 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.php
  • template-parts/content-preview-1.php
  • template-parts/content-preview-2.php
  • template-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>

优势

  • 直接渲染
  • 兼容性好

测试验证

测试场景 1Shortcode 格式

测试步骤

  1. 创建新文章
  2. 使用 [mermaid]...[/mermaid] 格式插入图表
  3. 发布文章
  4. 查看文章页面
  5. 查看首页预览

预期结果

  • 文章页面正确渲染 Mermaid 图表
  • 首页预览显示 [Mermaid 图表] 占位符

测试场景 2Markdown 代码块格式

测试步骤

  1. 创建新文章
  2. 使用 ```mermaid 格式插入图表
  3. 发布文章
  4. 查看文章页面

预期结果

  • 代码块被转换为 <div class="mermaid-from-codeblock">
  • 图表正确渲染
  • 不显示代码高亮的行号和复制按钮

测试场景 3PJAX 切换

测试步骤

  1. 在首页点击文章链接PJAX 加载)
  2. 查看 Mermaid 图表是否渲染
  3. 返回首页PJAX 加载)
  4. 再次点击文章

预期结果

  • 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: 因为:

  1. 预览内容会被 wp_trim_words() 截断,可能破坏图表代码
  2. 在列表页渲染大量图表会影响性能
  3. 使用占位符更简洁明了

Q4: 如何添加新的 Mermaid 格式支持?

A: 在 detectMermaidBlocks()selectors 数组中添加新的选择器,并在 extractMermaidCode() 中添加对应的提取逻辑。

总结

本次修复解决了 Mermaid 渲染的三个主要问题:

  1. 启用代码块转换:移除了阻止转换的 return; 语句
  2. 完善检测机制:添加了完整的选择器列表,支持多种格式
  3. 修复预览显示:在预览中用占位符替代原始代码

用户现在可以:

  • 使用 [mermaid]...[/mermaid] shortcode 格式(推荐)
  • 使用 ```mermaid Markdown 代码块格式
  • 在首页预览中看到友好的占位符而不是原始代码
  • 享受完整的 Mermaid 图表渲染功能

所有修改都遵循了 Argon 主题的代码规范,并保持了向后兼容性。