feat: 实现 Mermaid 代码块魔改支持

- 添加 convertMermaidCodeblocks() 函数,在代码高亮前拦截 mermaid 代码块
- 支持标准 Markdown 代码块 (\\\mermaid) 渲染
- 更新 detectMermaidBlocks() 添加 mermaid-from-codeblock 选择器
- 更新 extractMermaidCode() 支持新容器类型
- 创建测试文件 test-codeblock-magic.html
- 更新用户文档、开发者文档和 FAQ
- 完全绕过代码高亮和 WordPress 格式化
- 支持 PJAX 页面切换
- 特殊字符和换行符正确保留
This commit is contained in:
2026-01-24 21:35:12 +08:00
parent e5e8a245be
commit 29bfd284e0
18 changed files with 5566 additions and 50 deletions

View File

@@ -0,0 +1,50 @@
# Mermaid 代码块魔改支持
## 概述
本 spec 旨在实现对标准 Markdown 代码块 ` ```mermaid ` 的支持,通过在代码高亮之前拦截并转换代码块,完全绕过 WordPress、WP-Markdown 插件和代码高亮的干扰。
## 核心思路
参考主题中数学公式的实现方式:
- **数学公式**:使用特殊分隔符(`$...$`),不会被 WordPress 和代码高亮干扰
- **Mermaid**:使用代码块(` ```mermaid `),需要在代码高亮前拦截并转换
## 实现方案
1. **代码块拦截**:在 `highlightJsRender()` 函数开始处添加预处理
2. **格式转换**:将 `<pre><code class="language-mermaid">` 转换为 `<div class="mermaid-from-codeblock">`
3. **渲染检测**:在 `detectMermaidBlocks()` 中添加新的选择器
4. **代码提取**:在 `extractMermaidCode()` 中支持新的容器类型
## 优势
- ✅ 使用标准 Markdown 语法
- ✅ 在编辑器中清晰可见
- ✅ 不被 WordPress 格式化干扰
- ✅ 不被代码高亮干扰
- ✅ 支持 PJAX 页面切换
- ✅ 兼容现有的 Shortcode 和容器语法
## 文件结构
```
.kiro/specs/mermaid-codeblock-magic/
├── README.md # 本文件
├── requirements.md # 详细需求文档
├── design.md # 设计文档(待创建)
└── tasks.md # 任务列表(待创建)
```
## 下一步
1. 审核 `requirements.md` 需求文档
2. 创建 `design.md` 设计文档
3. 创建 `tasks.md` 任务列表
4. 开始实现
## 参考
- 数学公式实现:`footer.php` 第 36-147 行
- 代码高亮实现:`argontheme.js` 第 3942-4000 行
- Mermaid 渲染实现:`argontheme.js` 第 4430-4750 行

View File

@@ -0,0 +1,821 @@
# Mermaid 代码块魔改支持 - 设计文档
## 1. 设计概述
### 1.1 设计目标
实现标准 Markdown 代码块 (` ```mermaid `) 的 Mermaid 图表渲染,通过在代码高亮之前拦截并转换代码块,完全绕过 WordPress 和代码高亮的干扰。
### 1.2 核心设计理念
**提前拦截,转换容器**:在代码高亮处理之前,将 `<pre><code class="language-mermaid">` 转换为 `<div class="mermaid-from-codeblock">`,使其不被代码高亮处理,同时能被 Mermaid 渲染系统识别。
### 1.3 设计参考
参考主题中数学公式的实现方式:
- 数学公式使用特殊分隔符(`$...$`),不会被代码高亮处理
- Mermaid 代码块通过提前转换,达到类似效果
- 两者都在 PJAX 加载后重新处理
### 1.4 技术栈
- **JavaScript**:原生 JavaScript + jQuery主题现有技术栈
- **Mermaid.js**:主题已集成的图表渲染库
- **执行时机**:代码高亮之前(`highlightJsRender()` 函数开始处)
## 2. 架构设计
### 2.1 整体流程
```mermaid
flowchart TD
A[页面加载/PJAX切换] --> B[highlightJsRender 调用]
B --> C[convertMermaidCodeblocks 执行]
C --> D[查找 mermaid 代码块]
D --> E{找到代码块?}
E -->|是| F[提取纯文本代码]
E -->|否| G[继续代码高亮]
F --> H[创建 mermaid-from-codeblock 容器]
H --> I[替换原始代码块]
I --> J[标记已处理]
J --> G
G --> K[代码高亮处理其他代码块]
K --> L[detectMermaidBlocks 检测]
L --> M[提取 Mermaid 代码]
M --> N[mermaid.init 渲染]
```
### 2.2 模块设计
#### 模块 1代码块转换器 (convertMermaidCodeblocks)
**职责**:在代码高亮前拦截并转换 mermaid 代码块
**输入**DOM 树(包含未处理的代码块)
**输出**:转换后的 DOM 树mermaid 代码块已替换为容器)
**核心逻辑**
1. 使用多个选择器查找代码块
2. 提取纯文本代码
3. 创建新容器
4. 替换原始元素
#### 模块 2代码提取器 (extractMermaidCode)
**职责**:从不同格式的容器中提取 Mermaid 代码
**输入**DOM 元素(可能是 div、pre、code
**输出**:纯文本 Mermaid 代码
**支持格式**
- `<div class="mermaid-from-codeblock">`(新增)
- `<div class="mermaid-shortcode">`
- `<div class="mermaid">`
- `<pre><code class="language-mermaid">`(降级)
#### 模块 3Mermaid 检测器 (detectMermaidBlocks)
**职责**:检测页面中所有需要渲染的 Mermaid 容器
**输入**DOM 树
**输出**:需要渲染的元素列表
**检测优先级**
1. `div.mermaid-shortcode`Shortcode 格式)
2. `div.mermaid-from-codeblock`(代码块魔改格式)
3. `div.mermaid`(标准格式)
4. `pre code.language-mermaid`(降级格式)
### 2.3 数据流设计
```
原始 HTML:
<pre><code class="language-mermaid">
flowchart TD
A --> B
</code></pre>
↓ convertMermaidCodeblocks()
转换后 HTML:
<div class="mermaid-from-codeblock" data-processed="true">
flowchart TD
A --> B
</div>
↓ detectMermaidBlocks()
检测到的代码:
"flowchart TD\n A --> B"
↓ mermaid.init()
渲染后 HTML:
<div class="mermaid-from-codeblock" data-processed="true">
<svg>...</svg>
</div>
```
## 3. 详细设计
### 3.1 代码块转换函数
#### 函数签名
```javascript
function convertMermaidCodeblocks()
```
#### 实现位置
`argontheme.js` 第 3942 行之前(`highlightJsRender()` 函数开始处)
#### 选择器设计
```javascript
const selectors = [
'pre > code.language-mermaid', // 标准 Markdown 格式(最常见)
'pre > code.mermaid', // 简化格式
'code.language-mermaid', // 无 pre 包裹
'pre[data-lang="mermaid"]' // 自定义属性格式
];
```
**设计理由**
- 支持多种插件生成的 HTML 结构
- 优先匹配最常见的格式
- 提供降级支持
#### 重复处理防护
```javascript
if (element.dataset.mermaidProcessed) {
return; // 跳过已处理的元素
}
```
**设计理由**
- 避免 PJAX 切换时重复处理
- 防止多次调用导致的错误
- 使用 data 属性标记状态
#### 代码提取逻辑
```javascript
let code = element.textContent.trim();
```
**设计理由**
- `textContent` 获取纯文本,避免 HTML 实体
- `trim()` 移除前后空白
- 不进行任何字符转换,保持原始内容
#### 容器创建逻辑
```javascript
const container = document.createElement('div');
container.className = 'mermaid-from-codeblock';
container.textContent = code;
container.dataset.processed = 'true';
```
**设计理由**
- 使用 `textContent` 而非 `innerHTML`,避免 XSS
- 添加特定类名,便于识别来源
- 标记已处理状态
#### 元素替换逻辑
```javascript
const targetElement = element.closest('pre') || element;
targetElement.parentNode.replaceChild(container, targetElement);
```
**设计理由**
- 优先替换整个 `<pre>` 元素
- 如果没有 `<pre>` 包裹,替换 `<code>` 元素
- 保留原始位置和上下文
### 3.2 集成点设计
#### 集成点 1highlightJsRender() 函数
**位置**`argontheme.js` 第 3942 行
**修改前**
```javascript
function highlightJsRender(){
if (typeof(hljs) == "undefined"){
return;
}
// ... 代码高亮逻辑
}
```
**修改后**
```javascript
function highlightJsRender(){
// 在代码高亮之前,先处理 Mermaid 代码块
convertMermaidCodeblocks();
if (typeof(hljs) == "undefined"){
return;
}
// ... 代码高亮逻辑
}
```
**设计理由**
- 在代码高亮之前执行,确保 mermaid 代码块不被处理
- 不影响其他代码块的高亮
- 执行顺序:转换 → 高亮 → 渲染
#### 集成点 2detectMermaidBlocks() 函数
**位置**`argontheme.js` 第 4430 行
**修改前**
```javascript
const selectors = [
'div.mermaid-shortcode',
'div.mermaid',
'pre code.language-mermaid',
// ...
];
```
**修改后**
```javascript
const selectors = [
'div.mermaid-shortcode', // Shortcode 格式
'div.mermaid-from-codeblock', // 代码块魔改格式(新增)
'div.mermaid', // 标准格式
'pre code.language-mermaid', // Markdown 格式(降级)
'pre[data-lang="mermaid"]', // 自定义属性格式
'code.mermaid' // 简化格式
];
```
**设计理由**
- 添加新的容器类型到检测列表
- 优先级高于标准 `mermaid`
- 保留降级选择器,确保兼容性
#### 集成点 3extractMermaidCode() 函数
**位置**`argontheme.js` 第 4650 行
**修改前**
```javascript
// 处理 Shortcode 格式
if (element.classList.contains('mermaid-shortcode')) {
code = element.textContent;
this.logDebug('从 Shortcode 格式提取代码');
}
```
**修改后**
```javascript
// 处理 Shortcode 格式
if (element.classList.contains('mermaid-shortcode')) {
code = element.textContent;
this.logDebug('从 Shortcode 格式提取代码');
}
// 处理代码块魔改格式
else if (element.classList.contains('mermaid-from-codeblock')) {
code = element.textContent;
this.logDebug('从代码块魔改格式提取代码');
}
```
**设计理由**
- 与 Shortcode 格式使用相同的提取方式
- 添加调试日志,便于追踪
- 保持代码一致性
### 3.3 PJAX 兼容设计
#### 执行时机
PJAX 加载完成后的回调链(`argontheme.js` 第 2862-2890 行):
```javascript
$(document).on('pjax:complete', function() {
// ... 其他初始化
try { highlightJsRender(); } catch (err) { ... } // 包含代码块转换
// ... 其他初始化
});
```
**设计理由**
- `highlightJsRender()` 已在 PJAX 回调中调用
- 代码块转换自动在每次 PJAX 切换后执行
- 无需额外修改 PJAX 逻辑
#### 重复处理防护
使用 `data-processed` 属性标记已处理的元素:
```javascript
if (element.dataset.mermaidProcessed) {
return;
}
// ... 处理逻辑
element.dataset.mermaidProcessed = 'true';
```
**设计理由**
- 避免同一元素被多次转换
- 支持 PJAX 页面切换
- 轻量级标记,不影响性能
### 3.4 错误处理设计
#### 空代码检查
```javascript
let code = element.textContent.trim();
if (!code) {
return; // 跳过空代码块
}
```
**设计理由**
- 避免创建空容器
- 减少不必要的 DOM 操作
- 提高性能
#### Try-Catch 包裹
```javascript
try {
convertMermaidCodeblocks();
} catch (err) {
console.error('Mermaid 代码块转换失败:', err);
}
```
**设计理由**
- 捕获异常,不中断其他代码块的处理
- 记录错误日志,便于调试
- 提供降级方案(代码块仍可通过降级选择器检测)
#### 降级支持
如果代码块转换失败,仍可通过降级选择器检测:
```javascript
'pre code.language-mermaid' // 降级选择器
```
**设计理由**
- 确保即使转换失败,仍能渲染
- 提供多层保障
- 增强系统健壮性
## 4. 接口设计
### 4.1 公共函数
#### convertMermaidCodeblocks()
```javascript
/**
* 在代码高亮之前转换 Mermaid 代码块
* 将 <pre><code class="language-mermaid"> 转换为 <div class="mermaid-from-codeblock">
*
* @returns {void}
*/
function convertMermaidCodeblocks() {
// 实现逻辑
}
```
### 4.2 数据结构
#### 容器元素结构
```html
<div class="mermaid-from-codeblock" data-processed="true">
flowchart TD
A --> B
</div>
```
**属性说明**
- `class="mermaid-from-codeblock"`:标识来源于代码块
- `data-processed="true"`:标记已处理
- 内容:纯文本 Mermaid 代码
### 4.3 选择器优先级
| 优先级 | 选择器 | 用途 |
|--------|--------|------|
| 1 | `pre > code.language-mermaid` | 标准 Markdown 格式 |
| 2 | `pre > code.mermaid` | 简化格式 |
| 3 | `code.language-mermaid` | 无 pre 包裹 |
| 4 | `pre[data-lang="mermaid"]` | 自定义属性格式 |
## 5. 性能设计
### 5.1 性能目标
- 单个代码块处理时间 < 10ms
- 不影响页面加载速度
- 不增加额外的 HTTP 请求
### 5.2 性能优化策略
#### 优化 1使用原生 JavaScript
```javascript
document.querySelectorAll(selector) // 而非 $(selector)
```
**理由**:原生方法性能更好,减少 jQuery 开销
#### 优化 2提前返回
```javascript
if (element.dataset.mermaidProcessed) {
return; // 提前返回,避免不必要的处理
}
```
**理由**:减少重复处理,提高效率
#### 优化 3批量处理
```javascript
selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(element => {
// 处理逻辑
});
});
```
**理由**:一次性查找所有元素,减少 DOM 查询次数
#### 优化 4最小化 DOM 操作
```javascript
const container = document.createElement('div');
container.className = 'mermaid-from-codeblock';
container.textContent = code;
container.dataset.processed = 'true';
targetElement.parentNode.replaceChild(container, targetElement);
```
**理由**:一次性创建和替换,减少重排和重绘
### 5.3 性能监控
#### 调试日志
```javascript
this.logDebug('处理了 ' + count + ' 个 Mermaid 代码块');
this.logDebug('代码内容前100字符: ' + code.substring(0, 100));
```
**理由**:便于追踪性能问题,不影响生产环境
## 6. 安全设计
### 6.1 XSS 防护
#### 使用 textContent 而非 innerHTML
```javascript
container.textContent = code; // 安全
// container.innerHTML = code; // 不安全
```
**理由**`textContent` 会自动转义 HTML防止 XSS 攻击
#### 代码来源验证
```javascript
let code = element.textContent.trim();
if (!code) {
return; // 拒绝空代码
}
```
**理由**:避免处理恶意或无效的代码块
### 6.2 DOM 操作安全
#### 安全的元素替换
```javascript
const targetElement = element.closest('pre') || element;
if (targetElement.parentNode) {
targetElement.parentNode.replaceChild(container, targetElement);
}
```
**理由**:检查父节点存在,避免 null 引用错误
## 7. 测试设计
### 7.1 单元测试
#### 测试用例 1标准代码块转换
```javascript
// 输入
<pre><code class="language-mermaid">
flowchart TD
A --> B
</code></pre>
// 预期输出
<div class="mermaid-from-codeblock" data-processed="true">
flowchart TD
A --> B
</div>
```
#### 测试用例 2空代码块处理
```javascript
// 输入
<pre><code class="language-mermaid"></code></pre>
// 预期输出
<pre><code class="language-mermaid"></code></pre> //
```
#### 测试用例 3重复处理防护
```javascript
// 第一次处理
convertMermaidCodeblocks(); // 转换成功
// 第二次处理
convertMermaidCodeblocks(); // 跳过已处理的元素
```
#### 测试用例 4特殊字符保留
```javascript
// 输入
<pre><code class="language-mermaid">
A --> B
C -- text --> D
</code></pre>
// 预期输出
代码中的 --> -- 保持不变
```
### 7.2 集成测试
#### 测试场景 1与代码高亮集成
1. 页面包含 mermaid 代码块和其他代码块
2. 调用 `highlightJsRender()`
3. 验证 mermaid 代码块被转换,其他代码块被高亮
#### 测试场景 2与 Mermaid 渲染集成
1. 页面包含转换后的容器
2. 调用 `detectMermaidBlocks()`
3. 验证容器被检测到
4. 调用 `mermaid.init()`
5. 验证图表正确渲染
#### 测试场景 3PJAX 兼容性
1. 初始页面加载,代码块正确转换和渲染
2. PJAX 切换到新页面
3. 验证新页面的代码块正确转换和渲染
4. 验证已转换的代码块不被重复处理
### 7.3 浏览器测试
#### 测试矩阵
| 浏览器 | 版本 | 测试项 |
|--------|------|--------|
| Chrome | 最新版 | 全部功能 |
| Firefox | 最新版 | 全部功能 |
| Safari | 最新版 | 全部功能 |
| Edge | 最新版 | 全部功能 |
#### 测试项
- 代码块转换
- 图表渲染
- PJAX 切换
- 性能表现
### 7.4 测试文件
创建 `tests/test-codeblock-magic.html`
```html
<!DOCTYPE html>
<html>
<head>
<title>Mermaid 代码块魔改测试</title>
</head>
<body>
<!-- 测试用例 1标准格式 -->
<pre><code class="language-mermaid">
flowchart TD
A --> B
</code></pre>
<!-- 测试用例 2多个代码块 -->
<pre><code class="language-mermaid">
graph LR
C --> D
</code></pre>
<!-- 测试用例 3特殊字符 -->
<pre><code class="language-mermaid">
flowchart TD
A -- text --> B
C ==> D
</code></pre>
<!-- 测试用例 4空代码块 -->
<pre><code class="language-mermaid"></code></pre>
</body>
</html>
```
## 8. 部署设计
### 8.1 部署步骤
#### 步骤 1修改 argontheme.js
1.`highlightJsRender()` 函数开始处添加 `convertMermaidCodeblocks()` 调用
2. 实现 `convertMermaidCodeblocks()` 函数
3. 修改 `detectMermaidBlocks()` 函数,添加新选择器
4. 修改 `extractMermaidCode()` 函数,支持新容器类型
#### 步骤 2测试验证
1. 创建测试文件 `tests/test-codeblock-magic.html`
2. 在本地环境测试所有用例
3. 验证 PJAX 兼容性
4. 检查浏览器控制台无错误
#### 步骤 3文档更新
1. 更新 `docs/mermaid-usage-guide.md`
2. 更新 `docs/mermaid-developer-guide.md`
3. 更新 `docs/mermaid-faq.md`
#### 步骤 4发布
1. 提交代码到 Git
2. 更新版本号
3. 发布更新
### 8.2 回滚方案
如果出现问题,可以快速回滚:
1. 移除 `convertMermaidCodeblocks()` 调用
2. 移除新添加的选择器
3. 恢复原始代码
**降级方案**
- 用户仍可使用 Shortcode 格式
- 用户仍可使用容器语法
- 不影响现有功能
### 8.3 兼容性保证
#### 向后兼容
- 不影响现有的 Shortcode 格式
- 不影响现有的容器语法
- 不影响其他代码块的高亮
#### 向前兼容
- 预留扩展接口
- 支持未来的新格式
- 易于维护和升级
## 9. 监控与维护
### 9.1 日志设计
#### 调试日志
```javascript
this.logDebug('开始转换 Mermaid 代码块');
this.logDebug('找到 ' + elements.length + ' 个代码块');
this.logDebug('代码内容: ' + code.substring(0, 100));
this.logDebug('转换完成');
```
#### 错误日志
```javascript
console.error('Mermaid 代码块转换失败:', err);
console.error('元素:', element);
console.error('代码:', code);
```
### 9.2 性能监控
#### 性能指标
- 代码块转换时间
- 页面加载时间
- 内存使用情况
#### 监控方法
```javascript
const startTime = performance.now();
convertMermaidCodeblocks();
const endTime = performance.now();
console.log('转换耗时:', endTime - startTime, 'ms');
```
### 9.3 维护计划
#### 定期检查
- 每月检查浏览器兼容性
- 每季度检查性能表现
- 每半年检查代码质量
#### 更新策略
- 跟进 Mermaid.js 版本更新
- 跟进 WordPress 版本更新
- 跟进浏览器标准更新
## 10. 风险与缓解
### 10.1 技术风险
#### 风险 1与其他插件冲突
**影响**:中等
**概率**:低
**缓解措施**
- 使用唯一的类名 `mermaid-from-codeblock`
- 添加命名空间,避免冲突
- 提供配置选项,允许禁用
#### 风险 2性能问题
**影响**:低
**概率**:低
**缓解措施**
- 优化选择器,减少 DOM 查询
- 使用缓存,避免重复处理
- 添加性能监控
#### 风险 3浏览器兼容性
**影响**:中等
**概率**:低
**缓解措施**
- 使用标准 API
- 添加 polyfill
- 提供降级方案
### 10.2 用户体验风险
#### 风险 1误转换其他代码块
**影响**:高
**概率**:极低
**缓解措施**
- 使用精确的选择器
- 添加类名检查
- 提供白名单机制
#### 风险 2特殊字符丢失
**影响**:高
**概率**:极低
**缓解措施**
- 使用 `textContent` 保留原始内容
- 不进行任何字符转换
- 添加测试用例验证
## 11. 未来扩展
### 11.1 短期扩展1-2 周)
#### 配置选项
添加主题设置选项:
- 是否启用代码块魔改
- 选择器优先级配置
- 调试模式开关
#### 性能优化
- 添加缓存机制
- 批量处理优化
- 延迟加载支持
### 11.2 中期扩展1-2 月)
#### 编辑器支持
- 添加编辑器预览功能
- 支持实时渲染
- 提供语法提示
#### 移动端优化
- 优化移动端显示
- 支持触摸交互
- 响应式布局
### 11.3 长期扩展3-6 月)
#### 多图表库支持
- 支持 PlantUML
- 支持 GraphViz
- 支持 D3.js
#### 高级功能
- 图表编辑器
- 图表导出PNG、SVG
- 图表分享
## 12. 总结
### 12.1 设计优势
1. **简单高效**:只需添加一个函数,修改三个位置
2. **兼容性好**:不影响现有功能,支持多种格式
3. **性能优秀**:使用原生 JavaScript优化 DOM 操作
4. **易于维护**:代码清晰,注释详细,易于理解
5. **安全可靠**:防止 XSS处理异常提供降级
### 12.2 关键决策
| 决策 | 理由 |
|------|------|
| 在代码高亮前拦截 | 避免代码高亮干扰 |
| 使用 textContent | 保留原始内容,防止 XSS |
| 创建新容器类型 | 便于识别来源,支持多种格式 |
| 添加重复处理防护 | 支持 PJAX避免重复转换 |
| 提供降级支持 | 确保即使转换失败仍能渲染 |
### 12.3 实施建议
1. **分步实施**:先实现核心功能,再添加优化
2. **充分测试**:创建完整的测试用例,覆盖所有场景
3. **文档完善**:更新用户文档和开发者文档
4. **监控反馈**:收集用户反馈,持续优化
### 12.4 成功标准
- ✅ 可以使用 ` ```mermaid ` 代码块编写图表
- ✅ 代码块不会被代码高亮处理
- ✅ 图表正确渲染
- ✅ 特殊字符不被转换
- ✅ 换行符正确保留
- ✅ PJAX 切换正常工作
- ✅ 性能无明显影响
- ✅ 兼容所有主流浏览器

View File

@@ -0,0 +1,501 @@
# Mermaid 代码块魔改支持 - 需求文档
## 1. 项目概述
### 1.1 背景
当前 Argon 主题支持 Mermaid 图表渲染,但存在多个标记方式的兼容性问题:
- **标准 Markdown 代码块** (` ```mermaid `):被 WP-Markdown 插件和代码高亮干扰
- **容器语法** (`::: mermaid ... :::`):空行导致内容截断
- **Shortcode** (`[mermaid]...[/mermaid]`):可用但不符合 Markdown 标准
用户希望使用标准 Markdown 语法 ` ```mermaid `,但需要绕过所有干扰。
### 1.2 核心问题
1. WP-Markdown 插件会将 ` ```mermaid ` 代码块用 `document.write()` 包裹
2. WordPress 的 `wptexturize()` 会自动转换特殊字符(`--```
3. 主题的代码高亮会处理 mermaid 代码块,添加行号和控制按钮
4. 三方冲突导致 Mermaid 代码无法正确渲染
### 1.3 解决方案
**魔改代码块显示**:在代码高亮之前拦截 mermaid 代码块,将其转换为 Mermaid 渲染容器,完全绕过代码高亮和 WordPress 格式化。
### 1.4 参考实现
主题中数学公式的实现方式可以作为参考:
- **MathJax/KaTeX**:使用特定分隔符(`$...$``\(...\)`)标记数学公式
- **渲染时机**:在 PJAX 加载完成后调用 `MathJax.typeset()``renderMathInElement()`
- **不干扰代码高亮**:数学公式使用特殊标记,不会被代码高亮处理
- **WordPress 兼容**:数学公式分隔符不会被 WordPress 自动转换
**关键差异**
- 数学公式使用**内联标记**`$...$`),不需要代码块
- Mermaid 需要使用**代码块**` ```mermaid `),需要在代码高亮前拦截
- 数学公式库自动扫描页面Mermaid 需要手动检测和渲染
## 2. 用户故事
### 2.1 作为博客作者
**我想要**:使用标准 Markdown 语法 ` ```mermaid ` 编写流程图
**以便**:在原生编辑器中清晰可见,符合 Markdown 标准,无需学习特殊语法
**验收标准**
- 可以使用 ` ```mermaid ` 代码块编写 Mermaid 图表
- 代码块不会被代码高亮处理(无行号、无控制按钮)
- 代码块会被正确转换为 Mermaid 图表
- 支持所有 Mermaid 语法flowchart, sequence, class, state 等)
### 2.2 作为博客作者
**我想要**Mermaid 代码中的特殊字符不被 WordPress 转换
**以便**:箭头符号 `-->` 不会变成 `>`,图表能正确渲染
**验收标准**
- 箭头符号 `-->` 保持不变
- 双横线 `--` 保持不变
- 其他特殊字符(`==`, `~~`, `::` 等)保持不变
- 换行符正确保留
### 2.3 作为博客作者
**我想要**Mermaid 代码块在编辑器中显示为代码块
**以便**:编辑时能清晰看到代码结构,方便修改
**验收标准**
- 在 WordPress 原生编辑器中显示为代码块
- 在 WP-Markdown 编辑器中显示为代码块
- 代码块有语法高亮(编辑器层面)
- 保存后前端正确渲染为图表
### 2.4 作为开发者
**我想要**:拦截逻辑在代码高亮之前执行
**以便**:避免代码高亮干扰 Mermaid 渲染
**验收标准**
-`highlightJsRender()` 函数开始处添加预处理
- 查找所有 `pre > code.language-mermaid` 元素
- 提取纯文本代码(不经过任何处理)
- 创建 Mermaid 渲染容器
- 替换原始代码块元素
### 2.5 作为开发者
**我想要**:支持多种 Mermaid 代码块格式
**以便**:兼容不同插件和编辑器生成的 HTML 结构
**验收标准**
- 支持 `<pre><code class="language-mermaid">` 格式
- 支持 `<pre><code class="mermaid">` 格式
- 支持 `<code class="language-mermaid">` 格式(无 pre 包裹)
- 支持 `<pre data-lang="mermaid">` 格式
## 3. 功能需求
### 3.1 代码块拦截(核心功能)
**需求描述**:在代码高亮之前拦截 mermaid 代码块
**实现位置**`argontheme.js``highlightJsRender()` 函数开始处(第 3942 行)
**参考实现**:类似数学公式在 PJAX 加载后的处理方式(第 2862-2880 行)
**处理流程**
1.`highlightJsRender()` 函数开始处添加预处理
2. 查找所有 mermaid 代码块(多种选择器)
3. 遍历每个代码块
4. 提取纯文本代码
5. 创建 Mermaid 渲染容器
6. 替换原始代码块元素
7. 标记已处理(避免重复处理)
**选择器优先级**
```javascript
const selectors = [
'pre > code.language-mermaid', // 标准格式(最常见)
'pre > code.mermaid', // 简化格式
'code.language-mermaid', // 无 pre 包裹
'pre[data-lang="mermaid"]' // 自定义属性格式
];
```
**实现示例**
```javascript
function highlightJsRender(){
// 在代码高亮之前,先处理 Mermaid 代码块
convertMermaidCodeblocks();
// 原有的代码高亮逻辑
if (typeof(hljs) == "undefined"){
return;
}
// ...
}
function convertMermaidCodeblocks(){
// 查找所有 mermaid 代码块
const selectors = [
'pre > code.language-mermaid',
'pre > code.mermaid',
'code.language-mermaid',
'pre[data-lang="mermaid"]'
];
selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(element => {
// 避免重复处理
if (element.dataset.mermaidProcessed) {
return;
}
// 提取代码
let code = element.textContent.trim();
if (!code) {
return;
}
// 创建容器
const container = document.createElement('div');
container.className = 'mermaid-from-codeblock';
container.textContent = code;
container.dataset.processed = 'true';
// 替换元素
const targetElement = element.closest('pre') || element;
targetElement.parentNode.replaceChild(container, targetElement);
});
});
}
```
### 3.2 代码提取
**需求描述**:从不同格式的代码块中提取纯文本代码
**处理逻辑**
- 使用 `textContent` 获取纯文本(避免 HTML 实体)
- 移除前后空白字符(`trim()`
- 不进行任何字符转换(保持原始内容)
- 检查代码是否为空
**特殊处理**
- 如果代码块包含 `<script>` 标签WP-Markdown 生成),先移除
- 如果代码块被其他元素包裹,递归查找 `code` 元素
### 3.3 容器创建
**需求描述**:创建 Mermaid 渲染容器,替换原始代码块
**容器结构**
```html
<div class="mermaid-from-codeblock" data-processed="true">
flowchart TD
A --> B
</div>
```
**容器属性**
- `class="mermaid-from-codeblock"`:标识来源于代码块
- `data-processed="true"`:标记已处理,避免重复
- `textContent`:纯文本 Mermaid 代码(不使用 `innerHTML`
**替换逻辑**
- 使用 `replaceWith()` 替换原始元素
- 如果原始元素在 `<pre>` 中,替换整个 `<pre>` 元素
- 保留原始元素的位置和上下文
### 3.4 渲染检测
**需求描述**:在 Mermaid 渲染时检测新的容器类型
**实现位置**`argontheme.js``detectMermaidBlocks()` 函数(第 4430 行)
**参考实现**:类似数学公式的自动检测机制
**修改内容**
```javascript
const selectors = [
'div.mermaid-shortcode', // Shortcode 格式
'div.mermaid-from-codeblock', // 代码块魔改格式(新增)
'div.mermaid', // 标准格式
'pre code.language-mermaid', // Markdown 格式(降级)
'pre[data-lang="mermaid"]', // 自定义属性格式
'code.mermaid' // 简化格式
];
```
**优先级说明**
- `mermaid-from-codeblock` 优先级高于标准 `mermaid`
- 避免与其他检测逻辑冲突
- 如果代码块转换失败,仍可通过降级选择器检测
### 3.5 代码提取适配
**需求描述**:在 `extractMermaidCode()` 函数中支持新的容器类型
**实现位置**`argontheme.js``extractMermaidCode()` 函数(第 4650 行)
**参考实现**:类似 Shortcode 格式的处理方式
**处理逻辑**
```javascript
// 处理代码块魔改格式
if (element.classList.contains('mermaid-from-codeblock')) {
code = element.textContent;
this.logDebug('从代码块魔改格式提取代码');
}
```
**提取方式**
- 直接使用 `textContent` 获取纯文本
- 不进行任何转换或清理
- 保持与其他格式一致的处理方式
### 3.6 PJAX 兼容
**需求描述**:确保在 PJAX 页面切换后仍能正常工作
**实现位置**PJAX 加载完成回调(第 2862-2890 行)
**参考实现**:数学公式在 PJAX 后重新渲染
**处理逻辑**
- 代码块转换在 `highlightJsRender()` 中执行
- `highlightJsRender()` 已在 PJAX 回调中调用(第 2887 行)
- 无需额外修改,自动支持 PJAX
**验证要点**
- PJAX 切换后,新页面的 mermaid 代码块能正确转换
- 已转换的代码块不会重复处理
- Mermaid 图表能正确渲染
## 4. 非功能需求
### 4.1 性能要求
- 拦截处理应在 10ms 内完成(单个代码块)
- 不影响页面加载速度
- 不增加额外的 HTTP 请求
### 4.2 兼容性要求
- 兼容 WordPress 5.0+
- 兼容 WP-Markdown 插件
- 兼容其他 Markdown 插件Jetpack Markdown 等)
- 兼容主题的代码高亮功能
### 4.3 可维护性要求
- 代码逻辑清晰,易于理解
- 添加详细的注释说明
- 使用统一的命名规范
- 遵循主题现有的代码风格
### 4.4 调试支持
- 使用 `this.logDebug()` 输出调试信息
- 记录处理的代码块数量
- 记录提取的代码内容(前 100 字符)
- 记录容器创建和替换过程
## 5. 技术约束
### 5.1 代码风格
- 使用 Tab 缩进
- 使用单引号 `'`
- 使用严格相等 `===`
- 函数名使用驼峰命名
- 添加 JSDoc 注释
### 5.2 jQuery 使用
- 优先使用原生 JavaScript
- 仅在必要时使用 jQuery
- 避免混用原生和 jQuery 方法
### 5.3 错误处理
- 使用 try-catch 包裹关键代码
- 捕获异常后记录日志
- 不中断其他代码块的处理
- 提供降级方案
### 5.4 执行顺序约束(关键)
**必须严格遵守以下执行顺序**
1. **代码块转换**`convertMermaidCodeblocks()`
-`highlightJsRender()` 函数开始处执行
-`<pre><code class="language-mermaid">` 转换为 `<div class="mermaid-from-codeblock">`
- 必须在代码高亮之前完成
2. **代码高亮**`highlightJsRender()`
- 处理所有代码块,但跳过 mermaid 相关的
- 已有跳过逻辑(第 3963-3970 行)
- 不会处理已转换的 `<div>` 元素
3. **Mermaid 检测**`detectMermaidBlocks()`
- 在页面加载完成后执行
- 检测所有 Mermaid 容器(包括新的 `mermaid-from-codeblock`
- 提取代码并准备渲染
4. **Mermaid 渲染**`mermaid.init()`
- 最后执行
- 将代码渲染为 SVG 图表
**参考实现**
```javascript
// PJAX 加载完成后的执行顺序(第 2862-2890 行)
try { waterflowInit(); } catch (err) { ... }
try { lazyloadInit(); } catch (err) { ... }
try { zoomifyInit(); } catch (err) { ... }
try { highlightJsRender(); } catch (err) { ... } // 代码高亮(包含代码块转换)
try { panguInit(); } catch (err) { ... }
// ... 其他初始化
// Mermaid 渲染在单独的地方调用
```
## 6. 测试需求
### 6.1 单元测试
- 测试代码块检测逻辑
- 测试代码提取逻辑
- 测试容器创建逻辑
- 测试替换逻辑
### 6.2 集成测试
- 测试与代码高亮的集成
- 测试与 Mermaid 渲染的集成
- 测试与 WP-Markdown 的集成
- 测试与 WordPress 的集成
### 6.3 浏览器测试
- Chrome 最新版
- Firefox 最新版
- Safari 最新版
- Edge 最新版
### 6.4 测试用例
创建测试文件 `tests/test-codeblock-magic.html`,包含:
- 标准 Markdown 代码块
- 多个代码块
- 嵌套代码块
- 空代码块
- 特殊字符代码块
- 多行代码块
## 7. 文档需求
### 7.1 用户文档
- 更新 `docs/mermaid-usage-guide.md`
- 添加代码块魔改方式的说明
- 提供使用示例
- 说明优缺点
### 7.2 开发者文档
- 更新 `docs/mermaid-developer-guide.md`
- 说明实现原理
- 提供代码示例
- 说明扩展方式
### 7.3 FAQ 文档
- 更新 `docs/mermaid-faq.md`
- 添加常见问题
- 提供解决方案
- 说明注意事项
## 8. 验收标准
### 8.1 功能验收
- [ ] 可以使用 ` ```mermaid ` 代码块编写图表
- [ ] 代码块不会被代码高亮处理
- [ ] 图表正确渲染
- [ ] 特殊字符不被转换
- [ ] 换行符正确保留
### 8.2 性能验收
- [ ] 单个代码块处理时间 < 10ms
- [ ] 页面加载时间无明显增加
- [ ] 无额外的 HTTP 请求
### 8.3 兼容性验收
- [ ] 兼容 WordPress 5.0+
- [ ] 兼容 WP-Markdown 插件
- [ ] 兼容主题代码高亮
- [ ] 兼容所有主流浏览器
### 8.4 代码质量验收
- [ ] 代码风格符合规范
- [ ] 添加详细注释
- [ ] 无 ESLint 错误
- [ ] 无 console 错误
## 9. 风险评估
### 9.1 技术风险
- **风险**:可能与其他插件冲突
- **影响**:中等
- **缓解措施**:添加兼容性检测,提供降级方案
### 9.2 性能风险
- **风险**:大量代码块可能影响性能
- **影响**:低
- **缓解措施**:优化选择器,使用缓存
### 9.3 兼容性风险
- **风险**:不同插件生成的 HTML 结构不同
- **影响**:中等
- **缓解措施**:支持多种选择器,添加降级逻辑
## 10. 后续优化
### 10.1 短期优化1-2 周)
- 添加配置选项(是否启用代码块魔改)
- 优化性能(缓存、批量处理)
- 完善错误处理
### 10.2 中期优化1-2 月)
- 支持更多 Mermaid 配置选项
- 添加编辑器预览功能
- 优化移动端显示
### 10.3 长期优化3-6 月)
- 支持其他图表库PlantUML、GraphViz 等)
- 添加图表编辑器
- 支持图表导出
## 11. 参考资料
### 11.1 主题现有实现
- **数学公式渲染**`footer.php` 第 36-147 行):
- MathJax 3使用 `$...$``\(...\)` 分隔符
- MathJax 2使用 `$...$``\(...\)` 分隔符
- KaTeX使用 `$$...$$``$...$` 分隔符
- 渲染时机:页面加载完成后自动扫描
- PJAX 支持:在 PJAX 回调中重新调用渲染函数(第 2862-2880 行)
- **代码高亮**`argontheme.js` 第 3942-4000 行):
- 使用 highlight.js 库
- 处理 `<pre><code>` 元素
- 添加行号、控制按钮、复制功能
- 跳过 `.no-hljs``.mermaid` 类的代码块
- **Mermaid 渲染**`argontheme.js` 第 4430-4750 行):
- 检测多种格式的 Mermaid 代码块
- 提取代码内容
- 调用 `mermaid.init()` 渲染图表
- 支持容器语法和 Shortcode
### 11.2 实现对比
| 特性 | 数学公式 | Mermaid当前 | Mermaid魔改后 |
|------|----------|----------------|------------------|
| 标记方式 | 内联分隔符 `$...$` | 代码块 ` ```mermaid ` | 代码块 ` ```mermaid ` |
| WordPress 干扰 | 无(分隔符不被转换) | 有(特殊字符被转换) | 无(提前拦截) |
| 代码高亮干扰 | 无(不是代码块) | 有(被当作代码块) | 无(提前转换) |
| 渲染时机 | 页面加载后自动 | 页面加载后手动检测 | 页面加载后手动检测 |
| PJAX 支持 | 是(重新调用渲染) | 是(重新检测) | 是(重新转换+检测) |
| 编辑器可见性 | 可见(内联文本) | 可见(代码块) | 可见(代码块) |
| 标准兼容性 | LaTeX 标准 | Markdown 标准 | Markdown 标准 |
### 11.3 相关文档
- [Mermaid 官方文档](https://mermaid.js.org/)
- [WP-Markdown 插件文档](https://wordpress.org/plugins/wp-markdown/)
- [WordPress Codex](https://codex.wordpress.org/)
### 11.2 相关代码
- `argontheme.js` - 主题核心 JS
- `functions.php` - WordPress 函数
- `style.css` - 主题样式
### 11.3 相关 Issue
- 代码高亮干扰 Mermaid 渲染
- WordPress 自动转换特殊字符
- 容器语法空行截断问题

View File

@@ -0,0 +1,188 @@
# Mermaid 代码块魔改支持 - 任务列表
## 概述
实现标准 Markdown 代码块 (` ```mermaid `) 的 Mermaid 图表渲染,通过在代码高亮之前拦截并转换代码块,完全绕过 WordPress 和代码高亮的干扰。
## 任务列表
### 1. 核心功能实现
- [ ] 1.1 实现 `convertMermaidCodeblocks()` 函数
- **需求**: 3.1 代码块拦截(核心功能)
- **位置**: `argontheme.js` 第 3942 行之前(`highlightJsRender()` 函数开始处)
- **功能**:
- 使用多个选择器查找 mermaid 代码块
- 支持 `pre > code.language-mermaid``pre > code.mermaid``code.language-mermaid``pre[data-lang="mermaid"]` 格式
- 提取纯文本代码(使用 `textContent`
- 创建 `<div class="mermaid-from-codeblock">` 容器
- 替换原始代码块元素
- 添加 `data-processed="true"` 标记防止重复处理
- **参考**: 设计文档 3.1 节
- [ ] 1.2 集成到 `highlightJsRender()` 函数
- **需求**: 3.1 代码块拦截(核心功能)
- **位置**: `argontheme.js` 第 3942 行
- **修改**: 在函数开始处调用 `convertMermaidCodeblocks()`
- **执行顺序**: 转换 → 代码高亮 → Mermaid 渲染
- **参考**: 设计文档 3.2 节(集成点 1
### 2. Mermaid 检测适配
- [ ] 2.1 更新 `detectMermaidBlocks()` 函数
- **需求**: 3.4 渲染检测
- **位置**: `argontheme.js` 第 4430 行
- **修改**: 在 selectors 数组中添加 `'div.mermaid-from-codeblock'`
- **优先级**: 放在 `'div.mermaid-shortcode'` 之后,`'div.mermaid'` 之前
- **参考**: 设计文档 3.2 节(集成点 2
- [ ] 2.2 更新 `extractMermaidCode()` 函数
- **需求**: 3.5 代码提取适配
- **位置**: `argontheme.js` 第 4650 行
- **修改**: 添加对 `mermaid-from-codeblock` 类的处理分支
- **提取方式**: 使用 `element.textContent` 直接获取
- **参考**: 设计文档 3.2 节(集成点 3
### 3. 测试与验证
- [ ] 3.1 创建测试文件
- **需求**: 6.4 测试用例
- **文件**: `tests/test-codeblock-magic.html`
- **内容**:
- 标准 Markdown 代码块 (`pre > code.language-mermaid`)
- 多个代码块(测试批量处理)
- 特殊字符代码块(`-->`, `--`, `==` 等)
- 空代码块(测试边界情况)
- 多行代码块(测试换行符保留)
- **参考**: 设计文档 7.4 节
- [ ] 3.2 功能测试
- **需求**: 6.1 单元测试、6.2 集成测试
- **测试项**:
- 代码块正确转换为容器
- 代码块不被代码高亮处理
- Mermaid 图表正确渲染
- 特殊字符不被转换(`-->` 保持不变)
- 换行符正确保留
- 重复处理防护生效
- **参考**: 设计文档 7.1 节、7.2 节
- [ ] 3.3 PJAX 兼容性测试
- **需求**: 3.6 PJAX 兼容
- **测试项**:
- 初始页面加载,代码块正确转换和渲染
- PJAX 切换到新页面,新页面的代码块正确转换和渲染
- 已转换的代码块不被重复处理
- 无 JavaScript 错误
- **参考**: 设计文档 3.3 节
- [ ] 3.4 浏览器兼容性测试
- **需求**: 6.3 浏览器测试
- **测试浏览器**: Chrome、Firefox、Safari、Edge最新版
- **测试项**: 代码块转换、图表渲染、PJAX 切换、性能表现
- **参考**: 设计文档 7.3 节
### 4. 文档更新
- [ ] 4.1 更新用户文档
- **需求**: 7.1 用户文档
- **文件**: `docs/mermaid-usage-guide.md`
- **内容**:
- 添加代码块魔改方式的说明
- 提供使用示例(标准 Markdown 语法)
- 说明优缺点(优点:标准语法;缺点:需要主题支持)
- 与其他方式的对比
- **参考**: 需求文档 7.1 节
- [ ] 4.2 更新开发者文档
- **需求**: 7.2 开发者文档
- **文件**: `docs/mermaid-developer-guide.md`
- **内容**:
- 说明实现原理(提前拦截、转换容器)
- 提供代码示例(`convertMermaidCodeblocks()` 函数)
- 说明扩展方式(如何添加新的选择器)
- 执行顺序说明
- **参考**: 需求文档 7.2 节
- [ ] 4.3 更新 FAQ 文档
- **需求**: 7.3 FAQ 文档
- **文件**: `docs/mermaid-faq.md`
- **内容**:
- 添加常见问题(如何使用标准 Markdown 语法?)
- 提供解决方案(启用代码块魔改功能)
- 说明注意事项(需要主题版本 >= X.X.X
- 故障排查指南
- **参考**: 需求文档 7.3 节
### 5. 性能优化(可选)
- [ ] 5.1* 添加性能监控
- **需求**: 4.1 性能要求
- **功能**:
- 使用 `performance.now()` 记录转换耗时
- 使用 `console.log()` 输出性能数据(仅调试模式)
- 记录处理的代码块数量
- **目标**: 单个代码块处理时间 < 10ms
- **参考**: 设计文档 5.3 节
- [ ] 5.2* 优化选择器性能
- **需求**: 4.1 性能要求
- **优化**:
- 使用更精确的选择器(减少匹配范围)
- 批量处理元素(减少 DOM 查询次数)
- 提前返回(跳过已处理的元素)
- **参考**: 设计文档 5.2 节
### 6. 错误处理增强(可选)
- [ ] 6.1* 添加错误日志
- **需求**: 5.3 错误处理
- **功能**:
- 使用 try-catch 包裹关键代码
- 捕获异常后记录日志(`console.error()`
- 不中断其他代码块的处理
- **参考**: 设计文档 3.4 节
- [ ] 6.2* 提供降级方案
- **需求**: 5.3 错误处理
- **功能**:
- 如果转换失败,保留原始代码块
- 原始代码块仍可通过降级选择器检测(`pre code.language-mermaid`
- 确保即使转换失败,仍能渲染
- **参考**: 设计文档 3.4 节
## 任务说明
### 优先级
- **必须完成**: 1.1 - 2.2核心功能、3.1 - 3.3测试验证、4.1 - 4.3(文档更新)
- **可选任务**: 5.1 - 5.2性能优化、6.1 - 6.2(错误处理增强)
### 执行顺序
1. 先完成核心功能1.1 - 1.2
2. 再完成 Mermaid 检测适配2.1 - 2.2
3. 然后进行测试验证3.1 - 3.4
4. 最后更新文档4.1 - 4.3
5. 可选任务可在主要功能完成后进行
### 验收标准
- ✅ 可以使用 ` ```mermaid ` 代码块编写图表
- ✅ 代码块不会被代码高亮处理
- ✅ 图表正确渲染
- ✅ 特殊字符不被转换
- ✅ 换行符正确保留
- ✅ PJAX 切换正常工作
- ✅ 性能无明显影响
- ✅ 兼容所有主流浏览器
## 注意事项
1. **执行顺序约束**: 必须严格遵守"转换 → 代码高亮 → Mermaid 渲染"的执行顺序
2. **代码风格**: 使用 Tab 缩进、单引号、严格相等(`===`
3. **安全性**: 使用 `textContent` 而非 `innerHTML`,防止 XSS
4. **兼容性**: 保持与现有功能的兼容,不影响 Shortcode 和容器语法
5. **调试**: 添加详细的调试日志,便于追踪问题
## 参考文档
- **需求文档**: `.kiro/specs/mermaid-codeblock-magic/requirements.md`
- **设计文档**: `.kiro/specs/mermaid-codeblock-magic/design.md`
- **代码规范**: `.kiro/steering/code-style.md`

View File

@@ -87,7 +87,7 @@
- **Validates: Requirements 7.3**
- _Requirements: 7.3_
- [~] 6. Checkpoint - 基础功能验证
- [x] 6. Checkpoint - 基础功能验证
- 确保所有测试通过
- 在测试环境中验证基础渲染功能
- 测试不同类型的 Mermaid 图表(流程图、时序图、类图)
@@ -172,7 +172,7 @@
- **Validates: Requirements 10.5**
- _Requirements: 10.5_
- [~] 12. Checkpoint - 完整功能验证
- [x] 12. Checkpoint - 完整功能验证
- 确保所有测试通过
- 测试所有配置选项
- 测试主题切换功能
@@ -180,13 +180,13 @@
- 测试插件兼容性
- 如有问题,询问用户
- [~] 13. 添加设置页预览功能
- [x] 13. 添加设置页预览功能
- 在设置页添加 Mermaid 预览区域
- 实现实时预览功能
- 添加示例图表代码
- _Requirements: 5.6_
- [~] 14. 编写文档和注释
- [x] 14. 编写文档和注释
- 为所有函数添加 PHPDoc 和 JSDoc 注释
- 在设置页添加使用说明
- 创建用户文档(如何使用 Mermaid
@@ -200,14 +200,14 @@
- 测试 CDN 加载失败的降级处理
- _Requirements: 9.1, 9.2, 9.3_
- [~] 16. 最终验证和优化
- [x] 16. 最终验证和优化
- 运行所有单元测试和属性测试
- 检查代码覆盖率PHP ≥80%JS ≥85%
- 进行性能测试(页面加载时间、渲染速度)
- 进行浏览器兼容性测试
- 优化代码和注释
- [~] 17. 手动测试清单
- [x] 17. 手动测试清单
- 验证图表颜色与页面背景色的对比度
- 验证图表容器样式与主题整体风格的一致性
- 测试所有 Mermaid 官方图表类型

View File

@@ -3939,7 +3939,63 @@ function getCodeFromBlock(block){
codeOfBlocks[block.id] = res;
return res;
}
/**
* 在代码高亮之前转换 Mermaid 代码块
* 将 <pre><code class="language-mermaid"> 转换为 <div class="mermaid-from-codeblock">
* 这样可以避免代码高亮干扰 Mermaid 渲染
*/
function convertMermaidCodeblocks(){
// 支持多种代码块格式
const selectors = [
'pre > code.language-mermaid', // 标准 Markdown 格式(最常见)
'pre > code.mermaid', // 简化格式
'code.language-mermaid', // 无 pre 包裹
'pre[data-lang="mermaid"]' // 自定义属性格式
];
let processedCount = 0;
selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(element => {
// 避免重复处理
if (element.dataset.mermaidProcessed) {
return;
}
// 提取代码
let code = element.textContent.trim();
if (!code) {
return;
}
// 创建容器
const container = document.createElement('div');
container.className = 'mermaid-from-codeblock';
container.textContent = code;
container.dataset.processed = 'true';
// 替换元素
const targetElement = element.closest('pre') || element;
if (targetElement.parentNode) {
targetElement.parentNode.replaceChild(container, targetElement);
processedCount++;
}
// 标记已处理
element.dataset.mermaidProcessed = 'true';
});
});
if (processedCount > 0 && typeof console !== 'undefined' && console.log) {
console.log('[Mermaid] 转换了 ' + processedCount + ' 个代码块');
}
}
function highlightJsRender(){
// 在代码高亮之前,先处理 Mermaid 代码块
convertMermaidCodeblocks();
if (typeof(hljs) == "undefined"){
return;
}
@@ -4430,8 +4486,9 @@ void 0;
// 检测规则(优先级从高到低)
const selectors = [
'div.mermaid-shortcode', // Shortcode 格式(推荐)
'div.mermaid-from-codeblock', // 代码块魔改格式(新增)
'div.mermaid', // 标准格式
'pre code.language-mermaid', // Markdown 格式
'pre code.language-mermaid', // Markdown 格式(降级)
'pre[data-lang="mermaid"]', // 自定义属性格式
'code.mermaid' // 简化格式
];
@@ -4696,6 +4753,11 @@ void 0;
code = element.textContent;
this.logDebug('从 Shortcode 格式提取代码');
}
// 处理代码块魔改格式(新增)
else if (element.classList.contains('mermaid-from-codeblock')) {
code = element.textContent;
this.logDebug('从代码块魔改格式提取代码');
}
// 处理 Markdown 容器语法格式
else if (element.classList.contains('mermaid-container-block')) {
code = element.textContent;

View File

@@ -0,0 +1,171 @@
fix: 修复容器语法和 WP-Markdown 的两个关键问题
## 问题描述
根据用户反馈,发现两个严重问题:
### 问题 1: WP-Markdown document.write 重复输出
**错误信息**
```
No diagram type detected matching given configuration for text:
document.write("flowchart TD ...")flowchart TD ...
```
**原因分析**
- WP-Markdown 生成的 HTML 结构:`<div class="mermaid"><script>document.write("...")</script>flowchart TD ...</div>`
- script 标签后面还有一份重复的代码
- 当前代码只提取了 script 内容,但没有移除 script 标签
- 导致后续的 `element.textContent` 包含了重复内容
### 问题 2: 容器语法空行导致内容截断
**错误信息**
```
Parse error on line 1: flowchart TD Sta
Expecting 'NEWLINE', 'SPACE', 'GRAPH', got 'ALPHA'
```
**原因分析**
- 使用 `::: mermaid ... :::` 语法时WP-Markdown 遇到空行会分割内容
- 空行后的内容被识别为新的段落或代码块
- 原有的单元素检测逻辑无法处理跨多个元素的情况
- 导致只提取到第一个元素的内容("flowchart TD Sta"
## 修复方案
### 修复 1: 移除 script 标签避免重复argontheme.js:4575-4578
在 `extractMermaidCode()` 函数中,提取完 script 内容后立即移除标签:
```javascript
// 重要:移除 script 标签,避免重复渲染
// WP-Markdown 会在 script 后面再输出一次代码
scriptTag.remove();
```
**效果**
- ✅ 避免 document.write 内容和后续文本重复
- ✅ 确保只提取一次完整代码
- ✅ 不影响其他格式的提取
### 修复 2: 跨元素收集容器语法内容argontheme.js:4468-4570
完全重写 `detectContainerBlocks()` 和 `extractContainerContent()` 函数:
**新的检测逻辑**
1. 查找所有可能包含 `::: mermaid` 的元素p, pre, code, div
2. 找到开始标记后,收集所有后续兄弟元素
3. 直到遇到 `:::` 结束标记
4. 合并所有内容,保留空行
**关键代码**
```javascript
// 收集所有内容直到结束标记
while (currentElement) {
processedElements.add(currentElement);
let text = currentElement.textContent.trim();
// 检查是否是结束标记
if (text === ':::' || text.endsWith(':::')) {
foundEnd = true;
break;
}
// 添加当前元素的内容
if (text) {
codeLines.push(text);
} else {
// 空元素,添加空行
codeLines.push('');
}
currentElement = currentElement.nextElementSibling;
}
// 合并所有行
let code = codeLines.join('\n').trim();
```
**效果**
- ✅ 支持跨多个元素收集内容
- ✅ 正确处理空行(保留为空字符串)
- ✅ 完整提取所有 mermaid 代码
- ✅ 避免内容截断
## 测试场景
### 场景 1: WP-Markdown 格式
```html
<div class="mermaid">
<script>document.write("flowchart TD\n A --> B")</script>
flowchart TD
A --> B
</div>
```
**预期**:只提取 script 中的内容,忽略后面的重复文本
### 场景 2: 容器语法(无空行)
```
::: mermaid
flowchart TD
A --> B
:::
```
**预期**:正常提取完整代码
### 场景 3: 容器语法(有空行)
```
::: mermaid
flowchart TD
A[开始]
B[处理]
C[结束]
A --> B --> C
:::
```
**预期**:保留所有空行,完整提取代码
### 场景 4: 容器语法(被分割成多个元素)
```html
<p>::: mermaid</p>
<p>flowchart TD</p>
<p> A[开始]</p>
<p></p>
<p> B[处理]</p>
<p>:::</p>
```
**预期**:跨元素收集,合并为完整代码
## 影响范围
- ✅ 修复了两个严重的渲染错误
- ✅ 不影响其他标记格式
- ✅ 向后兼容
- ✅ 提升容器语法的鲁棒性
## 相关文件
- `argontheme.js` - 核心修复
- `docs/mermaid-usage-guide.md` - 更新文档
## 提交信息
```
fix: 修复容器语法和 WP-Markdown 的两个关键问题
- 修复 WP-Markdown document.write 重复输出问题
- 改进容器语法检测,支持跨多个元素收集内容
- 解决空行导致内容被分割成多个元素的问题
```
Commit: b6d9f8c
## 后续建议
1. **测试验证**:在实际文章中测试包含空行的复杂 mermaid 图表
2. **性能优化**:如果页面有大量元素,可以考虑优化查找算法
3. **错误处理**:添加更详细的日志,帮助调试边缘情况

69
commit-msg-final.txt Normal file
View File

@@ -0,0 +1,69 @@
feat: 添加 Markdown 容器语法支持,修复 WPMD 代码提取问题
问题描述:
- WP-Markdown 插件将 Markdown 代码块转换为特殊格式
- 传统标记方式会被 WPMD 套上代码高亮窗口,导致嵌套结构
- 某些字符被自动转义,导致渲染失败
- 之前的正则表达式只能提取到第一个单词
解决方案:
添加 Markdown 容器语法支持(::: mermaid ... :::
- 符合 Markdown 扩展规范VuePress、Docusaurus 等使用相同语法)
- 不会被 WPMD 当作代码块处理,避免嵌套问题
- 语法简洁,易于编写和阅读
- 易于迁移到其他平台
修复内容:
1. 改进正则表达式为 ([\s\S]*?),匹配包括换行在内的所有字符
2. 添加三层降级方案:
- 方案1: 匹配 document.write("...")
- 方案2: 直接提取引号内容
- 方案3: 纯文本提取
3. 增加详细的调试日志(原始内容、提取长度、最终代码)
4. 优化解码顺序(先 HTML 实体,后转义字符)
5. 添加容器语法检测逻辑TreeWalker
代码变更:
- functions.php:
* argon_has_mermaid_content(): 添加容器语法检测
- argontheme.js:
* detectMermaidBlocks(): 添加容器语法检测
* detectContainerBlocks(): 新增函数,检测 ::: mermaid 容器
* extractContainerContent(): 新增函数,提取容器内容
* extractMermaidCode(): 支持容器语法的代码提取
- tests/test-wp-markdown-format.html:
* 添加 7 种测试场景
* 包含容器语法和标准格式测试
- docs/mermaid-usage-guide.md:
* 详细说明容器语法使用方法
* 提供使用示例和最佳实践
* 包含故障排除指南
支持的标记格式(按优先级):
1. ::: mermaid ... ::: - Markdown 容器语法 ⭐(推荐)
2. <div class="mermaid"> - 标准格式WPMD 生成)
3. <pre><code class="language-mermaid"> - Markdown 格式
4. <pre data-lang="mermaid"> - 自定义属性格式
5. <code class="mermaid"> - 简化格式
推荐使用方式:
::: mermaid
flowchart TD
A[开始] --> B[处理]
B --> C[结束]
:::
测试方法:
1. 访问测试页面https://blog.cartol.top/wp-content/themes/argon/tests/test-wp-markdown-format.html
2. 查看控制台日志,确认所有测试用例都能正确提取和渲染
3. 在文章中使用推荐的容器语法
4. 如果还有问题,查看控制台的详细日志
注意事项:
- 强烈推荐使用 Markdown 容器语法,避免 WPMD 处理
- 传统 Markdown 代码块仍然支持,但可能有嵌套问题
- 所有标记方式都会自动解码 HTML 实体和转义字符
- 容器语法符合现代 Markdown 扩展规范,易于迁移

View File

@@ -0,0 +1,96 @@
fix: 修复代码高亮和容器语法的两个关键问题
## 问题描述
1. **代码高亮干扰 mermaid 渲染**
- 传统 Markdown 代码块(```mermaid使用 document.write
- 代码高亮会处理这些代码块,导致 mermaid 无法正常渲染
2. **容器语法空行处理错误**
- 使用 ::: mermaid 语法时,空行会导致内容被截断
- WPMD 将空行后的内容识别为代码块
## 修复方案
### 1. 代码高亮排除 mermaidargontheme.js:3942-3962
在 `highlightJsRender()` 函数中添加检查:
```javascript
// 跳过 mermaid 代码块(避免代码高亮干扰 mermaid 渲染)
if ($(block).hasClass("language-mermaid") || $(block).hasClass("mermaid")){
return;
}
// 跳过在 .mermaid 容器内的代码块
if ($(block).closest('.mermaid').length > 0){
return;
}
```
**效果**
- ✅ mermaid 代码块不会被代码高亮处理
- ✅ 避免嵌套结构和渲染冲突
- ✅ 普通代码块仍正常高亮
### 2. 容器语法保留空行argontheme.js:4508-4530
修改 `extractContainerContent()` 函数:
```javascript
// 移除开始标记 ::: mermaid保留后面的换行符和空行
text = text.replace(/^:::\s*mermaid\s*\n?/i, '');
// 移除结束标记 :::(保留前面的换行符和空行)
text = text.replace(/\n?:::\s*$/i, '');
// 不要 trim保留代码中的空行
if (!text) {
return null;
}
```
**效果**
- ✅ 空行被正确保留
- ✅ 多行 mermaid 代码完整提取
- ✅ 避免内容被截断
## 测试验证
创建了 `tests/test-mermaid-fixes.html` 测试页面,包含:
1. **代码高亮排除测试**
- Markdown 格式 mermaid应排除
- div.mermaid 格式(应排除)
- 普通代码块(应高亮)
2. **容器语法空行测试**
- 包含空行的流程图
- 包含空行的时序图
- 包含多个连续空行
3. **WP-Markdown 兼容性测试**
- document.write 格式
## 影响范围
- ✅ 不影响现有功能
- ✅ 向后兼容所有标记格式
- ✅ 提升用户体验
## 相关文件
- `argontheme.js` - 核心修复
- `docs/mermaid-usage-guide.md` - 更新文档
- `tests/test-mermaid-fixes.html` - 测试页面
## 提交信息
```
fix: 修复代码高亮和容器语法的两个关键问题
- 代码高亮排除 mermaid 代码块,避免干扰渲染
- 容器语法正确处理空行,不再截断内容
- 添加测试页面验证修复效果
```
Commit: 0ac5794

View File

@@ -0,0 +1,78 @@
feat: 添加多种 Mermaid 标记方式,避免 WPMD 处理问题
问题描述:
- WP-Markdown 插件将 Markdown 代码块转换为特殊格式
- 传统标记方式会被 WPMD 套上代码高亮窗口,导致嵌套结构
- 某些字符被自动转义,导致渲染失败
- 之前的正则表达式只能提取到第一个单词
新增功能:
1. Argon 自定义标记(推荐):<div class="argon-mermaid">...</div>
- 不会被 WPMD 处理
- 语法简单清晰
- 支持所有 Mermaid 图表类型
2. HTML 注释标记:<!-- mermaid -->...<!-- /mermaid -->
- 在编辑器中不可见
- 不会被任何插件处理
- 适合需要隐藏标记的场景
3. data 属性标记:<div data-mermaid>...</div>
- 符合 HTML5 规范
- 语义化标记
- 不会被 WPMD 处理
修复内容:
1. 改进正则表达式为 ([\s\S]*?),匹配包括换行在内的所有字符
2. 添加三层降级方案:
- 方案1: 匹配 document.write("...")
- 方案2: 直接提取引号内容
- 方案3: 纯文本提取
3. 增加详细的调试日志(原始内容、提取长度、最终代码)
4. 优化解码顺序(先 HTML 实体,后转义字符)
5. 添加 HTML 注释标记检测逻辑TreeWalker
代码变更:
- argontheme.js:
* detectMermaidBlocks(): 添加新选择器和注释检测
* detectCommentBlocks(): 新增函数,检测 HTML 注释标记
* extractCommentContent(): 新增函数,提取注释之间的内容
* extractMermaidCode(): 支持新标记格式的代码提取
- tests/test-wp-markdown-format.html:
* 添加 9 种测试场景
* 包含所有支持的标记格式
* 使用改进后的提取逻辑
- docs/mermaid-wpmd-usage.md:
* 详细说明所有标记方式
* 提供使用示例和最佳实践
* 包含故障排除指南
支持的标记格式(按优先级):
1. <div class="mermaid"> - WPMD 标准格式
2. <div class="argon-mermaid"> - Argon 自定义格式 ⭐
3. <div data-mermaid> - data 属性格式
4. <!-- mermaid -->...<!-- /mermaid --> - HTML 注释格式
5. <pre><code class="language-mermaid"> - Markdown 格式
6. <pre data-lang="mermaid"> - 自定义属性格式
7. <code class="mermaid"> - 简化格式
测试方法:
1. 访问测试页面https://blog.cartol.top/wp-content/themes/argon/tests/test-wp-markdown-format.html
2. 查看控制台日志,确认所有测试用例都能正确提取和渲染
3. 在文章中使用推荐的标记方式:<div class="argon-mermaid">...</div>
4. 如果还有问题,查看控制台的详细日志
推荐使用方式:
<div class="argon-mermaid">
flowchart TD
A[开始] --> B[处理]
B --> C[结束]
</div>
注意事项:
- 强烈推荐使用 Argon 自定义标记,避免 WPMD 处理
- HTML 注释标记适合需要隐藏标记的场景
- 传统 Markdown 代码块仍然支持,但可能有嵌套问题
- 所有标记方式都会自动解码 HTML 实体和转义字符

File diff suppressed because it is too large Load Diff

712
docs/mermaid-faq.md Normal file
View File

@@ -0,0 +1,712 @@
# Mermaid 图表常见问题解答 (FAQ)
## 目录
- [基础问题](#基础问题)
- [配置问题](#配置问题)
- [渲染问题](#渲染问题)
- [兼容性问题](#兼容性问题)
- [性能问题](#性能问题)
- [高级问题](#高级问题)
---
## 基础问题
### Q1: 什么是 Mermaid
**A:** Mermaid 是一个基于 JavaScript 的图表和图形工具,它使用类似 Markdown 的文本语法来创建和修改图表。您可以用简单的文本代码创建流程图、时序图、类图等多种专业图表。
**优势:**
- 📝 文本即代码,易于版本控制
- 🎨 自动布局,无需手动调整
- 🔄 易于修改和维护
- 📱 响应式设计,自适应屏幕
---
### Q2: Argon 主题支持哪些 Mermaid 图表类型?
**A:** Argon 主题支持 Mermaid 的所有主要图表类型:
1. **流程图 (Flowchart)** - 展示流程和决策
2. **时序图 (Sequence Diagram)** - 描述对象交互
3. **类图 (Class Diagram)** - 展示类结构
4. **状态图 (State Diagram)** - 表示状态转换
5. **饼图 (Pie Chart)** - 显示数据占比
6. **甘特图 (Gantt Chart)** - 项目进度管理
7. **用户旅程图 (User Journey)** - 用户体验流程
8. **Git 图 (Git Graph)** - 版本控制可视化
详细示例请参考[用户指南](mermaid-user-guide.md#支持的图表类型)。
---
### Q3: 如何在文章中插入 Mermaid 图表?
**A:** 有三种方式:
**方式 1标准 Markdown 代码块**(推荐)⭐
````markdown
三个反引号mermaid
flowchart TD
A[开始] --> B[结束]
三个反引号
````
**优点:**
- ✅ 符合标准 Markdown 语法
- ✅ 在所有 Markdown 编辑器中都能正确显示
- ✅ 易于迁移到其他平台GitHub、GitLab、Typora 等)
- ✅ 主题自动拦截处理,避免代码高亮干扰
**方式 2Markdown 容器语法**(备选)
````markdown
::: mermaid
flowchart TD
A[开始] --> B[结束]
:::
````
**优点:**
- ✅ 符合 Markdown 扩展规范VuePress、Docusaurus 等)
- ✅ 不会被 WP-Markdown 当作代码块处理
**方式 3Shortcode 格式**(兼容)
```
[mermaid]
flowchart TD
A[开始] --> B[结束]
[/mermaid]
```
**优点:**
- ✅ WordPress 原生支持
- ✅ 兼容性最好
**缺点:**
- ❌ 不符合 Markdown 标准
- ❌ 在其他平台无法使用
---
### Q4: 为什么推荐使用标准 Markdown 代码块?
**A:** 因为标准 Markdown 代码块 (` ```mermaid `) 是最通用的方式:
- **GitHub** 使用这种语法
- **GitLab** 使用这种语法
- **Typora** 使用这种语法
- **VS Code** 使用这种语法
- **符合 CommonMark 规范**
Argon 主题通过**代码块魔改**技术,在代码高亮之前拦截并转换 mermaid 代码块,因此:
- ✅ 不会被代码高亮处理(无行号、无控制按钮)
- ✅ 不会有字符转义问题(`-->` 保持不变)
- ✅ 不会有嵌套结构问题
- ✅ 完全符合标准 Markdown 语法
- ✅ 易于迁移到其他平台
```mermaid
flowchart TD
A --> B
```
````
**方式 2HTML 标签**
```html
<div class="mermaid">
flowchart TD
A --> B
</div>
```
**注意:** 使用前需要在主题设置中启用 Mermaid 支持。
---
### Q4: 需要安装额外的插件吗?
**A:** 不需要。Argon 主题内置了 Mermaid 支持,开箱即用。
**但是:**
- 如果您已经安装了 Mermaid 相关插件(如 WP Githuber MD主题会自动检测并避免重复加载
- 主题会智能判断是否需要加载 Mermaid 库
---
## 配置问题
### Q5: 如何启用 Mermaid 支持?
**A:** 按照以下步骤操作:
1. 登录 WordPress 后台
2. 进入 **外观 → Argon 主题设置**
3. 找到 **Mermaid 图表** 分类
4. 勾选 **"启用 Mermaid 支持"**
5. 点击 **"保存设置"**
---
### Q6: 应该选择哪个 CDN 来源?
**A:** 推荐选择:
**首选jsDelivr CDN**
- ✅ 全球 CDN速度快
- ✅ 稳定性高
- ✅ 免费使用
**备选unpkg CDN**
- 作为备用选项
**特殊情况:**
- **内网环境** → 使用本地文件
- **特定版本需求** → 使用自定义 CDN
- **极致速度** → 下载本地文件
**主题优势:** 即使主 CDN 失败,主题会自动尝试备用 CDN确保可用性。
---
### Q7: 如何使用自定义 CDN
**A:** 步骤如下:
1. 在 **CDN 来源** 中选择 **"自定义 CDN 地址"**
2. 在 **自定义 CDN 地址** 输入框中填入完整的 URL
3. 保存设置
**URL 格式要求:**
- 必须是有效的 URL
- 必须以 `.js` 结尾
- 必须使用 `http://` 或 `https://` 协议
**示例:**
```
https://cdn.example.com/mermaid@10.0.0/mermaid.min.js
```
---
### Q8: 图表主题应该选择哪个?
**A:** 推荐选择 **"自动切换"**。
**原因:**
- 自动跟随页面的日间/夜间模式
- 日间模式使用浅色主题
- 夜间模式使用深色主题
- 用户体验最佳
**其他选项:**
- **默认主题** - 固定使用浅色
- **深色主题** - 固定使用深色
- **森林主题** - 绿色主题
- **中性主题** - 灰色主题
---
### Q9: 什么时候需要启用调试模式?
**A:** 在以下情况下启用:
1. **图表不显示** - 查看是否有加载错误
2. **渲染失败** - 查看详细的错误信息
3. **主题切换异常** - 检查主题切换逻辑
4. **CDN 加载问题** - 查看 CDN 加载状态
5. **开发测试** - 开发新功能时调试
**如何使用:**
1. 启用调试模式
2. 打开浏览器开发者工具F12
3. 切换到"控制台"标签
4. 查看以 `[Argon Mermaid]` 开头的日志
**注意:** 生产环境建议关闭调试模式。
---
## 渲染问题
### Q10: 图表不显示,只显示代码怎么办?
**A:** 按以下步骤排查:
**步骤 1检查是否启用**
- 确认主题设置中已启用 Mermaid 支持
**步骤 2检查代码格式**
- 确认使用了正确的代码块格式
- 检查是否有语法错误
**步骤 3检查浏览器控制台**
- 按 F12 打开开发者工具
- 查看是否有 JavaScript 错误
**步骤 4启用调试模式**
- 在主题设置中启用调试模式
- 查看详细的日志信息
**步骤 5验证代码**
- 访问 [Mermaid Live Editor](https://mermaid.live/)
- 粘贴代码验证语法是否正确
---
### Q11: 图表显示"渲染失败"错误?
**A:** 这通常是代码语法错误导致的。
**解决方法:**
1. **查看错误详情**
- 点击错误提示中的"查看原始代码"
- 查看错误类型和错误信息
2. **常见语法错误:**
- 缺少必要的关键字
- 箭头符号错误
- 节点 ID 重复
- 引号不匹配
- 缩进不正确
3. **使用在线编辑器验证**
- 访问 [Mermaid Live Editor](https://mermaid.live/)
- 粘贴代码并查看错误提示
- 根据提示修正语法
4. **参考官方文档**
- [Mermaid 语法参考](https://mermaid.js.org/intro/syntax-reference.html)
- 查看对应图表类型的语法规则
---
### Q12: 图表在夜间模式下看不清?
**A:** 这是主题配置问题。
**解决方法:**
1. 进入 **主题设置 → Mermaid 图表 → 外观设置**
2. 将 **图表主题** 设置为 **"自动切换"**
3. 保存设置
**原理:**
- 自动切换模式会检测页面主题
- 日间模式使用浅色图表主题
- 夜间模式使用深色图表主题
**如果仍有问题:**
- 清除浏览器缓存
- 刷新页面
- 检查是否有其他 CSS 冲突
---
### Q13: 图表太大,超出容器怎么办?
**A:** Mermaid 图表会自动适应容器宽度,但如果图表过于复杂,可能会出现问题。
**解决方法:**
**方法 1简化图表**
- 减少节点数量
- 拆分为多个小图表
- 使用子图组织内容
**方法 2自定义样式**
```css
.mermaid-container {
max-width: 100%;
overflow-x: auto;
}
.mermaid-container svg {
max-width: 100%;
height: auto;
}
```
**方法 3调整图表方向**
```mermaid
flowchart LR /* 横向布局 */
A --> B
```
```mermaid
flowchart TD /* 纵向布局 */
A --> B
```
---
### Q14: 如何在评论中使用 Mermaid
**A:** 评论中需要使用 HTML 格式。
**步骤:**
1. **确保评论允许 HTML**
- 检查 WordPress 评论设置
- 确认允许使用 HTML 标签
2. **使用 HTML 格式**
```html
<div class="mermaid">
flowchart LR
A --> B
</div>
```
3. **提交评论**
- 评论会在前台自动渲染为图表
**注意:**
- 不能使用 Markdown 代码块格式
- 必须使用 `<div class="mermaid">` 包裹
- 代码需要正确的换行格式
---
## 兼容性问题
### Q15: 与其他插件冲突怎么办?
**A:** Argon 主题内置了智能兼容机制。
**自动检测的插件:**
- WP Githuber MD
- Markdown Block
- Code Syntax Block
**兼容策略:**
1. 主题会自动检测已安装的 Mermaid 插件
2. 如果检测到插件,主题只提供样式增强
3. 避免重复加载 Mermaid 库
**查看兼容性状态:**
1. 进入 **主题设置 → Mermaid 图表 → 高级选项**
2. 查看 **插件兼容性检测** 部分
3. 查看检测结果和建议
**如果仍有冲突:**
- 禁用主题的 Mermaid 支持,使用插件
- 或禁用插件,使用主题的 Mermaid 支持
- 不要同时启用多个 Mermaid 功能
---
### Q16: 检测到多个 Mermaid 插件怎么办?
**A:** 这会导致重复加载和冲突。
**建议:**
1. **只保留一个** - 选择功能最完善的插件
2. **或使用主题** - 禁用所有插件,使用主题的 Mermaid 支持
**如何选择:**
- **插件功能更多** → 禁用主题支持,使用插件
- **主题集成更好** → 禁用插件,使用主题支持
- **性能优先** → 使用主题支持(按需加载)
---
### Q17: 在不同编辑器中如何使用?
**A:** 不同编辑器使用方法略有不同。
**Gutenberg 编辑器:**
1. 添加"代码"块或"自定义 HTML"块
2. 输入 Mermaid 代码
3. 使用 `<div class="mermaid">` 包裹
**经典编辑器:**
1. 切换到"文本"模式
2. 使用 HTML 格式
3. 使用 `<div class="mermaid">` 包裹
**Markdown 编辑器(如 WP-Markdown**
1. 使用代码块语法
2. 指定语言为 `mermaid`
````markdown
```mermaid
flowchart TD
A --> B
```
````
**WP Githuber MD**
- 插件自带 Mermaid 支持
- 主题会自动检测并避免冲突
- 使用插件的 Mermaid 功能即可
---
## 性能问题
### Q18: Mermaid 会影响页面加载速度吗?
**A:** 主题已做了充分的性能优化。
**优化措施:**
1. **按需加载**
- 只在包含 Mermaid 代码的页面加载库
- 没有 Mermaid 代码的页面不加载
2. **异步加载**
- Mermaid 库使用 async 属性异步加载
- 不阻塞页面渲染
3. **CDN 加速**
- 使用全球 CDN 加速加载
- 浏览器缓存减少重复加载
4. **智能检测**
- 检测插件是否已加载库
- 避免重复加载
**实际影响:**
- Mermaid 库大小约 300KBgzip 后约 100KB
- 首次加载约 0.5-1 秒
- 后续访问使用缓存,几乎无影响
---
### Q19: 一篇文章可以使用多少个图表?
**A:** 技术上没有限制,但建议控制数量。
**建议:**
- **小型图表** - 不超过 10 个
- **中型图表** - 不超过 5 个
- **大型图表** - 不超过 3 个
**原因:**
- 过多图表会增加渲染时间
- 影响页面性能
- 用户体验下降
**优化建议:**
1. 合并相关图表
2. 使用子图组织内容
3. 复杂图表考虑使用图片替代
4. 分页展示大量图表
---
### Q20: 如何优化 Mermaid 性能?
**A:** 以下是一些优化建议:
**1. 使用本地文件**
- 下载 Mermaid 库到主题目录
- 启用"使用本地镜像"
- 减少网络请求
**2. 简化图表**
- 减少节点数量
- 避免过于复杂的关系
- 使用简洁的文本
**3. 启用浏览器缓存**
- CDN 文件会自动缓存
- 减少重复加载
**4. 按需加载**
- 主题已自动实现
- 只在需要时加载库
**5. 使用 CDN**
- 利用 CDN 的全球加速
- 减少服务器负载
---
## 高级问题
### Q21: 如何自定义 Mermaid 样式?
**A:** 可以通过 CSS 自定义样式。
**方法 1使用主题自定义 CSS**
1. 进入 **外观 → 自定义 → 额外 CSS**
2. 添加自定义样式
**示例:**
```css
/* 自定义图表容器样式 */
.mermaid-container {
background: #f5f5f5;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
/* 自定义错误提示样式 */
.mermaid-error-container {
background: #fff3cd;
border-left: 4px solid #ffc107;
}
```
**方法 2修改主题文件**
- 编辑 `style.css`
- 在 Mermaid 相关部分添加样式
- 不推荐(主题更新会覆盖)
---
### Q22: 如何导出 Mermaid 图表为图片?
**A:** 有多种方法可以导出图表。
**方法 1使用 Mermaid Live Editor**
1. 访问 [Mermaid Live Editor](https://mermaid.live/)
2. 粘贴代码
3. 点击"Export"按钮
4. 选择 PNG 或 SVG 格式
**方法 2浏览器截图**
1. 在浏览器中打开文章
2. 使用截图工具截取图表
3. Windows: Win + Shift + S
4. Mac: Cmd + Shift + 4
**方法 3开发者工具**
1. 右键点击图表 → 检查元素
2. 找到 SVG 元素
3. 右键 → Copy → Copy outerHTML
4. 保存为 .svg 文件
5. 使用工具转换为 PNG
**方法 4使用插件**
- 安装浏览器截图插件
- 如 Awesome Screenshot
- 直接截取并保存
---
### Q23: 如何在 Mermaid 代码中使用中文?
**A:** Mermaid 完全支持中文,直接使用即可。
**示例:**
```mermaid
flowchart TD
开始([开始]) --> 处理[处理数据]
处理 --> 判断{是否成功?}
判断 -->|是| 成功([成功])
判断 -->|否| 失败([失败])
```
**注意事项:**
1. **引号问题**
- 如果文本包含特殊字符,使用引号包裹
- `A["包含特殊字符的文本"]`
2. **编码问题**
- 确保文件编码为 UTF-8
- WordPress 默认使用 UTF-8
3. **字体问题**
- 确保浏览器支持中文字体
- 现代浏览器都支持
---
### Q24: 如何在 Mermaid 中添加链接?
**A:** Mermaid 支持为节点添加链接。
**语法:**
```mermaid
flowchart TD
A[节点 A]
B[节点 B]
A --> B
click A "https://example.com" "点击访问"
click B "https://example.com" _blank
```
**参数说明:**
- 第一个参数:节点 ID
- 第二个参数:链接 URL
- 第三个参数:提示文本或打开方式
- `"提示文本"` - 鼠标悬停提示
- `_blank` - 新标签页打开
- `_self` - 当前标签页打开
---
### Q25: 如何使用 Mermaid 的高级功能?
**A:** Mermaid 支持许多高级功能。
**1. 子图 (Subgraph)**
```mermaid
flowchart TD
subgraph 输入阶段
A[接收] --> B[验证]
end
subgraph 处理阶段
B --> C[处理]
end
```
**2. 样式定义**
```mermaid
flowchart TD
A[节点 A]
B[节点 B]
A --> B
style A fill:#f9f,stroke:#333,stroke-width:4px
style B fill:#bbf,stroke:#333,stroke-width:2px
```
**3. 类样式**
```mermaid
flowchart TD
A[节点 A]:::someclass
B[节点 B]:::someclass
classDef someclass fill:#f96,stroke:#333
```
**4. 注释**
```mermaid
%% 这是注释,不会显示
flowchart TD
A --> B %% 行尾注释
```
**更多功能:**
- 查看 [Mermaid 官方文档](https://mermaid.js.org/)
- 参考各图表类型的详细语法
---
## 获取更多帮助
### 官方资源
- 📚 [Mermaid 官方文档](https://mermaid.js.org/)
- 🎨 [Mermaid Live Editor](https://mermaid.live/)
- 💬 [Mermaid GitHub](https://github.com/mermaid-js/mermaid)
### Argon 主题支持
- 🐛 [提交 Issue](https://github.com/solstice23/argon-theme/issues)
- 📖 [主题文档](https://github.com/solstice23/argon-theme)
- 💡 [用户指南](mermaid-user-guide.md)
### 社区资源
- 🌐 WordPress 论坛
- 💬 主题用户群
- 📝 技术博客和教程
---
**最后更新:** 2024-01-22
**文档版本:** 1.0.0

View File

@@ -2,7 +2,30 @@
## 推荐的标记方式
### Markdown 容器语法(推荐)⭐
### 1. 标准 Markdown 代码块(推荐)⭐
```markdown
三个反引号mermaid
flowchart TD
A[开始] --> B[处理]
B --> C[结束]
三个反引号
```
**优点**
- ✅ 符合标准 Markdown 语法
- ✅ 在所有 Markdown 编辑器中都能正确显示
- ✅ 支持语法高亮(编辑器层面)
- ✅ 易于迁移到其他平台GitHub、GitLab、Typora 等)
- ✅ 主题自动拦截处理,避免代码高亮干扰
- ✅ 支持所有 Mermaid 图表类型
**工作原理**
- 主题在代码高亮之前拦截 mermaid 代码块
- 自动转换为 Mermaid 渲染容器
- 完全绕过代码高亮和 WordPress 格式化
### 2. Markdown 容器语法(备选)
```markdown
::: mermaid
@@ -20,19 +43,41 @@ flowchart TD
- ✅ 在纯文本编辑器中也很清晰
- ✅ 易于迁移到其他平台
### 为什么使用容器语法?
### 3. Shortcode 格式(兼容)
**Markdown 容器语法** (`::: mermaid ... :::`) 是现代 Markdown 扩展的标准方式:
```
[mermaid]
flowchart TD
A[开始] --> B[处理]
B --> C[结束]
[/mermaid]
```
- **VuePress** 使用这种语法
- **Docusaurus** 使用这种语法
- **MkDocs** 使用类似语法
- **符合 CommonMark 扩展规范**
**优点**
- ✅ WordPress 原生支持
- ✅ 不会被任何插件干扰
- ✅ 兼容性最好
这种语法不会被 WP-Markdown 插件当作代码块处理,因此
- 不会被套上代码高亮窗口
**缺点**
- ❌ 不符合 Markdown 标准
- ❌ 在其他平台无法使用
- ❌ 编辑器中不显示为代码块
### 为什么推荐标准 Markdown 代码块?
**标准 Markdown 代码块** (` ```mermaid `) 是最通用的方式:
- **GitHub** 使用这种语法
- **GitLab** 使用这种语法
- **Typora** 使用这种语法
- **VS Code** 使用这种语法
- **符合 CommonMark 规范**
Argon 主题通过**代码块魔改**技术,在代码高亮之前拦截并转换 mermaid 代码块,因此:
- 不会被代码高亮处理(无行号、无控制按钮)
- 不会有字符转义问题(`-->` 保持不变)
- 不会有嵌套结构问题
- 不会有字符转义问题
- 完全符合标准 Markdown 语法
---
@@ -40,6 +85,17 @@ flowchart TD
### 流程图
**标准 Markdown 代码块:**
```markdown
三个反引号mermaid
flowchart LR
A[用户] --> B{登录?}
B -->|是| C[显示首页]
B -->|否| D[跳转登录页]
三个反引号
```
**容器语法:**
```markdown
::: mermaid
flowchart LR
@@ -52,18 +108,18 @@ flowchart LR
### 时序图
```markdown
::: mermaid
三个反引号mermaid
sequenceDiagram
Alice->>Bob: Hello Bob!
Bob-->>Alice: Hi Alice!
Alice->>Bob: How are you?
:::
三个反引号
```
### 类图
```markdown
::: mermaid
三个反引号mermaid
classDiagram
class Animal {
+String name
@@ -75,13 +131,13 @@ classDiagram
+bark()
}
Animal <|-- Dog
:::
三个反引号
```
### 甘特图
```markdown
::: mermaid
三个反引号mermaid
gantt
title 项目进度
dateFormat YYYY-MM-DD
@@ -91,31 +147,31 @@ gantt
section 开发
前端开发 :b1, after a2, 10d
后端开发 :b2, after a2, 12d
:::
三个反引号
```
### 状态图
```markdown
::: mermaid
三个反引号mermaid
stateDiagram-v2
[*] --> 待审核
待审核 --> 已通过: 审核通过
待审核 --> 已拒绝: 审核拒绝
已通过 --> [*]
已拒绝 --> [*]
:::
三个反引号
```
### 饼图
```markdown
::: mermaid
三个反引号mermaid
pie title 宠物分布
"狗" : 386
"猫" : 85
"兔子" : 15
:::
三个反引号
```
---
@@ -195,22 +251,30 @@ pie title 宠物分布
## 最佳实践
### 1. 使用容器语法
### 1. 使用标准 Markdown 代码块
**推荐:**
```markdown
三个反引号mermaid
flowchart TD
A --> B
三个反引号
```
**也可以使用容器语法:**
```markdown
::: mermaid
flowchart TD
A --> B
:::
```
**不推荐:**
**不推荐Shortcode**
```
三个反引号mermaid
[mermaid]
flowchart TD
A --> B
三个反引号
[/mermaid]
```
### 2. 避免特殊字符
@@ -252,19 +316,48 @@ flowchart TD
Argon 主题支持以下格式(按优先级排序):
1. `::: mermaid ... :::` - Markdown 容器语法 ⭐(推荐)
2. `<div class="mermaid">` - 标准格式WPMD 生成
3. `<pre><code class="language-mermaid">` - Markdown 格式
4. `<pre data-lang="mermaid">` - 自定义属性格式
5. `<code class="mermaid">` - 简化格式
1. ` ```mermaid ... ``` ` - 标准 Markdown 代码块 ⭐(推荐)
2. `::: mermaid ... :::` - Markdown 容器语法(备选
3. `[mermaid]...[/mermaid]` - Shortcode 格式(兼容)
4. `<div class="mermaid">` - 标准格式WPMD 生成)
5. `<pre><code class="language-mermaid">` - Markdown 格式(降级)
6. `<pre data-lang="mermaid">` - 自定义属性格式
7. `<code class="mermaid">` - 简化格式
### 代码块魔改技术
**工作原理**
1. **拦截阶段**(在代码高亮之前)
- 查找所有 `<pre><code class="language-mermaid">` 元素
- 提取纯文本代码(使用 `textContent`
- 创建 `<div class="mermaid-from-codeblock">` 容器
- 替换原始代码块元素
2. **代码高亮阶段**
- 处理其他代码块
- 跳过 mermaid 相关的元素
3. **Mermaid 渲染阶段**
- 检测所有 Mermaid 容器(包括新的 `mermaid-from-codeblock`
- 提取代码并渲染为 SVG 图表
**优势**
- ✅ 完全绕过代码高亮干扰
- ✅ 特殊字符不被转换(`-->` 保持不变)
- ✅ 换行符正确保留
- ✅ 支持 PJAX 页面切换
- ✅ 性能无明显影响
### 代码提取逻辑
1. **检测代码块**
- CSS 选择器查找标准格式
- TreeWalker 查找容器语法
- 代码块魔改:在代码高亮前拦截
2. **提取代码**
- 代码块魔改格式:直接提取 `textContent`
- 容器语法:移除 `::: mermaid``:::`
- WPMD 格式:正则提取 `document.write()` 内容
- 标准格式:直接提取文本内容
@@ -329,11 +422,16 @@ Argon 主题支持以下格式(按优先级排序):
## 更新日志
### 2026-01-24
-**新增代码块魔改支持**:支持标准 Markdown 代码块 (` ```mermaid `)
- ✅ 在代码高亮之前拦截并转换 mermaid 代码块
- ✅ 完全绕过代码高亮和 WordPress 格式化
- ✅ 特殊字符不被转换(`-->` 保持不变)
- ✅ 换行符正确保留
- ✅ 支持 PJAX 页面切换
- ✅ 添加 Markdown 容器语法支持(`::: mermaid ... :::`
- ✅ 修复 WP-Markdown 格式的代码提取问题
- ✅ 改进正则表达式,支持多行代码
- ✅ 添加降级方案和详细日志
- ✅ 简化标记方式,只保留容器语法作为推荐方式
- ✅ 修复代码高亮干扰 mermaid 渲染的问题(排除 mermaid 代码块)
- ✅ 修复容器语法中空行导致内容被截断的问题
- ✅ 修复 WP-Markdown 的 document.write 重复输出问题

719
docs/mermaid-user-guide.md Normal file
View File

@@ -0,0 +1,719 @@
# Argon 主题 Mermaid 图表使用指南
## 目录
1. [功能简介](#功能简介)
2. [快速开始](#快速开始)
3. [支持的图表类型](#支持的图表类型)
4. [使用方法](#使用方法)
5. [主题设置](#主题设置)
6. [常见问题](#常见问题)
7. [最佳实践](#最佳实践)
8. [故障排除](#故障排除)
---
## 功能简介
Argon 主题内置了 Mermaid 图表支持,让您可以在文章中轻松创建各种专业的图表,包括:
- 📊 **流程图** - 展示业务流程和逻辑关系
- 📈 **时序图** - 描述系统交互和时间顺序
- 🏗️ **类图** - 展示面向对象的类结构
- 📉 **状态图** - 表示状态机和状态转换
- 🥧 **饼图** - 显示数据占比
- 📅 **甘特图** - 项目进度管理
- 🗺️ **用户旅程图** - 用户体验流程
- 🌳 **Git 图** - 版本控制分支可视化
### 主要特性
**零配置使用** - 开箱即用,无需额外插件
**自动主题切换** - 跟随页面日间/夜间模式
**智能加载** - 只在需要时加载库文件
**插件兼容** - 自动检测并避免重复加载
**错误提示** - 友好的错误信息和调试支持
**CDN 降级** - 多个 CDN 自动切换,确保可用性
---
## 快速开始
### 1. 启用 Mermaid 支持
进入 **WordPress 后台 → 外观 → Argon 主题设置 → Mermaid 图表**,勾选"启用 Mermaid 支持"。
### 2. 在文章中使用
在文章编辑器中,使用以下格式插入 Mermaid 代码:
````markdown
```mermaid
flowchart TD
Start([开始]) --> Process[处理数据]
Process --> End([结束])
```
````
或使用 HTML 格式:
```html
<div class="mermaid">
flowchart TD
Start([开始]) --> Process[处理数据]
Process --> End([结束])
</div>
```
### 3. 发布并查看
保存文章后,在前台页面即可看到渲染后的图表。
---
## 支持的图表类型
### 1. 流程图 (Flowchart)
展示流程和决策逻辑。
````markdown
```mermaid
flowchart TD
A[开始] --> B{判断条件}
B -->|是| C[执行操作 A]
B -->|否| D[执行操作 B]
C --> E[结束]
D --> E
```
````
**节点形状:**
- `[文本]` - 矩形
- `([文本])` - 圆角矩形
- `{文本}` - 菱形(判断)
- `((文本))` - 圆形
- `[[文本]]` - 子程序
### 2. 时序图 (Sequence Diagram)
描述对象之间的交互顺序。
````markdown
```mermaid
sequenceDiagram
participant 用户
participant 服务器
participant 数据库
用户->>服务器: 发送请求
服务器->>数据库: 查询数据
数据库-->>服务器: 返回结果
服务器-->>用户: 响应数据
```
````
**箭头类型:**
- `->` - 实线箭头
- `-->` - 虚线箭头
- `->>` - 实线箭头(带箭头)
- `-->>` - 虚线箭头(带箭头)
### 3. 类图 (Class Diagram)
展示面向对象的类结构。
````markdown
```mermaid
classDiagram
class Animal {
+String name
+int age
+makeSound()
}
class Dog {
+String breed
+bark()
}
class Cat {
+meow()
}
Animal <|-- Dog
Animal <|-- Cat
```
````
### 4. 状态图 (State Diagram)
表示状态机和状态转换。
````markdown
```mermaid
stateDiagram-v2
[*] --> 待处理
待处理 --> 处理中: 开始处理
处理中 --> 已完成: 处理成功
处理中 --> 失败: 处理失败
失败 --> 待处理: 重试
已完成 --> [*]
```
````
### 5. 饼图 (Pie Chart)
显示数据占比。
````markdown
```mermaid
pie title 浏览器市场份额
"Chrome" : 65
"Safari" : 15
"Firefox" : 10
"Edge" : 7
"其他" : 3
```
````
### 6. 甘特图 (Gantt Chart)
项目进度管理。
````markdown
```mermaid
gantt
title 项目开发计划
dateFormat YYYY-MM-DD
section 设计阶段
需求分析 :a1, 2024-01-01, 7d
UI 设计 :a2, after a1, 5d
section 开发阶段
前端开发 :b1, after a2, 10d
后端开发 :b2, after a2, 12d
section 测试阶段
功能测试 :c1, after b1, 5d
```
````
### 7. 用户旅程图 (User Journey)
描述用户体验流程。
````markdown
```mermaid
journey
title 用户购物旅程
section 浏览商品
访问网站: 5: 用户
搜索商品: 3: 用户
查看详情: 4: 用户
section 下单
加入购物车: 4: 用户
填写信息: 2: 用户
支付: 3: 用户
section 收货
等待发货: 2: 用户
收到商品: 5: 用户
```
````
### 8. Git 图 (Git Graph)
版本控制分支可视化。
````markdown
```mermaid
gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
```
````
---
## 使用方法
### 在 Markdown 编辑器中使用
如果您使用 Markdown 编辑器(如 WP-Markdown直接使用代码块语法
````markdown
```mermaid
flowchart LR
A --> B
B --> C
```
````
### 在 Gutenberg 编辑器中使用
1. 添加"代码"块或"自定义 HTML"块
2. 输入 Mermaid 代码
3. 使用 `<div class="mermaid">` 包裹
```html
<div class="mermaid">
flowchart LR
A --> B
B --> C
</div>
```
### 在经典编辑器中使用
切换到"文本"模式,使用 HTML 格式:
```html
<div class="mermaid">
flowchart LR
A --> B
B --> C
</div>
```
---
## 主题设置
### 基本设置
#### 启用 Mermaid 支持
**位置:** Argon 主题设置 → Mermaid 图表 → 基本设置
勾选此选项以启用 Mermaid 图表渲染功能。
#### CDN 来源
选择 Mermaid 库的加载来源:
- **jsDelivr CDN** (推荐) - 全球 CDN速度快稳定性高
- **unpkg CDN** - 备用 CDN
- **自定义 CDN 地址** - 使用自己的 CDN 或镜像
- **本地文件** - 使用主题目录中的本地文件
**建议:** 使用 jsDelivr CDN主题会自动在多个 CDN 之间切换以确保可用性。
#### 自定义 CDN 地址
当选择"自定义 CDN 地址"时,输入完整的 Mermaid 库 URL。
**格式要求:**
- 必须是有效的 URL
- 必须以 `.js` 结尾
- 必须使用 `http://` 或 `https://` 协议
**示例:**
```
https://cdn.example.com/mermaid@10.0.0/mermaid.min.js
```
### 外观设置
#### 图表主题
选择 Mermaid 图表的配色主题:
- **自动切换** (推荐) - 跟随页面日间/夜间模式自动切换
- **默认主题** - 浅色主题,适合日间模式
- **深色主题** - 深色主题,适合夜间模式
- **森林主题** - 绿色主题
- **中性主题** - 灰色主题
**建议:** 使用"自动切换",让图表主题与页面主题保持一致。
### 高级选项
#### 使用本地镜像
启用后,如果检测到主题目录中存在 Mermaid 库文件,将优先使用本地文件而不是 CDN。
**本地文件路径:**
```
wp-content/themes/argon/assets/vendor/mermaid/mermaid.min.js
```
**适用场景:**
- 内网环境无法访问外部 CDN
- 需要使用特定版本的 Mermaid
- 追求极致的加载速度
#### 调试模式
启用后,将在浏览器控制台输出详细的 Mermaid 渲染日志。
**日志内容包括:**
- 初始化状态
- 检测到的代码块数量
- 渲染成功/失败信息
- 主题切换记录
- CDN 加载状态
**使用方法:**
1. 启用调试模式
2. 打开浏览器开发者工具F12
3. 切换到"控制台"标签
4. 查看以 `[Argon Mermaid]` 开头的日志
#### 插件兼容性检测
主题会自动检测已安装的 Mermaid 插件,避免重复加载库文件。
**支持的插件:**
- WP Githuber MD
- Markdown Block
- Code Syntax Block
**兼容策略:**
- 如果检测到插件,主题将只提供样式增强
- 如果未检测到插件,主题将负责加载 Mermaid 库
- 如果检测到多个插件,会显示警告信息
---
## 常见问题
### Q1: 图表不显示,只显示代码?
**可能原因:**
1. 未启用 Mermaid 支持
2. 代码格式不正确
3. JavaScript 加载失败
**解决方法:**
1. 检查主题设置中是否启用了 Mermaid 支持
2. 确认代码格式正确(参考本文档示例)
3. 打开浏览器控制台查看是否有错误信息
4. 启用调试模式查看详细日志
### Q2: 图表显示"渲染失败"错误?
**可能原因:**
1. Mermaid 代码语法错误
2. 使用了不支持的图表类型
3. 代码格式不符合规范
**解决方法:**
1. 检查代码语法是否正确
2. 使用 [Mermaid Live Editor](https://mermaid.live/) 验证代码
3. 查看错误提示中的详细信息
4. 参考本文档中的示例代码
### Q3: 图表在夜间模式下看不清?
**解决方法:**
1. 进入主题设置 → Mermaid 图表 → 外观设置
2. 将"图表主题"设置为"自动切换"
3. 图表会自动跟随页面主题切换
### Q4: CDN 加载失败怎么办?
**主题已内置降级机制:**
1. 主 CDN 失败时,自动尝试备用 CDN
2. 所有 CDN 都失败时,显示友好的错误提示
**手动解决:**
1. 切换到其他 CDN 来源
2. 使用自定义 CDN 地址
3. 下载本地文件并启用"使用本地镜像"
### Q5: 与其他插件冲突?
**主题已内置兼容机制:**
- 自动检测已安装的 Mermaid 插件
- 避免重复加载库文件
- 只提供样式增强功能
**如果仍有冲突:**
1. 查看插件兼容性检测结果
2. 禁用主题的 Mermaid 支持,使用插件
3. 或禁用插件,使用主题的 Mermaid 支持
### Q6: 如何在评论中使用 Mermaid
**方法:**
1. 评论中使用 HTML 格式
2. 使用 `<div class="mermaid">` 包裹代码
**示例:**
```html
<div class="mermaid">
flowchart LR
A --> B
</div>
```
**注意:** 需要确保评论允许 HTML 标签。
### Q7: 图表太大,超出容器?
**解决方法:**
1. Mermaid 图表会自动适应容器宽度
2. 如果图表过于复杂,考虑简化或拆分
3. 使用 CSS 自定义样式调整大小
**自定义样式示例:**
```css
.mermaid-container {
max-width: 100%;
overflow-x: auto;
}
```
### Q8: 如何导出图表为图片?
**方法 1使用浏览器截图**
1. 在浏览器中打开文章
2. 使用截图工具截取图表部分
**方法 2使用 Mermaid Live Editor**
1. 访问 [Mermaid Live Editor](https://mermaid.live/)
2. 粘贴代码
3. 点击"Export"导出为 PNG/SVG
**方法 3使用浏览器开发者工具**
1. 右键点击图表 → 检查元素
2. 找到 SVG 元素
3. 复制 SVG 代码或导出为图片
---
## 最佳实践
### 1. 代码格式规范
**推荐:**
```mermaid
flowchart TD
A[开始] --> B[处理]
B --> C[结束]
```
**不推荐:**
```mermaid
flowchart TD
A[开始]-->B[处理]
B-->C[结束]
```
**建议:**
- 使用缩进保持代码可读性
- 箭头两侧添加空格
- 每行一个语句
### 2. 节点命名
**推荐:**
```mermaid
flowchart TD
start([开始])
process[处理数据]
decision{是否成功?}
```
**不推荐:**
```mermaid
flowchart TD
a([开始])
b[处理数据]
c{是否成功?}
```
**建议:**
- 使用有意义的节点 ID
- 节点文本简洁明了
- 避免使用特殊字符
### 3. 图表复杂度
**建议:**
- 单个图表不超过 20 个节点
- 复杂流程拆分为多个图表
- 使用子图组织相关节点
**示例:**
```mermaid
flowchart TD
subgraph 输入阶段
A[接收数据] --> B[验证数据]
end
subgraph 处理阶段
B --> C[处理数据]
C --> D[保存结果]
end
```
### 4. 性能优化
**建议:**
- 避免在一篇文章中使用过多图表(建议不超过 10 个)
- 复杂图表考虑使用图片替代
- 启用 CDN 加速加载
### 5. 可访问性
**建议:**
- 为图表添加文字说明
- 使用清晰的节点文本
- 避免仅依赖颜色传达信息
**示例:**
```html
<div class="mermaid-wrapper">
<p>以下是用户注册流程图:</p>
<div class="mermaid">
flowchart TD
Start([用户访问注册页]) --> Input[填写信息]
Input --> Validate{验证信息}
Validate -->|通过| Register[注册成功]
Validate -->|失败| Input
</div>
</div>
```
### 6. 版本控制
**建议:**
- 在文章中记录 Mermaid 代码版本
- 复杂图表保存源代码备份
- 使用注释说明图表用途
**示例:**
```mermaid
%% 用户注册流程图
%% 版本: 1.0
%% 更新日期: 2024-01-20
flowchart TD
Start --> End
```
---
## 故障排除
### 调试步骤
1. **启用调试模式**
- 进入主题设置 → Mermaid 图表 → 高级选项
- 勾选"启用调试模式"
2. **打开浏览器控制台**
- 按 F12 打开开发者工具
- 切换到"控制台"标签
3. **查看日志信息**
- 查找以 `[Argon Mermaid]` 开头的日志
- 记录错误信息和警告
4. **验证代码语法**
- 访问 [Mermaid Live Editor](https://mermaid.live/)
- 粘贴代码并检查是否有语法错误
5. **检查网络请求**
- 在开发者工具中切换到"网络"标签
- 查看 Mermaid 库是否成功加载
- 检查是否有 404 或其他错误
### 常见错误代码
#### 错误 1: Parse error on line X
**原因:** Mermaid 代码语法错误
**解决:**
1. 检查代码语法是否正确
2. 使用 Mermaid Live Editor 验证
3. 参考官方文档修正语法
#### 错误 2: Mermaid 库未加载
**原因:** CDN 加载失败或被阻止
**解决:**
1. 检查网络连接
2. 切换到其他 CDN 来源
3. 使用本地文件
#### 错误 3: 主题切换失败
**原因:** 配置错误或 JavaScript 冲突
**解决:**
1. 检查主题设置是否正确
2. 禁用其他可能冲突的插件
3. 清除浏览器缓存
### 获取帮助
如果以上方法都无法解决问题,请:
1. **收集信息:**
- WordPress 版本
- Argon 主题版本
- 浏览器类型和版本
- 错误信息和日志
- 问题复现步骤
2. **提交问题:**
- 访问 [Argon 主题 GitHub](https://github.com/solstice23/argon-theme/issues)
- 创建新 Issue
- 提供详细的问题描述和信息
3. **社区支持:**
- 访问主题官方论坛
- 搜索类似问题
- 向社区求助
---
## 相关资源
### 官方文档
- [Mermaid 官方文档](https://mermaid.js.org/)
- [Mermaid 语法参考](https://mermaid.js.org/intro/syntax-reference.html)
- [Mermaid Live Editor](https://mermaid.live/)
### 教程和示例
- [Mermaid 快速入门](https://mermaid.js.org/intro/getting-started.html)
- [流程图教程](https://mermaid.js.org/syntax/flowchart.html)
- [时序图教程](https://mermaid.js.org/syntax/sequenceDiagram.html)
- [类图教程](https://mermaid.js.org/syntax/classDiagram.html)
### 工具和插件
- [Mermaid Chart](https://www.mermaidchart.com/) - 在线图表编辑器
- [VS Code Mermaid 插件](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
- [Chrome Mermaid 扩展](https://chrome.google.com/webstore/search/mermaid)
---
## 更新日志
### 版本 1.0.0 (2024-01-22)
- ✨ 初始版本发布
- ✅ 支持所有主要图表类型
- ✅ 自动主题切换
- ✅ 插件兼容性检测
- ✅ CDN 降级机制
- ✅ 错误提示和调试支持
---
## 反馈与建议
如果您在使用过程中有任何问题或建议,欢迎:
- 📧 发送邮件至主题作者
- 💬 在 GitHub 上提交 Issue
- 🌟 为项目点赞支持
感谢您使用 Argon 主题!

View File

@@ -3217,6 +3217,239 @@ function themeoptions_page(){
</td>
</tr>
<tr><th class="subtitle"><h3 id="subsection-mermaid-preview"><?php _e('预览与示例', 'argon');?></h3></th></tr>
<tr>
<th><label><?php _e('实时预览', 'argon');?></label></th>
<td>
<div id="mermaid-preview-container" style="margin-bottom: 20px;">
<div style="margin-bottom: 10px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold;">
<?php _e('选择示例图表:', 'argon'); ?>
</label>
<select id="mermaid-example-selector" style="width: 100%; max-width: 400px; padding: 5px;">
<option value="flowchart"><?php _e('流程图 (Flowchart)', 'argon'); ?></option>
<option value="sequence"><?php _e('时序图 (Sequence Diagram)', 'argon'); ?></option>
<option value="class"><?php _e('类图 (Class Diagram)', 'argon'); ?></option>
<option value="state"><?php _e('状态图 (State Diagram)', 'argon'); ?></option>
<option value="gantt"><?php _e('甘特图 (Gantt Chart)', 'argon'); ?></option>
<option value="pie"><?php _e('饼图 (Pie Chart)', 'argon'); ?></option>
<option value="git"><?php _e('Git 图 (Git Graph)', 'argon'); ?></option>
</select>
</div>
<div style="margin-bottom: 10px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold;">
<?php _e('Mermaid 代码:', 'argon'); ?>
</label>
<textarea id="mermaid-code-input" rows="10" style="width: 100%; font-family: monospace; padding: 10px; border: 1px solid #ddd; border-radius: 4px;"></textarea>
</div>
<div style="margin-bottom: 10px;">
<button type="button" id="mermaid-render-btn" class="button button-primary">
<?php _e('渲染预览', 'argon'); ?>
</button>
<button type="button" id="mermaid-reset-btn" class="button">
<?php _e('重置', 'argon'); ?>
</button>
</div>
<div style="margin-bottom: 10px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold;">
<?php _e('预览效果:', 'argon'); ?>
</label>
<div id="mermaid-preview-output" style="padding: 20px; background: #f9f9f9; border: 1px solid #ddd; border-radius: 4px; min-height: 200px; overflow-x: auto;">
<p style="color: #666; text-align: center; margin: 80px 0;">
<?php _e('请选择示例或输入 Mermaid 代码,然后点击"渲染预览"按钮', 'argon'); ?>
</p>
</div>
</div>
<div id="mermaid-preview-error" style="display: none; padding: 10px; background: #fff3cd; border: 1px solid #ffc107; border-radius: 4px; margin-top: 10px;">
<p style="margin: 0; color: #856404;">
<strong><?php _e('渲染错误:', 'argon'); ?></strong>
<span id="mermaid-error-message"></span>
</p>
</div>
</div>
<p class="description">
<?php _e('在此预览区域可以实时测试 Mermaid 图表的渲染效果。选择示例图表或输入自定义代码,点击"渲染预览"查看效果。', 'argon'); ?>
</p>
<script>
// Mermaid 示例代码
const mermaidExamples = {
flowchart: `flowchart TD
A[开始] --> B{是否登录?}
B -->|是| C[显示主页]
B -->|否| D[跳转登录页]
C --> E[结束]
D --> E`,
sequence: `sequenceDiagram
participant 用户
participant 浏览器
participant 服务器
用户->>浏览器: 输入网址
浏览器->>服务器: 发送请求
服务器-->>浏览器: 返回页面
浏览器-->>用户: 显示内容`,
class: `classDiagram
class Animal {
+String name
+int age
+makeSound()
}
class Dog {
+String breed
+bark()
}
class Cat {
+String color
+meow()
}
Animal <|-- Dog
Animal <|-- Cat`,
state: `stateDiagram-v2
[*] --> 待机
待机 --> 运行: 启动
运行 --> 暂停: 暂停
暂停 --> 运行: 继续
运行 --> 停止: 停止
停止 --> [*]`,
gantt: `gantt
title 项目开发计划
dateFormat YYYY-MM-DD
section 设计阶段
需求分析 :a1, 2024-01-01, 7d
UI设计 :a2, after a1, 5d
section 开发阶段
前端开发 :b1, after a2, 10d
后端开发 :b2, after a2, 12d
section 测试阶段
功能测试 :c1, after b1, 5d
性能测试 :c2, after b2, 3d`,
pie: `pie title 编程语言使用占比
"JavaScript" : 35
"Python" : 25
"Java" : 20
"C++" : 12
"其他" : 8`,
git: `gitGraph
commit
commit
branch develop
checkout develop
commit
commit
checkout main
merge develop
commit
commit`
};
// 初始化
jQuery(document).ready(function($) {
const $selector = $('#mermaid-example-selector');
const $codeInput = $('#mermaid-code-input');
const $renderBtn = $('#mermaid-render-btn');
const $resetBtn = $('#mermaid-reset-btn');
const $output = $('#mermaid-preview-output');
const $error = $('#mermaid-preview-error');
const $errorMsg = $('#mermaid-error-message');
// 加载默认示例
$codeInput.val(mermaidExamples.flowchart);
// 切换示例
$selector.on('change', function() {
const example = $(this).val();
$codeInput.val(mermaidExamples[example]);
});
// 渲染预览
$renderBtn.on('click', function() {
const code = $codeInput.val().trim();
if (!code) {
alert('<?php _e('请输入 Mermaid 代码', 'argon'); ?>');
return;
}
// 隐藏错误信息
$error.hide();
// 显示加载状态
$output.html('<p style="color: #666; text-align: center; margin: 80px 0;"><?php _e('正在渲染...', 'argon'); ?></p>');
// 动态加载 Mermaid 库
if (typeof mermaid === 'undefined') {
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js';
script.onload = function() {
renderMermaid(code);
};
script.onerror = function() {
showError('<?php _e('Mermaid 库加载失败,请检查网络连接', 'argon'); ?>');
};
document.head.appendChild(script);
} else {
renderMermaid(code);
}
});
// 重置
$resetBtn.on('click', function() {
$selector.val('flowchart').trigger('change');
$output.html('<p style="color: #666; text-align: center; margin: 80px 0;"><?php _e('请选择示例或输入 Mermaid 代码,然后点击"渲染预览"按钮', 'argon'); ?></p>');
$error.hide();
});
// 渲染函数
function renderMermaid(code) {
try {
// 获取当前主题设置
const themeSelect = $('select[name="argon_mermaid_theme"]');
let theme = themeSelect.length ? themeSelect.val() : 'default';
// 如果是自动切换,根据当前页面模式选择主题
if (theme === 'auto') {
theme = $('html').hasClass('darkmode') ? 'dark' : 'default';
}
// 初始化 Mermaid
mermaid.initialize({
startOnLoad: false,
theme: theme,
securityLevel: 'loose',
logLevel: 'error'
});
// 生成唯一 ID
const id = 'mermaid-preview-' + Date.now();
// 渲染
mermaid.render(id, code).then(function(result) {
$output.html(result.svg);
$error.hide();
}).catch(function(error) {
showError(error.message || error.toString());
});
} catch (error) {
showError(error.message || error.toString());
}
}
// 显示错误
function showError(message) {
$output.html('<p style="color: #666; text-align: center; margin: 80px 0;"><?php _e('渲染失败', 'argon'); ?></p>');
$errorMsg.text(message);
$error.show();
}
});
</script>
</td>
</tr>
<!-- ========== 16. 高级设置 ========== -->
<tr><th class="subtitle"><h2 id="section-advanced"><?php _e('高级设置', 'argon');?></h2></th></tr>

View File

@@ -0,0 +1,187 @@
# AI 评论审核流程说明
## 流程概述
本文档通过 Mermaid 流程图详细展示用户提交评论后,系统进行 AI 审核的全流程涵盖预处理、规则判断、AI 检测、结果处理、数据学习等核心环节。
## 流程图
::: mermaid
flowchart TD
Start([用户提交评论]) --> PreProcess[预处理评论<br/>钩子preprocess_comment/post_comment_preprocessing]
PreProcess --> CheckEnabled{启用 AI 检测?}
CheckEnabled -->|否| SaveComment[保存评论]
CheckEnabled -->|是| CheckMode{检测模式?}
CheckMode -->|manual关闭实时检测| SaveComment
CheckMode -->|keyword/sample/all| CheckLoggedIn{已登录用户?}
CheckLoggedIn -->|是且跳过登录用户| SaveComment
CheckLoggedIn -->|否或不跳过| CheckWhitelist{在白名单?}
CheckWhitelist -->|是| SaveComment
CheckWhitelist -->|否| CheckKeyword[检查关键字触发]
CheckKeyword --> DecideCheck{决定是否检测}
DecideCheck -->|keyword模式且触发关键字| NeedCheck[需要检测]
DecideCheck -->|sample模式且触发关键字| NeedCheck
DecideCheck -->|sample模式且随机抽中| NeedCheck
DecideCheck -->|all模式| NeedCheck
DecideCheck -->|其他情况| SaveComment
NeedCheck --> SetPending[强制设置 comment_approved=0<br/>待审核状态]
SetPending --> SetFlag[设置 _argon_needs_spam_check=true]
SetFlag --> SaveKeywords[保存触发的关键字]
SaveKeywords --> SaveComment
SaveComment --> CommentPost[评论入库后处理<br/>钩子comment_post/post_comment_updatemetas]
CommentPost --> SaveMeta[保存评论元数据]
SaveMeta --> CheckNeedFlag{有 _argon_needs_spam_check 标记?}
CheckNeedFlag -->|否| ShowPending[显示审核中状态]
CheckNeedFlag -->|是| SaveCheckMeta[保存检测标记到数据库]
SaveCheckMeta --> AutoDetect[触发自动检测<br/>钩子comment_post/argon_auto_detect_spam_on_comment]
AutoDetect --> CheckSaved{有检测标记?}
CheckSaved -->|否| End1([结束])
CheckSaved -->|是| CheckDetected{已检测过?}
CheckDetected -->|是| End2([结束])
CheckDetected -->|否| CheckReason{检测原因?}
CheckReason -->|关键字触发| SyncDetect[立即同步检测]
CheckReason -->|其他| AsyncDetect[异步检测延迟1秒]
SyncDetect --> DetectHandler[检测处理函数<br/>argon_async_spam_detection_handler]
AsyncDetect --> DetectHandler
DetectHandler --> CallAI[调用 AI API<br/>argon_detect_spam_comment]
CallAI --> GetPrompt[根据 Prompt 模式获取提示词]
CallAI --> BuildContext[构建评论上下文(用户名+内容)]
BuildContext --> SendAPI[发送到 AI API]
SendAPI --> ParseResult[解析 AI 返回结果]
ParseResult --> SaveTime[记录检测时间]
SaveTime --> GenCode[生成识别码]
GenCode --> UpdateStats[更新用户统计]
UpdateStats --> CheckResult{检测结果?}
CheckResult -->|内容违规(高置信度)| CheckAction1{自动处理方式?}
CheckResult -->|内容违规(低置信度)| MarkLowConf[标记为疑似垃圾<br/>等待人工审核]
CheckResult -->|内容正常/用户名违规/无邮箱| TrashNoEmail[移入回收站]
CheckResult -->|内容正常/用户名违规/有邮箱| ChangeUsername[修改用户名]
CheckResult -->|都正常| MarkNormal[标记为正常评论]
CheckAction1 -->|trash| TrashComment[移入回收站]
CheckAction1 -->|hold| HoldComment[标记为待审核]
CheckAction1 -->|mark| MarkOnly[仅标记不处理]
TrashComment --> SendSpamEmail[发送垃圾评论通知]
HoldComment --> SendSpamEmail
MarkOnly --> SaveResult1[保存检测结果]
SendSpamEmail --> SaveResult1
MarkLowConf --> SaveResult2[保存检测结果]
TrashNoEmail --> SaveResult3[保存检测结果]
ChangeUsername --> GenNewName[生成新用户名]
GenNewName --> UpdateDB[更新数据库]
UpdateDB --> SendChangeEmail[发送用户名变更通知]
SendChangeEmail --> SaveResult4[保存检测结果]
MarkNormal --> SaveResult5[保存检测结果]
SaveResult1 --> AILearn{启用 AI 学习?}
SaveResult2 --> AILearn
SaveResult3 --> AILearn
SaveResult4 --> AILearn
SaveResult5 --> AILearn
AILearn -->|是| ExtractKeywords[提取关键词]
AILearn -->|否| DetectEnd([检测完成])
ExtractKeywords --> UpdateKeywords[更新学习关键词库]
UpdateKeywords --> DetectEnd
ShowPending --> UserView([用户看到:审核中状态])
DetectEnd --> AdminReview([管理员审核])
style Start fill:#e1f5e1,stroke:#2e7d32,stroke-width:2px
style End1 fill:#ffe1e1,stroke:#c62828,stroke-width:2px
style End2 fill:#ffe1e1,stroke:#c62828,stroke-width:2px
style DetectEnd fill:#e1f5e1,stroke:#2e7d32,stroke-width:2px
style UserView fill:#fff4e1,stroke:#ff8f00,stroke-width:2px
style AdminReview fill:#e1e8ff,stroke:#1565c0,stroke-width:2px
style NeedCheck fill:#ffcccc,stroke:#c62828,stroke-width:1px
style SetPending fill:#ffcccc,stroke:#c62828,stroke-width:1px
style TrashComment fill:#ff6b6b,stroke:#c62828,stroke-width:1px
style TrashNoEmail fill:#ff6b6b,stroke:#c62828,stroke-width:1px
style HoldComment fill:#ffa500,stroke:#ff8f00,stroke-width:1px
style MarkLowConf fill:#ffa500,stroke:#ff8f00,stroke-width:1px
style ChangeUsername fill:#4ecdc4,stroke:#00897b,stroke-width:1px
style MarkNormal fill:#95e1d3,stroke:#2e7d32,stroke-width:1px
:::
## 流程关键节点说明
### 1. 预处理阶段
- 触发 `preprocess_comment`/`post_comment_preprocessing` 钩子,完成评论基础清洗。
- 优先判断是否启用 AI 检测,未启用则直接保存评论。
### 2. 检测规则判断
- 检测模式分 4 类manual关闭、keyword关键字、sample抽样、all全量
- 白名单用户、已登录且配置跳过的用户,直接跳过检测。
- keyword/sample 模式下,仅关键字触发/随机抽中时才启动检测。
### 3. AI 检测执行
- 关键字触发:立即同步检测;其他情况:延迟 1 秒异步检测。
- 调用 `argon_detect_spam_comment` 接口,拼接用户名+评论内容作为上下文发送 AI。
### 4. 结果处理逻辑
| 检测结果 | 处理方式 |
|-------------------------|-----------------------------------|
| 内容违规(高置信度)| 按配置自动处理(移入回收站/待审核/仅标记) |
| 内容违规(低置信度)| 标记疑似垃圾,等待人工审核 |
| 用户名违规(无邮箱)| 直接移入回收站 |
| 用户名违规(有邮箱)| 自动生成新用户名并通知用户 |
| 内容+用户名均正常 | 标记为正常评论 |
### 5. 后续环节
- 所有检测结果均保存至数据库,支持 AI 学习功能(提取关键词更新词库)。
- 用户侧仅展示"审核中"状态,最终结果需管理员复核。
## 技术说明
### 使用的钩子
- `preprocess_comment` - 评论预处理
- `post_comment_preprocessing` - 评论预处理(备用)
- `comment_post` - 评论入库后
- `post_comment_updatemetas` - 更新评论元数据
- `argon_auto_detect_spam_on_comment` - 自动检测触发
### 关键函数
- `argon_detect_spam_comment()` - AI 检测主函数
- `argon_async_spam_detection_handler()` - 异步检测处理
- `argon_get_spam_detection_prompt()` - 获取检测 Prompt
- `argon_build_comment_context()` - 构建评论上下文
### 数据库字段
- `comment_approved` - 评论审核状态0=待审核1=已通过)
- `_argon_needs_spam_check` - 是否需要 AI 检测标记
- `_argon_spam_detection_result` - AI 检测结果
- `_argon_spam_detection_time` - 检测时间戳
- `_argon_spam_keywords` - 触发的关键字
## 配置建议
### 小型博客(评论量 < 100/天)
- 检测模式keyword关键字触发
- Prompt 模式:标准模式
- 自动处理阈值:置信度 > 0.9
### 中型博客(评论量 100-500/天)
- 检测模式sample智能抽样
- Prompt 模式:标准模式
- 自动处理阈值:置信度 > 0.85
### 大型博客(评论量 > 500/天)
- 检测模式sample智能抽样 30-40%
- Prompt 模式:极简模式
- 自动处理阈值:置信度 > 0.8
- 定期批量扫描待审核评论
## 注意事项
1. **API 成本控制**:合理设置检测模式和抽样比例
2. **误判处理**:始终保留人工审核入口
3. **隐私保护**:不要将敏感信息发送给 AI
4. **性能优化**:关键字触发使用同步检测,其他使用异步
5. **定期优化**:根据误判率调整 Prompt 和阈值

View File

@@ -0,0 +1,295 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mermaid 代码块魔改测试</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background: #f5f5f5;
}
.test-case {
background: white;
padding: 20px;
margin-bottom: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.test-case h3 {
margin-top: 0;
color: #333;
border-bottom: 2px solid #007bff;
padding-bottom: 10px;
}
.test-case .description {
color: #666;
margin-bottom: 15px;
font-size: 14px;
}
.mermaid-from-codeblock {
background: #f8f9fa;
padding: 15px;
border-radius: 4px;
border: 1px solid #dee2e6;
}
pre {
background: #f8f9fa;
padding: 15px;
border-radius: 4px;
border: 1px solid #dee2e6;
overflow-x: auto;
}
code {
font-family: 'Courier New', Courier, monospace;
}
</style>
<!-- Mermaid 库 -->
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
</head>
<body>
<h1>Mermaid 代码块魔改测试</h1>
<p>本页面用于测试标准 Markdown 代码块 (<code>```mermaid</code>) 的 Mermaid 图表渲染功能。</p>
<!-- 测试用例 1标准格式 -->
<div class="test-case">
<h3>测试用例 1标准 Markdown 格式</h3>
<div class="description">
格式:<code>&lt;pre&gt;&lt;code class="language-mermaid"&gt;</code>
</div>
<pre><code class="language-mermaid">
flowchart TD
A[开始] --> B{判断}
B -->|是| C[执行操作]
B -->|否| D[跳过]
C --> E[结束]
D --> E
</code></pre>
</div>
<!-- 测试用例 2多个代码块 -->
<div class="test-case">
<h3>测试用例 2多个代码块批量处理</h3>
<div class="description">
测试同一页面中多个 Mermaid 代码块的处理
</div>
<pre><code class="language-mermaid">
graph LR
A[客户端] --> B[服务器]
B --> C[数据库]
C --> B
B --> A
</code></pre>
<br>
<pre><code class="language-mermaid">
sequenceDiagram
participant 用户
participant 系统
用户->>系统: 发送请求
系统->>用户: 返回响应
</code></pre>
</div>
<!-- 测试用例 3特殊字符 -->
<div class="test-case">
<h3>测试用例 3特殊字符保留</h3>
<div class="description">
测试箭头符号 <code>--&gt;</code>、双横线 <code>--</code>、等号 <code>==</code> 等特殊字符是否正确保留
</div>
<pre><code class="language-mermaid">
flowchart TD
A --> B
B -- 文本 --> C
C ==> D
D -.-> E
E ~~~ F
</code></pre>
</div>
<!-- 测试用例 4空代码块 -->
<div class="test-case">
<h3>测试用例 4空代码块边界情况</h3>
<div class="description">
测试空代码块是否会导致错误
</div>
<pre><code class="language-mermaid"></code></pre>
<p style="color: #666; font-size: 14px;">空代码块应该被跳过,不会创建容器</p>
</div>
<!-- 测试用例 5多行代码块 -->
<div class="test-case">
<h3>测试用例 5多行代码块换行符保留</h3>
<div class="description">
测试多行代码块中的换行符是否正确保留
</div>
<pre><code class="language-mermaid">
graph TB
subgraph 子图1
A1[节点A1]
A2[节点A2]
end
subgraph 子图2
B1[节点B1]
B2[节点B2]
end
A1 --> B1
A2 --> B2
</code></pre>
</div>
<!-- 测试用例 6简化格式 -->
<div class="test-case">
<h3>测试用例 6简化格式</h3>
<div class="description">
格式:<code>&lt;pre&gt;&lt;code class="mermaid"&gt;</code>
</div>
<pre><code class="mermaid">
pie title 数据分布
"类别A" : 45
"类别B" : 30
"类别C" : 25
</code></pre>
</div>
<!-- 测试用例 7无 pre 包裹 -->
<div class="test-case">
<h3>测试用例 7无 pre 包裹</h3>
<div class="description">
格式:<code>&lt;code class="language-mermaid"&gt;</code>(无 pre 标签)
</div>
<code class="language-mermaid">
flowchart LR
Start --> Stop
</code>
</div>
<!-- 测试用例 8自定义属性格式 -->
<div class="test-case">
<h3>测试用例 8自定义属性格式</h3>
<div class="description">
格式:<code>&lt;pre data-lang="mermaid"&gt;</code>
</div>
<pre data-lang="mermaid">
stateDiagram-v2
[*] --> 状态1
状态1 --> 状态2
状态2 --> [*]
</pre>
</div>
<!-- 测试用例 9复杂图表 -->
<div class="test-case">
<h3>测试用例 9复杂图表</h3>
<div class="description">
测试复杂的 Mermaid 图表渲染
</div>
<pre><code class="language-mermaid">
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
</code></pre>
</div>
<script>
// 初始化 Mermaid
mermaid.initialize({
startOnLoad: false,
theme: 'default',
securityLevel: 'loose'
});
// 模拟主题的 convertMermaidCodeblocks 函数
function convertMermaidCodeblocks(){
const selectors = [
'pre > code.language-mermaid',
'pre > code.mermaid',
'code.language-mermaid',
'pre[data-lang="mermaid"]'
];
let processedCount = 0;
selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(element => {
if (element.dataset.mermaidProcessed) {
return;
}
let code = element.textContent.trim();
if (!code) {
return;
}
const container = document.createElement('div');
container.className = 'mermaid-from-codeblock';
container.textContent = code;
container.dataset.processed = 'true';
const targetElement = element.closest('pre') || element;
if (targetElement.parentNode) {
targetElement.parentNode.replaceChild(container, targetElement);
processedCount++;
}
element.dataset.mermaidProcessed = 'true';
});
});
console.log('[Mermaid] 转换了 ' + processedCount + ' 个代码块');
}
// 渲染 Mermaid 图表
function renderMermaidCharts(){
const blocks = document.querySelectorAll('.mermaid-from-codeblock');
console.log('[Mermaid] 找到 ' + blocks.length + ' 个待渲染的图表');
blocks.forEach((block, index) => {
const id = 'mermaid-' + Date.now() + '-' + index;
const code = block.textContent;
try {
mermaid.render(id, code).then(result => {
block.innerHTML = result.svg;
console.log('[Mermaid] 成功渲染图表 ' + (index + 1));
}).catch(error => {
console.error('[Mermaid] 渲染失败:', error);
block.innerHTML = '<div style="color: red; padding: 10px; border: 1px solid red; border-radius: 4px;">渲染失败: ' + error.message + '</div>';
});
} catch (error) {
console.error('[Mermaid] 渲染异常:', error);
}
});
}
// 页面加载完成后执行
document.addEventListener('DOMContentLoaded', function(){
console.log('[测试] 开始执行代码块转换');
convertMermaidCodeblocks();
console.log('[测试] 开始渲染 Mermaid 图表');
setTimeout(renderMermaidCharts, 100);
});
</script>
</body>
</html>

View File

@@ -120,7 +120,7 @@ flowchart TD
return blocks;
}
// 提取代码块内容
// 提取代码块内容(使用改进后的正则)
function extractMermaidCode(element) {
let code = '';
@@ -128,25 +128,31 @@ flowchart TD
const scriptTag = element.querySelector('script');
if (scriptTag) {
const scriptContent = scriptTag.textContent || scriptTag.innerText;
console.log('[测试] 原始 script 内容:', scriptContent);
console.log('[测试] 原始 script 内容:', scriptContent.substring(0, 100));
// 匹配 document.write("...") 或 document.write('...')
let match = scriptContent.match(/document\.write\s*\(\s*"((?:[^"\\]|\\.)*)"\s*\)/s);
if (!match) {
match = scriptContent.match(/document\.write\s*\(\s*'((?:[^'\\]|\\.)*)'\s*\)/s);
}
// 使用改进后的正则:[\s\S]*? 匹配包括换行在内的所有字符
let match = scriptContent.match(/document\.write\s*\(\s*["']([\s\S]*?)["']\s*\)/);
if (match && match[1]) {
code = match[1];
console.log('[测试] 提取到代码(转义前):', code);
console.log('[测试] 从 document.write() 提取到代码,长度:', code.length);
} else {
// 降级方案:直接提取引号内容
match = scriptContent.match(/["']([\s\S]*?)["']/);
if (match && match[1]) {
code = match[1];
console.log('[测试] 从引号内提取到代码,长度:', code.length);
} else {
const clonedElement = element.cloneNode(true);
const scripts = clonedElement.querySelectorAll('script');
scripts.forEach(script => script.remove());
code = clonedElement.textContent;
console.log('[测试] 使用降级方案提取代码');
}
}
} else {
code = element.textContent;
console.log('[测试] 从纯文本提取代码');
}
} else if (element.tagName === 'CODE') {
code = element.textContent;
@@ -172,7 +178,7 @@ flowchart TD
.replace(/\\'/g, "'")
.replace(/\\\\/g, '\\');
console.log('[测试] 最终提取的代码:', code);
console.log('[测试] 最终提取的代码:', code.substring(0, 100) + (code.length > 100 ? '...' : ''));
return code.trim();
}