回答

收藏

将markdown转换为word的脚本

工具 工具 160 人阅读 | 0 人回复 | 2025-07-02

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. Markdown to Word Converter (简化版)
  5. 不依赖外部库的版本,适用于网络受限环境

  6. 功能:
  7. 1. 将Markdown转换为格式化的纯文本
  8. 2. 生成HTML版本(可复制粘贴到Word)
  9. 3. 不需要安装任何外部库
  10. """

  11. import os
  12. import sys
  13. import re
  14. from pathlib import Path


  15. def markdown_to_text(md_content):
  16.     """将Markdown内容转换为格式化的纯文本"""
  17.     lines = md_content.split('\n')
  18.     text_lines = []
  19.    
  20.     for line in lines:
  21.         line = line.strip()
  22.         
  23.         if not line:
  24.             text_lines.append('')
  25.             continue
  26.         
  27.         # 处理标题
  28.         if line.startswith('#'):
  29.             level = len(line) - len(line.lstrip('#'))
  30.             title_text = line.lstrip('#').strip()
  31.             
  32.             # 根据级别添加不同的格式
  33.             if level == 1:
  34.                 text_lines.append('=' * 50)
  35.                 text_lines.append(f"【主标题】 {title_text}")
  36.                 text_lines.append('=' * 50)
  37.             elif level == 2:
  38.                 text_lines.append('-' * 40)
  39.                 text_lines.append(f"【二级标题】 {title_text}")
  40.                 text_lines.append('-' * 40)
  41.             elif level == 3:
  42.                 text_lines.append(f"【三级标题】 {title_text}")
  43.                 text_lines.append('-' * 20)
  44.             else:
  45.                 text_lines.append(f"{'  ' * (level-1)}● {title_text}")
  46.             continue
  47.         
  48.         # 处理列表项
  49.         if line.startswith(('- ', '* ', '+ ')):
  50.             list_text = line[2:].strip()
  51.             # 移除markdown格式符号
  52.             list_text = clean_markdown_formatting(list_text)
  53.             text_lines.append(f"  • {list_text}")
  54.             continue
  55.         
  56.         # 处理编号列表
  57.         if re.match(r'^\d+\.', line):
  58.             list_text = re.sub(r'^\d+\.\s*', '', line)
  59.             list_text = clean_markdown_formatting(list_text)
  60.             number = re.match(r'^(\d+)\.', line).group(1)
  61.             text_lines.append(f"  {number}. {list_text}")
  62.             continue
  63.         
  64.         # 处理代码块
  65.         if line.startswith('```'):
  66.             if '```' in line and len(line) > 3:
  67.                 # 单行代码块
  68.                 code = line.replace('```', '').strip()
  69.                 text_lines.append(f"【代码】 {code}")
  70.             else:
  71.                 text_lines.append('【代码块开始】')
  72.             continue
  73.         
  74.         # 处理表格
  75.         if '|' in line and line.count('|') >= 2:
  76.             cells = [cell.strip() for cell in line.split('|')[1:-1]]
  77.             if cells:
  78.                 table_line = ' | '.join(cells)
  79.                 text_lines.append(f"【表格】 {table_line}")
  80.             continue
  81.         
  82.         # 处理普通段落
  83.         if line:
  84.             clean_text = clean_markdown_formatting(line)
  85.             text_lines.append(clean_text)
  86.    
  87.     return '\n'.join(text_lines)


  88. def markdown_to_html(md_content):
  89.     """将Markdown内容转换为简单的HTML"""
  90.     lines = md_content.split('\n')
  91.     html_lines = []
  92.    
  93.     html_lines.append('''<!DOCTYPE html>
  94. <html>
  95. <head>
  96.     <meta charset="UTF-8">
  97.     <title>Markdown转换结果</title>
  98.     <style>
  99.         body { font-family: Arial, "Microsoft YaHei", sans-serif; line-height: 1.6; margin: 40px; }
  100.         h1 { color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 10px; }
  101.         h2 { color: #34495e; border-bottom: 2px solid #bdc3c7; padding-bottom: 8px; }
  102.         h3 { color: #7f8c8d; }
  103.         ul, ol { margin: 10px 0; padding-left: 30px; }
  104.         li { margin: 5px 0; }
  105.         code { background-color: #f8f8f8; padding: 2px 5px; border-radius: 3px; }
  106.         pre { background-color: #f8f8f8; padding: 15px; border-radius: 5px; overflow-x: auto; }
  107.         table { border-collapse: collapse; width: 100%; margin: 20px 0; }
  108.         th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
  109.         th { background-color: #f2f2f2; }
  110.         strong { color: #2c3e50; }
  111.         em { color: #e74c3c; }
  112.         .warning { color: #e67e22; font-weight: bold; }
  113.     </style>
  114. </head>
  115. <body>''')
  116.    
  117.     in_code_block = False
  118.     code_lines = []
  119.    
  120.     for line in lines:
  121.         original_line = line
  122.         line = line.strip()
  123.         
  124.         if not line and not in_code_block:
  125.             html_lines.append('<br>')
  126.             continue
  127.         
  128.         # 处理代码块
  129.         if line.startswith('```'):
  130.             if in_code_block:
  131.                 # 结束代码块
  132.                 html_lines.append('<pre><code>')
  133.                 html_lines.extend(code_lines)
  134.                 html_lines.append('</code></pre>')
  135.                 code_lines = []
  136.                 in_code_block = False
  137.             else:
  138.                 # 开始代码块
  139.                 in_code_block = True
  140.             continue
  141.         
  142.         if in_code_block:
  143.             code_lines.append(html_escape(original_line))
  144.             continue
  145.         
  146.         # 处理标题
  147.         if line.startswith('#'):
  148.             level = len(line) - len(line.lstrip('#'))
  149.             title_text = line.lstrip('#').strip()
  150.             title_text = apply_html_formatting(title_text)
  151.             
  152.             if level <= 6:
  153.                 html_lines.append(f'<h{level}>{title_text}</h{level}>')
  154.             else:
  155.                 html_lines.append(f'<h6>{title_text}</h6>')
  156.             continue
  157.         
  158.         # 处理列表项
  159.         if line.startswith(('- ', '* ', '+ ')):
  160.             list_text = line[2:].strip()
  161.             list_text = apply_html_formatting(list_text)
  162.             html_lines.append(f'<ul><li>{list_text}</li></ul>')
  163.             continue
  164.         
  165.         # 处理编号列表
  166.         if re.match(r'^\d+\.', line):
  167.             list_text = re.sub(r'^\d+\.\s*', '', line)
  168.             list_text = apply_html_formatting(list_text)
  169.             html_lines.append(f'<ol><li>{list_text}</li></ol>')
  170.             continue
  171.         
  172.         # 处理表格
  173.         if '|' in line and line.count('|') >= 2:
  174.             cells = [cell.strip() for cell in line.split('|')[1:-1]]
  175.             if cells:
  176.                 html_cells = [f'<td>{apply_html_formatting(cell)}</td>' for cell in cells]
  177.                 html_lines.append(f'<table><tr>{"".join(html_cells)}</tr></table>')
  178.             continue
  179.         
  180.         # 处理普通段落
  181.         if line:
  182.             formatted_text = apply_html_formatting(line)
  183.             html_lines.append(f'<p>{formatted_text}</p>')
  184.    
  185.     html_lines.append('</body></html>')
  186.     return '\n'.join(html_lines)


  187. def clean_markdown_formatting(text):
  188.     """清理markdown格式符号"""
  189.     # 移除粗体
  190.     text = re.sub(r'\*\*(.*?)\*\*', r'【\1】', text)
  191.     # 移除斜体
  192.     text = re.sub(r'\*(.*?)\*', r'\1', text)
  193.     # 移除代码标记
  194.     text = re.sub(r'`(.*?)`', r'【代码:\1】', text)
  195.     # 移除链接,保留文本
  196.     text = re.sub(r'\[([^\]]+)\]\([^)]+\)', r'\1', text)
  197.     # 保留警告符号
  198.     text = text.replace('⚠️', '【警告】')
  199.    
  200.     return text


  201. def apply_html_formatting(text):
  202.     """应用HTML格式"""
  203.     # HTML转义
  204.     text = html_escape(text)
  205.    
  206.     # 粗体
  207.     text = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', text)
  208.     # 斜体
  209.     text = re.sub(r'\*(.*?)\*', r'<em>\1</em>', text)
  210.     # 代码
  211.     text = re.sub(r'`(.*?)`', r'<code>\1</code>', text)
  212.     # 链接
  213.     text = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'<a href="\2">\1</a>', text)
  214.     # 警告符号
  215.     text = text.replace('⚠️', '<span class="warning">⚠️</span>')
  216.    
  217.     return text


  218. def html_escape(text):
  219.     """HTML转义"""
  220.     return (text.replace('&', '&amp;')
  221.                 .replace('<', '&lt;')
  222.                 .replace('>', '&gt;')
  223.                 .replace('"', '&quot;')
  224.                 .replace("'", '&#39;'))


  225. def main():
  226.     """主函数"""
  227.     # 默认文件路径
  228.     default_md_file = r"D:\BaiduSyncdisk\api111\网站结构说明.md"
  229.    
  230.     # 获取输入文件路径
  231.     if len(sys.argv) > 1:
  232.         md_file = Path(sys.argv[1])
  233.     else:
  234.         md_file = Path(default_md_file)
  235.    
  236.     # 检查输入文件是否存在
  237.     if not md_file.exists():
  238.         print(f"错误: 文件不存在 - {md_file}")
  239.         print(f"请确保文件路径正确,或者将文件路径作为参数传递给脚本")
  240.         print(f"用法: python {sys.argv[0]} <markdown文件路径>")
  241.         return
  242.    
  243.     print(f"📁 输入文件: {md_file}")
  244.     print("-" * 50)
  245.    
  246.     try:
  247.         # 读取markdown文件
  248.         with open(md_file, 'r', encoding='utf-8') as f:
  249.             md_content = f.read()
  250.         
  251.         print("✅ 文件读取成功")
  252.         
  253.         # 生成纯文本版本
  254.         text_output = markdown_to_text(md_content)
  255.         text_file = md_file.with_suffix('.txt')
  256.         
  257.         with open(text_file, 'w', encoding='utf-8') as f:
  258.             f.write(text_output)
  259.         
  260.         print(f"📄 纯文本版本已生成: {text_file}")
  261.         
  262.         # 生成HTML版本
  263.         html_output = markdown_to_html(md_content)
  264.         html_file = md_file.with_suffix('.html')
  265.         
  266.         with open(html_file, 'w', encoding='utf-8') as f:
  267.             f.write(html_output)
  268.         
  269.         print(f"🌐 HTML版本已生成: {html_file}")
  270.         
  271.         print("\n📋 使用说明:")
  272.         print("1. 纯文本版本(.txt): 可以直接复制粘贴到任何文档")
  273.         print("2. HTML版本(.html): 用浏览器打开,然后复制粘贴到Word保持格式")
  274.         print("   - 在浏览器中打开生成的HTML文件")
  275.         print("   - 按Ctrl+A全选,然后Ctrl+C复制")
  276.         print("   - 在Word中按Ctrl+V粘贴,格式会自动保留")
  277.         
  278.         print(f"\n✅ 转换完成!生成了2个文件:")
  279.         print(f"   📄 {text_file}")
  280.         print(f"   🌐 {html_file}")
  281.         
  282.     except Exception as e:
  283.         print(f"❌ 转换失败: {str(e)}")


  284. if __name__ == "__main__":
  285.     main()
复制代码
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

143 积分
25 主题
热门推荐