AgentStack
SKILL verified MIT Self-run

Paper To Storyboard

skill-maoransun-paper-to-storyboard-skill · by MaoranSun

Convert an academic PDF paper into a single-page scrollytelling website (index.html + style.css + script.js + extracted figures + optional AI cover) using a fixed dark/light scroll-snap chassis. Use when the user provides a PDF and asks for a "storyboard", "scrollytelling page", "paper-to-web", "narrative website", or "convert paper to webpage".

No reviews yet
0 installs
9 views
0.0% view→install

Install

$ agentstack add skill-maoransun-paper-to-storyboard-skill

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Paper To Storyboard? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

paper-to-storyboard

Turn an academic paper PDF into a dark, scroll-snap, single-page website with the same chassis as the reference example. The chassis (HTML scaffold, CSS layout/animations, vanilla JS IntersectionObserver) is fixed. Only the color palette and per-section content change per paper.

> Run this skill on a strong model (Opus). The hard part isn't the scripts — it's the judgement: mapping a paper onto the 9-slot narrative arc, rewriting body copy to fit display type, picking layouts and a palette, and composing the cover concept. Weaker models (e.g. Sonnet) tend to produce flat narratives, mis-assigned layouts, and verbatim-dumped paragraphs. If you're not on Opus, tell the user to switch with /model opus before invoking.

Inputs

  • pdf_path (required, absolute path)
  • out_dir (default: ./storyboard/)
  • palette (optional: warm | cool | earth | clinical | tech) — if omitted, ask the user via AskUserQuestion
  • mode (optional: dark | light) — if omitted, ask the user
  • typography (optional: editorial | modern | tech | academic) — if omitted, ask the user
  • generate_cover (optional: true | false) — if omitted, ask the user
  • title_override, subtitle_override (optional)

When any of palette, mode, typography, generate_cover is explicitly supplied by the user when they invoke the skill, skip the corresponding question and use the supplied value.

Style options

  • palette — color family. Auto-pick from topic keywords; explicit palette arg wins.
  • modedark keeps the reference chassis (white-on-dark with animated gradient + noise). light flips text to near-black, bg to light tints of the palette, button colors, overlays, and animation opacities.
  • typography — font pairing:
  • editorial: Playfair Display + Inter (default — newspaper/longform feel)
  • modern: Space Grotesk + Inter (clean, product-design)
  • tech: JetBrains Mono + Inter (engineering / lab notebook)
  • academic: Crimson Pro + Source Sans (journal / scholarly)

Workflow

Execute these steps in order. The skill directory is ~/.claude/skills/paper-to-storyboard/. Run each script with absolute paths.

1. Ingest PDF text

python3 ~/.claude/skills/paper-to-storyboard/scripts/extract_text.py  /content.json

Produces content.json with {title, authors, affiliations, abstract, doi, keywords, sections[], figures_meta[], stats_candidates[], tables[]}.

tables[] holds ruled tables pulled by pdfplumber, each tagged with numeric_columns and a chart_ready flag (true = it has at least one label column and one numeric column). These are ground-truth values — prefer them as the data source for a chart slot (see step 6). Extraction is best-effort: it catches ruled tables well, may miss borderless ones, and can merge multi-line headers — always eyeball the rows before charting.

2. Extract figures

python3 ~/.claude/skills/paper-to-storyboard/scripts/extract_figures.py  /figures/

Produces figures/figure1.pngfigureN.png and figures/figures.json with captions, page numbers, bboxes.

3. Make figures transparent

For each figure that will appear in the page (typically all of them):

python3 ~/.claude/skills/paper-to-storyboard/scripts/make_transparent.py /figures/figureN.png /figureN.png

This writes transparent PNGs directly into out_dir/ (alongside the templates), where the HTML references them. The default mode is corner flood-fill (good for plot figures with white backgrounds). For photos/schematics, pass --mode rembg. If rembg isn't installed, it falls back to the flood-fill mode with a warning.

4. Ask the user for style choices

Before building the storyboard, read enough of the PDF to draft a 1-sentence topic summary, then use AskUserQuestion to let the user pick the visual style. Show your recommendation as the first option in each list, label it (Recommended), and explain why in its description.

Issue these questions in a single AskUserQuestion call (batch them — don't ask one at a time):

  1. Palette — 4 options out of warm, cool, earth, clinical, tech (recommended first, then 3 sensible alternatives for this paper).
  • Keyword guide for the recommendation: heat/energy/fire → warm; water/climate/ocean → cool; biology/ecology/agriculture/plants → earth; medicine/clinical/health/disease → clinical; computing/AI/ML/robotics → tech. Urban / cities / sociology papers often fit cool or earth. Default warm.
  1. Mode — 2 options: dark, light.
  • Default dark (matches the reference chassis identity, more cinematic). Recommend light only when the paper is text-heavy with few or busy figures where readability dominates.
  1. Typography — 4 options: editorial, modern, tech, academic.
  • Keyword guide for the recommendation: longform/humanities/policy → editorial; product / startup / design → modern; CS / AI / engineering → tech; medicine / scholarly / journal → academic.
  1. Generate cover? — 2 options: Generate (~$0.04), Skip.
  • In the Generate option's description, show the 1-sentence cover concept you'd send to the image model so the user can preview what they'd be paying for.
  • Recommend Generate if OPENAI_API_KEY is set, otherwise Skip.

Use the user's answers in the steps below. If the user picks Skip for cover, omit step 5 and don't add cover_image to the title section.

5. (Optional) Generate the title cover image

Only if the user picked Generate in step 4. Compose a 1-sentence --concept describing the paper:

python3 ~/.claude/skills/paper-to-storyboard/scripts/generate_cover.py \
  --concept "" \
  --palette  \
  --mode  \
  --out /cover.png

Calls OpenAI gpt-image-1 (~$0.04 medium, $0.25 high — defaults to medium). To preview the prompt without spending: add --prompt-only.

When cover.png exists in out_dir AND the title section in storyboard.json has "cover_image": "cover.png", render.py automatically inlines it as the title-bg with a palette-tinted gradient overlay. If either is missing, the title slot falls back to the default gradient.

If OPENAI_API_KEY isn't set, generation will fail with a clear error — fall back to skipping the cover and proceed.

6. Map content to storyboard slots

Read content.json and figures/figures.json. Build a storyboard JSON object matching schemas/storyboard.schema.json. Save as /storyboard.json.

The schema has 9 fixed slots (you may skip slot 6 if the paper has only one main result):

| Slot | Suggested layout(s) | Maps to | |------|---------------------|---------| | 0 — title | title | Paper title (rewritten as a hook), 1-line subtitle from abstract | | 1 — hook | split, quote | First paragraph of Introduction ("why now") | | 2 — problem | split, split_reverse, quote | The gap/limitation paragraph | | 3 — method | split, split_reverse, stacked | One-line methods + schematic figure | | 4 — keyFinding | impact, impact_single, stats_grid, chart | Headline number(s) | | 5 — dataNarrative | split, stacked | Main results figure + body + insight callout | | 6 — secondaryFinding | split_reverse, comparison | Temporal/subgroup result or A-vs-B contrast (skippable) | | 7 — insight | insight, quote | Discussion takeaway, call-to-action or pull quote | | 8 — credits | credits | Authors, affiliations, DOI link |

Layout catalogue

  • title — hero. Big heading + subtitle, optional cover_image background.
  • split — text-left, figure-right (default workhorse).
  • split_reverse — figure-left, text-right (alternate to break rhythm).
  • split_no_image — text-only with optional insight callout.
  • stacked — figure on top, text below. For wide/panoramic figures.
  • fullbleed — figure fills the section as background, text overlays in a glass panel. Avoid for paper figures — most scientific charts don't read well at viewport scale and the glass panel competes with the data. Reserved for the rare atmospheric photo or hero rendering (not for plots/maps/diagrams from a paper).
  • quote — large italic pull-quote with attribution. Lift a striking sentence verbatim.
  • impact — two big numbers vs. each other.
  • impact_single — one big number with a caption.
  • stats_grid — 3–4 metric cards (stat_items: [{number, label, accent}]).
  • chart — vanilla (no-CDN) bar chart that grows on scroll and shows exact values on hover/focus. Use it instead of stats_grid when 2–6 numbers form a comparison the reader should see as bars (e.g. an ablation, before/after, per-group precision). Spec lives in a chart object: {type: "bar", unit, y_max, data_source, series: [{label, value, accent}]}. Only bar is supported — line/scatter are intentionally excluded because their values can't be recovered reliably. data_source is mandatory and load-bearing: use "table" or "text" only when the numbers are ground-truth (a data table or values quoted in the prose); use "estimated" if you read them off a figure by eye — that renders an "approximate, not exact" caption so the reader isn't misled. Never fabricate values to fill a chart; if you can't source the numbers, use a non-chart layout.
  • comparison — two/three side-by-side text columns (columns: [{heading, body, accent}]).
  • insight — discussion takeaway with a call-to-action box.
  • credits — authors + affiliations + DOI button.

accent modifiers (for stats_grid cards and comparison columns): warm, cool, caution, extreme. Empty = default.

Rules for filling slots:

  • Rewrite paper prose into 1–3 short sentences per slot (paper prose is too dense for 1.2rem display type).
  • Lift headline numbers and key definitions verbatim from the paper.
  • For slot 4, the two big numbers should be a meaningful comparison (e.g., baseline vs treatment, outdoor vs indoor). If the paper has no natural comparison, use a single big number and one short descriptor.
  • Charts (slot 4 alt): if content.json has a chart_ready table whose rows form a clean 2–6 bar comparison, prefer the chart layout over stats_grid. Read the actual rows (don't trust the merged header blindly), pick one label column + one numeric column, and emit a chart object with data_source: "table". If the numbers come from prose instead, use data_source: "text". Only use data_source: "estimated" if you read values off a figure by eye — and prefer not to: a wrong value under a real citation is worse than no chart. Never invent values.
  • For each split-layout slot, pick a figure from figures.json by relevance (use the caption to judge). Same figure should not be reused across slots.
  • If the paper has fewer than 4 figures, some split-layout slots become bare (drop the image_content div).

7. Emit the site

Copy the templates and substitute placeholders:

python3 ~/.claude/skills/paper-to-storyboard/scripts/render.py \
  --storyboard /storyboard.json \
  --palette  \
  [--mode dark|light] \
  [--typography editorial|modern|tech|academic] \
  --out 

This writes index.html, style.css, script.js to out_dir. The transparent figures (step 3) should already be in out_dir.

8. Preview

python3 ~/.claude/skills/paper-to-storyboard/scripts/preview.py 

Prints http://localhost:8765/ and opens it on macOS.

Reference

A fully filled storyboard.json example ships in this skill: examples/reference_storyboard.json. Additional rendered examples live under examples/ in the repo (https://github.com/MaoranSun/paper-to-storyboard).

Dependencies

pip install pdfplumber pymupdf pillow
# Optional, for background removal of complex figures:
pip install rembg

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.