欧卡2中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

需要三步,才能开始

只需两步,慢速开始

查看: 44|回复: 0
收起左侧

复杂的markdown测试

[复制链接]
哄你叉叉 发表于 2025-7-28 12:21 | 显示全部楼层 |阅读模式
本帖最后由 哄你叉叉 于 2025-8-11 15:29 编辑

我理解问题所在了。我们需要更精确地处理列表中的代码块。以下是专门针对列表代码块渲染问题的修复方案,同时确保不影响现有的主题帖和回帖渲染:

 复制代码 隐藏代码
<script> // 创建WeakSet跟踪已处理元素 const markdownProcessed = new WeakSet(); window.parseMarkdown = function(element) {   // 跳过已处理元素   if (markdownProcessed.has(element)) return;   try {     // 修复关键问题:还原转义的markdown标签     if (element.innerHTML.includes('<markdown>')) {       element.innerHTML = element.innerHTML         .replace(/<markdown>/gi, '<markdown>')         .replace(/<\/markdown>/gi, '</markdown>');     }     const rawContent = element.textContent;     // 预处理特殊语法     const preprocessed = rawContent       .replace(/\[x\]/g, '✅')       .replace(/\[ \]/g, '⬜');     // 配置marked.js - 确保正确处理列表代码块     marked.setOptions({       breaks: true,       gfm: true,       silent: true, // 禁用控制台警告       smartLists: false // 禁用智能列表处理     });     // 解析并安全过滤     const parsed = marked.parse(preprocessed);     element.innerHTML = DOMPurify.sanitize(parsed, {       ADD_TAGS: ['markdown'] // 允许保留markdown标签     });     // 标记为已处理     markdownProcessed.add(element);     // 高亮代码块 - 添加列表代码块专门处理     element.querySelectorAll('pre > code:not(.hljs), li > code:not(.hljs)').forEach((codeBlock) => {       // 处理列表中的代码块 - 核心修复       if (codeBlock.parentNode.nodeName === 'LI') {         // 检查是否是真正的代码块(包含```标记)         if (codeBlock.textContent.includes('```')) {           // 创建pre容器           const pre = document.createElement('pre');           // 提取代码内容(移除```标记)           const codeContent = codeBlock.textContent             .replace(/```[a-z]*\n/g, '') // 移除开头的```             .replace(/\n```/g, ''); // 移除结尾的```           // 创建新的代码元素           const newCode = document.createElement('code');           newCode.textContent = codeContent;           // 设置语言类           const langMatch = codeBlock.textContent.match(/```(\w+)/);           if (langMatch) {             newCode.className = `language-${langMatch[1]}`;           }           // 组装结构           pre.appendChild(newCode);           // 替换原始代码块           codeBlock.parentNode.replaceChild(pre, codeBlock);           // 更新引用           codeBlock = newCode;         }       }       // 自动语言检测       if (!codeBlock.className) {         const languageMatch = codeBlock.textContent.match(/^(\w+)\n/);         if (languageMatch) {           codeBlock.className = `language-${languageMatch[1]}`;         }       }       // 应用高亮       hljs.highlightElement(codeBlock);     });   } catch (e) {     console.error('Markdown解析错误:', e);     // 出错时保留原始内容     element.innerHTML = DOMPurify.sanitize(element.innerHTML);   } }; // 初始加载处理 document.addEventListener('DOMContentLoaded', function() {   // 处理所有.t_f元素(主题帖和回帖)   document.querySelectorAll('.t_f').forEach(td => {     // 检查是否包含markdown内容     if (td.innerHTML.includes('<markdown>') || td.querySelector('markdown')) {       parseMarkdown(td);     }   });   // 添加MutationObserver监听动态内容   const observer = new MutationObserver(mutations => {     mutations.forEach(mutation => {       mutation.addedNodes.forEach(node => {         // 检查新增节点         if (node.nodeType === 1) { // Element节点           // 检查.t_f容器           if (node.classList.contains('t_f')) {             parseMarkdown(node);           }           // 检查子节点中的.t_f容器           else if (node.querySelectorAll) {             node.querySelectorAll('.t_f').forEach(parseMarkdown);           }         }       });     });   });   observer.observe(document.body, {     childList: true,     subtree: true   }); }); // AJAX内容处理(增强版) $(document).ajaxStop(function() {   setTimeout(() => {     // 处理所有未处理的.t_f元素     document.querySelectorAll('.t_f:not([data-processed])').forEach(el => {       parseMarkdown(el);     });   }, 300); // 增加延迟确保DOM完全更新 }); // 添加调试功能 window.debugListCode = function() {   console.groupCollapsed('列表代码块状态');   document.querySelectorAll('li > code').forEach(codeBlock => {     console.log('列表中的代码块:', {       text: codeBlock.textContent.substring(0, 50) + (codeBlock.textContent.length > 50 ? '...' : ''),       containsBackticks: codeBlock.textContent.includes('```'),       parent: codeBlock.parentNode     });   });   console.groupEnd(); }; </script>

关键修复点 - 专门处理列表中的代码块:

 复制代码 隐藏代码
// 处理列表中的代码块 - 核心修复 if (codeBlock.parentNode.nodeName === 'LI') {   // 检查是否是真正的代码块(包含```标记)   if (codeBlock.textContent.includes('```')) {     // 创建pre容器     const pre = document.createElement('pre');     // 提取代码内容(移除```标记)     const codeContent = codeBlock.textContent       .replace(/```[a-z]*\n/g, '') // 移除开头的```       .replace(/\n```/g, ''); // 移除结尾的```     // 创建新的代码元素     const newCode = document.createElement('code');     newCode.textContent = codeContent;     // 设置语言类     const langMatch = codeBlock.textContent.match(/```(\w+)/);     if (langMatch) {       newCode.className = `language-${langMatch[1]}`;     }     // 组装结构     pre.appendChild(newCode);     // 替换原始代码块     codeBlock.parentNode.replaceChild(pre, codeBlock);     // 更新引用     codeBlock = newCode;   } }

额外的CSS修复(添加到header.php):

 复制代码 隐藏代码
/* 确保列表中的代码块正确显示 */ .t_f li > pre {   margin: 10px 0;   padding: 12px;   background: #f8f9fa;   border: 1px solid #eaecef;   border-radius: 4px;   overflow: auto; } .t_f li > pre code {   background: none !important;   padding: 0 !important;   border: none !important;   border-radius: 0 !important; }

使用说明:

  1. 将上述完整JS代码复制到footer.php
  2. 将CSS代码添加到header.php
  3. 在浏览器控制台执行 debugListCode() 查看列表代码块状态

如果问题仍然存在 - 最终解决方案

如果以上方案仍不能解决问题,请使用这个专门为列表代码块设计的解析器替代方案:

 复制代码 隐藏代码
// 在parseMarkdown函数内部替换解析部分 const parsed = marked.parse(preprocessed); // 替换为: function customMarkdownParser(markdown) {   // 专门处理列表中的代码块   return markdown.replace(/(^(\s*)[-*]\s+.*\n)(\s*)```([\s\S]*?)```/gm, (match, p1, p2, p3, p4) => {     // p1: 列表项内容     // p2: 列表缩进     // p3: 代码块前的空格     // p4: 代码内容     return `${p1}${p3}<pre><code>${p4}</code></pre>`;   }); } const customParsed = customMarkdownParser(preprocessed); const parsed = marked.parse(customParsed);

调试建议:

在代码块处理部分添加详细日志:

 复制代码 隐藏代码
console.log('处理代码块:', {   isList: codeBlock.parentNode.nodeName === 'LI',   containsBackticks: codeBlock.textContent.includes('```'),   text: codeBlock.textContent.substring(0, 50) + (codeBlock.textContent.length > 50 ? '...' : '') }); if (codeBlock.parentNode.nodeName === 'LI' && codeBlock.textContent.includes('```')) {   console.log('转换列表代码块');   console.log('原始内容:', codeBlock.textContent);   console.log('处理后内容:', codeContent); }

这个方案专门针对列表中的代码块进行了深度处理:

  1. 精确识别包含```标记的列表代码块
  2. 自动移除```标记并提取纯代码内容
  3. 创建正确的<pre><code>结构
  4. 保留代码语言信息
  5. 应用正确的语法高亮

同时保留了您原有代码中主题帖和回帖渲染的所有功能。请尝试这个方案,它应该能解决列表代码块渲染问题。



本帖子中包含更多资源

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

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

客服QQ936487697|联系我们|手机版|欧卡2中国 ( 湘ICP备11020288号-1 )

GMT+8, 2025-8-25 14:46 , Processed in 0.085621 second(s), 9 queries , Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

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