v0.13: add Quarto/xelatex PDF engine and fix ReportLab wide-table rendering
build_report.py:
- add --engine quarto option: Quarto 1.9 + xelatex pipeline with
CJK font setup (Source Han Serif/Sans CN via fontspec),
automatic {.landscape} wrapping for wide tables (>=8 cols),
TOC/references placeholder replacement, sources.jsonl backfill
- prepare_qmd(): converts Markdown to .qmd with proper YAML front matter,
writes _preamble.tex for longtable/pdflscape/lscape packages
- _detect_wide_tables(), _build_references_block(): helper functions
- ReportLab path unchanged (remains default)
report-template.py:
- render_table(): force equal-width column distribution for tables
with >=4 cols or any cell >30 chars, preventing negative availWidth
crash on mixed CJK/English content
- render_table_blocks(): split long tables (>25 rows) into chunks to
avoid NoneType comparison crash in ReportLab splitByRow logic
.gitignore:
- add rules for LaTeX temp files (*.aux, xetest.*, *.qmd, _preamble.tex)
- add projects/ to gitignore (research data, not source code)
README.md:
- update status to v0.13
- rewrite PDF section as dual-engine guide with install steps,
comparison table, and landscape table chunking guidance
- add Quarto troubleshooting (font italic mapping, tlmgr path, param_size)
- add v0.13 to changelog
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
> 生物医药行业的 AI 驱动深度研究流水线。基于 OpenCode 多 agent 协作,以麦肯锡/德勤式方法论产出专业级研究报告(PDF + DOCX)。
|
||||
|
||||
**当前状态**:v0.12 迭代完成。OpenCode 全流程可用(Phase 1-4),搜索网关、模型预设与 Phase 4 统一 pipeline 已落地;Codex native adapter 与 OpenCode 保持并列入口。
|
||||
**当前状态**:v0.13 迭代完成。新增 Quarto/xelatex PDF 引擎(`--engine quarto`),解决 ReportLab 超宽表格渲染 bug;ReportLab 引擎保留为默认后备。Quarto 依赖独立安装,不影响现有环境。
|
||||
详见 `PLAN.md` 了解完整方案、版本记录与迭代路径。
|
||||
|
||||
---
|
||||
@@ -87,94 +87,8 @@ opencode # 启动 TUI
|
||||
|
||||
**跑单个 Python 脚本**(不用先激活):
|
||||
```bash
|
||||
uv run python .opencode/templates/report-template.py --input ... --output ...
|
||||
```
|
||||
|
||||
**加新依赖**:
|
||||
```bash
|
||||
uv add <package> # 自动更新 pyproject.toml 和 uv.lock
|
||||
```
|
||||
|
||||
**同步到最新锁定版本**(新 clone 或切分支后):
|
||||
```bash
|
||||
uv sync
|
||||
```
|
||||
|
||||
如果你用 [direnv](https://direnv.net/),可在项目根目录建 `.envrc`:
|
||||
```bash
|
||||
source scripts/activate.sh
|
||||
```
|
||||
这样 `cd` 进项目目录会自动激活,`cd` 出去会自动卸载。
|
||||
|
||||
---
|
||||
|
||||
## 可用命令
|
||||
|
||||
| 命令 | 功能 | 状态 |
|
||||
|---|---|---|
|
||||
| `/dr-init <主题>` | 初始化新研究,启动访谈 | ✅ 可用 |
|
||||
| `/dr-frame [slug]` | Phase 1:生成 8-15 章双语研究框架 | ✅ 可用 |
|
||||
| `/dr-research [slug]` | Phase 2:并行深度研究 | ✅ 可用 |
|
||||
| `/dr-review [slug]` | Phase 3:总编审校 | ✅ 可用 |
|
||||
| `/dr-finalize [slug]` | Phase 4:英文合稿 → 中文翻译/术语核查/润色 → PDF+DOCX | ✅ 可用 |
|
||||
| `/dr-models [profile]` | 解析模型预设(simple / medium / premium 等) | ✅ 可用 |
|
||||
| `/dr-apply-models <profile>` | 把模型预设写入 OpenCode/Codex agent 文件 | ✅ 可用 |
|
||||
| `/dr-glossary [slug]` | 术语表事实核查 | ✅ 可用 |
|
||||
| `/dr-status [slug]` | 查看进度 | ✅ 可用 |
|
||||
|
||||
### 典型流程
|
||||
|
||||
```
|
||||
1. /dr-init GLP-1 减重药物市场
|
||||
→ dr-plan 向你提 8 个访谈问题(研究类型、受众、时间范围等)
|
||||
→ 你回答后,生成 projects/glp1-obesity-market-2026/manifest.json
|
||||
|
||||
2. /dr-frame
|
||||
→ dr-plan 调用 skill:search-strategy
|
||||
→ 委派 3-4 个 dr-searcher(Haiku,轻量)并行初扫
|
||||
→ 生成 8-15 章框架到 phase1/framework.md
|
||||
→ 暂停等你确认
|
||||
|
||||
3. 你审核框架,或提修改意见,或直接确认
|
||||
→ 确认后,manifest.phase1.approved = true
|
||||
|
||||
4. /dr-research
|
||||
→ dr-pm 分批并行调度 dr-analyst 深研
|
||||
→ dr-verifier 做反方验证
|
||||
→ 产出 phase2/drafts、evidence、sources.jsonl
|
||||
|
||||
5. /dr-review
|
||||
→ dr-chief-editor 通读审校,产出 phase3/critique.md
|
||||
|
||||
6. /dr-finalize
|
||||
→ dr-editor-in-chief 合并英文终稿
|
||||
→ Python 脚本执行 translate → glossary → apply_glossary → polish → build_report
|
||||
→ 产出 final_zh_polished.md、PDF、DOCX
|
||||
```
|
||||
|
||||
### Phase 4 Python 流水线
|
||||
|
||||
Phase 4 已切到统一 pipeline(替代式):由 Python 控制切块、并发、重试与断点续传:
|
||||
|
||||
```bash
|
||||
uv run python scripts/phase4_pipeline.py <slug>
|
||||
# 等价入口(支持模型预设)
|
||||
uv run python scripts/dr.py finalize <slug> --model-profile medium
|
||||
```
|
||||
|
||||
默认行为:
|
||||
- 自动估算 translate/polish 并发(`--translate-workers 0` / `--polish-workers 0`)
|
||||
- glossary 仅核查低置信度术语(`--glossary-mode low-confidence`)
|
||||
|
||||
你也可以手动分步执行:
|
||||
|
||||
```bash
|
||||
uv run python scripts/translate.py <slug> --workers 4
|
||||
uv run python scripts/build_glossary.py <slug> --workers 4
|
||||
uv run python scripts/apply_glossary.py <slug> --input phase4/final_zh.md --dry-run
|
||||
uv run python scripts/apply_glossary.py <slug> --input phase4/final_zh.md
|
||||
uv run python scripts/polish.py <slug> --workers 4
|
||||
uv run python scripts/build_report.py <slug>
|
||||
uv run python scripts/build_report.py <slug> # 默认 ReportLab
|
||||
uv run python scripts/build_report.py <slug> --engine quarto # Quarto/xelatex
|
||||
```
|
||||
|
||||
网络不稳或 API 限流时,把 `--workers` 降到 `3` 或 `1` 即可断点续跑。
|
||||
@@ -318,12 +232,71 @@ OpenCode 的常见陷阱:AI 在主会话里装样子地"委派"子 agent,实
|
||||
|
||||
Phase 1 分配章节配额,Phase 2 自检,不足返工。见 `skills/length-budget/SKILL.md`。
|
||||
|
||||
### 4. 中文 PDF 无坑
|
||||
### 4. 中文 PDF 双引擎
|
||||
|
||||
`build_report.py` 现在支持两套 PDF 引擎,按需选择:
|
||||
|
||||
#### 引擎 A:ReportLab(默认,无额外依赖)
|
||||
|
||||
```bash
|
||||
uv run python scripts/build_report.py <slug>
|
||||
```
|
||||
|
||||
- 字体:思源宋 + 思源黑 + 霞鹜文楷(全 SIL OFL,可商用嵌入)
|
||||
- 样式:集中在 `build_styles()`,所有字号行距单点维护
|
||||
- 引擎:ReportLab(纯 Python,30,000 字 3-5 秒出稿)
|
||||
- 图表:matplotlib 预渲染 300 DPI PNG 嵌入
|
||||
- 速度:30,000 字 3-5 秒出稿
|
||||
- 局限:超宽表格(≥4 列且含长文本)需借助列宽 patch 或改为 bullet list 格式
|
||||
|
||||
#### 引擎 B:Quarto / xelatex(`--engine quarto`,推荐用于宽表报告)
|
||||
|
||||
```bash
|
||||
uv run python scripts/build_report.py <slug> --engine quarto
|
||||
```
|
||||
|
||||
- 排版引擎:xelatex(TeX Live / TinyTeX),LaTeX 级排版质量
|
||||
- 字体:同样使用思源宋 + 思源黑,通过 fontspec 加载
|
||||
- 宽表支持:超宽表通过 `longtable` + `tbl-colwidths` 精确指定列宽比例,不溢出
|
||||
- 横向页面:通过 `{.landscape}` div 包裹超宽表,自动插入 `pdflscape` 代码(注意:101 行以上的 landscape longtable 可能触发 TeX `param_size` 上限,建议拆成 ≤20 行的子表块)
|
||||
- 图表:暂不嵌入 matplotlib 图表(使用文字描述代替)
|
||||
|
||||
**安装 Quarto 引擎**(一次性,系统级):
|
||||
|
||||
```bash
|
||||
# 1. 安装 Quarto CLI
|
||||
# 下载页:https://github.com/quarto-dev/quarto-cli/releases/latest
|
||||
# Linux 选 .deb 安装包,macOS 选 .pkg
|
||||
|
||||
# 2. 安装 TinyTeX(Quarto 内置命令)
|
||||
quarto install tinytex
|
||||
|
||||
# 3. 安装中文 LaTeX 支持包
|
||||
~/.TinyTeX/bin/x86_64-linux/tlmgr install ctex xecjk cjk xetex
|
||||
# macOS 路径通常为:~/.TinyTeX/bin/universal-darwin/tlmgr
|
||||
|
||||
# 4. 注册思源字体到 fontconfig
|
||||
# (先确认字体已下载:bash .opencode/templates/fonts/download-fonts.sh)
|
||||
mkdir -p ~/.fonts
|
||||
cp .opencode/templates/fonts/*.otf ~/.fonts/
|
||||
cp .opencode/templates/fonts/*.ttf ~/.fonts/
|
||||
cp .opencode/templates/fonts/ttf/*.ttf ~/.fonts/
|
||||
fc-cache -fv ~/.fonts
|
||||
|
||||
# 5. 验证
|
||||
quarto --version # 应输出 1.x.x
|
||||
fc-list | grep "Source Han" # 应看到思源字体条目
|
||||
```
|
||||
|
||||
**两引擎对比**:
|
||||
|
||||
| 指标 | ReportLab | Quarto/xelatex |
|
||||
|------|-----------|----------------|
|
||||
| 安装复杂度 | 无额外依赖 | 需安装 Quarto + TinyTeX |
|
||||
| 渲染速度 | 3-5 秒 | 30-90 秒(LaTeX 编译) |
|
||||
| 宽表格处理 | 需 workaround | longtable 原生支持 |
|
||||
| 横向页面 | 不支持 | 支持(≤20 行/块) |
|
||||
| 字体嵌入 | OTF 直接嵌入 | fontspec 系统字体 |
|
||||
| 输出体积 | ~1.2 MB/100页 | ~0.9 MB/100页 |
|
||||
| 目录生成 | 自定义实现 | LaTeX 自动 \tableofcontents |
|
||||
|
||||
### 5. zenmux 双 provider(Claude cache 关键)
|
||||
|
||||
@@ -394,6 +367,51 @@ ls .opencode/templates/fonts/*.otf | wc -l # 应为 6+
|
||||
python .opencode/templates/report-template.py --help
|
||||
```
|
||||
|
||||
### Quarto PDF 生成失败
|
||||
|
||||
**字体找不到(`Could not resolve font "Source Han Serif CN/I"`)**:
|
||||
|
||||
CJK 字体没有斜体变体,fontspec 默认会找 `/I` 导致报错。`build_report.py --engine quarto` 已通过 `mainfontoptions: [ItalicFont=...]` 自动绕开,无需手动处理。若自行编写 `.qmd`,需在 YAML 里加:
|
||||
|
||||
```yaml
|
||||
format:
|
||||
pdf:
|
||||
pdf-engine: xelatex
|
||||
CJKmainfont: "Source Han Serif CN"
|
||||
mainfontoptions:
|
||||
- BoldFont=Source Han Serif CN
|
||||
- ItalicFont=Source Han Serif CN
|
||||
- BoldItalicFont=Source Han Serif CN
|
||||
```
|
||||
|
||||
**`tlmgr` 找不到**:
|
||||
|
||||
TinyTeX 不在系统 PATH,用完整路径:
|
||||
```bash
|
||||
~/.TinyTeX/bin/x86_64-linux/tlmgr install <package> # Linux
|
||||
~/.TinyTeX/bin/universal-darwin/tlmgr install <package> # macOS
|
||||
```
|
||||
|
||||
**`TeX capacity exceeded [parameter stack size]`**(landscape 大表):
|
||||
|
||||
pdflscape 的 `\LS@makefcolumn` 在 101 行以上的 longtable 里递归过深,耗尽 TeX 的 `param_size`。解决方法:把超大表拆成每块 ≤20 行的子表,每块都包在 `{.landscape}` div 里:
|
||||
|
||||
```markdown
|
||||
::: {.landscape}
|
||||
| 列1 | 列2 | ... |
|
||||
|---|---|---|
|
||||
| 第1-20行 | ... |
|
||||
:::
|
||||
|
||||
::: {.landscape}
|
||||
| 列1 | 列2 | ... |
|
||||
|---|---|---|
|
||||
| 第21-40行 | ... |
|
||||
:::
|
||||
```
|
||||
|
||||
若使用 `build_report.py --engine quarto`,可通过传入预处理好的 `.md`(宽表已拆块)来避免此问题。
|
||||
|
||||
### uv 安装后找不到
|
||||
uv 官方脚本把 uv 装到 `~/.local/bin/`。若终端里 `which uv` 找不到:
|
||||
```bash
|
||||
@@ -442,6 +460,9 @@ direnv allow
|
||||
- Skill 配置:https://opencode.ai/docs/skills
|
||||
- MCP Servers:https://opencode.ai/docs/mcp-servers
|
||||
- ReportLab 文档:https://docs.reportlab.com
|
||||
- Quarto 文档:https://quarto.org/docs/output-formats/pdf-basics.html
|
||||
- Quarto PDF 引擎:https://quarto.org/docs/output-formats/pdf-engine.html
|
||||
- Quarto 表格文档:https://quarto.org/docs/authoring/tables.html
|
||||
- 思源字体:https://github.com/adobe-fonts
|
||||
- 霞鹜文楷:https://github.com/lxgw/LxgwWenKai
|
||||
|
||||
@@ -452,5 +473,6 @@ direnv allow
|
||||
- **v0.1** (2026-04-20) — MVP 路径 2 完成:dr-plan + dr-pm 两主 agent、4 个核心 skill、2 个命令、ReportLab 模板基础版、字体下载脚本
|
||||
- **v0.2** (2026-04-20) — 双 provider 架构(zenmux-anthropic + zenmux),解决 Claude prompt cache 生效问题
|
||||
- **v0.3** (2026-04-20) — 修正 v0.2 模型名(回到 Opus 4.7 / Sonnet 4.6 / Gemini 3.1 Pro / GPT-5.4 Pro 等真实 slug);改 venv + requirements.txt 跨平台方案(macOS + Debian);新增 `scripts/setup.sh`、`scripts/activate.sh`
|
||||
- **v0.13** (2026-05-02) — `build_report.py` 新增 `--engine quarto` 选项:Quarto 1.9 + xelatex 引擎,解决 ReportLab 超宽表格渲染 bug(`negative availWidth`/`NoneType` 问题);`report-template.py` 同步修复(`render_table_blocks` 分块 + 等宽列强制分配);README 补充双引擎安装指南与排错
|
||||
|
||||
见 `PLAN.md` §12 了解完整变更历史。
|
||||
|
||||
Reference in New Issue
Block a user