allow copy original text instead of renderend text

这个提交包含在:
binary-husky
2025-03-09 00:04:27 +08:00
父节点 07974a26d0
当前提交 e78e8b0909
共有 3 个文件被更改,包括 87 次插入12 次删除

查看文件

@@ -3,7 +3,8 @@ import re
import os
import math
import html
import base64
import gzip
from loguru import logger
from textwrap import dedent
from functools import lru_cache
@@ -325,6 +326,14 @@ def markdown_convertion_for_file(txt):
# cat them together
return pre + convert_stage_5 + suf
def compress_string(s):
compress_string = gzip.compress(s.encode('utf-8'))
return base64.b64encode(compress_string).decode()
def decompress_string(s):
decoded_string = base64.b64decode(s)
return gzip.decompress(decoded_string).decode('utf-8')
@lru_cache(maxsize=128) # 使用 lru缓存 加快转换速度
def markdown_convertion(txt):
"""
@@ -336,6 +345,12 @@ def markdown_convertion(txt):
# print('警告,输入了已经经过转化的字符串,二次转化可能出问题')
return txt # 已经被转化过,不需要再次转化
# 在文本中插入一个base64编码的原始文本,以便在复制时能够获得原始文本
raw_text_encoded = compress_string(txt)
raw_text_node = f'<div class="raw_text">{raw_text_encoded}</div>'
suf = raw_text_node + "</div>"
# 用于查找数学公式的正则表达式
find_equation_pattern = r'<script type="math/tex(?:.*?)>(.*?)</script>'
txt = fix_markdown_indent(txt)
@@ -493,6 +508,7 @@ def simple_markdown_convertion(text):
suf = "</div>"
if text.startswith(pre) and text.endswith(suf):
return text # 已经被转化过,不需要再次转化
text = compat_non_markdown_input(text) # 兼容非markdown输入
text = markdown.markdown(
text,

查看文件

@@ -332,3 +332,7 @@
text-wrap: wrap;
opacity: 0.8;
}
.raw_text {
display: none;
}

查看文件

@@ -259,7 +259,24 @@ function cancel_loading_status() {
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// 第 2 部分: 复制按钮
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// 解压缩函数
function decompressString(compressedString) {
// 第1步Base64解码
const binaryString = atob(compressedString);
// 第2步将二进制字符串转换为Uint8Array
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// 第3步使用DecompressionStream (基于Web Streams API)进行gzip解压缩
const ds = new DecompressionStream('gzip');
const decompressedStream = new Response(new Blob([bytes])).body.pipeThrough(ds);
// 第4步获取解压后的数据并转换为字符串
return new Response(decompressedStream).text();
}
var allow_auto_read_continously = true;
var allow_auto_read_tts_flag = false;
@@ -283,19 +300,56 @@ function addCopyButton(botElement, index, is_last_in_arr) {
return;
}
var copyButton = document.createElement('button');
copyButton.classList.add('copy-bot-btn');
copyButton.setAttribute('aria-label', 'Copy');
copyButton.innerHTML = copyIcon;
copyButton.addEventListener('click', async () => {
const textToCopy = botElement.innerText;
// var copyButton = document.createElement('button');
// copyButton.classList.add('copy-bot-btn');
// copyButton.setAttribute('aria-label', 'Copy');
// copyButton.innerHTML = copyIcon;
// copyButton.addEventListener('click', async () => {
// const textToCopy = botElement.innerText;
// try {
// // push_text_to_audio(textToCopy).catch(console.error);
// if ("clipboard" in navigator) {
// await navigator.clipboard.writeText(textToCopy);
// copyButton.innerHTML = copiedIcon;
// setTimeout(() => {
// copyButton.innerHTML = copyIcon;
// }, 1500);
// } else {
// const textArea = document.createElement("textarea");
// textArea.value = textToCopy;
// document.body.appendChild(textArea);
// textArea.select();
// try {
// document.execCommand('copy');
// copyButton.innerHTML = copiedIcon;
// setTimeout(() => {
// copyButton.innerHTML = copyIcon;
// }, 1500);
// } catch (error) {
// console.error("Copy failed: ", error);
// }
// document.body.removeChild(textArea);
// }
// } catch (error) {
// console.error("Copy failed: ", error);
// }
// });
// 原始文本拷贝
var copyButtonOrig = document.createElement('button');
copyButtonOrig.classList.add('copy-bot-btn');
copyButtonOrig.setAttribute('aria-label', 'Copy');
copyButtonOrig.innerHTML = copyIcon;
copyButtonOrig.addEventListener('click', async () => {
try {
const base64gzipcode = botElement.getElementsByClassName('raw_text')[0].innerText;
const textToCopy = await decompressString(base64gzipcode);
// push_text_to_audio(textToCopy).catch(console.error);
if ("clipboard" in navigator) {
await navigator.clipboard.writeText(textToCopy);
copyButton.innerHTML = copiedIcon;
copyButtonOrig.innerHTML = copiedIcon;
setTimeout(() => {
copyButton.innerHTML = copyIcon;
copyButtonOrig.innerHTML = copyIcon;
}, 1500);
} else {
const textArea = document.createElement("textarea");
@@ -304,9 +358,9 @@ function addCopyButton(botElement, index, is_last_in_arr) {
textArea.select();
try {
document.execCommand('copy');
copyButton.innerHTML = copiedIcon;
copyButtonOrig.innerHTML = copiedIcon;
setTimeout(() => {
copyButton.innerHTML = copyIcon;
copyButtonOrig.innerHTML = copyIcon;
}, 1500);
} catch (error) {
console.error("Copy failed: ", error);
@@ -345,7 +399,8 @@ function addCopyButton(botElement, index, is_last_in_arr) {
var messageBtnColumn = document.createElement('div');
messageBtnColumn.classList.add('message-btn-row');
messageBtnColumn.appendChild(copyButton);
// messageBtnColumn.appendChild(copyButton);
messageBtnColumn.appendChild(copyButtonOrig);
if (enable_tts) {
messageBtnColumn.appendChild(audioButton);
}