posterskill-academic-posters
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseposterskill — Academic Poster Generator
posterskill — 学术海报生成工具
Skill by ara.so — Daily 2026 Skills collection.
posterskill is a Claude Code skill that generates print-ready, interactive conference posters from your Overleaf paper source. It produces a single self-contained HTML file with a built-in drag-and-drop visual editor — no build step, no server required.
由ara.so开发的Skill — 属于Daily 2026 Skills合集。
posterskill是一款Claude Code技能,可从你的Overleaf论文源文件生成可直接打印、支持交互的会议海报。它会生成一个独立的自包含HTML文件,内置拖放式可视化编辑器——无需构建步骤,无需服务器。
Installation & Setup
安装与设置
bash
git clone git@github.com:ethanweber/posterskill.git poster
cd posterbash
git clone git@github.com:ethanweber/posterskill.git poster
cd posterClone your Overleaf paper source
克隆你的Overleaf论文源文件
git clone https://git.overleaf.com/YOUR_PROJECT_ID overleaf
git clone https://git.overleaf.com/YOUR_PROJECT_ID overleaf
Optional: add reference posters for style matching
可选:添加参考海报以匹配风格
cp ~/Downloads/some_reference_poster.pdf references/
Start Claude Code and trigger the skill:
```bash
claude/make-posterClaude will ask for your project website URL and any formatting specs, then generate a directory with .
poster/index.htmlcp ~/Downloads/some_reference_poster.pdf references/
启动Claude Code并触发该技能:
```bash
claude/make-posterClaude会询问你的项目网站URL和格式规范,然后生成包含的目录。
index.htmlposter/Directory Structure
目录结构
poster/ # this repo
├── .claude/
│ └── commands/
│ └── make-poster.md # the skill command
├── overleaf/ # your cloned Overleaf project
├── references/ # optional reference PDFs for style matching
└── poster/ # generated output
├── index.html # the poster (self-contained)
└── logos/ # downloaded institutional logosposter/ # 本仓库
├── .claude/
│ └── commands/
│ └── make-poster.md # 技能命令
├── overleaf/ # 你克隆的Overleaf项目
├── references/ # 可选的参考PDF,用于风格匹配
└── poster/ # 生成的输出文件
├── index.html # 海报文件(自包含)
└── logos/ # 下载的机构标识What Gets Generated
生成内容说明
The output is a React app (loaded via CDN) containing:
poster/index.html- — each card's title, color, and JSX body content
CARD_REGISTRY - — column structure and card ordering
DEFAULT_LAYOUT - — institutional logos for the header
DEFAULT_LOGOS - — programmatic API for layout automation
window.posterAPI
输出的是一个通过CDN加载的React应用,包含:
poster/index.html- — 每个卡片的标题、颜色和JSX主体内容
CARD_REGISTRY - — 列结构与卡片排序
DEFAULT_LAYOUT - — 页眉处的机构标识
DEFAULT_LOGOS - — 用于布局自动化的编程式API
window.posterAPI
Visual Editor Features
可视化编辑器功能
Open in Chrome to access the built-in editor:
poster/index.html| Feature | How to Use |
|---|---|
| Resize columns | Drag column dividers left/right |
| Resize cards | Drag row dividers up/down within a column |
| Swap cards | Click one diamond handle, then another |
| Move/insert cards | Click a handle, then click a drop zone |
| Adjust font size | Click A- / A+ buttons in toolbar |
| Preview print layout | Click Preview button |
| Export layout | Click Copy Config to get JSON |
在Chrome中打开即可访问内置编辑器:
poster/index.html| 功能 | 使用方法 |
|---|---|
| 调整列宽 | 左右拖动列分隔线 |
| 调整卡片高度 | 在列内上下拖动行分隔线 |
| 交换卡片 | 点击一个菱形手柄,再点击另一个 |
| 移动/插入卡片 | 点击手柄,然后点击放置区域 |
| 调整字体大小 | 点击工具栏中的A- / **A+**按钮 |
| 预览打印布局 | 点击预览按钮 |
| 导出布局 | 点击复制配置获取JSON |
Programmatic API (window.posterAPI
)
window.posterAPI编程式API (window.posterAPI
)
window.posterAPIAvailable in the browser console or via Playwright automation:
js
// Swap two cards by ID
posterAPI.swapCards('method', 'results')
// Move a card to a specific column and position
posterAPI.moveCard('quant', 'col1', 2)
// Resize a column (in mm)
posterAPI.setColumnWidth('col1', 280)
// Set a specific card's height (in mm)
posterAPI.setCardHeight('method', 150)
// Scale all text globally
posterAPI.setFontScale(1.5)
// Measure whitespace waste (lower = better layout)
posterAPI.getWaste()
// Get the current layout as an object
posterAPI.getLayout()
// Get the full config as JSON (paste back to Claude)
posterAPI.getConfig()
// Reset to default layout
posterAPI.resetLayout()可在浏览器控制台或通过Playwright自动化使用:
js
// 通过ID交换两张卡片
posterAPI.swapCards('method', 'results')
// 将卡片移动到指定列和位置
posterAPI.moveCard('quant', 'col1', 2)
// 调整列宽(单位:毫米)
posterAPI.setColumnWidth('col1', 280)
// 设置指定卡片的高度(单位:毫米)
posterAPI.setCardHeight('method', 150)
// 全局缩放所有文本
posterAPI.setFontScale(1.5)
// 测量空白浪费率(数值越低,布局越优)
posterAPI.getWaste()
// 获取当前布局对象
posterAPI.getLayout()
// 获取完整配置的JSON(可粘贴回Claude)
posterAPI.getConfig()
// 重置为默认布局
posterAPI.resetLayout()Iteration Workflow
迭代工作流程
The core loop for refining your poster:
- Claude generates first draft, opens in your browser
poster/index.html - You edit in the browser — drag dividers, swap cards, resize columns
- Click "Copy Config" in the toolbar to export your layout as JSON
- Paste the JSON back to Claude — it updates in the HTML
DEFAULT_LAYOUT - Repeat until the layout is perfect
- Print to PDF: File → Print → Margins: None, Background Graphics: On
优化海报的核心循环:
- Claude生成初稿,在浏览器中打开
poster/index.html - 你在浏览器中编辑 — 拖动分隔线、交换卡片、调整列宽
- **点击“复制配置”**导出布局为JSON
- 将JSON粘贴回Claude — 它会更新HTML中的
DEFAULT_LAYOUT - 重复直到布局完美
- 打印为PDF:文件 → 打印 → 边距:无,背景图形:开启
Playwright Automation (used internally by Claude)
Playwright自动化(Claude内部使用)
Claude uses Playwright to automate layout verification. You can use it too:
js
const { chromium } = require('playwright');
async function optimizePoster() {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(`file://${__dirname}/poster/index.html`);
// Use the posterAPI to adjust layout programmatically
const waste = await page.evaluate(() => posterAPI.getWaste());
console.log('Whitespace waste:', waste);
// Resize a column
await page.evaluate(() => posterAPI.setColumnWidth('col1', 300));
// Take a screenshot for visual verification
await page.screenshot({ path: 'poster-preview.png', fullPage: true });
// Generate PDF at print resolution
await page.pdf({
path: 'poster.pdf',
width: '841mm', // A0 landscape width
height: '1189mm',
printBackground: true,
});
await browser.close();
}Claude使用Playwright自动验证布局,你也可以使用:
js
const { chromium } = require('playwright');
async function optimizePoster() {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(`file://${__dirname}/poster/index.html`);
// 使用posterAPI以编程方式调整布局
const waste = await page.evaluate(() => posterAPI.getWaste());
console.log('Whitespace waste:', waste);
// 调整列宽
await page.evaluate(() => posterAPI.setColumnWidth('col1', 300));
// 截图用于视觉验证
await page.screenshot({ path: 'poster-preview.png', fullPage: true });
// 生成打印分辨率的PDF
await page.pdf({
path: 'poster.pdf',
width: '841mm', // A0横向宽度
height: '1189mm',
printBackground: true,
});
await browser.close();
}Card Registry Structure
卡片注册表结构
Each card in the poster is defined in :
CARD_REGISTRYjs
const CARD_REGISTRY = {
abstract: {
title: "Abstract",
color: "#f0f4ff",
body: `
<p>Your abstract text here. Supports full JSX including
<strong>bold</strong>, <em>italic</em>, and inline math.</p>
`
},
method: {
title: "Method",
color: "#fff8f0",
body: `
<img src="figures/pipeline.png" style={{width:'100%'}} />
<p>Caption describing the pipeline above.</p>
`
},
results: {
title: "Results",
color: "#f0fff4",
body: `
<table>...</table>
`
}
};海报中的每个卡片都在中定义:
CARD_REGISTRYjs
const CARD_REGISTRY = {
abstract: {
title: "Abstract",
color: "#f0f4ff",
body: `
<p>Your abstract text here. Supports full JSX including
<strong>bold</strong>, <em>italic</em>, and inline math.</p>
`
},
method: {
title: "Method",
color: "#fff8f0",
body: `
<img src="figures/pipeline.png" style={{width:'100%'}} />
<p>Caption describing the pipeline above.</p>
`
},
results: {
title: "Results",
color: "#f0fff4",
body: `
<table>...</table>
`
}
};Default Layout Structure
默认布局结构
js
const DEFAULT_LAYOUT = {
columns: [
{
id: 'col1',
widthMm: 280,
cards: ['abstract', 'method']
},
{
id: 'col2',
widthMm: 320,
cards: ['results', 'quant']
},
{
id: 'col3',
widthMm: 280,
cards: ['conclusion', 'references']
}
]
};js
const DEFAULT_LAYOUT = {
columns: [
{
id: 'col1',
widthMm: 280,
cards: ['abstract', 'method']
},
{
id: 'col2',
widthMm: 320,
cards: ['results', 'quant']
},
{
id: 'col3',
widthMm: 280,
cards: ['conclusion', 'references']
}
]
};Inputs Claude Uses
Claude使用的输入信息
| Input | Where It Comes From | Required |
|---|---|---|
| Paper content | | Yes |
| Project website | URL (asked at runtime) | Yes |
| Reference posters | | No |
| Author website | URL for brand matching | No |
| Formatting specs | Conference URL or text | Asked if missing |
| Logos | Auto-downloaded to | Auto |
| 输入内容 | 来源 | 是否必填 |
|---|---|---|
| 论文内容 | | 是 |
| 项目网站 | 运行时询问的URL | 是 |
| 参考海报 | | 否 |
| 作者网站 | 用于品牌匹配的URL | 否 |
| 格式规范 | 会议URL或文本 | 缺失时询问 |
| 标识 | 自动下载到 | 自动处理 |
Common Patterns
常见使用模式
Adding a custom figure card
添加自定义图片卡片
js
// In CARD_REGISTRY, add a new card
custom_fig: {
title: "Qualitative Results",
color: "#fafafa",
body: `
<div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:'8px'}}>
<img src="figures/result1.png" style={{width:'100%'}} />
<img src="figures/result2.png" style={{width:'100%'}} />
</div>
<p style={{fontSize:'0.85em', textAlign:'center'}}>
Comparison on held-out test scenes.
</p>
`
}Then add it to :
DEFAULT_LAYOUTjs
{ id: 'col2', widthMm: 320, cards: ['results', 'custom_fig'] }js
// 在CARD_REGISTRY中添加新卡片
custom_fig: {
title: "Qualitative Results",
color: "#fafafa",
body: `
<div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:'8px'}}>
<img src="figures/result1.png" style={{width:'100%'}} />
<img src="figures/result2.png" style={{width:'100%'}} />
</div>
<p style={{fontSize:'0.85em', textAlign:'center'}}>
Comparison on held-out test scenes.
</p>
`
}然后将其添加到:
DEFAULT_LAYOUTjs
{ id: 'col2', widthMm: 320, cards: ['results', 'custom_fig'] }Logos configuration
标识配置
js
const DEFAULT_LOGOS = [
{ src: 'logos/university.png', height: 60 },
{ src: 'logos/lab.png', height: 50 },
{ src: 'logos/sponsor.png', height: 45 },
];js
const DEFAULT_LOGOS = [
{ src: 'logos/university.png', height: 60 },
{ src: 'logos/lab.png', height: 50 },
{ src: 'logos/sponsor.png', height: 45 },
];Printing to PDF
打印为PDF
In Chrome:
- Open
poster/index.html - Click Preview to verify layout
- /
Ctrl+PCmd+P - Set Margins: None
- Enable Background graphics
- Set paper size to your conference spec (A0, 36×48in, etc.)
- Save as PDF
在Chrome中:
- 打开
poster/index.html - 点击预览验证布局
- 按/
Ctrl+PCmd+P - 设置边距:无
- 开启背景图形
- 设置纸张尺寸为会议要求(A0、36×48英寸等)
- 保存为PDF
Troubleshooting
常见问题排查
Poster looks different in print vs browser
→ Use Chrome (not Firefox/Safari). Enable "Background graphics" in print dialog.
Figures not loading
→ Ensure figure paths in the HTML are relative to . Claude copies figures to — verify the directory exists.
poster/index.htmlposter/figures/Logos not fetched
→ Claude uses Playwright to download logos from your project website. If it fails, manually copy logo files to and update paths.
poster/logos/DEFAULT_LOGOSLayout config not updating after paste
→ Make sure you paste the full JSON from Copy Config — Claude looks for the complete and objects to replace.
DEFAULT_LAYOUTDEFAULT_LOGOSFont too small/large for poster size
→ Use in the browser console, or click A+ / A- buttons, then Copy Config and paste to Claude.
posterAPI.setFontScale(1.2)Whitespace gaps between cards
→ Run in console to quantify. Use to tune card heights, or drag row dividers manually.
posterAPI.getWaste()posterAPI.setCardHeight('cardId', heightMm)海报打印效果与浏览器显示不一致
→ 使用Chrome(不要用Firefox/Safari)。在打印对话框中开启“背景图形”。
图片无法加载
→ 确保HTML中的图片路径是相对于的。Claude会将图片复制到目录——请确认该目录存在。
poster/index.htmlposter/figures/标识未获取到
→ Claude使用Playwright从你的项目网站下载标识。如果失败,手动将标识文件复制到并更新中的路径。
poster/logos/DEFAULT_LOGOS粘贴后布局配置未更新
→ 确保粘贴的是“复制配置”中的完整JSON——Claude会查找完整的和对象进行替换。
DEFAULT_LAYOUTDEFAULT_LOGOS海报尺寸下字体过大/过小
→ 在浏览器控制台使用,或点击A+ / **A-**按钮,然后复制配置并粘贴回Claude。
posterAPI.setFontScale(1.2)卡片之间存在空白间隙
→ 在控制台运行量化空白率。使用调整卡片高度,或手动拖动行分隔线。
posterAPI.getWaste()posterAPI.setCardHeight('cardId', heightMm)Example Output
示例输出
See the Fillerbuster poster (repo) as a live example of posterskill output.
查看Fillerbuster海报(仓库),这是posterskill输出的一个实际示例。",