找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
Close
查看: 29|回复: 0

[维护日志] [2026-06-11] [功能] [Markdown引用块合并] - 连续引用块按空行分组合并功能实现

[复制链接]
  • 打卡等级:本地老炮

9336

威望

6912

金钱

1万

贡献

管理员

自由的灵魂

积分
106852
主题
5602
回帖
26633
注册时间
2003-4-10
最后登录
2026-8-14
发表于 2026-6-11 11:57:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
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】标签):

  1. // 智能合并连续引用块(空行分隔的引用分成独立的引用块)
  2. function mergeConsecutiveQuotes(text) {
  3.     const lines = text.split('\n');
  4.     const result = [];
  5.     let i = 0;
  6.    
  7.     while (i < lines.length) {
  8.         const line = lines[i];
  9.         const trimmedLine = line.trim();
  10.         
  11.         // 检测是否是引用行
  12.         if (trimmedLine.startsWith('>')) {
  13.             // 收集当前引用块的所有行(直到遇到空行或非引用行)
  14.             let quoteLines = [];
  15.             let hasEmptyLine = false;
  16.             
  17.             while (i < lines.length) {
  18.                 const currentLine = lines[i];
  19.                 const currentTrimmed = currentLine.trim();
  20.                
  21.                 // 遇到空行,引用块结束(保留空行标记)
  22.                 if (currentTrimmed === '') {
  23.                     hasEmptyLine = true;
  24.                     i++;
  25.                     break;
  26.                 }
  27.                
  28.                 // 遇到非引用行,引用块结束
  29.                 if (!currentTrimmed.startsWith('>')) {
  30.                     break;
  31.                 }
  32.                
  33.                 // 移除开头的 > 和可选空格,保留内容
  34.                 let content = currentLine.replace(/^>\s?/, '');
  35.                 quoteLines.push(content);
  36.                 i++;
  37.             }
  38.             
  39.             // 输出合并后的引用块(直接输出 [quote] 标签)
  40.             if (quoteLines.length > 0) {
  41.                 const quoteContent = quoteLines.join('\n');
  42.                 result.push(`[quote]${quoteContent}[/quote]`);
  43.             }
  44.             
  45.             // 如果遇到了空行,添加一个空行
  46.             if (hasEmptyLine) {
  47.                 result.push('');
  48.             }
  49.         } else {
  50.             // 非引用行,直接保留
  51.             result.push(line);
  52.             i++;
  53.         }
  54.     }
  55.    
  56.     return result.join('\n');
  57. }
复制代码


markdownToUBB函数中的调用方式:

  1.     // 智能合并连续引用块(根据空行分组)- 直接输出 [quote] 标签
  2.     ubb = mergeConsecutiveQuotes(ubb);
复制代码


❌ 注意:不需要再调用以下代码(会导致重复转换):

  1.     // 这行必须删除,因为 mergeConsecutiveQuotes 已经输出 [quote] 标签
  2.     // ubb = ubb.replace(/^>\s+(.*)$/gm, '[quote]$1[/quote]');
复制代码





3、最终实现效果

输入(Markdown)输出(UBB)
> 第一行
> 第二行
> 第三行
第一行
第二行
第三行

> 第一段第一行
> 第一段第二行

> 第二段第一行
第一段第一行
第一段第二行
第二段第一行

> 引用1

普通文本
引用1

普通文本





4、重要技术沉淀

踩坑点

  • 函数职责要单一mergeConsecutiveQuotes要么只负责合并(返回带>的行),要么直接输出UBB标签,不能混合两种方式
  • 调用顺序决定结果:先合并再转换 vs 在合并函数内直接转换,两种方式只能选其一
  • 多级列表修复的影响:列表解析函数的修改不应影响引用块处理逻辑,需确保各功能模块独立

固化摘要

  1. 引用块合并核心规则:
  2. 1. 连续引用行(之间无空行)→ 合并成一个 [quote] 块
  3. 2. 有空行分隔的引用行 → 分成独立的 [quote] 块
  4. 3. 合并函数应直接输出 [quote] 标签,避免二次转换
  5. 4. 必须删除原有的 ubb.replace(/^>\s+.*$/gm, '[quote]$1[/quote]') 调用
复制代码





5、进一步优化的可能性

  • 支持嵌套引用:Markdown支持引用块内嵌套引用(> > 内容),当前版本未处理
  • 引用块内格式保留:引用块内的加粗、链接等Markdown格式应保留并转换
  • 性能优化:大文档时可考虑流式处理,避免多次大字符串操作
  • 配置化:将引用块的分隔符(空行)行为暴露为可配置选项


不懂就搜!点此搜点拨论坛。如果本坛没有,请尝试点此问AI,或跟帖提问。
发帖前注意看置顶帖
不定期借助AI对点拨论坛陈年老帖进行挖坟回复,打扰勿怪!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|点拨论坛 |网站地图|网站地图

GMT+8, 2026-8-14 20:42 , Processed in 0.047344 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表