feat: 添加 Mermaid Shortcode 支持(推荐方式)
- 新增 [mermaid]...[/mermaid] shortcode - 支持 theme、width、height、align 参数 - 不依赖 WP-Markdown 的处理方式 - 不会被 WordPress 自动格式化破坏 - 在原生编辑器中清晰可见 - 添加完整的使用指南和示例
This commit is contained in:
@@ -4429,6 +4429,7 @@ void 0;
|
|||||||
|
|
||||||
// 检测规则(优先级从高到低)
|
// 检测规则(优先级从高到低)
|
||||||
const selectors = [
|
const selectors = [
|
||||||
|
'div.mermaid-shortcode', // Shortcode 格式(推荐)
|
||||||
'div.mermaid', // 标准格式
|
'div.mermaid', // 标准格式
|
||||||
'pre code.language-mermaid', // Markdown 格式
|
'pre code.language-mermaid', // Markdown 格式
|
||||||
'pre[data-lang="mermaid"]', // 自定义属性格式
|
'pre[data-lang="mermaid"]', // 自定义属性格式
|
||||||
@@ -4690,8 +4691,13 @@ void 0;
|
|||||||
extractMermaidCode(element) {
|
extractMermaidCode(element) {
|
||||||
let code = '';
|
let code = '';
|
||||||
|
|
||||||
|
// 处理 Shortcode 格式(推荐)
|
||||||
|
if (element.classList.contains('mermaid-shortcode')) {
|
||||||
|
code = element.textContent;
|
||||||
|
this.logDebug('从 Shortcode 格式提取代码');
|
||||||
|
}
|
||||||
// 处理 Markdown 容器语法格式
|
// 处理 Markdown 容器语法格式
|
||||||
if (element.classList.contains('mermaid-container-block')) {
|
else if (element.classList.contains('mermaid-container-block')) {
|
||||||
code = element.textContent;
|
code = element.textContent;
|
||||||
this.logDebug('从 Markdown 容器语法提取代码');
|
this.logDebug('从 Markdown 容器语法提取代码');
|
||||||
}
|
}
|
||||||
|
|||||||
505
docs/mermaid-shortcode-guide.md
Normal file
505
docs/mermaid-shortcode-guide.md
Normal file
@@ -0,0 +1,505 @@
|
|||||||
|
# Mermaid Shortcode 使用指南
|
||||||
|
|
||||||
|
## 为什么使用 Shortcode?
|
||||||
|
|
||||||
|
在 WP-Markdown 环境下,使用 Shortcode 是最可靠的 Mermaid 图表标记方式:
|
||||||
|
|
||||||
|
### 优点 ✅
|
||||||
|
|
||||||
|
1. **不依赖 WP-Markdown 的处理方式**
|
||||||
|
- 不会被 WordPress 自动格式化破坏
|
||||||
|
- 不会将 `-->` 转换为 `–>`
|
||||||
|
- 不会丢失换行符
|
||||||
|
|
||||||
|
2. **在原生编辑器中清晰可见**
|
||||||
|
- 经典编辑器:文本模式下直接可见
|
||||||
|
- Gutenberg 编辑器:使用"短代码"块
|
||||||
|
- 易于编辑和维护
|
||||||
|
|
||||||
|
3. **支持参数配置**
|
||||||
|
- 可以设置主题(theme)
|
||||||
|
- 可以设置宽度(width)
|
||||||
|
- 可以设置高度(height)
|
||||||
|
- 可以设置对齐方式(align)
|
||||||
|
|
||||||
|
4. **完全兼容**
|
||||||
|
- 与其他 Shortcode 一样使用
|
||||||
|
- 不需要额外插件
|
||||||
|
- 不需要修改 WP-Markdown
|
||||||
|
|
||||||
|
### 对比其他方式
|
||||||
|
|
||||||
|
| 方式 | 优点 | 缺点 |
|
||||||
|
|------|------|------|
|
||||||
|
| **Shortcode** ⭐ | 可靠、易用、支持参数 | 需要记住语法 |
|
||||||
|
| 容器语法 `::: mermaid` | 符合 Markdown 规范 | 被 WP 格式化破坏 |
|
||||||
|
| 代码块 ` ```mermaid ` | 通用 | 被代码高亮干扰 |
|
||||||
|
| HTML `<div class="mermaid">` | 灵活 | 编辑不便 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 基本用法
|
||||||
|
|
||||||
|
### 语法
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
flowchart TD
|
||||||
|
A[开始] --> B[处理]
|
||||||
|
B --> C[结束]
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 在经典编辑器中使用
|
||||||
|
|
||||||
|
1. 切换到"文本"模式(不是"可视化"模式)
|
||||||
|
2. 输入 Shortcode:
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
你的 Mermaid 代码
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
3. 保存并预览
|
||||||
|
|
||||||
|
### 在 Gutenberg 编辑器中使用
|
||||||
|
|
||||||
|
1. 添加"短代码"块(Shortcode Block)
|
||||||
|
2. 输入 Shortcode:
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
你的 Mermaid 代码
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
3. 保存并预览
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 参数说明
|
||||||
|
|
||||||
|
### theme - 主题
|
||||||
|
|
||||||
|
设置图表主题,支持以下值:
|
||||||
|
- `default` - 默认主题(浅色)
|
||||||
|
- `dark` - 深色主题
|
||||||
|
- `forest` - 森林主题
|
||||||
|
- `neutral` - 中性主题
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
[mermaid theme="dark"]
|
||||||
|
flowchart TD
|
||||||
|
A --> B
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### width - 宽度
|
||||||
|
|
||||||
|
设置图表容器宽度,支持:
|
||||||
|
- 百分比:`100%`, `80%`, `50%`
|
||||||
|
- 像素值:`800px`, `600px`
|
||||||
|
- 自动:`auto`
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
[mermaid width="80%"]
|
||||||
|
flowchart TD
|
||||||
|
A --> B
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### height - 高度
|
||||||
|
|
||||||
|
设置图表容器高度,支持:
|
||||||
|
- 像素值:`600px`, `400px`
|
||||||
|
- 自动:`auto`(默认)
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
[mermaid height="500px"]
|
||||||
|
flowchart TD
|
||||||
|
A --> B
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### align - 对齐方式
|
||||||
|
|
||||||
|
设置图表对齐方式,支持:
|
||||||
|
- `left` - 左对齐
|
||||||
|
- `center` - 居中(默认)
|
||||||
|
- `right` - 右对齐
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
[mermaid align="left"]
|
||||||
|
flowchart TD
|
||||||
|
A --> B
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 组合使用
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid theme="dark" width="80%" height="500px" align="center"]
|
||||||
|
flowchart TD
|
||||||
|
A[开始] --> B[处理]
|
||||||
|
B --> C[结束]
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
### 示例 1: 简单流程图
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
flowchart TD
|
||||||
|
Start([开始]) --> Process[处理数据]
|
||||||
|
Process --> Decision{是否成功?}
|
||||||
|
Decision -->|是| Success[显示成功]
|
||||||
|
Decision -->|否| Error[显示错误]
|
||||||
|
Success --> End([结束])
|
||||||
|
Error --> End
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 2: 时序图
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
sequenceDiagram
|
||||||
|
participant User as 用户
|
||||||
|
participant Server as 服务器
|
||||||
|
participant DB as 数据库
|
||||||
|
|
||||||
|
User->>Server: 发送请求
|
||||||
|
Server->>DB: 查询数据
|
||||||
|
DB-->>Server: 返回数据
|
||||||
|
Server-->>User: 返回响应
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 3: 类图
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
classDiagram
|
||||||
|
class Animal {
|
||||||
|
+String name
|
||||||
|
+int age
|
||||||
|
+makeSound()
|
||||||
|
}
|
||||||
|
class Dog {
|
||||||
|
+String breed
|
||||||
|
+bark()
|
||||||
|
}
|
||||||
|
class Cat {
|
||||||
|
+String color
|
||||||
|
+meow()
|
||||||
|
}
|
||||||
|
Animal <|-- Dog
|
||||||
|
Animal <|-- Cat
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 4: 甘特图
|
||||||
|
|
||||||
|
```
|
||||||
|
[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
|
||||||
|
性能测试 :c2, after b2, 3d
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 5: 状态图
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> 待审核
|
||||||
|
待审核 --> 已通过: 审核通过
|
||||||
|
待审核 --> 已拒绝: 审核拒绝
|
||||||
|
已通过 --> [*]
|
||||||
|
已拒绝 --> [*]
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 6: 饼图
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
pie title 编程语言使用占比
|
||||||
|
"JavaScript" : 386
|
||||||
|
"Python" : 285
|
||||||
|
"Java" : 215
|
||||||
|
"C++" : 115
|
||||||
|
"其他" : 85
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 7: ER 图
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
erDiagram
|
||||||
|
USER ||--o{ ORDER : places
|
||||||
|
ORDER ||--|{ ORDER_ITEM : contains
|
||||||
|
PRODUCT ||--o{ ORDER_ITEM : "ordered in"
|
||||||
|
|
||||||
|
USER {
|
||||||
|
int id PK
|
||||||
|
string name
|
||||||
|
string email
|
||||||
|
}
|
||||||
|
ORDER {
|
||||||
|
int id PK
|
||||||
|
int user_id FK
|
||||||
|
date created_at
|
||||||
|
}
|
||||||
|
PRODUCT {
|
||||||
|
int id PK
|
||||||
|
string name
|
||||||
|
decimal price
|
||||||
|
}
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 8: 带样式的流程图
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
flowchart TD
|
||||||
|
Start([用户提交评论]) --> PreProcess[预处理]
|
||||||
|
PreProcess --> CheckEnabled{启用 AI 检测?}
|
||||||
|
CheckEnabled -->|是| AICheck[AI 检测]
|
||||||
|
CheckEnabled -->|否| Save[保存评论]
|
||||||
|
AICheck --> Result{检测结果?}
|
||||||
|
Result -->|垃圾评论| Trash[移入回收站]
|
||||||
|
Result -->|正常评论| Save
|
||||||
|
|
||||||
|
style Start fill:#e1f5e1,stroke:#2e7d32,stroke-width:2px
|
||||||
|
style Trash fill:#ff6b6b,stroke:#c62828,stroke-width:2px
|
||||||
|
style Save fill:#95e1d3,stroke:#2e7d32,stroke-width:2px
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### 1. Shortcode 不生效怎么办?
|
||||||
|
|
||||||
|
**可能原因**:
|
||||||
|
- 主题未更新到最新版本
|
||||||
|
- 使用了"可视化"模式编辑
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
1. 更新 Argon 主题到最新版本
|
||||||
|
2. 切换到"文本"模式编辑
|
||||||
|
3. 检查 Shortcode 语法是否正确
|
||||||
|
|
||||||
|
### 2. 图表渲染失败怎么办?
|
||||||
|
|
||||||
|
**排查步骤**:
|
||||||
|
|
||||||
|
1. **检查 Mermaid 语法**
|
||||||
|
- 访问 [Mermaid Live Editor](https://mermaid.live/)
|
||||||
|
- 粘贴你的代码验证语法
|
||||||
|
|
||||||
|
2. **查看浏览器控制台**
|
||||||
|
- 按 F12 打开开发者工具
|
||||||
|
- 查看 Console 标签页
|
||||||
|
- 搜索错误信息
|
||||||
|
|
||||||
|
3. **检查主题设置**
|
||||||
|
- WordPress 后台 → 外观 → Argon 主题选项
|
||||||
|
- 找到"Mermaid 图表"分类
|
||||||
|
- 确认"启用 Mermaid 支持"已开启
|
||||||
|
|
||||||
|
### 3. 如何迁移现有的容器语法?
|
||||||
|
|
||||||
|
如果你之前使用了 `::: mermaid ... :::` 语法,可以批量替换:
|
||||||
|
|
||||||
|
**查找**:
|
||||||
|
```
|
||||||
|
::: mermaid
|
||||||
|
```
|
||||||
|
|
||||||
|
**替换为**:
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
**查找**:
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
```
|
||||||
|
|
||||||
|
**替换为**:
|
||||||
|
```
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 可以在评论中使用吗?
|
||||||
|
|
||||||
|
不可以。Shortcode 只能在文章和页面中使用,评论中不支持。
|
||||||
|
|
||||||
|
### 5. 可以嵌套使用吗?
|
||||||
|
|
||||||
|
不可以。Shortcode 不支持嵌套,每个图表需要独立的 `[mermaid]...[/mermaid]` 标签。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 最佳实践
|
||||||
|
|
||||||
|
### 1. 使用有意义的节点 ID
|
||||||
|
|
||||||
|
**推荐**:
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
flowchart TD
|
||||||
|
UserSubmit([用户提交]) --> Validate[验证数据]
|
||||||
|
Validate --> Save[保存数据]
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
**不推荐**:
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
flowchart TD
|
||||||
|
A --> B
|
||||||
|
B --> C
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 添加适当的注释
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
flowchart TD
|
||||||
|
%% 用户流程
|
||||||
|
Start([开始]) --> Login[登录]
|
||||||
|
|
||||||
|
%% 验证流程
|
||||||
|
Login --> Check{验证成功?}
|
||||||
|
Check -->|是| Dashboard[进入控制台]
|
||||||
|
Check -->|否| Error[显示错误]
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 使用样式定义
|
||||||
|
|
||||||
|
```
|
||||||
|
[mermaid]
|
||||||
|
flowchart TD
|
||||||
|
Success[成功] --> End
|
||||||
|
Error[错误] --> End
|
||||||
|
|
||||||
|
style Success fill:#95e1d3,stroke:#2e7d32
|
||||||
|
style Error fill:#ff6b6b,stroke:#c62828
|
||||||
|
[/mermaid]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 保持图表简洁
|
||||||
|
|
||||||
|
- 避免过多的节点(建议 < 20 个)
|
||||||
|
- 使用子图(subgraph)组织复杂流程
|
||||||
|
- 考虑拆分为多个图表
|
||||||
|
|
||||||
|
### 5. 测试后再发布
|
||||||
|
|
||||||
|
1. 先在 [Mermaid Live Editor](https://mermaid.live/) 中测试
|
||||||
|
2. 确认语法正确后再粘贴到文章中
|
||||||
|
3. 使用"预览"功能查看效果
|
||||||
|
4. 确认无误后再发布
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 技术细节
|
||||||
|
|
||||||
|
### Shortcode 实现
|
||||||
|
|
||||||
|
Argon 主题在 `functions.php` 中注册了 `mermaid` shortcode:
|
||||||
|
|
||||||
|
```php
|
||||||
|
add_shortcode('mermaid','shortcode_mermaid');
|
||||||
|
function shortcode_mermaid($attr,$content=""){
|
||||||
|
// 预处理内容
|
||||||
|
$content = shortcode_content_preprocess($attr, $content);
|
||||||
|
|
||||||
|
// 获取参数
|
||||||
|
$theme = isset( $attr['theme'] ) ? $attr['theme'] : 'default';
|
||||||
|
$width = isset( $attr['width'] ) ? $attr['width'] : '100%';
|
||||||
|
$height = isset( $attr['height'] ) ? $attr['height'] : 'auto';
|
||||||
|
$align = isset( $attr['align'] ) ? $attr['align'] : 'center';
|
||||||
|
|
||||||
|
// 生成 HTML
|
||||||
|
$out = '<div class="mermaid-shortcode-container">';
|
||||||
|
$out .= '<div class="mermaid-shortcode" ...>';
|
||||||
|
$out .= esc_html($content);
|
||||||
|
$out .= '</div></div>';
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### JavaScript 检测
|
||||||
|
|
||||||
|
在 `argontheme.js` 中,Mermaid 渲染器会自动检测 `div.mermaid-shortcode` 元素:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const selectors = [
|
||||||
|
'div.mermaid-shortcode', // Shortcode 格式(推荐)
|
||||||
|
'div.mermaid', // 标准格式
|
||||||
|
// ...
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
### 安全性
|
||||||
|
|
||||||
|
- 使用 `esc_html()` 转义输出,防止 XSS 攻击
|
||||||
|
- 使用 `esc_attr()` 转义属性值
|
||||||
|
- 不执行任何用户提供的 JavaScript 代码
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 相关资源
|
||||||
|
|
||||||
|
- [Mermaid 官方文档](https://mermaid.js.org/)
|
||||||
|
- [Mermaid Live Editor](https://mermaid.live/)
|
||||||
|
- [WordPress Shortcode API](https://developer.wordpress.org/plugins/shortcodes/)
|
||||||
|
- [Argon 主题文档](https://argon-docs.solstice23.top/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 更新日志
|
||||||
|
|
||||||
|
### 2026-01-24
|
||||||
|
- ✅ 添加 Mermaid Shortcode 支持
|
||||||
|
- ✅ 支持 theme、width、height、align 参数
|
||||||
|
- ✅ 自动检测和渲染
|
||||||
|
- ✅ 完整的使用文档和示例
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
使用 Shortcode 是在 WP-Markdown 环境下最可靠的 Mermaid 图表标记方式:
|
||||||
|
|
||||||
|
1. **简单易用**:`[mermaid]...[/mermaid]`
|
||||||
|
2. **功能强大**:支持主题、尺寸、对齐等参数
|
||||||
|
3. **完全兼容**:不需要额外插件或修改
|
||||||
|
4. **易于维护**:在编辑器中清晰可见
|
||||||
|
|
||||||
|
推荐所有用户使用 Shortcode 方式编写 Mermaid 图表!
|
||||||
@@ -4586,6 +4586,32 @@ function shortcode_video($attr,$content=""){
|
|||||||
$out .= "</video>";
|
$out .= "</video>";
|
||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
add_shortcode('mermaid','shortcode_mermaid');
|
||||||
|
function shortcode_mermaid($attr,$content=""){
|
||||||
|
// 预处理内容:移除 WordPress 自动添加的 <p> 和 <br> 标签
|
||||||
|
$content = shortcode_content_preprocess($attr, $content);
|
||||||
|
|
||||||
|
// 获取参数
|
||||||
|
$theme = isset( $attr['theme'] ) ? $attr['theme'] : 'default';
|
||||||
|
$width = isset( $attr['width'] ) ? $attr['width'] : '100%';
|
||||||
|
$height = isset( $attr['height'] ) ? $attr['height'] : 'auto';
|
||||||
|
$align = isset( $attr['align'] ) ? $attr['align'] : 'center';
|
||||||
|
|
||||||
|
// 生成唯一 ID
|
||||||
|
$chart_id = 'mermaid-' . mt_rand(1000000000, 9999999999);
|
||||||
|
|
||||||
|
// 构建输出
|
||||||
|
$out = '<div class="mermaid-shortcode-container" style="text-align: ' . esc_attr($align) . ';">';
|
||||||
|
$out .= '<div class="mermaid-shortcode" ';
|
||||||
|
$out .= 'id="' . esc_attr($chart_id) . '" ';
|
||||||
|
$out .= 'data-theme="' . esc_attr($theme) . '" ';
|
||||||
|
$out .= 'style="width: ' . esc_attr($width) . '; height: ' . esc_attr($height) . ';">';
|
||||||
|
$out .= esc_html($content);
|
||||||
|
$out .= '</div>';
|
||||||
|
$out .= '</div>';
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
add_shortcode('hide_reading_time','shortcode_hide_reading_time');
|
add_shortcode('hide_reading_time','shortcode_hide_reading_time');
|
||||||
function shortcode_hide_reading_time($attr,$content=""){
|
function shortcode_hide_reading_time($attr,$content=""){
|
||||||
return "";
|
return "";
|
||||||
@@ -9200,7 +9226,8 @@ function argon_has_mermaid_content($content) {
|
|||||||
'/<div[^>]*class=["\']([^"\']*\s)?mermaid(\s[^"\']*)?["\'][^>]*>/i', // <div class="mermaid">
|
'/<div[^>]*class=["\']([^"\']*\s)?mermaid(\s[^"\']*)?["\'][^>]*>/i', // <div class="mermaid">
|
||||||
'/<code[^>]*class=["\']([^"\']*\s)?language-mermaid(\s[^"\']*)?["\'][^>]*>/i', // <code class="language-mermaid">
|
'/<code[^>]*class=["\']([^"\']*\s)?language-mermaid(\s[^"\']*)?["\'][^>]*>/i', // <code class="language-mermaid">
|
||||||
'/<pre[^>]*data-lang=["\']mermaid["\'][^>]*>/i', // <pre data-lang="mermaid">
|
'/<pre[^>]*data-lang=["\']mermaid["\'][^>]*>/i', // <pre data-lang="mermaid">
|
||||||
'/<code[^>]*class=["\']([^"\']*\s)?mermaid(\s[^"\']*)?["\'][^>]*>/i' // <code class="mermaid">
|
'/<code[^>]*class=["\']([^"\']*\s)?mermaid(\s[^"\']*)?["\'][^>]*>/i', // <code class="mermaid">
|
||||||
|
'/:::\s*mermaid/i' // ::: mermaid (Markdown 容器语法)
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($patterns as $pattern) {
|
foreach ($patterns as $pattern) {
|
||||||
|
|||||||
365
tests/test-shortcode-example.md
Normal file
365
tests/test-shortcode-example.md
Normal file
@@ -0,0 +1,365 @@
|
|||||||
|
# AI 垃圾评论检测系统架构
|
||||||
|
|
||||||
|
## 系统概述
|
||||||
|
|
||||||
|
本文档展示 Argon 主题的 AI 垃圾评论检测系统的完整架构和流程。
|
||||||
|
|
||||||
|
## 主流程图
|
||||||
|
|
||||||
|
[mermaid theme="default" width="100%" align="center"]
|
||||||
|
flowchart TD
|
||||||
|
Start([用户提交评论]) --> PreProcess[预处理评论]
|
||||||
|
PreProcess --> CheckEnabled{启用 AI 检测?}
|
||||||
|
|
||||||
|
CheckEnabled -->|否| DirectSave[直接保存评论]
|
||||||
|
CheckEnabled -->|是| CheckMode{检测模式?}
|
||||||
|
|
||||||
|
CheckMode -->|manual| DirectSave
|
||||||
|
CheckMode -->|keyword| CheckKeyword[检查关键字]
|
||||||
|
CheckMode -->|sample| CheckSample[智能抽样]
|
||||||
|
CheckMode -->|all| NeedCheck[需要检测]
|
||||||
|
|
||||||
|
CheckKeyword --> KeywordMatch{匹配关键字?}
|
||||||
|
KeywordMatch -->|是| NeedCheck
|
||||||
|
KeywordMatch -->|否| DirectSave
|
||||||
|
|
||||||
|
CheckSample --> SampleDecision{抽中?}
|
||||||
|
SampleDecision -->|是| NeedCheck
|
||||||
|
SampleDecision -->|否| DirectSave
|
||||||
|
|
||||||
|
NeedCheck --> SetPending[设置待审核状态]
|
||||||
|
SetPending --> SaveWithFlag[保存评论并标记]
|
||||||
|
SaveWithFlag --> TriggerDetect[触发 AI 检测]
|
||||||
|
|
||||||
|
TriggerDetect --> CallAPI[调用 AI API]
|
||||||
|
CallAPI --> ParseResult[解析结果]
|
||||||
|
|
||||||
|
ParseResult --> CheckConfidence{置信度?}
|
||||||
|
CheckConfidence -->|高| AutoHandle[自动处理]
|
||||||
|
CheckConfidence -->|中| ManualReview[人工审核]
|
||||||
|
CheckConfidence -->|低| MarkNormal[标记正常]
|
||||||
|
|
||||||
|
AutoHandle --> CheckAction{处理方式?}
|
||||||
|
CheckAction -->|trash| MoveTrash[移入回收站]
|
||||||
|
CheckAction -->|hold| KeepPending[保持待审核]
|
||||||
|
CheckAction -->|mark| JustMark[仅标记]
|
||||||
|
|
||||||
|
MoveTrash --> NotifyAdmin[通知管理员]
|
||||||
|
KeepPending --> NotifyAdmin
|
||||||
|
JustMark --> SaveResult[保存结果]
|
||||||
|
ManualReview --> SaveResult
|
||||||
|
MarkNormal --> SaveResult
|
||||||
|
NotifyAdmin --> SaveResult
|
||||||
|
|
||||||
|
SaveResult --> AILearn{启用学习?}
|
||||||
|
AILearn -->|是| ExtractKeywords[提取关键词]
|
||||||
|
AILearn -->|否| End([结束])
|
||||||
|
ExtractKeywords --> UpdateDB[更新词库]
|
||||||
|
UpdateDB --> End
|
||||||
|
|
||||||
|
DirectSave --> End
|
||||||
|
|
||||||
|
style Start fill:#e1f5e1,stroke:#2e7d32,stroke-width:2px
|
||||||
|
style End fill:#e1f5e1,stroke:#2e7d32,stroke-width:2px
|
||||||
|
style MoveTrash fill:#ff6b6b,stroke:#c62828,stroke-width:2px
|
||||||
|
style MarkNormal fill:#95e1d3,stroke:#2e7d32,stroke-width:2px
|
||||||
|
style ManualReview fill:#ffa500,stroke:#ff8f00,stroke-width:2px
|
||||||
|
[/mermaid]
|
||||||
|
|
||||||
|
## 检测模式详解
|
||||||
|
|
||||||
|
[mermaid theme="default" width="80%" align="center"]
|
||||||
|
flowchart LR
|
||||||
|
subgraph Manual[Manual 模式]
|
||||||
|
M1[关闭实时检测]
|
||||||
|
M2[仅手动扫描]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph Keyword[Keyword 模式]
|
||||||
|
K1[关键字触发]
|
||||||
|
K2[精准检测]
|
||||||
|
K3[低成本]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph Sample[Sample 模式]
|
||||||
|
S1[智能抽样]
|
||||||
|
S2[平衡准确性]
|
||||||
|
S3[控制成本]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph All[All 模式]
|
||||||
|
A1[全量检测]
|
||||||
|
A2[最高准确性]
|
||||||
|
A3[高成本]
|
||||||
|
end
|
||||||
|
|
||||||
|
style Manual fill:#e3f2fd
|
||||||
|
style Keyword fill:#fff3e0
|
||||||
|
style Sample fill:#f3e5f5
|
||||||
|
style All fill:#fce4ec
|
||||||
|
[/mermaid]
|
||||||
|
|
||||||
|
## AI 检测流程
|
||||||
|
|
||||||
|
[mermaid theme="default" width="90%"]
|
||||||
|
sequenceDiagram
|
||||||
|
participant User as 用户
|
||||||
|
participant WP as WordPress
|
||||||
|
participant Argon as Argon 主题
|
||||||
|
participant AI as AI API
|
||||||
|
participant DB as 数据库
|
||||||
|
|
||||||
|
User->>WP: 提交评论
|
||||||
|
WP->>Argon: 触发 preprocess_comment
|
||||||
|
Argon->>Argon: 检查检测规则
|
||||||
|
|
||||||
|
alt 需要检测
|
||||||
|
Argon->>DB: 保存评论(待审核)
|
||||||
|
Argon->>AI: 发送检测请求
|
||||||
|
AI-->>Argon: 返回检测结果
|
||||||
|
Argon->>Argon: 解析结果和置信度
|
||||||
|
|
||||||
|
alt 高置信度垃圾评论
|
||||||
|
Argon->>DB: 移入回收站
|
||||||
|
Argon->>WP: 发送通知邮件
|
||||||
|
else 中等置信度
|
||||||
|
Argon->>DB: 标记待人工审核
|
||||||
|
else 正常评论
|
||||||
|
Argon->>DB: 标记为正常
|
||||||
|
end
|
||||||
|
|
||||||
|
Argon->>DB: 保存检测记录
|
||||||
|
|
||||||
|
opt 启用 AI 学习
|
||||||
|
Argon->>AI: 提取关键词
|
||||||
|
AI-->>Argon: 返回关键词
|
||||||
|
Argon->>DB: 更新学习词库
|
||||||
|
end
|
||||||
|
else 跳过检测
|
||||||
|
Argon->>DB: 直接保存评论
|
||||||
|
end
|
||||||
|
|
||||||
|
WP-->>User: 显示提交结果
|
||||||
|
[/mermaid]
|
||||||
|
|
||||||
|
## 数据库结构
|
||||||
|
|
||||||
|
[mermaid theme="default" width="85%"]
|
||||||
|
erDiagram
|
||||||
|
COMMENT ||--o{ COMMENT_META : has
|
||||||
|
COMMENT {
|
||||||
|
bigint comment_ID PK
|
||||||
|
bigint comment_post_ID FK
|
||||||
|
text comment_content
|
||||||
|
varchar comment_author
|
||||||
|
varchar comment_author_email
|
||||||
|
varchar comment_author_IP
|
||||||
|
datetime comment_date
|
||||||
|
varchar comment_approved
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMENT_META {
|
||||||
|
bigint meta_id PK
|
||||||
|
bigint comment_id FK
|
||||||
|
varchar meta_key
|
||||||
|
longtext meta_value
|
||||||
|
}
|
||||||
|
|
||||||
|
SPAM_DETECTION ||--|| COMMENT : detects
|
||||||
|
SPAM_DETECTION {
|
||||||
|
bigint id PK
|
||||||
|
bigint comment_id FK
|
||||||
|
varchar result
|
||||||
|
float confidence
|
||||||
|
text reason
|
||||||
|
text keywords
|
||||||
|
datetime detected_at
|
||||||
|
varchar detection_code
|
||||||
|
}
|
||||||
|
|
||||||
|
LEARNED_KEYWORDS ||--o{ SPAM_DETECTION : learns_from
|
||||||
|
LEARNED_KEYWORDS {
|
||||||
|
bigint id PK
|
||||||
|
varchar keyword
|
||||||
|
int weight
|
||||||
|
varchar category
|
||||||
|
datetime created_at
|
||||||
|
datetime updated_at
|
||||||
|
}
|
||||||
|
[/mermaid]
|
||||||
|
|
||||||
|
## 系统状态机
|
||||||
|
|
||||||
|
[mermaid theme="default" width="70%"]
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> Submitted: 用户提交
|
||||||
|
|
||||||
|
Submitted --> Pending: 需要检测
|
||||||
|
Submitted --> Approved: 跳过检测
|
||||||
|
|
||||||
|
Pending --> Detecting: 开始检测
|
||||||
|
Detecting --> Analyzed: 检测完成
|
||||||
|
|
||||||
|
Analyzed --> Spam: 高置信度垃圾
|
||||||
|
Analyzed --> Suspicious: 中等置信度
|
||||||
|
Analyzed --> Clean: 低置信度/正常
|
||||||
|
|
||||||
|
Spam --> Trash: 自动处理
|
||||||
|
Spam --> Hold: 保持待审核
|
||||||
|
Spam --> Marked: 仅标记
|
||||||
|
|
||||||
|
Suspicious --> ManualReview: 等待人工审核
|
||||||
|
Clean --> Approved: 自动通过
|
||||||
|
|
||||||
|
ManualReview --> Approved: 管理员批准
|
||||||
|
ManualReview --> Trash: 管理员拒绝
|
||||||
|
|
||||||
|
Hold --> Approved: 管理员批准
|
||||||
|
Hold --> Trash: 管理员拒绝
|
||||||
|
|
||||||
|
Marked --> Approved: 管理员批准
|
||||||
|
Marked --> Trash: 管理员拒绝
|
||||||
|
|
||||||
|
Trash --> [*]
|
||||||
|
Approved --> [*]
|
||||||
|
|
||||||
|
note right of Detecting
|
||||||
|
调用 AI API
|
||||||
|
解析返回结果
|
||||||
|
计算置信度
|
||||||
|
end note
|
||||||
|
|
||||||
|
note right of ManualReview
|
||||||
|
显示在后台
|
||||||
|
等待管理员操作
|
||||||
|
end note
|
||||||
|
[/mermaid]
|
||||||
|
|
||||||
|
## 性能优化策略
|
||||||
|
|
||||||
|
[mermaid theme="default" width="95%"]
|
||||||
|
flowchart TD
|
||||||
|
subgraph Input[输入优化]
|
||||||
|
I1[关键字预过滤]
|
||||||
|
I2[白名单用户]
|
||||||
|
I3[智能抽样]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph Process[处理优化]
|
||||||
|
P1[异步检测]
|
||||||
|
P2[批量处理]
|
||||||
|
P3[缓存结果]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph API[API 优化]
|
||||||
|
A1[Prompt 优化]
|
||||||
|
A2[Token 控制]
|
||||||
|
A3[超时处理]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph Storage[存储优化]
|
||||||
|
S1[索引优化]
|
||||||
|
S2[定期清理]
|
||||||
|
S3[归档历史]
|
||||||
|
end
|
||||||
|
|
||||||
|
Input --> Process
|
||||||
|
Process --> API
|
||||||
|
API --> Storage
|
||||||
|
|
||||||
|
style Input fill:#e8f5e9
|
||||||
|
style Process fill:#e3f2fd
|
||||||
|
style API fill:#fff3e0
|
||||||
|
style Storage fill:#f3e5f5
|
||||||
|
[/mermaid]
|
||||||
|
|
||||||
|
## 配置建议矩阵
|
||||||
|
|
||||||
|
[mermaid theme="default" width="100%"]
|
||||||
|
graph TB
|
||||||
|
subgraph Small[小型博客 < 100评论/天]
|
||||||
|
S1[检测模式: keyword]
|
||||||
|
S2[Prompt: 标准模式]
|
||||||
|
S3[置信度阈值: > 0.9]
|
||||||
|
S4[自动处理: trash]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph Medium[中型博客 100-500评论/天]
|
||||||
|
M1[检测模式: sample 30%]
|
||||||
|
M2[Prompt: 标准模式]
|
||||||
|
M3[置信度阈值: > 0.85]
|
||||||
|
M4[自动处理: hold]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph Large[大型博客 > 500评论/天]
|
||||||
|
L1[检测模式: sample 40%]
|
||||||
|
L2[Prompt: 极简模式]
|
||||||
|
L3[置信度阈值: > 0.8]
|
||||||
|
L4[自动处理: mark]
|
||||||
|
L5[定期批量扫描]
|
||||||
|
end
|
||||||
|
|
||||||
|
style Small fill:#c8e6c9
|
||||||
|
style Medium fill:#fff9c4
|
||||||
|
style Large fill:#ffccbc
|
||||||
|
[/mermaid]
|
||||||
|
|
||||||
|
## 错误处理流程
|
||||||
|
|
||||||
|
[mermaid theme="default" width="85%"]
|
||||||
|
flowchart TD
|
||||||
|
Start([检测开始]) --> CallAPI[调用 AI API]
|
||||||
|
|
||||||
|
CallAPI --> CheckResponse{响应状态?}
|
||||||
|
|
||||||
|
CheckResponse -->|成功| ParseJSON[解析 JSON]
|
||||||
|
CheckResponse -->|超时| Timeout[超时处理]
|
||||||
|
CheckResponse -->|错误| APIError[API 错误]
|
||||||
|
|
||||||
|
ParseJSON --> ValidateData{数据有效?}
|
||||||
|
ValidateData -->|是| ProcessResult[处理结果]
|
||||||
|
ValidateData -->|否| DataError[数据错误]
|
||||||
|
|
||||||
|
Timeout --> RetryCheck{重试次数?}
|
||||||
|
RetryCheck -->|< 3| Retry[重试请求]
|
||||||
|
RetryCheck -->|>= 3| FallbackPending[降级:待审核]
|
||||||
|
|
||||||
|
Retry --> CallAPI
|
||||||
|
|
||||||
|
APIError --> LogError[记录错误日志]
|
||||||
|
DataError --> LogError
|
||||||
|
|
||||||
|
LogError --> NotifyAdmin[通知管理员]
|
||||||
|
NotifyAdmin --> FallbackPending
|
||||||
|
|
||||||
|
ProcessResult --> SaveResult[保存结果]
|
||||||
|
FallbackPending --> SaveResult
|
||||||
|
|
||||||
|
SaveResult --> End([结束])
|
||||||
|
|
||||||
|
style Timeout fill:#ffccbc
|
||||||
|
style APIError fill:#ffccbc
|
||||||
|
style DataError fill:#ffccbc
|
||||||
|
style FallbackPending fill:#fff9c4
|
||||||
|
style ProcessResult fill:#c8e6c9
|
||||||
|
[/mermaid]
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
通过以上流程图,我们可以清晰地看到:
|
||||||
|
|
||||||
|
1. **主流程**:从用户提交到最终处理的完整流程
|
||||||
|
2. **检测模式**:四种模式的特点和适用场景
|
||||||
|
3. **时序交互**:各组件之间的交互顺序
|
||||||
|
4. **数据结构**:数据库表关系和字段定义
|
||||||
|
5. **状态机**:评论的各种状态转换
|
||||||
|
6. **性能优化**:多层次的优化策略
|
||||||
|
7. **配置建议**:不同规模博客的推荐配置
|
||||||
|
8. **错误处理**:完善的异常处理机制
|
||||||
|
|
||||||
|
这个系统设计充分考虑了:
|
||||||
|
- ✅ 准确性:多级置信度判断
|
||||||
|
- ✅ 性能:异步处理、智能抽样
|
||||||
|
- ✅ 成本:灵活的检测模式
|
||||||
|
- ✅ 可靠性:完善的错误处理
|
||||||
|
- ✅ 可维护性:清晰的架构设计
|
||||||
197
tests/test-single-element-container.html
Normal file
197
tests/test-single-element-container.html
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>单元素容器语法测试</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
.test-case {
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 20px 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
color: #333;
|
||||||
|
border-bottom: 2px solid #007bff;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
.success {
|
||||||
|
color: green;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
color: red;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
background: #f4f4f4;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow-x: auto;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>单元素容器语法测试</h1>
|
||||||
|
<p>测试 WP-Markdown 将整个容器语法放在一个 <p> 元素中的情况</p>
|
||||||
|
|
||||||
|
<!-- 测试用例 1: 简单流程图(单元素) -->
|
||||||
|
<div class="test-case">
|
||||||
|
<h2>测试 1: 简单流程图(单元素,带全角箭头)</h2>
|
||||||
|
<p>::: mermaid<br>flowchart TD<br> Start([开始]) –> Process[处理]<br> Process –> End([结束])<br>:::</p>
|
||||||
|
<div id="result1"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 测试用例 2: 带样式的流程图(单元素) -->
|
||||||
|
<div class="test-case">
|
||||||
|
<h2>测试 2: 带样式定义(单元素)</h2>
|
||||||
|
<p>::: mermaid<br>flowchart LR<br> A[开始] –> B[处理]<br> B –> C[结束]<br> style A fill:#e1f5e1,stroke:#2e7d32<br> style C fill:#ffe1e1,stroke:#c62828<br>:::</p>
|
||||||
|
<div id="result2"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 测试用例 3: 复杂流程图(单元素,模拟 AI 评论审核) -->
|
||||||
|
<div class="test-case">
|
||||||
|
<h2>测试 3: 复杂流程图(单元素,多个节点)</h2>
|
||||||
|
<p>::: mermaid<br>flowchart TD<br> Start([用户提交评论]) –> PreProcess[预处理]<br> PreProcess –> CheckEnabled{启用 AI 检测?}<br> CheckEnabled –>|否| SaveComment[保存评论]<br> CheckEnabled –>|是| CheckMode{检测模式?}<br> CheckMode –>|manual| SaveComment<br> CheckMode –>|keyword/sample/all| AICheck[AI 检测]<br> AICheck –> CheckResult{检测结果?}<br> CheckResult –>|垃圾评论| Trash[移入回收站]<br> CheckResult –>|正常评论| SaveComment<br> style Start fill:#e1f5e1,stroke:#2e7d32<br> style Trash fill:#ff6b6b,stroke:#c62828<br>:::</p>
|
||||||
|
<div id="result3"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
|
||||||
|
<script>
|
||||||
|
// 模拟 Argon 主题的 htmlToText 函数(增强版)
|
||||||
|
function htmlToText(html) {
|
||||||
|
// 将 <br> 和 <br/> 转换为换行符
|
||||||
|
let text = html.replace(/<br\s*\/?>/gi, '\n');
|
||||||
|
// 移除其他 HTML 标签
|
||||||
|
text = text.replace(/<[^>]+>/g, '');
|
||||||
|
// 解码 HTML 实体
|
||||||
|
text = text
|
||||||
|
.replace(/ /g, ' ')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, "'")
|
||||||
|
.replace(/–/g, '-') // EN DASH
|
||||||
|
.replace(/—/g, '--') // EM DASH
|
||||||
|
.replace(/→/g, '->') // RIGHTWARDS ARROW
|
||||||
|
.replace(/–/g, '-') // EN DASH (named entity)
|
||||||
|
.replace(/—/g, '--') // EM DASH (named entity)
|
||||||
|
.replace(/→/g, '->'); // RIGHTWARDS ARROW (named entity)
|
||||||
|
|
||||||
|
// 转换 Unicode 字符(WordPress 可能直接输出 Unicode)
|
||||||
|
text = text
|
||||||
|
.replace(/–/g, '-') // U+2013 EN DASH
|
||||||
|
.replace(/—/g, '--') // U+2014 EM DASH
|
||||||
|
.replace(/→/g, '->'); // U+2192 RIGHTWARDS ARROW
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取单元素容器语法内容
|
||||||
|
function extractSingleElementContainer(element) {
|
||||||
|
let html = element.innerHTML;
|
||||||
|
let text = element.textContent.trim();
|
||||||
|
|
||||||
|
console.log('[测试] 原始 HTML:', html.substring(0, 200));
|
||||||
|
console.log('[测试] 原始文本:', text.substring(0, 200));
|
||||||
|
|
||||||
|
if (!text.startsWith('::: mermaid')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否整个内容都在一个元素中
|
||||||
|
if (text.includes(':::') && text.lastIndexOf(':::') > 10) {
|
||||||
|
console.log('[测试] 检测到单元素容器语法');
|
||||||
|
|
||||||
|
// 使用 htmlToText 转换
|
||||||
|
let fullText = htmlToText(html);
|
||||||
|
console.log('[测试] 转换后文本:', fullText.substring(0, 200));
|
||||||
|
|
||||||
|
// 移除开始和结束标记
|
||||||
|
fullText = fullText.replace(/^:::\s*mermaid\s*/i, '').trim();
|
||||||
|
fullText = fullText.replace(/:::\s*$/, '').trim();
|
||||||
|
|
||||||
|
console.log('[测试] 最终代码:', fullText);
|
||||||
|
return fullText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试函数
|
||||||
|
function testMermaid(testId, resultId) {
|
||||||
|
const element = document.querySelector(`#${testId}`).previousElementSibling;
|
||||||
|
const resultDiv = document.getElementById(resultId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const code = extractSingleElementContainer(element);
|
||||||
|
|
||||||
|
if (!code) {
|
||||||
|
resultDiv.innerHTML = '<p class="error">❌ 提取失败:未找到代码</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查换行符
|
||||||
|
const lines = code.split('\n');
|
||||||
|
console.log(`[测试 ${testId}] 提取到 ${lines.length} 行代码`);
|
||||||
|
|
||||||
|
// 检查箭头符号
|
||||||
|
const hasCorrectArrows = code.includes('-->') || code.includes('->');
|
||||||
|
const hasWrongArrows = code.includes('–>') || code.includes('→');
|
||||||
|
|
||||||
|
// 渲染图表
|
||||||
|
mermaid.render(`mermaid-${testId}`, code).then(result => {
|
||||||
|
resultDiv.innerHTML = `
|
||||||
|
<p class="success">✅ 渲染成功</p>
|
||||||
|
<p>提取到 ${lines.length} 行代码</p>
|
||||||
|
<p>箭头符号: ${hasCorrectArrows ? '✅ 正确 (-->)' : '❌ 错误'}</p>
|
||||||
|
<p>全角箭头: ${hasWrongArrows ? '❌ 存在 (–>)' : '✅ 不存在'}</p>
|
||||||
|
<details>
|
||||||
|
<summary>查看提取的代码</summary>
|
||||||
|
<pre>${code}</pre>
|
||||||
|
</details>
|
||||||
|
${result.svg}
|
||||||
|
`;
|
||||||
|
}).catch(error => {
|
||||||
|
resultDiv.innerHTML = `
|
||||||
|
<p class="error">❌ 渲染失败: ${error.message}</p>
|
||||||
|
<p>箭头符号: ${hasCorrectArrows ? '✅ 正确 (-->)' : '❌ 错误'}</p>
|
||||||
|
<p>全角箭头: ${hasWrongArrows ? '❌ 存在 (–>)' : '✅ 不存在'}</p>
|
||||||
|
<details>
|
||||||
|
<summary>查看提取的代码</summary>
|
||||||
|
<pre>${code}</pre>
|
||||||
|
</details>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
resultDiv.innerHTML = `<p class="error">❌ 错误: ${error.message}</p>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
mermaid.initialize({
|
||||||
|
startOnLoad: false,
|
||||||
|
theme: 'default',
|
||||||
|
securityLevel: 'loose'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 运行测试
|
||||||
|
testMermaid('test1', 'result1');
|
||||||
|
testMermaid('test2', 'result2');
|
||||||
|
testMermaid('test3', 'result3');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user