有bug,当markdown中有html代码时,显示格式错乱

BUG反馈 · 114 次浏览
wilsons 创建于 3天18小时前

比如,如下文本

### 示例代码

以下是一个简单的HTML和JavaScript示例,展示如何实现右键菜单“问AI”功能:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>右键问AI</title>
    <style>
        .context-menu {
            display: none;
            position: absolute;
            background-color: white;
            border: 1px solid #ccc;
            padding: 5px;
        }
    </style>
</head>
<body>
    <p>右键点击这段文字问AI</p>
    <div class="context-menu">
        <button onclick="askAI()">问AI</button>
    </div>

    <script>
        document.addEventListener('contextmenu', function(event) {
            event.preventDefault();
            const contextMenu = document.querySelector('.context-menu');
            contextMenu.style.display = 'block';
            contextMenu.style.left = `${event.pageX}px`;
            contextMenu.style.top = `${event.pageY}px`;
        });

        document.addEventListener('click', function() {
            const contextMenu = document.querySelector('.context-menu');
            contextMenu.style.display = 'none';
        });

        function askAI() {
            const selectedText = window.getSelection().toString();
            if (selectedText) {
                alert(`你问的AI是:${selectedText}`);
            } else {
                alert('请选择一些文字再问AI');
            }
        }
    </script>
</body>
</html>
```

这个示例展示了如何通过右键菜单调用一个简单的函数来获取选中的文字并显示一个提示框。实际应用中,这个函数可以被修改为调用AI API来获取回复。

显示为

wilsons 最后更新于 2025/2/2

『扪』 3天15小时前 :

抱歉,水平有限,暂时无力解决🤣

『扪』 最后更新于 3天15小时前
wilsons 3天7小时前 :

我修复了这个问题,主要是因为markdown中含有特殊字符引起的,并且采用了反撇号代替双引号包裹markdown代码

markdown_preview(子程序) - 子程序信息 - Quicker

『扪』 回复 wilsons 3天6小时前 :

可以哦,能否在该类型代码块右下角增加一个"运行HTML"的按钮功能👀,这样就完美了

wilsons 回复 『扪』 2天7小时前 :

已经增加了运行按钮,不过仅html和js才会有运行按钮


『扪』 回复 wilsons 2天7小时前 :

如果markdown内容包含 \n 等特殊字符时,不能原样展示,例如:

 **提问**:如何从文件路径中提取文件名,并处理路径中可能的非法字符?
**生成的表达式**:
```csharp $= // 设置默认值 var filePath = string.IsNullOrEmpty({文件路径}) ? "C:\\path\\to\\file.txt" : {文件路径}; // 如果 {文件路径} 为空或 null,使用默认值
// 处理非法字符 var safeFilePath = filePath.Replace(Path.GetInvalidFileNameChars(), "_");
// 提取文件名 var fileName = Path.GetFileName(safeFilePath); return fileName; // 从文件路径中提取文件名,并为参数设置默认值,同时处理路径中的非法字符 ```
### **解释**:
- **外部变量引用**:使用 `{文件路径}` 引用外部变量。 - **路径操作**:使用 `Path.GetFileName` 方法从文件路径中提取文件名。 - **默认值**:如果 `{文件路径}` 为空或 null,使用默认值 `"C:\\path\\to\\file.txt"`。 - **非法字符处理**:使用 `Path.GetInvalidFileNameChars` 方法获取所有非法字符,并使用 `Replace` 方法将这些非法字符替换为下划线 `_`。
### **附加解释**:
- **路径操作**:`Path.GetFileName` 方法用于从完整路径中提取文件名部分。 - **默认值**:为防止空值或 null 导致的错误,设置了默认值。 - **非法字符处理**:通过替换非法字符,确保文件名在文件系统中是有效的。
通过上述表达式,可以轻松地从文件路径中提取文件名,并处理路径中可能的非法字符。

『扪』 最后更新于 2天7小时前
wilsons 回复 『扪』 2天7小时前 :

没太懂,这个显示效果有问题吗?


『扪』 回复 wilsons 2天7小时前 :

路径少了一个"\"

『扪』 回复 『扪』 2天7小时前 :


『扪』 最后更新于 2天7小时前
回复内容
『扪』 2天7小时前
#1

我刚更新了一版子程序,你直接在我这个源代码上加吧,整合一下,不想折腾了😁(主要是问AI也问不出来,我又不太懂)

1.增加复制完整原始内容功能
2.优化提示文字


$$<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8"/>
  <title>Markdown Preview</title>
  <style>
    /* 全局样式 */
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
      line-height: 1.6;
      color: #24292e;
      padding: 20px;
      background-color: #f6f8fa;
    }
    /* 代码块容器样式 */     .code-container {       position: relative;       margin: 16px 0;       background-color: #0d1117; /* GitHub 代码块背景色 */       border-radius: 6px;       overflow: hidden;     }
    /* 代码块样式 */     pre {       margin: 0;       padding: 16px;       overflow: auto;       font-size: 14px;       line-height: 1.45;       color: #c9d1d9; /* GitHub 代码块文字颜色 */       background-color: transparent;     }
    code {       font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;     }
    /* 复制按钮样式 */     .copy-button {       position: absolute;       top: 8px;       right: 8px;       padding: 5px 10px;       background-color: #21262d;       color: #c9d1d9;       border: 1px solid rgba(240, 246, 252, 0.1);       border-radius: 6px;       cursor: pointer;       font-size: 12px;       transition: background-color 0.2s, border-color 0.2s;       opacity: 0;       visibility: hidden;     }
    .code-container:hover .copy-button {       opacity: 1;       visibility: visible;     }
    .copy-button:hover {       background-color: #30363d;       border-color: #8b949e;     }
    .copy-button:active {       background-color: #161b22;     }
    /* 右键菜单样式 */     #contextMenu {       display: none;       position: absolute;       background-color: #fff;       border: 1px solid #ccc;       padding: 10px;       box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);       z-index: 1000;     }
    #contextMenu button {       display: block;       width: 100%;       padding: 8px;       background-color: #f9f9f9;       border: none;       text-align: left;       cursor: pointer;       margin: 5px 0;     }
    #contextMenu button:hover {       background-color: #e1e1e1;     }
    /* 弹窗提示样式 */     #popupMessage {       display: none;       position: fixed;       top: 50%;       left: 50%;       transform: translate(-50%, -50%);       background-color: #4CAF50;       color: white;       padding: 20px;       border-radius: 10px;       box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);       font-size: 16px;       z-index: 1001;     }
    /* 表格样式 */     table {       width: 100%; /* 使表格宽度适应父容器 */       border-collapse: collapse; /* 合并单元格边框 */       margin: 10px 0; /* 上下边距 */     }
    /* 表格单元格样式 */     table td,     table th {       border: 1px solid #ccc; /* 表格边框颜色 */       padding: 8px 12px; /* 内边距,增大可点击区域 */       text-align: left; /* 默认左对齐,表头除外 */     }
    /* 表头单元格的样式 */     table th {       background-color: #dee8ee; /* 表头背景色 */       text-align: center; /* 表头文字居中 */       font-weight: bold; /* 加粗表头文字 */     }
    /* 表格偶数行背景色 */     tr:nth-child(even) {       background-color: #eff3f5; /* 偶数行背景色 */     }
    /* 表格奇数行背景色(可选) */     tr:nth-child(odd) {       background-color: #ffffff; /* 奇数行背景色 */     }
    /* 可选的鼠标悬停效果 */     tr:hover {       background-color: #f5f5f5; /* 鼠标悬停时的背景色 */     }
    /* 引用样式 */     blockquote {       display: block;       border-left: 8px solid #ccc; /* 默认边框颜色 */       padding: 5px 10px;       margin: 10px 0;       line-height: 1.0;       font-size: 100%;       background-color: #f9f9f9; /* 默认背景色 */     }
    /* 列表样式 */     ul,     ol {       margin: 10px 0 10px 20px;     }
    /* 行内代码样式 */     :not(pre) > code {       padding: 3px 6px;       background-color: rgba(175, 184, 193, 0.2);       border-radius: 6px;       font-size: 90%;       color: #c7254e;     }   </style>
<!-- 使用 GitHub 风格的 Highlight.js 主题(本地) -->   <link rel="stylesheet" href="styles/{styles_css_filename}.css"> </head> <body>   <div id="content"></div>
  <!-- 右键菜单 -->   <div id="contextMenu">     <button id="copyMarkdown">�� 复制完整的原始文本</button>   </div>
  <!-- 弹窗提示 -->   <div id="popupMessage">复制成功</div>
  <!-- 引入 Highlight.js 的 JS(本地) -->   <script src="scripts/{highlight_js_filename}.js"></script>   <!-- 引入 Marked.js(本地) -->   <script src="scripts/{marked_js_filename}.js"></script>
  <script>     // 示例 Markdown 内容     const markdownContent = {markdown};
    // 渲染 Markdown     function renderMarkdown() {       const contentDiv = document.getElementById('content');       contentDiv.innerHTML = marked.parse(markdownContent);
      // 高亮代码块       hljs.highlightAll();
      // 为代码块添加 .code-container 包裹       const codeBlocks = document.querySelectorAll('pre code');       codeBlocks.forEach(codeBlock => {         const preElement = codeBlock.parentElement; // 获取 <pre> 元素         if (!preElement.parentElement.classList.contains('code-container')) {           // 创建 .code-container 包裹           const container = document.createElement('div');           container.className = 'code-container';           preElement.parentNode.insertBefore(container, preElement);           container.appendChild(preElement);         }       });
      // 添加复制按钮       addCopyButtons();     }
    // 添加复制按钮到所有代码块     function addCopyButtons() {       // 获取所有代码块容器       const codeContainers = document.querySelectorAll('.code-container');
      codeContainers.forEach(container => {         // 如果已经添加过按钮,则跳过         if (container.querySelector('.copy-button')) {           return;         }
        // 创建复制按钮         const copyButton = document.createElement('button');         copyButton.textContent = '复制';         copyButton.className = 'copy-button';         copyButton.type = 'button'; // 防止按钮提交表单         copyButton.setAttribute('aria-label', '复制代码');
        // 监听按钮点击事件         copyButton.addEventListener('click', async () => {           // 获取代码块内容           const codeContent = container.querySelector('code').innerText;
          try {             // 尝试使用现代剪贴板 API             if (navigator.clipboard && navigator.clipboard.writeText) {               await navigator.clipboard.writeText(codeContent);             } else {               // 备选方案:使用 document.execCommand('copy')               const textarea = document.createElement('textarea');               textarea.value = codeContent;               textarea.style.position = 'fixed'; // 避免滚动               textarea.style.top = '-9999px';               document.body.appendChild(textarea);               textarea.focus();               textarea.select();               const successful = document.execCommand('copy');               document.body.removeChild(textarea);               if (!successful) throw new Error('复制命令未成功执行');             }
            // 提示用户复制成功             copyButton.textContent = '✔ 复制成功';             setTimeout(() => {               copyButton.textContent = '复制';             }, 2000); // 2秒后恢复按钮文字           } catch (err) {             // 提示用户复制失败             console.error('❌ 复制失败: ', err);             copyButton.textContent = '❌ 复制失败!';             setTimeout(() => {               copyButton.textContent = '复制';             }, 2000); // 2秒后恢复按钮文字           }         });
        // 将按钮添加到容器中         container.appendChild(copyButton);       });     }
    // 页面加载完成后渲染 Markdown     document.addEventListener('DOMContentLoaded', renderMarkdown);
    // 监听右键菜单的显示     document.addEventListener('contextmenu', (event) => {       event.preventDefault();       const contextMenu = document.getElementById('contextMenu');       contextMenu.style.display = 'block';       contextMenu.style.left = `${event.pageX}px`;       contextMenu.style.top = `${event.pageY}px`;
      // 复制完整 Markdown 内容       document.getElementById('copyMarkdown').addEventListener('click', () => {         try {           if (navigator.clipboard && navigator.clipboard.writeText) {             navigator.clipboard.writeText(markdownContent);             showPopupMessage('✔ 复制成功');           }         } catch (err) {           console.error('❌ 复制失败: ', err);         }         contextMenu.style.display = 'none'; // 隐藏菜单       });     });
    // 隐藏右键菜单     document.addEventListener('click', () => {       const contextMenu = document.getElementById('contextMenu');       contextMenu.style.display = 'none';     });
    // 显示弹窗提示     function showPopupMessage(message) {       const popupMessage = document.getElementById('popupMessage');       popupMessage.textContent = message;       popupMessage.style.display = 'block';
      setTimeout(() => {         popupMessage.style.display = 'none';       }, 1200); // 2秒后隐藏弹窗     }   </script> </body> </html>

『扪』 最后更新于 2天6小时前
wilsons 回复 『扪』 2天6小时前 :

没太懂你这个复制完整的原始文本和右侧的复制按钮有什么区别

『扪』 回复 wilsons 2天6小时前 :

就是可以直接在 右键菜单 复制传入的原始markdown文本,有时候只显示MD渲染窗口的话,会复制不到这些内容

『扪』 最后更新于 2天6小时前
wilsons 回复 『扪』 2天6小时前 :

哦哦,明白了,不过,我觉得这个最好放在预览前复制比较好。目前这个功能已经满足我的需求了。

我主要用这个功能做 问AI - by wilsons - 动作信息 - Quicker 这个动作。我这个动作在预览前可以复制markdown源码。

『扪』 回复 wilsons 2天6小时前 :

多一个选择总是没坏处的
-----------------------------------
另外,上面提到的那个问题可以解决不,我就是因为这个才没更新你这个子程序👀

这个顾虑没有的话,真的就完美了👍

wilsons 回复 『扪』 2天6小时前 :

> 上面提到的那个问题可以解决不

\n那个吗?应该可以的,把之前你写的替换\\啥的加上应该行,等会我试试。

wilsons 回复 『扪』 2天6小时前 :

这样应该行,更新了,你再测测看


『扪』 回复 wilsons 2天6小时前 :

可以了,我再多多测试一下其他各种情况~

wilsons 回复 『扪』 2天6小时前 :

ok

回复主贴