活力39173
在线时间13450 小时
阅读权限200
管理员
自由的灵魂
- 积分
- 106852
- 主题
- 5602
- 回帖
- 26633
- 注册时间
- 2003-4-10
- 最后登录
- 2026-8-14
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
1、问题缘起
在Markdown转UBB工具的使用过程中,发现引用块转换存在问题:
| 问题 | 描述 | | 引用块分裂 | 连续的多行引用(没有空行)被拆分成多个独立的【quote】标签
| | 引用块粘连 | 不同段落的引用(有空行分隔)被错误地合并在一起 | | 调用顺序错误 | mergeConsecutiveQuotes函数与replace转换的顺序导致功能失效 |
过程中发现并解决的衍生问题
- mergeConsecutiveQuotes函数内部直接输出【quote】标签 vs 先合并再转换的顺序问题
- 多级列表修复后引用合并功能被破坏的兼容性问题
- 函数返回值格式不一致导致的重复转换问题
2、解决方案
(1)简要技术分析
核心原理:在Markdown解析过程中,先对原始文本按空行分组合并连续的引用行,再统一转换为【quote】标签(或直接在合并函数内输出标签),从而保持引用块的语义分组。.
(2)修改文件列表
| 文件 | 绝对路径 | | Markdown转UBB工具 | /www/wwwroot/dianbo.org/tools/md2ubb/index.php |
(3)关键作用代码段
最终采用的mergeConsecutiveQuotes函数(直接在函数内输出【indent】标签):
- // 智能合并连续引用块(空行分隔的引用分成独立的引用块)
- function mergeConsecutiveQuotes(text) {
- const lines = text.split('\n');
- const result = [];
- let i = 0;
-
- while (i < lines.length) {
- const line = lines[i];
- const trimmedLine = line.trim();
-
- // 检测是否是引用行
- if (trimmedLine.startsWith('>')) {
- // 收集当前引用块的所有行(直到遇到空行或非引用行)
- let quoteLines = [];
- let hasEmptyLine = false;
-
- while (i < lines.length) {
- const currentLine = lines[i];
- const currentTrimmed = currentLine.trim();
-
- // 遇到空行,引用块结束(保留空行标记)
- if (currentTrimmed === '') {
- hasEmptyLine = true;
- i++;
- break;
- }
-
- // 遇到非引用行,引用块结束
- if (!currentTrimmed.startsWith('>')) {
- break;
- }
-
- // 移除开头的 > 和可选空格,保留内容
- let content = currentLine.replace(/^>\s?/, '');
- quoteLines.push(content);
- i++;
- }
-
- // 输出合并后的引用块(直接输出 [quote] 标签)
- if (quoteLines.length > 0) {
- const quoteContent = quoteLines.join('\n');
- result.push(`[quote]${quoteContent}[/quote]`);
- }
-
- // 如果遇到了空行,添加一个空行
- if (hasEmptyLine) {
- result.push('');
- }
- } else {
- // 非引用行,直接保留
- result.push(line);
- i++;
- }
- }
-
- return result.join('\n');
- }
复制代码
在markdownToUBB函数中的调用方式:
- // 智能合并连续引用块(根据空行分组)- 直接输出 [quote] 标签
- ubb = mergeConsecutiveQuotes(ubb);
复制代码
❌ 注意:不需要再调用以下代码(会导致重复转换):
- // 这行必须删除,因为 mergeConsecutiveQuotes 已经输出 [quote] 标签
- // ubb = ubb.replace(/^>\s+(.*)$/gm, '[quote]$1[/quote]');
复制代码
3、最终实现效果
| 输入(Markdown) | 输出(UBB) | > 第一行
> 第二行
> 第三行
|
| > 第一段第一行
> 第一段第二行
> 第二段第一行
|
| > 引用1
普通文本
|
普通文本
|
4、重要技术沉淀
踩坑点
- 函数职责要单一:mergeConsecutiveQuotes要么只负责合并(返回带>的行),要么直接输出UBB标签,不能混合两种方式
- 调用顺序决定结果:先合并再转换 vs 在合并函数内直接转换,两种方式只能选其一
- 多级列表修复的影响:列表解析函数的修改不应影响引用块处理逻辑,需确保各功能模块独立
固化摘要
- 引用块合并核心规则:
- 1. 连续引用行(之间无空行)→ 合并成一个 [quote] 块
- 2. 有空行分隔的引用行 → 分成独立的 [quote] 块
- 3. 合并函数应直接输出 [quote] 标签,避免二次转换
- 4. 必须删除原有的 ubb.replace(/^>\s+.*$/gm, '[quote]$1[/quote]') 调用
复制代码
5、进一步优化的可能性
- 支持嵌套引用:Markdown支持引用块内嵌套引用(> > 内容),当前版本未处理
- 引用块内格式保留:引用块内的加粗、链接等Markdown格式应保留并转换
- 性能优化:大文档时可考虑流式处理,避免多次大字符串操作
- 配置化:将引用块的分隔符(空行)行为暴露为可配置选项
|
|