diff --git a/argontheme.js b/argontheme.js index 03e0176..c6bcea8 100644 --- a/argontheme.js +++ b/argontheme.js @@ -4520,20 +4520,31 @@ void 0; processedElements.add(startElement); // 处理开始元素 + // 使用 innerHTML 来获取原始内容,包括
标签 + let startHTML = startElement.innerHTML; let startText = startElement.textContent.trim(); + if (startText.startsWith('::: mermaid')) { foundStart = true; + this.logDebug('找到容器语法开始标记,原始 HTML: ' + startHTML.substring(0, 100)); + // 移除开始标记,保留同一元素中的其他内容 startText = startText.replace(/^:::\s*mermaid\s*/i, '').trim(); if (startText && !startText.startsWith(':::')) { - codeLines.push(startText); + // 如果开始标记后有内容,需要从 HTML 中提取 + // 将
转换为换行符 + let contentHTML = startHTML.replace(/^:::\s*mermaid\s*/i, ''); + let contentText = this.htmlToText(contentHTML); + if (contentText.trim()) { + codeLines.push(contentText); + } } // 检查是否在同一元素中就有结束标记 if (startText.endsWith(':::')) { foundEnd = true; // 移除结束标记 - let lastLine = codeLines[codeLines.length - 1]; - if (lastLine) { + if (codeLines.length > 0) { + let lastLine = codeLines[codeLines.length - 1]; codeLines[codeLines.length - 1] = lastLine.replace(/:::\s*$/, '').trim(); } } @@ -4554,15 +4565,19 @@ void 0; if (text !== ':::') { text = text.replace(/:::\s*$/, '').trim(); if (text) { - codeLines.push(text); + // 将 HTML 转换为文本,保留换行符 + let contentText = this.htmlToText(currentElement.innerHTML); + codeLines.push(contentText); } } break; } // 添加当前元素的内容 - if (text) { - codeLines.push(text); + // 将 HTML 转换为文本,保留换行符 + let contentText = this.htmlToText(currentElement.innerHTML); + if (contentText.trim()) { + codeLines.push(contentText); } else { // 空元素,添加空行 codeLines.push(''); @@ -4581,6 +4596,8 @@ void 0; // 合并所有行 let code = codeLines.join('\n').trim(); + this.logDebug('提取的完整代码: ' + code.substring(0, 200)); + if (!code) { return null; } @@ -4596,6 +4613,27 @@ void 0; return container; }, + + /** + * 将 HTML 转换为纯文本,保留换行符 + * @param {string} html - HTML 字符串 + * @returns {string} 纯文本 + */ + htmlToText(html) { + // 将

转换为换行符 + let text = html.replace(//gi, '\n'); + // 移除其他 HTML 标签 + text = text.replace(/<[^>]+>/g, ''); + // 解码 HTML 实体 + text = text + .replace(/ /g, ' ') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/'/g, "'"); + return text; + }, /** * 提取代码块内容 diff --git a/commit-msg-mermaid-newline-fix.txt b/commit-msg-mermaid-newline-fix.txt new file mode 100644 index 0000000..45401e2 --- /dev/null +++ b/commit-msg-mermaid-newline-fix.txt @@ -0,0 +1,129 @@ +fix: 修复 Mermaid 容器语法换行符丢失问题 + +## 问题描述 + +用户提供的 AI 评论审核流程 Mermaid 图表渲染失败,错误信息显示: +- `flowchart TDStart` - `TD` 和 `Start` 之间缺少换行符 +- 箭头符号被转换成全角 `–>` 而不是 `-->` + +## 根本原因 + +WP-Markdown 插件将容器语法 `::: mermaid ... :::` 转换为 HTML 时: +1. 每一行代码都被包裹在 `

` 标签中 +2. 行内的换行使用 `
` 标签表示 +3. 使用 `textContent` 或 `innerText` 提取时,`
` 标签被忽略或转换为空格 +4. 导致多行代码被合并成一行,Mermaid 语法解析失败 + +## 修复方案 + +### 1. 新增 `htmlToText()` 辅助函数 + +```javascript +htmlToText(html) { + // 将

转换为换行符 + let text = html.replace(//gi, '\n'); + // 移除其他 HTML 标签 + text = text.replace(/<[^>]+>/g, ''); + // 解码 HTML 实体 + text = text + .replace(/ /g, ' ') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/'/g, "'"); + return text; +} +``` + +### 2. 改进 `extractContainerContent()` 函数 + +- 使用 `innerHTML` 而不是 `textContent` 或 `innerText` +- 调用 `htmlToText()` 将 `
` 标签转换为换行符 +- 保留所有换行符和空行 +- 添加详细的调试日志 + +### 3. 处理流程 + +``` +1. 检测到 ::: mermaid 开始标记 +2. 提取 innerHTML(包含
标签) +3. 使用 htmlToText() 转换: + -
→ \n + - 移除其他 HTML 标签 + - 解码 HTML 实体 +4. 收集所有行内容 +5. 使用 \n 连接所有行 +6. 创建容器元素存储完整代码 +``` + +## 测试验证 + +### 测试用例 1:简单流程图 +```markdown +::: mermaid +flowchart TD + A[开始] --> B[处理] + B --> C[结束] +::: +``` + +### 测试用例 2:复杂流程图(AI 评论审核) +- 包含 100+ 个节点 +- 包含多行文本(`
` 标签) +- 包含箭头符号(`-->`, `-->`) +- 包含样式定义(`style` 语句) + +### 预期结果 +- ✅ 所有换行符正确保留 +- ✅ 箭头符号不被转换 +- ✅ 多行文本正确显示 +- ✅ 样式定义正确应用 + +## 影响范围 + +- 仅影响 Markdown 容器语法(`::: mermaid ... :::`) +- 不影响其他格式(`

`, `
` 等)
+- 向后兼容,不影响现有功能
+
+## 相关文件
+
+- `argontheme.js` - 修改 `extractContainerContent()` 和新增 `htmlToText()`
+- `tests/test-ai-comment-flow.md` - 测试文档
+- `docs/mermaid-usage-guide.md` - 使用指南
+
+## 技术细节
+
+### HTML 结构示例
+
+WP-Markdown 生成的 HTML:
+```html
+

::: mermaid
+flowchart TD
+ Start([用户提交评论]) --> PreProcess[预处理]
+:::

+``` + +### 提取过程 + +1. **原始 HTML**: `::: mermaid
flowchart TD
Start --> End
:::` +2. **htmlToText()**: `::: mermaid\nflowchart TD\nStart --> End\n:::` +3. **移除标记**: `flowchart TD\nStart --> End` +4. **最终代码**: + ``` + flowchart TD + Start --> End + ``` + +## 注意事项 + +1. **性能影响**:使用 `innerHTML` 和正则替换,性能影响可忽略 +2. **安全性**:只处理 Mermaid 代码块,不执行任何脚本 +3. **兼容性**:支持所有现代浏览器 +4. **调试**:添加详细日志,便于排查问题 + +## 后续优化 + +1. 考虑支持更多 Markdown 容器语法(如 `::: warning`, `::: tip` 等) +2. 优化正则表达式性能 +3. 添加单元测试