markdown 转pdf支持页眉标签目录跳转封面插入
项目地址
https://gitee.com/han_gx/markdown-to-pdf
windows 下载地址 https://gitee.com/han_gx/markdown-to-pdf/releases/
下载之后运行 xxx.exe --help 查看帮助命令
D:\test>markdown_to_pdf_WIN64.exe --help
usage: markdown_to_pdf_WIN64.exe [-h] [-o OUTPUT] [--no-toc] [--toc-title TOC_TITLE] [--header HEADER]
[--header-left HEADER_LEFT] [--header-right HEADER_RIGHT]
[--header-position {left,center,right}] [--header-underline]
[--header-font-size HEADER_FONT_SIZE] [--header-font-color HEADER_FONT_COLOR]
[--footer FOOTER] [--footer-left FOOTER_LEFT] [--footer-right FOOTER_RIGHT]
[--footer-position {left,center,right}] [--footer-font-size FOOTER_FONT_SIZE]
[--footer-font-color FOOTER_FONT_COLOR] [--no-page-number]
[--page-number-format PAGE_NUMBER_FORMAT]
[--page-number-position {left,center,right}] [--margin-top MARGIN_TOP]
[--margin-bottom MARGIN_BOTTOM] [--margin-left MARGIN_LEFT]
[--margin-right MARGIN_RIGHT] [--paper-size {A4,Letter,Legal,A3,A5}] [--no-bookmarks]
[--no-h1-page-break] [--no-h2-page-break] [--cover COVER]
input_file
将 Markdown 文件转换为 PDF(使用 WeasyPrint,支持 PDF 书签)
positional arguments:
input_file 输入的 Markdown 文件路径
options:
-h, --help show this help message and exit
-o, --output OUTPUT 输出的 PDF 文件路径(默认:输入文件名.pdf)
--no-toc 不显示目录
--toc-title TOC_TITLE
目录标题(默认:目录)
--header HEADER 页眉文本(中间位置)
--header-left HEADER_LEFT
页眉左侧文本
--header-right HEADER_RIGHT
页眉右侧文本
--header-position {left,center,right}
页眉位置(默认:center,当使用--header-left或--header-right时自动启用左右布局)
--header-underline 为页眉添加下划线
--header-font-size HEADER_FONT_SIZE
页眉字体大小(默认:10pt)
--header-font-color HEADER_FONT_COLOR
页眉字体颜色(默认:#000000)
--footer FOOTER 页脚文本
--footer-left FOOTER_LEFT
页脚左侧文本
--footer-right FOOTER_RIGHT
页脚右侧文本
--footer-position {left,center,right}
页脚位置(默认:center)
--footer-font-size FOOTER_FONT_SIZE
页脚字体大小(默认:10pt)
--footer-font-color FOOTER_FONT_COLOR
页脚字体颜色(默认:#000000)
--no-page-number 不显示页码
--page-number-format PAGE_NUMBER_FORMAT
页码格式,可用 {page} "第 {page} 页"
--page-number-position {left,center,right}
页码位置(默认:center)
--margin-top MARGIN_TOP
上边距,单位 mm(默认:30)
--margin-bottom MARGIN_BOTTOM
下边距,单位 mm(默认:25)
--margin-left MARGIN_LEFT
左边距,单位 mm(默认:20)
--margin-right MARGIN_RIGHT
右边距,单位 mm(默认:20)
--paper-size {A4,Letter,Legal,A3,A5}
纸张大小(默认:A4)
--no-bookmarks 不生成 PDF 书签
--no-h1-page-break 一级标题分页(默认不分页)
--no-h2-page-break 二级标题分页(默认不分页)
--cover COVER 封面PDF文件路径
示例:
# 基本用法
python md_to_pdf_weasyprint.py input.md
# 自定义输出和配置
python md_to_pdf_weasyprint.py input.md -o output.pdf --header "文档标题"
# 完整配置示例
python md_to_pdf_weasyprint.py input.md \
--header "文档标题" \
--footer "公司名称" \
--page-number-format "第{page}页" \
--margin-top 30 --margin-bottom 30
概述
md_to_pdf_weasyprint.py 是一个功能强大的 Markdown 转 PDF 工具,基于 WeasyPrint 库开发。该工具支持生成专业的 PDF 文档,包括目录、页眉页脚、页码、PDF 书签、封面插入等高级功能。
主要特性
🎯 核心功能
- Markdown 转 PDF:将 Markdown 文件转换为高质量的 PDF 文档
- 自动目录生成:支持多级标题的目录自动生成
- PDF 书签支持:生成可点击的 PDF 书签导航
- 多页面目录链接:支持跨页面目录的可点击链接跳转
- 封面插入:支持 PDF 封面插入,保持原始质量
🎨 样式定制
- 页眉页脚:支持左中右布局的页眉页脚定制
- 页码格式:灵活的页码格式配置
- 页面边距:可自定义的页面边距设置
- 字体样式:页眉页脚字体大小和颜色定制
- 纸张尺寸:支持 A4、Letter、Legal 等多种纸张规格
📄 高级特性
- 智能分页控制:支持一级、二级标题的分页控制
- 图片处理:自动将本地图片转换为 data URI
- 代码块支持:保留代码块格式和语法高亮
- 表格优化:自动转换列表符号,优化表格显示
- 多语言支持:完美支持中文和英文混合文档
安装要求
必需依赖
pip install markdown
pip install weasyprint
pip install pymupdf # 用于PDF书签和链接功能
系统要求
- Python 3.7+
- Windows/Linux/macOS
- WeasyPrint 系统依赖(自动安装)
使用方法
基本用法
# 基本转换
python md_to_pdf_weasyprint.py input.md
# 指定输出文件
python md_to_pdf_weasyprint.py input.md -o output.pdf
高级配置
# 完整配置示例
python md_to_pdf_weasyprint.py input.md \
--header "文档标题" \
--footer "公司名称" \
--page-number-format "第{page}页" \
--margin-top 30 \
--margin-bottom 30 \
--cover cover.pdf
命令行参数详解
基本参数
| 参数 | 说明 | 默认值 |
|---|---|---|
input_file |
输入的 Markdown 文件路径 | 必需 |
-o, --output |
输出的 PDF 文件路径 | 输入文件名.pdf |
目录配置
| 参数 | 说明 | 默认值 |
|---|---|---|
--no-toc |
不显示目录 | False |
--toc-title |
目录标题 | "目录" |
页眉配置
| 参数 | 说明 | 默认值 |
|---|---|---|
--header |
页眉中间文本 | None |
--header-left |
页眉左侧文本 | None |
--header-right |
页眉右侧文本 | None |
--header-position |
页眉位置 | center |
--header-underline |
为页眉添加下划线 | False |
--header-font-size |
页眉字体大小 | 10pt |
--header-font-color |
页眉字体颜色 | #000000 |
页脚配置
| 参数 | 说明 | 默认值 |
|---|---|---|
--footer |
页脚文本 | None |
--footer-left |
页脚左侧文本 | None |
--footer-right |
页脚右侧文本 | None |
--footer-position |
页脚位置 | center |
--footer-font-size |
页脚字体大小 | 10pt |
--footer-font-color |
页脚字体颜色 | #000000 |
页码配置
| 参数 | 说明 | 默认值 |
|---|---|---|
--no-page-number |
不显示页码 | False |
--page-number-format |
页码格式 | |
--page-number-position |
页码位置 | center |
页面布局
| 参数 | 说明 | 默认值 |
|---|---|---|
--margin-top |
上边距 (mm) | 20 |
--margin-bottom |
下边距 (mm) | 25 |
--margin-left |
左边距 (mm) | 20 |
--margin-right |
右边距 (mm) | 20 |
--paper-size |
纸张大小 | A4 |
高级选项
| 参数 | 说明 | 默认值 |
|---|---|---|
--no-bookmarks |
不生成 PDF 书签 | False |
--no-h1-page-break |
一级标题分页 | False |
--no-h2-page-break |
二级标题分页 | False |
--cover |
封面PDF文件路径 | None |
核心类和方法
MarkdownToPDF 类
构造函数
def __init__(self, config: Optional[Dict[str, Any]] = None)
初始化转换器配置,支持以下配置项:
config = {
'show_toc': True, # 是否显示目录
'header_text': None, # 页眉文本
'footer_text': None, # 页脚文本
'page_number': True, # 是否显示页码
'page_number_format': '{page}', # 页码格式
'generate_bookmarks': True, # 是否生成PDF书签
'h1_page_break': True, # 一级标题是否分页
# ... 更多配置项
}
主要方法
convert() 方法
def convert(self, md_file: str, pdf_file: str, cover_pdf: Optional[str] = None)
功能:将 Markdown 文件转换为 PDF
参数:
md_file: 输入的 Markdown 文件路径pdf_file: 输出的 PDF 文件路径cover_pdf: 可选的封面 PDF 文件路径
处理流程:
- 读取并解析 Markdown 文件
- 提取和处理代码块
- 转换为 HTML
- 提取标题信息
- 生成目录
- 处理图片路径
- 生成 CSS 样式
- 使用 WeasyPrint 生成 PDF
- 添加目录链接
- 合并封面(如果提供)
核心功能详解
1. 目录生成和链接
多页面目录识别
工具使用智能算法识别多页面目录:
def _find_all_toc_pages(self, doc):
"""查找所有目录页面"""
# 1. 检查目录关键词
# 2. 验证标题格式
# 3. 连续性检查
# 4. 选择最大连续组
识别策略:
- 检查是否包含目录关键词('目录', 'contents', 'table of contents' 等)
- 验证页面是否包含多个标题格式(如 "1.", "2.", "1.1" 等)
- 采用分组检查和最大连续组选择策略
- 允许目录页面之间有合理间隔(≤3页)
目录链接添加
def _add_toc_links(self, pdf_path: str, headings: List[Dict[str, Any]])
功能特点:
- 支持跨页面目录的链接添加
- 智能标题匹配和页面定位
- 精确的文本位置查找
- 支持模糊匹配和容错处理
2. PDF 书签生成
使用 WeasyPrint 的 CSS 书签属性:
h1 {
bookmark-level: 1;
bookmark-label: content();
page-break-after: avoid;
}
h2 {
bookmark-level: 2;
bookmark-label: content();
page-break-after: avoid;
}
3. 封面插入技术
PDF 插入技术(推荐)
def _merge_pdf_with_cover(self, content_pdf_path: str, cover_pdf_path: str, output_pdf_path: str)
优势:
- 保持原始 PDF 质量
- 保留书签信息
- 支持多页面封面
- 自动调整页码
图片转换技术(备用)
def _extract_cover_full_image(self, cover_pdf_path: str) -> Optional[str]
特点:
- 高分辨率渲染(2倍缩放)
- PNG 格式输出
- Base64 编码嵌入
4. 样式系统
CSS 生成
def _generate_css(self) -> str
包含样式:
- 页面布局和边距
- 页眉页脚样式
- 标题样式和分页控制
- 目录样式
- 正文内容样式
- 代码块和表格样式
分页控制
/* 一级标题分页 */
h1 {
page-break-before: always;
}
/* 紧挨着h1的h2标题不分页 */
h1 + h2 {
page-break-before: avoid !important;
}
5. 图片处理
路径转换
def _fix_image_paths(self, html_content: str, base_path: str) -> str
处理逻辑:
- 检测相对路径图片
- 转换为绝对路径
- 读取图片文件
- 编码为 Base64
- 生成 data URI
支持的图片格式:
- JPEG, PNG, GIF, BMP
- 自动 MIME 类型检测
- 错误处理和警告提示
6. 代码块处理
提取和恢复
def _extract_code_blocks(self, md_text: str) -> Tuple[str, List[Tuple[str, str, str]]]
处理步骤:
- 使用正则表达式提取代码块
- 替换为占位符
- Markdown 转换
- 恢复代码块格式
- HTML 转义和语法高亮
配置详解
页眉页脚布局
单一位置模式
--header "文档标题" --header-position center
左中右布局模式
--header-left "公司名称" --header-center "文档标题" --header-right "版本号"
页码格式
# 简单页码
--page-number-format "{page}"
# 中文格式
--page-number-format "第{page}页"
# 总页数格式(降级为简单页码)
--page-number-format "{page}/{total}"
分页控制
标题分页
# 一级标题分页
--no-h1-page-break
# 二级标题分页
--no-h2-page-break
特殊分页规则
- 紧挨着一级标题的二级标题不分页
- 表格和代码块避免分页
- 图片避免分页
错误处理
常见错误和解决方案
1. 依赖缺失
错误: 请安装 markdown 库: pip install markdown
解决方案:安装必需的依赖库
2. 图片文件不存在
警告: 图片文件不存在: /path/to/image.png
解决方案:检查图片路径或移除无效图片引用
3. PDF 生成失败
生成 PDF 时出错: [具体错误信息]
解决方案:
- 检查 Markdown 文件语法
- 确认输出路径权限
- 查看详细错误信息
4. 封面合并失败
PDF合并失败: [具体错误信息]
解决方案:
- 检查封面 PDF 文件
- 确认文件权限
- 使用备用图片转换方案
性能优化
内存使用
- 流式处理大文件
- 及时释放资源
- 临时文件自动清理
处理速度
- 正则表达式优化
- 缓存机制
- 并行处理(未来版本)
扩展开发
添加新的样式
def _generate_css(self) -> str:
# 在现有CSS基础上添加新样式
custom_css = """
.custom-style {
/* 自定义样式 */
}
"""
return base_css + custom_css
添加新的功能
- 继承
MarkdownToPDF类 - 重写相应方法
- 添加配置选项
- 更新命令行参数
版本历史
当前版本特性
- ✅ 多页面目录链接支持
- ✅ PDF 书签生成
- ✅ 封面插入技术
- ✅ 智能分页控制
- ✅ 完整的中文支持
未来计划
- 🔄 更多纸张尺寸支持
- 🔄 自定义主题系统
- 🔄 批量处理功能
- 🔄 GUI 界面
许可证
本项目采用 MIT 许可证,详见 LICENSE 文件。
贡献指南
欢迎提交 Issue 和 Pull Request!
开发环境设置
# 克隆项目
git clone [项目地址]
# 安装依赖
pip install -r requirements.txt
# 运行测试
python -m pytest tests/
代码规范
- 遵循 PEP 8 规范
- 添加类型注解
- 编写单元测试
- 更新文档
联系方式
如有问题或建议,请通过以下方式联系:
- 提交 GitHub Issue
- 发送邮件至:[2584439485@qq.com]
最后更新:2025年11月17日
本文来自博客园踩坑狭,作者:韩若明瞳,转载请注明原文链接:https://www.cnblogs.com/han-guang-xue/p/19233676

浙公网安备 33010602011771号