Spaces:
Sleeping
Sleeping
File size: 3,614 Bytes
e2f726f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
/**
* Markdown渲染器库(支持HTML标签)
* 依赖:
* - markdown-it
* - highlight.js
* - clipboard.js
*/
const MarkdownRenderer = (function () {
// 初始化 markdown-it 实例,启用 HTML 支持
hljs.configure({
ignoreUnescapedHTML: true
});
const md = window.markdownit({
html: true, // 启用HTML标签支持
breaks: true,
xhtmlOut: true,
typographer: true, // 启用智能标点转换
highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(str, { language: lang }).value;
} catch (__) { }
}
return hljs.highlight(str, { language: 'plaintext' }).value;
}
});
/**
* 渲染Markdown内容为HTML
* @param {string} content - Markdown格式的内容
* @returns {string} 渲染后的HTML字符串
*/
function renderMessage(content) {
// 处理有序列表
content = content.replace(/(\d+)\.\s/g, ' $1\\. ');
// 渲染markdown内容
let renderedContent = md.render(content);
// 创建临时容器
const container = document.createElement('div');
container.innerHTML = renderedContent;
// 处理代码块
container.querySelectorAll('pre code').forEach((block) => {
const pre = block.parentNode;
const lang = block.className.split('-')[1] || 'plaintext';
// 生成唯一ID
pre.id = 'code-' + Math.random().toString(36).substr(2, 9);
// 创建代码头部
const header = document.createElement('div');
header.className = 'code-header bg-gradient-to-b from-gray-900 via-gray-800 to-gray-700 text-white rounded-lg rounded-br-none rounded-bl-none';
header.innerHTML = `
<div style="margin-left: 8px;">
<span class="code-language">${lang}</span>
<button class="copy-button" data-clipboard-target="#${pre.id}">✄</button>
</div>
`;
// 添加样式类
pre.classList.add('code-block', 'rounded-tr-none', 'rounded-tl-none');
pre.parentNode.insertBefore(header, pre);
// 代码高亮
hljs.highlightElement(block);
// 初始化复制功能
setTimeout(() => {
const clipboard = new ClipboardJS('.copy-button');
clipboard.on('success', function (e) {
e.trigger.textContent = '♫';
setTimeout(() => {
e.trigger.textContent = '✄';
}, 1000);
e.clearSelection();
});
clipboard.on('error', function (e) {
console.error('Copy failed!');
});
}, 0);
});
// 不再需要转换HTML实体,因为我们现在允许HTML标签
return container.innerHTML;
}
// 只暴露需要的方法
return {
render: renderMessage
};
})();
// 支持 CommonJS
if (typeof module !== 'undefined' && module.exports) {
module.exports = MarkdownRenderer;
}
// 支持 ES6 模块
if (typeof exports !== 'undefined') {
exports.default = MarkdownRenderer;
}
// 支持全局变量
if (typeof window !== 'undefined') {
window.MarkdownRenderer = MarkdownRenderer;
} |