用 markdown 库转换单个文件最稳,需安装第三方包 markdown,启用 tables、fenced_code、codehilite(依赖 pygments)、toc 等扩展,并显式指定 UTF-8 编码以避免乱码。

用 markdown 库转换单个文件最稳,别碰 mkdocs 或 pelican 这类静态站工具
直接依赖轻量库,避免引入构建流程和配置文件。Python 标准库不支持 Markdown 解析,必须装第三方包;markdown(PyPI 上名字就是 markdown)是事实标准,维护活跃、API 简洁、扩展性强。
安装命令:
pip install markdown
基础转换只需三行:
import markdown<br>with open("input.md") as f:<br> html = markdown.markdown(f.read())<br>with open("output.html", "w") as f:<br> f.write(html)注意:默认不支持表格、代码高亮、TOC 等扩展,需手动启用 —— 否则你看到的 HTML 里表格渲染成纯文本,代码块没 <pre><code> 嵌套。
立即学习“Python免费学习笔记(深入)”;
markdown.markdown() 的 extensions 参数决定输出质量
不传 extensions,连 | col1 | col2 | 这种表格都解析失败;传错名称(比如写成 "tables" 而不是 "mdx_tables")会静默忽略,毫无报错提示。
常用扩展及写法:
-
"tables":支持管道语法表格(必须小写字符串,不是类名) -
"fenced_code":识别 ``` 代码块(注意不是"codehilite",后者只负责高亮) -
"codehilite":配合fenced_code使用,生成带 class 的<pre><code class="py">,但需额外装pygments -
"toc":生成<div class="toc">,标题自动加id属性
推荐初始化方式:
md = markdown.Markdown(extensions=["tables", "fenced_code", "codehilite", "toc"])<br>html = md.convert(md_content)
注意:codehilite 扩展依赖 pygments,若没装会抛 ImportError;但错误信息只说 “No module named 'pygments'”,不会告诉你哪行触发的。
批量处理时路径和编码最容易出错
Windows 上常见问题:脚本在中文路径下运行,open() 默认用系统编码(如 GBK),读取 UTF-8 编码的 Markdown 文件就崩,报 UnicodeDecodeError: 'gbk' codec can't decode byte。
安全做法始终显式指定 encoding="utf-8":
for md_file in Path("docs").glob("*.md"): <br> with open(md_file, encoding="utf-8") as f:<br> content = f.read()<br> html = md.convert(content)<br> html_path = md_file.with_suffix(".html")<br> with open(html_path, "w", encoding="utf-8") as f:<br> f.write(html)另外注意:Path.glob() 返回的是 PosixPath 或 WindowsPath 对象,不能直接传给 open()(会报 TypeError: expected str, bytes or os.PathLike object),要用 str(md_file) 或更推荐的 md_file.open() 方式。
生成的 HTML 没 CSS 样式?这不是转换脚本该管的事
markdown 库只输出纯 HTML 片段(无 <html>、<head>),比如 md.convert("# Hello") 输出的是 <h1>Hello</h1>,不是完整网页。
如果要浏览器直接打开看得过去,得自己拼接模板:
template = """<!DOCTYPE html><br><html><head><meta charset="utf-8"><br><link rel="stylesheet" href="style.css"></head><br><body>{content}</body></html>"""<br>full_html = template.format(content=html)或者用 jinja2 渲染更灵活的布局(比如加导航栏、自动插入 TOC),但这就超出“转换”范畴了。重点记住:转换器不负责样式,别指望它吐出带 Bootstrap 的 HTML。
真正容易被忽略的是:TOC 扩展生成的目录是纯 HTML 字符串,藏在 md.toc 属性里,不在 md.convert() 返回值中;想把目录插到正文前,得手动拼接 md.toc + html,而且 md.toc 开头自带 <div class="toc">,别重复包裹。



















