v0.10: add native Codex adapter for deep research
This commit is contained in:
@@ -0,0 +1,303 @@
|
||||
---
|
||||
name: pdf-reportlab
|
||||
description: 用 ReportLab 生成专业中文 PDF 研究报告。集中样式管理、紧凑分页(widows/orphans/keepWithNext)、颜色层次、封面保密标识、页眉页脚简洁化。基于 9MW1911 综合战略报告的编排参考。
|
||||
---
|
||||
|
||||
# ReportLab 中文 PDF 模板使用指南(v0.5)
|
||||
|
||||
## 一、为什么是 ReportLab
|
||||
|
||||
- **完全可控**:每个字号、行距、颜色由代码说了算,不被引擎意外改动
|
||||
- **中文字体一次搞定**:`pdfmetrics.registerFont` 注册后全局可用,子集嵌入 PDF,无授权问题
|
||||
- **分页规则精确**:支持 widows/orphans、keepWithNext、splitByRow 等避免孤行/寡行
|
||||
- **图表嵌入高质量**:matplotlib 300 DPI PNG,速度快
|
||||
- **样式集中在 StyleSheet**:避免字号不一
|
||||
|
||||
---
|
||||
|
||||
## 二、模板入口
|
||||
|
||||
脚本:`.opencode/templates/report-template.py`
|
||||
|
||||
调用:
|
||||
```bash
|
||||
uv run python .opencode/templates/report-template.py \
|
||||
--input projects/<slug>/phase4/final.md \
|
||||
--manifest projects/<slug>/manifest.json \
|
||||
--output projects/<slug>/phase4/final.pdf \
|
||||
--fonts-dir .opencode/templates/fonts
|
||||
```
|
||||
|
||||
首次使用前:
|
||||
```bash
|
||||
bash .opencode/templates/fonts/download-fonts.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、字体注册(7 个字重)
|
||||
|
||||
```
|
||||
SrcSerif-Regular 思源宋体 Regular 正文
|
||||
SrcSerif-Bold 思源宋体 Bold 正文粗体
|
||||
SrcSans-Light 思源黑体 Light 页眉页脚
|
||||
SrcSans-Medium 思源黑体 Medium 三级标题/图表
|
||||
SrcSans-Bold 思源黑体 Bold 一二级标题
|
||||
SrcSans-Heavy 思源黑体 Heavy 封面大标题
|
||||
Kai 霞鹜文楷 Regular 摘要/引文
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、样式表(StyleSheet,集中管理)
|
||||
|
||||
| 样式名 | 字体 | 字号 | 行高 | 颜色 | 备注 |
|
||||
|---|---|---|---|---|---|
|
||||
| `body` | SrcSerif | 10.5 | 18 | `#1a1a1a` | 正文,首行缩进 21pt |
|
||||
| `body-bold` | SrcSerif-Bold | 10.5 | 18 | `#1a1a1a` | 行内加粗 |
|
||||
| `h1` | SrcSans-Bold | 18 | 28 | `#1e3a8a` | 章标题,前强制分页 |
|
||||
| `h2` | SrcSans-Bold | 14 | 22 | `#2c5282` | 节标题 |
|
||||
| `h3` | SrcSans-Medium | 12 | 18 | `#374151` | 小节标题 |
|
||||
| `quote` | Kai | 10.5 | 18 | `#4b5563` | 引文 |
|
||||
| `caption` | SrcSans-Medium | 9 | 13 | `#6b7280` | 图表标题 |
|
||||
| `footnote` | SrcSerif | 9 | 13 | `#374151` | 脚注/参考文献 |
|
||||
| `header-footer` | SrcSans-Light | 8 | 12 | `#9ca3af` | 页眉页脚 |
|
||||
| `cover-title` | SrcSans-Heavy | 28 | 40 | `#0f172a` | 封面主标题 |
|
||||
| `cover-subtitle` | SrcSans-Medium | 15 | 24 | `#475569` | 封面副标题 |
|
||||
| `cover-confidential` | SrcSans-Bold | 11 | 16 | `#dc2626` | 封面保密标识(红色)|
|
||||
| `cover-meta` | SrcSerif | 11 | 18 | `#334155` | 封面元信息 |
|
||||
| `summary` | SrcSerif | 11 | 20 | `#1a1a1a` | 执行摘要 |
|
||||
|
||||
---
|
||||
|
||||
## 五、分页规则(关键升级点)
|
||||
|
||||
### 章(h1)
|
||||
|
||||
- `pageBreakBefore=1`(每章新起一页)
|
||||
- `keepWithNext=1`(标题和下一段不分离)
|
||||
|
||||
### 节(h2)
|
||||
|
||||
- **禁止单独触发分页**
|
||||
- `keepWithNext=1`(标题紧跟内容)
|
||||
|
||||
### 小节(h3)
|
||||
|
||||
- 同 h2,`keepWithNext=1`
|
||||
|
||||
### 段落
|
||||
|
||||
- `widows=2, orphans=2`(避免寡行/孤行)
|
||||
- 每段之间 `spaceBefore=6, spaceAfter=6`
|
||||
|
||||
### 表格
|
||||
|
||||
- `TableStyle` 中启用 `splitByRow=True`(长表格按行分页)
|
||||
- `repeatRows=1`(表头在分页后重复)
|
||||
- 单元格 padding 统一 4-6pt
|
||||
|
||||
### 摘要/术语表/目录/参考文献
|
||||
|
||||
- 每个独占起始页(用 `PageBreak`)
|
||||
|
||||
---
|
||||
|
||||
## 六、封面模板(参考 9MW1911)
|
||||
|
||||
封面独立一页,无页眉页脚,布局:
|
||||
|
||||
```
|
||||
(上 30% 空白)
|
||||
|
||||
主标题(cover-title,黑色,居中)
|
||||
副标题(cover-subtitle,深灰,居中)
|
||||
|
||||
(中部 40% 空白)
|
||||
|
||||
[机密 | 仅供 XX 内部决策使用] (cover-confidential,红色,居中)
|
||||
|
||||
(下部 20%)
|
||||
|
||||
类型:研究类
|
||||
作者:Deep Research 系统 / <公司名>
|
||||
编制日期:YYYY 年 M 月
|
||||
版本:v1.0
|
||||
```
|
||||
|
||||
字段来源:
|
||||
- `manifest.report_title` / `report_subtitle`
|
||||
- `manifest.confidentiality` (如 "机密 | 仅供迈威生物内部决策使用")
|
||||
- `manifest.author` / `manifest.date` / `manifest.version`
|
||||
|
||||
---
|
||||
|
||||
## 七、页眉页脚(简洁化)
|
||||
|
||||
### 页眉
|
||||
|
||||
左边:报告简称(从 `manifest.report_title` 取前 15 字)
|
||||
右边:章节名(动态,从当前 h1 内容取)
|
||||
底线:`#e5e7eb` 浅灰分隔线
|
||||
|
||||
### 页脚
|
||||
|
||||
居中:页码(格式 `— X —`)
|
||||
字号:8pt,`#9ca3af` 浅灰
|
||||
|
||||
### 特殊页
|
||||
|
||||
- 封面:无页眉页脚
|
||||
- 免责声明:无页眉,仅页脚
|
||||
- 其他(摘要/术语表/目录/正文/附录/参考文献):有页眉页脚
|
||||
|
||||
---
|
||||
|
||||
## 八、报告结构(11 件套)
|
||||
|
||||
ReportLab 按以下顺序组装:
|
||||
|
||||
1. **封面**(cover PageTemplate)
|
||||
2. **免责声明**(normal PageTemplate,单页)
|
||||
3. **Executive Summary / 执行摘要**(summary PageTemplate,1-2 页)
|
||||
4. **Abstract / 摘要**(normal,单页)
|
||||
5. **Glossary / 术语表**(normal)
|
||||
6. **Table of Contents / 目录**(TOC,自动生成)
|
||||
7. **正文各章**(normal,每章 h1 强制分页)
|
||||
8. **结论与建议**(正文的一部分)
|
||||
9. **附录**(normal)
|
||||
10. **参考文献**(bibliography PageTemplate,footnote 样式)
|
||||
11. **版本信息**(normal,单页)
|
||||
|
||||
---
|
||||
|
||||
## 九、Markdown 支持范围
|
||||
|
||||
| Markdown | ReportLab 渲染 |
|
||||
|---|---|
|
||||
| `# 第 X 章 ...` | h1(新起一页,深蓝色)|
|
||||
| `## X.Y ...` | h2(节,蓝色,不分页)|
|
||||
| `### X.Y.Z ...` | h3(小节,深灰)|
|
||||
| `**粗体**` | inline `<b>` |
|
||||
| `*斜体*` | inline `<i>` |
|
||||
| `` `代码` `` | 等宽字体 |
|
||||
| `> 引文` | quote 样式(楷体,浅底色)|
|
||||
| `- 项` / `1. 项` | 项目符号列表 |
|
||||
| 表格 `\| \| \|` | Table,自动列宽 + splitByRow |
|
||||
| `` | 图片 + caption 样式 |
|
||||
| `[src_001]` | 上标引用 |
|
||||
| `---` | 分页符 |
|
||||
|
||||
**不支持**:HTML 标签、数学公式、代码块高亮。
|
||||
|
||||
---
|
||||
|
||||
## 十、图表嵌入
|
||||
|
||||
不用 ReportLab 原生绘图,全部预渲染为 PNG:
|
||||
|
||||
```python
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.font_manager as fm
|
||||
|
||||
font_path = '.opencode/templates/fonts/SourceHanSansSC-Medium.otf'
|
||||
fm.fontManager.addfont(font_path)
|
||||
plt.rcParams['font.family'] = 'Source Han Sans SC'
|
||||
plt.rcParams['axes.unicode_minus'] = False
|
||||
|
||||
fig, ax = plt.subplots(figsize=(6, 4), dpi=300)
|
||||
# ...
|
||||
plt.savefig('projects/<slug>/phase4/figures/fig_01_XXX.png', dpi=300, bbox_inches='tight')
|
||||
```
|
||||
|
||||
Markdown 中引用:`![图 1-1:2020-2025 GLP-1 市场规模(数据来源:[src_042])](figures/fig_01_XXX.png)`
|
||||
|
||||
---
|
||||
|
||||
## 十一、manifest 必需字段
|
||||
|
||||
```json
|
||||
{
|
||||
"slug": "...",
|
||||
"report_title": "自研 O-糖苷酶立项可行性研究报告",
|
||||
"report_subtitle": "对标 NEB 与 Merck 经典产品的技术路径、IP 壁垒与差异化战略",
|
||||
"confidentiality": "机密 | 仅供内部决策使用",
|
||||
"author": "Deep Research 系统",
|
||||
"date": "2026-04-21",
|
||||
"version": "1.0",
|
||||
"type": "研究类",
|
||||
"disclaimer": "本报告基于公开信息与 AI 辅助研究生成,仅供参考..."
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十二、常见坑与对策
|
||||
|
||||
| 坑 | 对策 |
|
||||
|---|---|
|
||||
| 中文字号不一 | 集中 StyleSheet,不在 Paragraph 里 inline 改 fontSize |
|
||||
| 行距太挤 | 行高 = 字号 × 1.5~1.7 |
|
||||
| 换行断错 | `wordWrap='CJK'` 必设 |
|
||||
| 表格被截断 | `splitByRow=True, repeatRows=1` |
|
||||
| 标题孤行(页末一个标题后直接新页)| `keepWithNext=1` |
|
||||
| 段落寡行(末段只剩一行在下页)| `widows=2, orphans=2` |
|
||||
| 图片变形 | 先 matplotlib 出 300 DPI PNG,再 `Image(path, width=..., kind="proportional")` |
|
||||
| 生成慢 | matplotlib 图表预渲染,不要在 PDF 生成阶段现算 |
|
||||
| 参考文献丢失 | dr-reporter 出稿前检查:读 citations.md,确认内容已写入 final.md |
|
||||
|
||||
---
|
||||
|
||||
## 十三、dr-reporter 调用流程
|
||||
|
||||
```
|
||||
1. 环境检查
|
||||
- 字体 ≥6 个 OTF 文件
|
||||
- final.md 存在
|
||||
- manifest.json 有必需字段
|
||||
|
||||
2. 回填参考文献(关键步骤,修复 v0.4 的 bug)
|
||||
- 读 citations.md 内容
|
||||
- 在 final.md 中找到"## 参考文献"段落
|
||||
- 如果段落内容是占位符(如 "[由 dr-reporter 自动生成]" 或为空)
|
||||
→ 替换为 citations.md 的完整内容
|
||||
- 写回 final.md
|
||||
|
||||
3. 图表检查
|
||||
- 扫描 final.md 中所有  图片引用
|
||||
- 验证每个 path 在 figures/ 目录下存在
|
||||
- 缺失图片 → 警告并继续,但汇报中注明
|
||||
|
||||
4. 生成 PDF
|
||||
uv run python .opencode/templates/report-template.py \
|
||||
--input projects/<slug>/phase4/final.md \
|
||||
--manifest projects/<slug>/manifest.json \
|
||||
--output projects/<slug>/phase4/final.pdf \
|
||||
--fonts-dir .opencode/templates/fonts
|
||||
|
||||
5. 生成 DOCX(可选)
|
||||
pandoc projects/<slug>/phase4/final.md \
|
||||
--from markdown --to docx \
|
||||
--output projects/<slug>/phase4/final.docx \
|
||||
--toc --toc-depth=3
|
||||
|
||||
6. 验证
|
||||
- PDF 文件大小 > 500KB(太小说明字体没嵌)
|
||||
- PDF 页数合理(按字数估算)
|
||||
- "参考文献"章节存在且非空
|
||||
|
||||
7. 汇报
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十四、输出卫生检查(必跑)
|
||||
|
||||
生成 PDF 前:
|
||||
|
||||
```bash
|
||||
# 加载 skill:output-hygiene
|
||||
python3 .opencode/templates/hygiene_check.py projects/<slug>/phase4/final.md
|
||||
```
|
||||
|
||||
禁止词残留 → 抛回 dr-polisher 再润色一轮。
|
||||
Reference in New Issue
Block a user