学术海报生成
目标:从论文或研究成果出发,产出一张可直接打印或投屏展示的学术海报。内容忠实于原文,版式清晰,站在 1–2 米外能读懂研究主线。
整个流程由本目录下的脚本完成,Claude 负责读懂论文、提炼内容、写 poster.json,以及检查成品:
论文 ──extract.py──▶ text.md + 图片 + 页面预览
│ (Claude 提炼内容,必要时用 make_chart.py 重绘图表)
▼
poster.json ──build_poster.py──▶ poster.html ──render.py──▶ poster.png / .pdf
下文中 SKILL_DIR 指本 SKILL.md 所在目录。所有命令在工作目录(如 poster_work/)中执行。
第 0 步:环境与参数
环境(首次使用时检查一次):
python3 -c "import playwright, jinja2, PIL, matplotlib" && fc-list :lang=zh | head -1
which pdftotext pdftoppm pdfimages pandoc
缺失时:pip install playwright jinja2 pillow matplotlib --break-system-packages、playwright install chromium;中文字体 apt-get install -y fonts-noto-cjk;PDF 工具 apt-get install -y poppler-utils。浏览器下载失败时,render.py --chrome /path/to/chromium 可指定系统浏览器。二维码需要可选的 qrcode 库,没有时让用户提供二维码图片。
参数:先从用户消息和附件中找,缺的用一次提问补齐(用户不在时按默认值执行,交付时说明):
| 参数 | 默认值 |
|---|---|
| 尺寸与方向 | A0-portrait(build_poster.py --list-sizes 查看全部,也可自定义像素) |
| 语言 | 跟随论文语言 |
| 主题配色 | 按学科选(build_poster.py --list-themes):人文历史→heritage-red,教育/文学→ink-classic,化学/医学→slate-teal,生命/环境→forest-green,数理/计算机→royal-purple,其他→academic-blue |
| 会议要求 | 无;若用户给出会议尺寸、版式或 Logo 要求,以其为准 |
| Logo、二维码链接 | 没有就不放,不编造 |
第 1 步:抽取素材
python SKILL_DIR/scripts/extract.py paper.pdf -o work/ # 也支持 .docx/.doc/.odt/.md/.txt
得到 work/text.md(每页有 <!-- page N --> 标记)、work/pages/(每页预览图)、work/figures/(嵌入位图)和 work/inventory.json(图/表标题候选及页码)。
- 通读
text.md,抓住研究问题、方法、关键数据和结论。 - 用 Read 查看
inventory.json中列出的图片,以及含图表页的pages/p-N.png。 - 矢量图、表格、公式不在
figures/里,按预览图估计比例坐标后截取:
python SKILL_DIR/scripts/extract.py crop work/…pdf --page 3 --box 0.08,0.12,0.92,0.48 -o work/figures/fig2.png
(box = 左,上,右,下,取值 0–1;截完用 Read 检查,不准就调整坐标重截)。 - 原文只有表格数据而没有合适的图时,可用
make_chart.py重绘(见第 3 步)。
第 2 步:提炼内容(最关键)
先确定结构,再写文字。详细规则见 references/content-guide.md,要点:
- 结构:实证研究用"研究背景 → 研究方法 → 研究结果 → 结论与启示";教育、人文类可用"研究背景 → 理论框架 → 实践设计/案例 → 效果与反思 → 结论与启示"。参考文献 3–6 条,致谢、联系方式、二维码有则放。
- 篇幅:A0 正文总量约 800–1200 字(英文 500–800 词),A1 约 60%。每块用短句和要点,删掉文献综述细节、推导过程和次要结果。
- 结果优先:结果区占版面 40–50%,以图表和关键数字(
stats)为主;每张图配一句结论式图注(写"说明了什么")。 - 结论:3–5 条,脱离全文也能读懂。
- 忠实性:所有数字、结论、引用必须来自原文;原文没有的信息(样本量、显著性、单位 Logo 等)宁缺不补,在交付说明里列出缺项。标题可以比论文标题更简练,但不改变含义。
第 3 步:编写 poster.json
字段规范见 references/poster-json-spec.md,完整示例见 examples/demo/poster.json。核心结构:
{
"lang": "zh", "size": "A0-portrait", "theme": "heritage-red",
"title": "…", "subtitle": "…",
"authors": [{"name": "张三", "aff": [1], "corresponding": true}],
"affiliations": ["某某大学 历史学院"],
"columns": [
{"sections": [{"title": "研究背景", "blocks": [{"p": "…"}, {"bullets": ["…"]}]}]},
{"sections": [ … ]},
{"sections": [ … ]}
],
"footer": {"references": ["…"], "acknowledgements": "…", "contact": "…", "qr": {"url": "…"}}
}
内容块类型:p 段落、bullets/numbered 列表、h3 小标题、callout 强调框、figure/figures 图片、stats 关键数字、steps 流程图、table 表格。行内标记:**加粗**、==高亮==、*强调色*、^上标^。
布局原则:竖版 3 栏、横版 4 栏;阅读顺序从左到右、每栏从上到下;结果区可用 "span": 2 跨两栏放大关键图;三栏内容量大致均衡;"emph": true 用于突出结论板块。
重绘图表(需要时):
python SKILL_DIR/scripts/make_chart.py chart.json -o work/figures/fig1.png
支持 bar、hbar、grouped、line。width 取 build_poster.py 输出的栏宽(A0 三栏约 640px),跨两栏时取对应宽度。柱状图数值轴从 0 开始;多系列用固定顺序的色觉友好配色,单系列用主题色并可 highlight 一个类别。数值必须照抄原文。
第 4 步:生成与渲染
python SKILL_DIR/scripts/build_poster.py poster.json # → poster.html,并提示栏宽与字数
python SKILL_DIR/scripts/render.py poster.html --autofit --check # 快速检查 + 低清预览
python SKILL_DIR/scripts/render.py poster.html --autofit # 正式输出 PNG(2×) + PDF + 预览图
--autofit 在 0.8–1.25 之间自动调整正文字号,使各栏不溢出且尽量填满,并把结果写回 HTML。打印用途可加 --scale 3(A0 约 216 dpi)。
第 5 步:检查与修正
逐项检查,不通过就改 poster.json 后重新 build + render:
- 脚本报告:无溢出;
--fit不低于 0.9(低于说明字太多,应精简文字而不是继续缩小);各栏填充率在 82% 以上(偏空的栏可挪入板块、放大图或补充原文中的要点)。 - 看成品:用 Read 查看
poster_preview.png,再用 Pillow 裁出局部看细节。检查标题醒目、阅读顺序清楚、没有大块空白或拥挤处、图表文字够大、图例不压数据。 - 核对事实:海报上的每个数字、结论与原文逐条对照。
- 中文显示:无方块字,标点与中英文混排正常。
第 6 步:交付
用 SendUserFile 发送 poster.png(display: render),以及 poster.pdf、poster.html、poster.json(attach)。回复用一两句话说明:所用尺寸与配色、内容取舍(省略了哪些次要结果)、原文缺失而未放入的信息。
用户提修改意见时,改 poster.json(或少量直接改 poster.html 的样式),重新渲染,只说明改了什么。需要整体换风格时用 build_poster.py --theme / --size 覆盖,不必改 JSON。