Files
argon-theme/commit-msg-mermaid-final-fix.txt
nanhaoluo bf8f973e91 fix: 修复 Mermaid 容器语法的换行符和特殊字符问题
## 问题描述

用户报告 Mermaid 图表仍然渲染失败:
1. `flowchart TDStart` - `TD` 和 `Start` 之间没有换行符(有两个空格)
2. 箭头符号变成全角 `–>` 而不是 `-->`

## 根本原因分析

### 问题 1: 换行符丢失

WP-Markdown 可能将整个容器语法内容放在**一个** `<p>` 元素中:
```html
<p>::: mermaid<br>flowchart TD<br>Start --> End<br>:::</p>
```

而不是多个独立的 `<p>` 元素。之前的代码只处理了多元素的情况。

### 问题 2: 特殊字符转换

WordPress 的自动格式化功能会将某些字符转换为排版字符:
- `--` → `–` (U+2013 EN DASH)
- `---` → `—` (U+2014 EM DASH)
- `->` → `→` (U+2192 RIGHTWARDS ARROW)

这些字符在 Mermaid 语法中有特殊含义,必须保持原样。

## 修复方案

### 1. 支持单元素容器语法

在 `extractContainerContent()` 函数中添加检测逻辑:

```javascript
// 检查是否整个内容都在一个元素中
if (startText.includes(':::') && startText.lastIndexOf(':::') > 10) {
	// 整个容器语法在一个元素中
	let fullText = this.htmlToText(startHTML);
	// 移除开始和结束标记
	fullText = fullText.replace(/^:::\s*mermaid\s*/i, '').trim();
	fullText = fullText.replace(/:::\s*$/, '').trim();
	// 创建容器并返回
}
```

### 2. 增强 htmlToText() 函数

添加更多字符转换规则:

```javascript
// HTML 实体
.replace(/&#8211;/g, '-')  // EN DASH
.replace(/&#8212;/g, '--') // EM DASH
.replace(/&#8594;/g, '->') // RIGHTWARDS ARROW
.replace(/&ndash;/g, '-')  // EN DASH (named entity)
.replace(/&mdash;/g, '--') // EM DASH (named entity)
.replace(/&rarr;/g, '->'); // RIGHTWARDS ARROW (named entity)

// Unicode 字符
.replace(/–/g, '-')   // U+2013 EN DASH
.replace(/—/g, '--')  // U+2014 EM DASH
.replace(/→/g, '->'); // U+2192 RIGHTWARDS ARROW
```

### 3. 添加详细调试日志

```javascript
this.logDebug('检查元素,textContent: ' + startText.substring(0, 50));
this.logDebug('innerHTML: ' + startHTML.substring(0, 100));
this.logDebug('检测到单元素容器语法');
this.logDebug('转换后的完整文本: ' + fullText.substring(0, 200));
this.logDebug('移除标记后的代码: ' + fullText.substring(0, 200));
```

## 处理流程

### 单元素容器语法

```
1. 检测到 ::: mermaid 开始标记
2. 检查 textContent 中是否包含结束标记 :::
3. 如果包含,说明整个内容在一个元素中
4. 提取 innerHTML
   原始: "::: mermaid<br>flowchart TD<br>Start –> End<br>:::"
5. 使用 htmlToText() 转换
   - <br> → \n
   - – → -
   - → → ->
   结果: "::: mermaid\nflowchart TD\nStart --> End\n:::"
6. 移除开始和结束标记
   结果: "flowchart TD\nStart --> End"
7. 创建容器元素存储代码
```

### 多元素容器语法(保持原有逻辑)

```
1. 检测到 ::: mermaid 开始标记
2. 遍历后续兄弟元素
3. 收集所有内容直到 ::: 结束标记
4. 使用 \n 连接所有行
5. 创建容器元素存储代码
```

## 测试验证

### 测试用例 1: 单元素容器语法
```html
<p>::: mermaid<br>
flowchart TD<br>
    A[开始] –> B[处理]<br>
    B –> C[结束]<br>
:::</p>
```

预期结果:
```
flowchart TD
    A[开始] --> B[处理]
    B --> C[结束]
```

### 测试用例 2: 多元素容器语法
```html
<p>::: mermaid</p>
<p>flowchart TD</p>
<p>A --> B</p>
<p>:::</p>
```

预期结果:
```
flowchart TD
A --> B
```

### 测试用例 3: 复杂流程图(AI 评论审核)
- 100+ 个节点
- 多行文本(`<br/>` 标签)
- 箭头符号(`-->`, `-->`)
- 样式定义(`style` 语句)

## 影响范围

- 仅影响 Markdown 容器语法(`::: mermaid ... :::`)
- 不影响其他格式(`<div class="mermaid">`, `<pre><code>` 等)
- 向后兼容,支持单元素和多元素两种情况

## 相关文件

- `argontheme.js` - 修改 `extractContainerContent()` 和 `htmlToText()`
- `tests/test-ai-comment-flow.md` - 测试文档

## 技术细节

### WordPress 自动格式化

WordPress 的 `wptexturize()` 函数会自动转换以下字符:
- `--` → `–` (EN DASH)
- `---` → `—` (EM DASH)
- `->` → `→` (RIGHTWARDS ARROW)
- `(c)` → `©` (COPYRIGHT SIGN)
- `(r)` → `®` (REGISTERED SIGN)
- `(tm)` → `™` (TRADE MARK SIGN)

这些转换对于普通文本是有益的,但对于代码块(如 Mermaid)是有害的。

### 解决方案

1. **禁用自动格式化**(不推荐)
   - 会影响整个网站的排版
   - 需要修改 WordPress 核心代码

2. **在提取时反转换**(推荐)
   - 只影响 Mermaid 代码块
   - 不影响其他内容
   - 易于维护

### 字符映射表

| 原始字符 | HTML 实体 | Unicode | 显示 |
|---------|----------|---------|------|
| `-` | `&#45;` | U+002D | - |
| `--` | `&#8211;` / `&ndash;` | U+2013 | – |
| `---` | `&#8212;` / `&mdash;` | U+2014 | — |
| `->` | `&#8594;` / `&rarr;` | U+2192 | → |

## 注意事项

1. **性能影响**:增加了字符串替换操作,但性能影响可忽略
2. **安全性**:只处理 Mermaid 代码块,不执行任何脚本
3. **兼容性**:支持所有现代浏览器
4. **调试**:添加详细日志,便于排查问题

## 后续优化

1. 考虑使用 DOMParser 解析 HTML,更可靠
2. 添加更多特殊字符的转换规则
3. 支持自定义字符映射表
4. 添加单元测试

## 参考资料

- [WordPress wptexturize() 函数](https://developer.wordpress.org/reference/functions/wptexturize/)
- [Unicode 字符表](https://unicode-table.com/)
- [Mermaid 语法文档](https://mermaid.js.org/intro/syntax-reference.html)
2026-01-24 20:56:43 +08:00

208 lines
5.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
fix: 修复 Mermaid 容器语法的换行符和特殊字符问题
## 问题描述
用户报告 Mermaid 图表仍然渲染失败:
1. `flowchart TDStart` - `TD` 和 `Start` 之间没有换行符(有两个空格)
2. 箭头符号变成全角 `>` 而不是 `-->`
## 根本原因分析
### 问题 1: 换行符丢失
WP-Markdown 可能将整个容器语法内容放在**一个** `<p>` 元素中:
```html
<p>::: mermaid<br>flowchart TD<br>Start --> End<br>:::</p>
```
而不是多个独立的 `<p>` 元素。之前的代码只处理了多元素的情况。
### 问题 2: 特殊字符转换
WordPress 的自动格式化功能会将某些字符转换为排版字符:
- `--` → `` (U+2013 EN DASH)
- `---` → `—` (U+2014 EM DASH)
- `->` → `→` (U+2192 RIGHTWARDS ARROW)
这些字符在 Mermaid 语法中有特殊含义,必须保持原样。
## 修复方案
### 1. 支持单元素容器语法
在 `extractContainerContent()` 函数中添加检测逻辑:
```javascript
// 检查是否整个内容都在一个元素中
if (startText.includes(':::') && startText.lastIndexOf(':::') > 10) {
// 整个容器语法在一个元素中
let fullText = this.htmlToText(startHTML);
// 移除开始和结束标记
fullText = fullText.replace(/^:::\s*mermaid\s*/i, '').trim();
fullText = fullText.replace(/:::\s*$/, '').trim();
// 创建容器并返回
}
```
### 2. 增强 htmlToText() 函数
添加更多字符转换规则:
```javascript
// HTML 实体
.replace(/&#8211;/g, '-') // EN DASH
.replace(/&#8212;/g, '--') // EM DASH
.replace(/&#8594;/g, '->') // RIGHTWARDS ARROW
.replace(/&ndash;/g, '-') // EN DASH (named entity)
.replace(/&mdash;/g, '--') // EM DASH (named entity)
.replace(/&rarr;/g, '->'); // RIGHTWARDS ARROW (named entity)
// Unicode 字符
.replace(//g, '-') // U+2013 EN DASH
.replace(/—/g, '--') // U+2014 EM DASH
.replace(/→/g, '->'); // U+2192 RIGHTWARDS ARROW
```
### 3. 添加详细调试日志
```javascript
this.logDebug('检查元素textContent: ' + startText.substring(0, 50));
this.logDebug('innerHTML: ' + startHTML.substring(0, 100));
this.logDebug('检测到单元素容器语法');
this.logDebug('转换后的完整文本: ' + fullText.substring(0, 200));
this.logDebug('移除标记后的代码: ' + fullText.substring(0, 200));
```
## 处理流程
### 单元素容器语法
```
1. 检测到 ::: mermaid 开始标记
2. 检查 textContent 中是否包含结束标记 :::
3. 如果包含,说明整个内容在一个元素中
4. 提取 innerHTML
原始: "::: mermaid<br>flowchart TD<br>Start > End<br>:::"
5. 使用 htmlToText() 转换
- <br> → \n
- → -
- → → ->
结果: "::: mermaid\nflowchart TD\nStart --> End\n:::"
6. 移除开始和结束标记
结果: "flowchart TD\nStart --> End"
7. 创建容器元素存储代码
```
### 多元素容器语法(保持原有逻辑)
```
1. 检测到 ::: mermaid 开始标记
2. 遍历后续兄弟元素
3. 收集所有内容直到 ::: 结束标记
4. 使用 \n 连接所有行
5. 创建容器元素存储代码
```
## 测试验证
### 测试用例 1: 单元素容器语法
```html
<p>::: mermaid<br>
flowchart TD<br>
A[开始] > B[处理]<br>
B > C[结束]<br>
:::</p>
```
预期结果:
```
flowchart TD
A[开始] --> B[处理]
B --> C[结束]
```
### 测试用例 2: 多元素容器语法
```html
<p>::: mermaid</p>
<p>flowchart TD</p>
<p>A --> B</p>
<p>:::</p>
```
预期结果:
```
flowchart TD
A --> B
```
### 测试用例 3: 复杂流程图AI 评论审核)
- 100+ 个节点
- 多行文本(`<br/>` 标签)
- 箭头符号(`-->`, `-->`
- 样式定义(`style` 语句)
## 影响范围
- 仅影响 Markdown 容器语法(`::: mermaid ... :::`
- 不影响其他格式(`<div class="mermaid">`, `<pre><code>` 等)
- 向后兼容,支持单元素和多元素两种情况
## 相关文件
- `argontheme.js` - 修改 `extractContainerContent()` 和 `htmlToText()`
- `tests/test-ai-comment-flow.md` - 测试文档
## 技术细节
### WordPress 自动格式化
WordPress 的 `wptexturize()` 函数会自动转换以下字符:
- `--` → `` (EN DASH)
- `---` → `—` (EM DASH)
- `->` → `→` (RIGHTWARDS ARROW)
- `(c)` → `©` (COPYRIGHT SIGN)
- `(r)` → `®` (REGISTERED SIGN)
- `(tm)` → `™` (TRADE MARK SIGN)
这些转换对于普通文本是有益的,但对于代码块(如 Mermaid是有害的。
### 解决方案
1. **禁用自动格式化**(不推荐)
- 会影响整个网站的排版
- 需要修改 WordPress 核心代码
2. **在提取时反转换**(推荐)✅
- 只影响 Mermaid 代码块
- 不影响其他内容
- 易于维护
### 字符映射表
| 原始字符 | HTML 实体 | Unicode | 显示 |
|---------|----------|---------|------|
| `-` | `&#45;` | U+002D | - |
| `--` | `&#8211;` / `&ndash;` | U+2013 | |
| `---` | `&#8212;` / `&mdash;` | U+2014 | — |
| `->` | `&#8594;` / `&rarr;` | U+2192 | → |
## 注意事项
1. **性能影响**:增加了字符串替换操作,但性能影响可忽略
2. **安全性**:只处理 Mermaid 代码块,不执行任何脚本
3. **兼容性**:支持所有现代浏览器
4. **调试**:添加详细日志,便于排查问题
## 后续优化
1. 考虑使用 DOMParser 解析 HTML更可靠
2. 添加更多特殊字符的转换规则
3. 支持自定义字符映射表
4. 添加单元测试
## 参考资料
- [WordPress wptexturize() 函数](https://developer.wordpress.org/reference/functions/wptexturize/)
- [Unicode 字符表](https://unicode-table.com/)
- [Mermaid 语法文档](https://mermaid.js.org/intro/syntax-reference.html)