python markdown 自定义扩展
参考博客:https://www.cnblogs.com/JiangLe/p/12682912.html
aiofiles 23.2.1
aiohttp 3.9.1
aiosignal 1.3.1
asgiref 3.7.2
attrs 23.1.0
autobahn 23.6.2
Automat 22.10.0
beautifulsoup4 4.12.3
certifi 2023.11.17
cffi 1.16.0
chardet 5.2.0
charset-normalizer 3.3.2
colorama 0.4.6
constantly 23.10.4
cryptography 42.0.2
daphne 4.0.0
Django 5.0.1
et-xmlfile 1.1.0
frozenlist 1.4.1
html5lib 1.1
hyperlink 21.0.0
idna 3.6
incremental 22.10.0
lxml 4.9.4
Markdown 3.7
multidict 6.0.4
numpy 1.26.4
openpyxl 3.1.2
pip 25.0.1
pyasn1 0.5.1
pyasn1-modules 0.3.0
pycparser 2.21
pyOpenSSL 24.0.0
requests 2.31.0
service-identity 24.1.0
setuptools 65.5.0
six 1.16.0
soupsieve 2.5
sqlparse 0.4.4
Twisted 23.10.0
twisted-iocpsupport 1.0.4
txaio 23.1.1
typing_extensions 4.9.0
tzdata 2023.4
urllib3 2.1.0
webencodings 0.5.1
yarl 1.9.4
zope.interface 6.1
md = markdown.Markdown(
extensions=[
# 包含 缩写、表格等常用扩展
# 'markdown.extensions.extra',
AddButtonToExtension(),
# 语法高亮扩展
# 'markdown.extensions.codehilite',
# 目录
# 'markdown.extensions.toc',
],
)
import markdown
from markdown.treeprocessors import Treeprocessor
from markdown.extensions import Extension
from xml.etree import ElementTree as ET
# 自定义 Treeprocessor 类
class AddButtonToTreeprocessor(Treeprocessor):
def run(self, root):
# 遍历文档树中的所有 <pre> 标签
for pre in root.iter('pre'):
# 创建一个 button 元素
button = ET.Element('button')
button.text = 'Copy Code'
button.set('onclick', 'alert("You clicked the copy button!")')
# 在 <pre> 标签之前插入按钮
pre.insert(0, button)
return root
# 自定义扩展类
class AddButtonToExtension(Extension):
def extendMarkdown(self, md):
# 注册自定义的 Treeprocessor
md.treeprocessors.register(AddButtonToTreeprocessor(md), 'add_button_to_pre', 15)
def convert_markdown_to_html(markdown_text):
# 创建 Markdown 实例并使用自定义扩展
# md = markdown.Markdown(extensions=[AddButtonToExtension()])
md = markdown.Markdown(extensions=[])
return md.convert(markdown_text)
def write_html_to_file(html_content, output_file):
with open(output_file, 'w', encoding='utf-8') as file:
file.write(html_content)
if __name__ == "__main__":
markdown_text = '''
# Heading 1
## Heading 2
this is c code
```
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
```
'''
html = convert_markdown_to_html(markdown_text)
print(html)
write_html_to_file(html, 'output.html')
代码可复制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pre Code Copy Button with Hover</title>
<style>
pre {
position: relative;
background-color: #f4f4f4;
padding: 20px;
border: 1px solid #ccc;
border-radius: 4px;
overflow-x: auto;
}
.copy-button {
position: absolute;
top: 10px;
right: 10px;
padding: 5px 10px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
opacity: 0; /* 默认隐藏按钮 */
transition: opacity 0.3s ease; /* 添加过渡效果 */
}
pre:hover .copy-button {
opacity: 1; /* 鼠标悬停时显示按钮 */
}
</style>
</head>
<body>
<pre>
<button class="copy-button">复制</button>
<code>
function add(a, b) {
return a + b;
}
const result = add(3, 5);
console.log(result);
</code>
</pre>
<script>
const copyButtons = document.querySelectorAll('.copy-button');
copyButtons.forEach(button => {
button.addEventListener('click', async () => {
const preElement = button.parentNode;
const codeElement = preElement.querySelector('code');
const codeText = codeElement.textContent;
try {
await navigator.clipboard.writeText(codeText);
button.textContent = '已复制';
setTimeout(() => {
button.textContent = '复制';
}, 2000);
} catch (err) {
console.error('复制失败:', err);
}
});
});
</script>
</body>
</html>