Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

, md_content, re.MULTILINE)\n if h1_match:\n metadata['title'] = h1_match.group(1).strip()\n\n # 提取 **字段**: 值 格式的元数据\n # 创建者\n creator_match = re.search(r'\\*\\*创建者\\*\\*:\\s*(.+?)

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

, md_content, re.MULTILINE)\n if creator_match:\n metadata['author'] = creator_match.group(1).strip()\n\n # 为谁创建\n for_match = re.search(r'\\*\\*为谁创建\\*\\*:\\s*(.+?)

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

, md_content, re.MULTILINE)\n if for_match:\n # 提取链接文本和URL\n link_match = re.search(r'\\[(.+?)\\]\\((.+?)\\)', for_match.group(1))\n if link_match:\n metadata['created_for'] = link_match.group(1)\n metadata['created_for_url'] = link_match.group(2)\n else:\n metadata['created_for'] = for_match.group(1).strip()\n\n # 基于\n based_match = re.search(r'\\*\\*基于\\*\\*:\\s*(.+?)

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

, md_content, re.MULTILINE)\n if based_match:\n metadata['based_on'] = based_match.group(1).strip()\n\n # 最后更新\n date_match = re.search(r'\\*\\*最后更新\\*\\*:\\s*(.+?)

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

, md_content, re.MULTILINE)\n if date_match:\n metadata['date'] = date_match.group(1).strip()\n\n return metadata\n\ndef extract_toc_structure(md_content):\n \"\"\"提取带序号的章节目录\"\"\"\n lines = md_content.split('\\n')\n toc = []\n\n for line in lines:\n # 主章节:## 1. 标题\n match_h2 = re.match(r'^## (\\d+)\\.\\s+(.+)

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

, line)\n if match_h2:\n num = match_h2.group(1)\n title = match_h2.group(2).strip()\n # 移除 emoji\n title = re.sub(r'[\\U0001F300-\\U0001F9FF]', '', title).strip()\n toc.append({\n 'level': 2,\n 'number': num,\n 'title': title,\n 'id': f\"{num}-{title}\".replace(' ', '-').replace(':', '').lower()\n })\n\n # 子章节:### 1.1 标题\n match_h3 = re.match(r'^### (\\d+\\.\\d+)\\s+(.+)

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

, line)\n if match_h3:\n num = match_h3.group(1)\n title = match_h3.group(2).strip()\n title = re.sub(r'[\\U0001F300-\\U0001F9FF]', '', title).strip()\n # 截断过长标题\n if len(title) > 50:\n title = title[:47] + '...'\n toc.append({\n 'level': 3,\n 'number': num,\n 'title': title,\n 'id': f\"{num}-{title}\".replace(' ', '-').replace(':', '').replace('.', '-').lower()\n })\n\n return toc\n\ndef generate_toc_html(toc_items):\n \"\"\"生成目录 HTML\"\"\"\n if not toc_items:\n return \"\"\n\n toc_html = \"\"\n for item in toc_items:\n if item['level'] == 2:\n toc_html += f'''\n \u003cdiv class=\"toc-item toc-h2\">\n \u003ca href=\"#{item['id']}\" class=\"toc-link\">\n \u003cspan class=\"toc-number\">{item['number']}\u003c/span>\n \u003cspan class=\"toc-title\">{item['title']}\u003c/span>\n \u003c/a>\n \u003c/div>\n '''\n else:\n toc_html += f'''\n \u003cdiv class=\"toc-item toc-h3\">\n \u003ca href=\"#{item['id']}\" class=\"toc-link\">\n \u003cspan class=\"toc-number\">{item['number']}\u003c/span>\n \u003cspan class=\"toc-title\">{item['title']}\u003c/span>\n \u003c/a>\n \u003c/div>\n '''\n\n return toc_html\n\ndef create_cover_and_toc(metadata, toc_html):\n \"\"\"创建封面和目录页\"\"\"\n title = metadata.get('title', '文档标题')\n subtitle = metadata.get('subtitle', '')\n author = metadata.get('author', '')\n date = metadata.get('date', '')\n created_for = metadata.get('created_for', '')\n created_for_url = metadata.get('created_for_url', '')\n based_on = metadata.get('based_on', '')\n\n toc_section = \"\"\n if toc_html:\n toc_section = f\"\"\"\n \u003c!-- 目录 -->\n \u003cdiv class=\"toc-page\">\n \u003ch2 class=\"toc-header\">目录\u003c/h2>\n \u003cdiv class=\"toc-content\">\n {toc_html}\n \u003c/div>\n \u003c/div>\n \"\"\"\n\n # 构建元信息区域\n meta_items = []\n if subtitle:\n meta_items.append(f'\u003cp class=\"cover-subtitle\">{subtitle}\u003c/p>')\n if based_on:\n meta_items.append(f'\u003cp class=\"cover-based\">{based_on}\u003c/p>')\n if created_for:\n if created_for_url:\n meta_items.append(f'\u003cp class=\"cover-for\">为 \u003ca href=\"{created_for_url}\">{created_for}\u003c/a> 用户创建\u003c/p>')\n else:\n meta_items.append(f'\u003cp class=\"cover-for\">为 {created_for} 用户创建\u003c/p>')\n if author:\n meta_items.append(f'\u003cp class=\"cover-author\">{author}\u003c/p>')\n if date:\n meta_items.append(f'\u003cp class=\"cover-date\">{date}\u003c/p>')\n\n meta_html = '\\n'.join(meta_items)\n\n return f\"\"\"\n \u003c!-- 封面 -->\n \u003cdiv class=\"apple-cover\">\n \u003cdiv class=\"cover-main\">\n \u003ch1 class=\"cover-title\">{title}\u003c/h1>\n \u003cdiv class=\"cover-meta\">\n {meta_html}\n \u003c/div>\n \u003c/div>\n \u003c/div>\n\n {toc_section}\n \"\"\"\n\ndef process_markdown(md_content):\n \"\"\"处理 Markdown 内容\"\"\"\n\n # 移除第一个 h1(已用于封面)\n md_content = re.sub(r'^# .+?\\n', '', md_content, count=1, flags=re.MULTILINE)\n\n # 移除开头的元数据行(**字段**: 值 格式)\n # 这些信息已经提取到封面,不需要在正文中重复显示\n metadata_patterns = [\n r'^\\*\\*创建者\\*\\*:.+?

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

,\n r'^\\*\\*为谁创建\\*\\*:.+?

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

,\n r'^\\*\\*基于\\*\\*:.+?

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

,\n r'^\\*\\*最后更新\\*\\*:.+?

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

,\n r'^\\*\\*适用场景\\*\\*:.+?

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…

,\n ]\n for pattern in metadata_patterns:\n md_content = re.sub(pattern, '', md_content, flags=re.MULTILINE)\n\n # 移除 emoji\n md_content = re.sub(r'[\\U0001F300-\\U0001F9FF]', '', md_content)\n\n # 处理 h2 主章节 - 添加 ID 和分页\n def add_h2_id(match):\n num = match.group(1)\n title = match.group(2).strip()\n id_str = f\"{num}-{title}\".replace(' ', '-').replace(':', '').lower()\n full_title = f\"{num}. {title}\"\n return f'\\n\u003cdiv class=\"chapter-break\">\u003c/div>\\n\\n\u003ch2 id=\"{id_str}\">{full_title}\u003c/h2>\\n'\n\n md_content = re.sub(r'\\n## (\\d+)\\.\\s+(.+?)\\n', add_h2_id, md_content)\n\n # 处理 h3 子章节 - 添加 ID\n def add_h3_id(match):\n num = match.group(1)\n title = match.group(2).strip()\n id_str = f\"{num}-{title}\".replace(' ', '-').replace(':', '').replace('.', '-').lower()\n full_title = f\"{num} {title}\"\n return f'\\n\u003ch3 id=\"{id_str}\">{full_title}\u003c/h3>\\n'\n\n md_content = re.sub(r'\\n### (\\d+\\.\\d+)\\s+(.+?)\\n', add_h3_id, md_content)\n\n # 转换 Markdown\n extras = [\n 'fenced-code-blocks',\n 'tables',\n 'break-on-newline',\n 'code-friendly',\n 'cuddled-lists',\n 'strike',\n 'task_list',\n ]\n\n html = markdown2.markdown(md_content, extras=extras)\n\n # 修复渲染\n html = re.sub(r'\u003ctable>', r'\u003ctable class=\"content-table\">', html)\n html = re.sub(r'\u003cpre>\u003ccode', r'\u003cpre class=\"code-block\">\u003ccode', html)\n html = re.sub(r'\u003cblockquote>', r'\u003cblockquote class=\"quote-block\">', html)\n\n return html\n\ndef get_apple_css():\n \"\"\"获取苹果设计风格 CSS\"\"\"\n return \"\"\"\n @page {\n size: A4;\n margin: 2.5cm 2cm 2cm 2cm;\n\n @top-left {\n content: string(doc-title);\n font-size: 8.5pt;\n color: #86868b;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n }\n\n @top-right {\n content: counter(page);\n font-size: 8.5pt;\n color: #86868b;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n }\n }\n\n @page:first {\n margin: 0;\n @top-left { content: none; }\n @top-right { content: none; }\n }\n\n @page:nth(2) {\n @top-left { content: none; }\n @top-right { content: none; }\n }\n\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'PingFang SC', sans-serif;\n font-size: 11pt;\n line-height: 1.7;\n color: #1d1d1f;\n background: white;\n -webkit-font-smoothing: antialiased;\n }\n\n /* 封面 */\n .apple-cover {\n height: 100vh;\n background: linear-gradient(135deg, #f5f5f7 0%, #ffffff 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n page-break-after: always;\n }\n\n .cover-main {\n text-align: center;\n padding: 60px;\n }\n\n .cover-title {\n font-size: 64pt;\n font-weight: 600;\n color: #1d1d1f;\n margin-bottom: 24px;\n letter-spacing: -2px;\n font-family: -apple-system, 'SF Pro Display', sans-serif;\n string-set: doc-title content();\n }\n\n .cover-subtitle {\n font-size: 24pt;\n font-weight: 400;\n color: #1d1d1f;\n margin-bottom: 24px;\n }\n\n .cover-meta {\n font-size: 12pt;\n color: #86868b;\n line-height: 2;\n margin-top: 36px;\n }\n\n .cover-based {\n font-size: 11pt;\n color: #86868b;\n margin-bottom: 8px;\n }\n\n .cover-for {\n font-size: 13pt;\n color: #1d1d1f;\n font-weight: 500;\n margin-bottom: 8px;\n }\n\n .cover-for a {\n color: #06c;\n text-decoration: none;\n }\n\n .cover-author {\n font-size: 11pt;\n color: #86868b;\n margin-bottom: 8px;\n }\n\n .cover-date {\n font-size: 11pt;\n color: #86868b;\n font-weight: 500;\n }\n\n /* 目录 */\n .toc-page {\n padding: 60px 50px;\n page-break-after: always;\n min-height: 100vh;\n }\n\n .toc-header {\n font-size: 28pt;\n font-weight: 600;\n color: #1d1d1f;\n margin-bottom: 32px;\n }\n\n .toc-content {\n column-count: 2;\n column-gap: 40px;\n }\n\n .toc-item {\n break-inside: avoid;\n margin-bottom: 6px;\n }\n\n .toc-h2 {\n margin-top: 14px;\n margin-bottom: 4px;\n }\n\n .toc-h2 .toc-link {\n font-size: 11.5pt;\n font-weight: 600;\n color: #1d1d1f;\n }\n\n .toc-h2 .toc-number {\n color: #06c;\n font-weight: 700;\n margin-right: 8px;\n }\n\n .toc-h3 {\n margin-left: 16px;\n }\n\n .toc-h3 .toc-link {\n font-size: 10pt;\n font-weight: 400;\n color: #424245;\n }\n\n .toc-h3 .toc-number {\n color: #86868b;\n margin-right: 6px;\n font-size: 9.5pt;\n }\n\n .toc-link {\n display: block;\n text-decoration: none;\n padding: 4px 0;\n }\n\n .toc-number {\n font-feature-settings: \"tnum\";\n }\n\n /* 标题 */\n .chapter-break {\n page-break-before: always;\n height: 0;\n }\n\n h2 {\n font-size: 22pt;\n font-weight: 600;\n color: #1d1d1f;\n margin-top: 0;\n margin-bottom: 28px;\n padding-bottom: 12px;\n border-bottom: 2px solid #d2d2d7;\n page-break-after: avoid;\n }\n\n h3 {\n font-size: 17pt;\n font-weight: 600;\n color: #1d1d1f;\n margin-top: 36px;\n margin-bottom: 18px;\n page-break-after: avoid;\n }\n\n h4 {\n font-size: 13pt;\n font-weight: 600;\n color: #424245;\n margin-top: 24px;\n margin-bottom: 12px;\n page-break-after: avoid;\n }\n\n /* 正文 */\n p {\n margin-bottom: 16px;\n }\n\n ul, ol {\n margin-left: 24px;\n margin-bottom: 20px;\n }\n\n li {\n margin-bottom: 10px;\n }\n\n /* 代码块 */\n .code-block {\n background: #f5f5f7;\n border: 1px solid #d2d2d7;\n border-radius: 8px;\n padding: 20px;\n margin: 24px 0;\n overflow-x: auto;\n font-family: 'SF Mono', 'Monaco', monospace;\n font-size: 10pt;\n line-height: 1.6;\n page-break-inside: avoid;\n }\n\n .code-block code {\n background: none;\n padding: 0;\n color: #1d1d1f;\n }\n\n code {\n background: #f5f5f7;\n padding: 3px 6px;\n border-radius: 4px;\n font-family: 'SF Mono', monospace;\n font-size: 10pt;\n color: #d70050;\n font-weight: 500;\n }\n\n /* 表格 */\n .content-table {\n width: 100%;\n border-collapse: collapse;\n margin: 28px 0;\n font-size: 10.5pt;\n }\n\n .content-table thead {\n background: #f5f5f7;\n }\n\n .content-table th {\n padding: 14px 16px;\n text-align: left;\n font-weight: 600;\n border-bottom: 2px solid #d2d2d7;\n }\n\n .content-table td {\n padding: 12px 16px;\n border-bottom: 1px solid #d2d2d7;\n color: #424245;\n page-break-inside: avoid;\n }\n\n /* 引用 */\n .quote-block {\n border-left: 3px solid #06c;\n padding-left: 20px;\n margin: 24px 0;\n color: #424245;\n page-break-inside: avoid;\n }\n\n /* 图片:不写 max-width 会让宽图横向溢出页面 */\n img {\n max-width: 100%;\n height: auto;\n page-break-inside: avoid;\n }\n\n /* 强调 */\n strong {\n color: #1d1d1f;\n font-weight: 600;\n }\n\n a {\n color: #06c;\n text-decoration: none;\n }\n\n hr {\n border: none;\n border-top: 1px solid #d2d2d7;\n margin: 36px 0;\n }\n\n /* 印刷质量 */\n p, li, .quote-block {\n orphans: 3;\n widows: 3;\n }\n\n h2, h3, h4 {\n page-break-after: avoid;\n }\n\n .code-block, .content-table, .quote-block {\n page-break-inside: avoid;\n }\n \"\"\"\n\ndef warn_missing_images(html, base_dir):\n \"\"\"检查 HTML 里的本地图片能不能找到,找不到就出声\n\n weasyprint 解析不到图片时是静默跳过的,PDF 照样生成、只是图没了。\n 这里提前扫一遍,让失败可见。\n \"\"\"\n import html as html_mod\n from urllib.parse import unquote, urlparse\n\n missing = []\n # 单引号和双引号都要收:markdown2 会把手写的 \u003cimg src='...'> 原样透传,\n # 只认双引号会漏掉它们——漏报比误报更糟,那正是这个函数要消灭的静默。\n for src_raw in re.findall(r'\u003cimg[^>]+\\bsrc=(?:\"([^\"]*)\"|\\'([^\\']*)\\')', html):\n src = src_raw[0] or src_raw[1]\n # HTML 实体要先还原再查文件:weasyprint 拿到的是解码后的路径,\n # 不解码会把 a&b.png 这种真实存在的文件误报成缺失。\n src = html_mod.unescape(src)\n parsed = urlparse(src)\n if parsed.scheme in ('http', 'https', 'data'):\n continue\n path = unquote(parsed.path)\n candidate = Path(path) if parsed.scheme == 'file' else base_dir / path\n if not candidate.exists():\n missing.append(src)\n\n if missing:\n print(f\"⚠️ 有 {len(missing)} 张图片找不到,PDF 里会缺失:\")\n for src in missing:\n print(f\" - {src}\")\n print(f\" (相对路径是相对于 {base_dir} 解析的)\")\n\n\ndef convert_markdown_to_pdf(input_file, output_file=None, title=None, author=None,\n subtitle=None):\n \"\"\"主转换函数\"\"\"\n\n # 读取输入文件\n print(f\"📖 读取文件: {input_file}\")\n with open(input_file, 'r', encoding='utf-8') as f:\n md_content = f.read()\n\n # 提取元数据\n print(\"📑 提取元数据...\")\n metadata = extract_metadata(md_content)\n\n # 命令行参数覆盖\n if title:\n metadata['title'] = title\n if author:\n metadata['author'] = author\n if subtitle:\n metadata['subtitle'] = subtitle\n\n # 提取目录\n print(\"📂 提取目录结构...\")\n toc_structure = extract_toc_structure(md_content)\n print(f\" ✓ 找到 {len([t for t in toc_structure if t['level'] == 2])} 个主章节\")\n print(f\" ✓ 找到 {len([t for t in toc_structure if t['level'] == 3])} 个子章节\")\n\n # 生成目录 HTML\n toc_html = generate_toc_html(toc_structure)\n\n # 处理 Markdown\n print(\"🎨 处理 Markdown 内容...\")\n html_content = process_markdown(md_content)\n\n # 生成完整 HTML\n print(\"📄 生成 HTML...\")\n full_html = f\"\"\"\n \u003c!DOCTYPE html>\n \u003chtml lang=\"zh-CN\">\n \u003chead>\n \u003cmeta charset=\"UTF-8\">\n \u003ctitle>{metadata.get('title', '文档')}\u003c/title>\n \u003c/head>\n \u003cbody>\n {create_cover_and_toc(metadata, toc_html)}\n \u003cdiv class=\"content\">\n {html_content}\n \u003c/div>\n \u003c/body>\n \u003c/html>\n \"\"\"\n\n # 生成 PDF\n print(\"📝 生成 PDF...\")\n if not output_file:\n output_file = str(Path(input_file).with_suffix('.pdf'))\n\n # base_url 必须给:不给的话 markdown 里的相对路径图片(含中文目录名)\n # 一张都解析不到,weasyprint 还不报错,PDF 静默少图。\n # 用输入文件自身的 file:// URI,相对路径就从它所在目录开始算。\n source_path = Path(input_file).resolve()\n base_url = source_path.as_uri()\n warn_missing_images(full_html, source_path.parent)\n\n css = CSS(string=get_apple_css())\n HTML(string=full_html, base_url=base_url).write_pdf(output_file, stylesheets=[css])\n\n print(f\"✅ 成功生成: {output_file}\")\n\n # 显示文件大小\n size_mb = os.path.getsize(output_file) / (1024 * 1024)\n print(f\"📊 文件大小: {size_mb:.1f} MB\")\n\ndef main():\n parser = argparse.ArgumentParser(\n description='将 Markdown 转换为苹果设计风格的 PDF 白皮书'\n )\n parser.add_argument('input', help='输入的 Markdown 文件')\n parser.add_argument('-o', '--output', help='输出的 PDF 文件(默认:与输入文件同名)')\n parser.add_argument('--title', help='自定义文档标题')\n parser.add_argument('--subtitle', help='自定义副标题')\n parser.add_argument('--author', help='自定义作者')\n\n args = parser.parse_args()\n\n try:\n convert_markdown_to_pdf(\n args.input,\n args.output,\n args.title,\n args.author,\n args.subtitle\n )\n except Exception as e:\n print(f\"❌ 转换失败: {e}\")\n import traceback\n traceback.print_exc()\n return 1\n\n return 0\n\nif __name__ == '__main__':\n exit(main())\n","content_type":"text/x-python; charset=utf-8","language":"python","size":19021,"content_sha256":"5caffc3122df3ab92561c0cc68e9a2025ef16b0ff033a361347365635c468d66"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Markdown to PDF Skill","type":"text"}]},{"type":"paragraph","content":[{"text":"将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"核心功能","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"专业排版","type":"text","marks":[{"type":"strong"}]},{"text":":书籍级排版质量,自动处理分页、孤行寡行","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"苹果设计","type":"text","marks":[{"type":"strong"}]},{"text":":SF 字体系统、现代简洁风格、专业配色","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"完整目录","type":"text","marks":[{"type":"strong"}]},{"text":":自动提取章节结构,双列布局,可点击跳转","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Markdown 完美支持","type":"text","marks":[{"type":"strong"}]},{"text":":代码块、表格、引用、列表等全部正确渲染","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"使用方法","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"基础用法","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 转换单个文件\npython scripts/convert.py input.md\n\n# 指定输出文件名\npython scripts/convert.py input.md -o \"我的白皮书.pdf\"\n\n# 自定义标题和作者\npython scripts/convert.py input.md --title \"技术白皮书\" --author \"花叔\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"图片路径","type":"text"}]},{"type":"paragraph","content":[{"text":"Markdown 里的相对路径图片,是","type":"text"},{"text":"相对 md 文件自身所在目录","type":"text","marks":[{"type":"strong"}]},{"text":"解析的,目录名和文件名带中文都可以:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"![示意图](图片/架构图.png) ← 和 md 文件同级的「图片」目录\n![示意图](./assets/arch.png)","type":"text"}]},{"type":"paragraph","content":[{"text":"找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"已知未解决:某些环境下 macOS「预览」打开是乱码","type":"text"}]},{"type":"paragraph","content":[{"text":"有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。","type":"text"},{"text":"这个问题还没有解决办法","type":"text","marks":[{"type":"strong"}]},{"text":",原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。","type":"text"}]},{"type":"paragraph","content":[{"text":"不要试图用 weasyprint 的 ","type":"text","marks":[{"type":"strong"}]},{"text":"full_fonts=True","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" 绕过它。","type":"text","marks":[{"type":"strong"}]},{"text":" 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection,","type":"text"},{"text":"full_fonts=True","type":"text","marks":[{"type":"code_inline"}]},{"text":" 会把整个 collection 的原始字节塞进 PDF 的 ","type":"text"},{"text":"/FontFile2","type":"text","marks":[{"type":"code_inline"}]},{"text":"(magic 是 ","type":"text"},{"text":"ttcf","type":"text","marks":[{"type":"code_inline"}]},{"text":" 而不是合法的 ","type":"text"},{"text":"\\x00\\x01\\x00\\x00","type":"text","marks":[{"type":"code_inline"}]},{"text":"),结果是","type":"text"},{"text":"文件暴涨到几十 MB,而且照样乱码","type":"text","marks":[{"type":"strong"}]},{"text":"——实测一段中文从 10 KB 变成 43 MB,渲染出来是「Oě 据⊤」。它让问题更糟,不是逃生出口。","type":"text"}]},{"type":"paragraph","content":[{"text":"碰到乱码时可以先试:升级 weasyprint、或在 CSS 里换一个非 collection 的字体。","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Markdown 文档要求","type":"text"}]},{"type":"paragraph","content":[{"text":"你的 Markdown 文档应该遵循以下结构:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"# 文档标题\n\n## 1. 第一章\n### 1.1 第一节\n### 1.2 第二节\n\n## 2. 第二章\n### 2.1 第一节","type":"text"}]},{"type":"paragraph","content":[{"text":"关键规则","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"主章节:","type":"text"},{"text":"## 1. 标题","type":"text","marks":[{"type":"code_inline"}]},{"text":"(数字 + 点 + 空格 + 标题)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"子章节:","type":"text"},{"text":"### 1.1 标题","type":"text","marks":[{"type":"code_inline"}]},{"text":"(数字.数字 + 空格 + 标题)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"这样才能正确提取目录","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"设计特点","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"封面设计","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"淡灰色渐变背景","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"大标题:64pt,简洁现代","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"副标题和元信息","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"目录设计","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"双列布局,单页展示","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"主章节粗体,子章节缩进","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"可点击跳转到对应章节","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"正文排版","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SF 字体系列(苹果设计语言)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"行高 1.7,舒适阅读","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"章节自动分页","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"孤行寡行控制","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"代码块","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"浅灰背景 + 细边框","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"圆角 8px","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SF Mono 等宽字体","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"自动避免分页","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"表格","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"清晰网格线","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"浅灰表头","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"自动保留表头(长表格分页时)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"配置选项","type":"text"}]},{"type":"paragraph","content":[{"text":"如果需要自定义样式,可以修改 ","type":"text"},{"text":"scripts/convert.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" 中的 CSS 变量:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"# 主色调\nPRIMARY_COLOR = '#06c' # 苹果蓝\nTEXT_COLOR = '#1d1d1f' # 主文本黑色\nGRAY_COLOR = '#86868b' # 浅灰色\n\n# 字体大小\nCOVER_TITLE_SIZE = '64pt'\nH2_SIZE = '22pt'\nH3_SIZE = '17pt'\nBODY_SIZE = '11pt'","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"常见问题","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Q: 目录为什么是空的?","type":"text"}]},{"type":"paragraph","content":[{"text":"A: 确保你的 Markdown 使用了正确的章节格式:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"## 1. 标题","type":"text","marks":[{"type":"code_inline"}]},{"text":" 而不是 ","type":"text"},{"text":"## 标题","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"### 1.1 标题","type":"text","marks":[{"type":"code_inline"}]},{"text":" 而不是 ","type":"text"},{"text":"### 标题","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Q: 代码块显示不正确?","type":"text"}]},{"type":"paragraph","content":[{"text":"A: 确保使用三个反引号包裹:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"```python\ndef hello():\n print(\"Hello\")\n```","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Q: 表格格式乱了?","type":"text"}]},{"type":"paragraph","content":[{"text":"A: 使用标准的 Markdown 表格语法:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"| 列1 | 列2 |\n|-----|-----|\n| 值1 | 值2 |","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Q: 如何修改字体?","type":"text"}]},{"type":"paragraph","content":[{"text":"A: 编辑 ","type":"text"},{"text":"scripts/convert.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" 中的 CSS,修改 ","type":"text"},{"text":"font-family","type":"text","marks":[{"type":"code_inline"}]},{"text":" 属性。","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Q: 生成的 PDF 太大?","type":"text"}]},{"type":"paragraph","content":[{"text":"A: 检查是否有大量图片,考虑压缩图片或使用外链。","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"依赖安装","type":"text"}]},{"type":"paragraph","content":[{"text":"首次使用需要安装 Python 依赖:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"pip3 install markdown2 weasyprint","type":"text"}]},{"type":"paragraph","content":[{"text":"如果遇到 WeasyPrint 安装问题(macOS):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"brew install pango\npip3 install weasyprint","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"示例","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"生成技术文档","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"python scripts/convert.py tech-guide.md -o \"技术指南.pdf\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"生成白皮书","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"python scripts/convert.py whitepaper.md --title \"产品白皮书\" --author \"团队\"","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"脚本说明","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"scripts/convert.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" - 主转换脚本","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"scripts/styles.css","type":"text","marks":[{"type":"code_inline"}]},{"text":" - CSS 样式定义(已嵌入脚本)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"templates/cover.html","type":"text","marks":[{"type":"code_inline"}]},{"text":" - 封面模板(已嵌入脚本)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"技术实现","type":"text"}]},{"type":"paragraph","content":[{"text":"本 Skill 使用:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"markdown2","type":"text","marks":[{"type":"strong"}]},{"text":":Markdown 解析(支持扩展语法)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"WeasyPrint","type":"text","marks":[{"type":"strong"}]},{"text":":HTML to PDF 转换(支持 CSS3)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"苹果设计系统","type":"text","marks":[{"type":"strong"}]},{"text":":SF 字体、专业配色、现代排版","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"更新日志","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"v1.0 (2025-12-24)","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"初始版本","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"支持完整 Markdown 语法","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"苹果设计风格","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"自动目录生成","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"书籍级排版质量","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"花叔出品","type":"text","marks":[{"type":"strong"}]},{"text":" | AI Native Coder · 独立开发者 公众号「花叔」| 30万+粉丝 | AI工具与效率提升 代表作:小猫补光灯(AppStore付费榜Top1)·《一本书玩转DeepSeek》","type":"text"}]}]}]},"metadata":{"date":"2026-11-02","name":"huashu-md-to-pdf","author":"@skillopedia","source":{"stars":2166,"repo_name":"huashu-skills","origin_url":"https://github.com/alchaincyf/huashu-skills/blob/HEAD/huashu-md-to-pdf/SKILL.md","repo_owner":"alchaincyf","body_sha256":"6accb3d469acb25df481e7bf0b44f4dd64b8cba8220f7f640f9f3c790cf1a43d","cluster_key":"3a60c7ac275d835ce35b42d1622674e96475f31141dfb6228daa7632700dbc1e","clean_bundle":{"format":"clean-skill-bundle-v1","source":"alchaincyf/huashu-skills/huashu-md-to-pdf/SKILL.md","text_bytes":25021,"source_commit":"7de517aa12f61ff31c46f1591fbeaf865160d69f","skills_sh_rank":12614,"attachment_count":3,"text_attachments":3,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"huashu-md-to-pdf/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"documents-office","category_label":"Documents"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"documents-office","import_tag":"skills-sh-top20k-2026-11","description":"将 Markdown 文档转换为专业的 PDF 白皮书,采用苹果设计风格。\n支持完整的 Markdown 语法(代码块、表格、引用、列表等)。\n自动生成封面、目录、页眉页脚。\n使用场景:技术文档、白皮书、教程、报告等需要专业排版的 Markdown 文档。\n"}},"renderedAt":1793666734907}

Markdown to PDF Skill 将 Markdown 文档转换为专业的苹果设计风格 PDF 白皮书。 核心功能 1. 专业排版 :书籍级排版质量,自动处理分页、孤行寡行 2. 苹果设计 :SF 字体系统、现代简洁风格、专业配色 3. 完整目录 :自动提取章节结构,双列布局,可点击跳转 4. Markdown 完美支持 :代码块、表格、引用、列表等全部正确渲染 使用方法 基础用法 图片路径 Markdown 里的相对路径图片,是 相对 md 文件自身所在目录 解析的,目录名和文件名带中文都可以: 找不到的图片会在转换时打印警告并列出路径。以前这种情况是静默跳过的,PDF 照样生成、只是没有图。 已知未解决:某些环境下 macOS「预览」打开是乱码 有用户报告生成的 PDF 在 macOS「预览」里是乱码,浏览器打开正常。 这个问题还没有解决办法 ,原因也还没定位——在一台用 Arial Unicode MS 渲染中文的机器上复现不出来,而报告者的字体环境和 weasyprint 版本都不清楚。 不要试图用 weasyprint 的 绕过它。 实测:macOS 上的中文字体(PingFang.ttc、Songti.ttc、Hiragino Sans GB.ttc)都是 TrueType Collection, 会把整个 collection 的原始字节塞进 PDF 的 (…