祝各位道友念头通达
GitHub Gitee 语雀 打赏

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 文件路径

处理流程

  1. 读取并解析 Markdown 文件
  2. 提取和处理代码块
  3. 转换为 HTML
  4. 提取标题信息
  5. 生成目录
  6. 处理图片路径
  7. 生成 CSS 样式
  8. 使用 WeasyPrint 生成 PDF
  9. 添加目录链接
  10. 合并封面(如果提供)

核心功能详解

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

处理逻辑

  1. 检测相对路径图片
  2. 转换为绝对路径
  3. 读取图片文件
  4. 编码为 Base64
  5. 生成 data URI

支持的图片格式

  • JPEG, PNG, GIF, BMP
  • 自动 MIME 类型检测
  • 错误处理和警告提示

6. 代码块处理

提取和恢复

def _extract_code_blocks(self, md_text: str) -> Tuple[str, List[Tuple[str, str, str]]]

处理步骤

  1. 使用正则表达式提取代码块
  2. 替换为占位符
  3. Markdown 转换
  4. 恢复代码块格式
  5. 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

添加新的功能

  1. 继承 MarkdownToPDF
  2. 重写相应方法
  3. 添加配置选项
  4. 更新命令行参数

版本历史

当前版本特性

  • ✅ 多页面目录链接支持
  • ✅ 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日

posted @ 2025-11-17 17:23  韩若明瞳  阅读(44)  评论(0)    收藏  举报