make-pdf
Skill8 starsChanged 6 months agoMITView on GitHub
Generate a polished PDF from markdown, HTML or code in the repo, with cover page, table of contents and margins.
- Reads credentials
21 other projects use a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- ethosagent/ethostheir own version, first seen Nov 3, 2026
- trungtm78/ClaudeSkillsedited, first seen Oct 25, 2026
- ignavm1/claude-skillstheir own version, first seen Oct 13, 2026
- leishifu666/skillstheir own version, first seen Oct 9, 2026
- IyedBecheikh/bstacktheir own version, first seen Oct 9, 2026
- garrytan/gstacktheir own version, first seen Oct 7, 2026
Used with
Projects with it also use ios-clean, ios-fix and 3 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
Saqlain-811Skillios-clean
Remove the DebugBridge SPM package and all #if DEBUG wiring from an iOS app. (gstack)
Also in 5 projects that use this
Saqlain-811Skillios-fix
Autonomous iOS bug fixer. (gstack)
Also in 5 projects that use this
bastosSkillios-design-review
Review iOS app UI/UX design quality using Apple's design principles and the Liquid Glass-era design language from WWDC25/26. Use when asked for a design review, UX critique, visual design assessment, or evaluation of an app's interface quality, design intent, alignment with the new Apple design system, or usability. Triggers: "design review", "UX review", "visual design critique", "review the UI", "does this design work", "evaluate this interface", "design feedback", "Liquid Glass review".
Also in 5 projects that use this
- +2 more from Saqlain-811
Other versions21 projects use a version of this.
Word for word · 0
None found.
Edited · 1
- trungtm78/ClaudeSkills★ 010% same
Wrote their own version · 20
- garrytan/gstack★ 141ksame name
- ethosagent/ethos★ 22same name
- giarld/skills★ 8same name
- GTMify/claude-skills-starter★ 2same name
- HanksChen0110/skills★ 2same name
- chloropine/cgstack★ 1same name
- Faaz17/Agents-and-Skills★ 1same name
- IyedBecheikh/bstack★ 1same name
- jpoindexter/theft-kit★ 1same name
- leishifu666/skills★ 1same name
10 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository62 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- address-pr-reviewSkill
- agent-evalSkill
- ai-cost-guardSkill
- autoplanSkill
- aws-costSkill
- bedrock-guardrailsSkill
- benchmarkSkill
- browseSkill
- canarySkill
- carefulSkill
- claudeSkill
- codexSkill
- connect-chromeSkill
- connect-reviewSkill
- context-restoreSkill
- context-saveSkill
- csoSkill
- design-consultationSkill
- design-htmlSkill
- design-reviewSkill
- design-shotgunSkill
- devex-reviewSkill
- diagramSkill
- document-generateSkill
- document-releaseSkill
- freezeSkill
- guardSkill
- healthSkill
- iac-reviewSkill
- improve-archSkill
- investigateSkill
- kb-reviewSkill
- land-and-deploySkill
- landing-reportSkill
- learnSkill
- mcp-reviewSkill
- office-hoursSkill
- open-browserSkill
- pair-agentSkill
- plan-ceo-reviewSkill
- plan-design-reviewSkill
- plan-devex-reviewSkill
- plan-eng-reviewSkill
- plan-tuneSkill
- pr-summarySkill
- qa-onlySkill
- qaSkill
- retroSkill
- reviewSkill
- scrapeSkill
- setup-browser-cookiesSkill
- setup-deploySkill
- shipSkill
- skillifySkill
- specSkill
- telegramSkill
- unfreezeSkill
- unslopSkill
- vibe-gcSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
8 rules. 0 are common, 2 are distinctive, and 6 are very specific to this project.
0
Common
Most of the 16 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 20
If this session was compacted, the copy of this skill in context may be cut off.
- Very specific: line 21
Read ${CLAUDE_SKILL_DIR}/SKILL.md from disk and resume at the step you are on.
- Distinctive: line 25
Use when asked to "make pdf", "generate pdf", "export to pdf", "create pdf report", or "pdf preview".
- Very specific: line 63
If NOT_FOUND, stop and tell the user:
- Very specific: line 100
Run the generator. The output path is the second positional argument — there is no --output flag, and any flag the CLI does not know fails …
- Very specific: line 148
Verify the render toolchain — browse binary, Chromium launch, pdftotext (optional) — then generate and open a smoke-test PDF:
- Very specific: line 328
If the user has a .md file open and says "make it look nice", propose "$P" generate --cover --toc and ask before running.
- Distinctive: line 363
If you discovered a non-obvious make-pdf behavior, flag pattern, or conversion quirk during this session, log it for future sessions:
“Common” is measured: kept by at least 6 in 10 of the 16 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
If this session was compacted, the copy of this skill in context may be cut off.
Read ${CLAUDE_SKILL_DIR}/SKILL.md from disk and resume at the step you are on.
When to invoke
Use when asked to "make pdf", "generate pdf", "export to pdf", "create pdf report", or "pdf preview".
Preamble
eval "$("${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-slug" 2>/dev/null)" 2>/dev/null || SLUG="unknown"
_LEARN_FILE="${VIBESTACK_HOME:-$HOME/.vibestack}/projects/${SLUG:-unknown}/learnings.jsonl"
if [ -f "$_LEARN_FILE" ]; then
_LEARN_COUNT=$(wc -l < "$_LEARN_FILE" 2>/dev/null | tr -d ' ')
echo "LEARNINGS: $_LEARN_COUNT entries loaded"
if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
"${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-learnings-search" --limit 5 2>/dev/null || true
fi
else
echo "LEARNINGS: none yet"
fi{{include lib/snippets/session-host.md}}
{{include lib/snippets/decision-brief.md}}
{{include lib/snippets/working-protocols.md}}
{{include lib/snippets/state-protocols.md}}
Step 0: Find the make-pdf renderer
# Env override first, then the launcher installed with this skill (resolves
# the repo's compiled binary or runs the CLI on bun).
P="${MAKE_PDF_BIN:-${CLAUDE_SKILL_DIR:-$HOME/.claude/skills/make-pdf}/bin/vibe-make-pdf}"
[ -x "$P" ] && "$P" version >/dev/null 2>&1 && echo "PDF_BIN: $P" || echo "NOT_FOUND"Each Bash call starts a fresh shell, so every later block that runs "$P" opens with
P='<PDF_BIN>': replace the placeholder with the path this block printed.
If NOT_FOUND, stop and tell the user:
make-pdf renderer not found. It ships with the vibestack repo. Run:
cd ~/data/vibestack && bun install && bun run build:make-pdf && ./install(Bun 1.3.3 or newer —bun --version. Older Bun ignores the build's--no-compile-autoload-dotenvflag, so the binary could read a project's.env; runbun upgradefirst.) Or set$MAKE_PDF_BINto the path of an existingmake-pdfbinary.After building, re-run
/make-pdf.
Step 1: Detect intent
Parse the user's input to determine what to do:
/make-pdfwith no args — Auto-detect: look for markdown files or ask what to convert/make-pdf preview <file>— Preview mode: render the print-styled HTML and open it in a browser/make-pdf setup— Setup mode: run$P setupto configure defaults/make-pdf <file or description>— Generate mode: produce a PDF from the specified input
Step 2A: Generate mode
- Identify the source file(s). If the user provided a path, use it. If not, ask:
What should I turn into a PDF? A) A specific file (provide path) B) All markdown files in this directory C) A generated report (I'll describe what to include) D) Something else - Determine output filename. Default:
<source-basename>.pdfin the same directory. - Run the generator. The output path is the second positional argument — there is no
--outputflag, and any flag the CLI does not know fails the run with exit 1:
P='<PDF_BIN>'
"$P" generate "<source>" "<output.pdf>" [flags]Common flags:
--cover— add a cover page (uses repo name + date)--toc— add a table of contents with page numbers--watermark "<text>"— overlay watermark text (e.g., "DRAFT", "CONFIDENTIAL")--margins <dim>— one dimension for all four margins (default:1in; also72pt,2.54cm,25mm)--page-size <size>—letter(default),a4,legal--title "<title>"— override document title--author "<name>"— set author metadata--to pdf|html|docx— output format (default:pdf)--no-confidential— suppress the CONFIDENTIAL footer stamped by default--strict— missing or remote images fail the run instead of warning
- Report the result:
PDF GENERATED
═══════════════════════════════════════════
Output: <output.pdf>
Size: <file size>
Pages: <page count>
═══════════════════════════════════════════Step 2B: Preview mode
Render the print-styled HTML and open it:
P='<PDF_BIN>'
"$P" preview "<source>" [flags]This writes an HTML file with the print CSS and opens it in the browser; no PDF is produced. Preview skips the diagram and image pre-pass, so diagram fences show as code. Report the path, and run generate mode when the user wants the PDF.
Step 2C: Setup mode
Verify the render toolchain — browse binary, Chromium launch, pdftotext (optional) — then
generate and open a smoke-test PDF:
P='<PDF_BIN>'
"$P" setupIt writes no config file. Report which checks passed and, if Chromium or the browse binary failed, relay the fix it printed before attempting any other mode.
Core patterns
80% case — memo/letter
One command, no flags. Gets a clean PDF with running header, page numbers, and a CONFIDENTIAL right-footer. Always pass the output path: without one the CLI writes to the OS temp directory, whose location varies by platform.
P='<PDF_BIN>'
"$P" generate letter.md letter.pdfBrand-free — no CONFIDENTIAL footer
The footer is on by default, so anything meant to leave the building needs it turned off:
P='<PDF_BIN>'
"$P" generate --no-confidential memo.md memo.pdfPublication mode — cover + TOC + chapter breaks
P='<PDF_BIN>'
"$P" generate --cover --toc --title "On Horizons" essay.md essay.pdfEach top-level H1 starts a new page. Disable with --no-chapter-breaks for memos that happen to have multiple H1s.
Draft-stage watermark
P='<PDF_BIN>'
"$P" generate --watermark DRAFT memo.md draft.pdfDiagonal DRAFT across every page. Drop the flag when final.
Diagrams — mermaid and excalidraw fences render as pictures
A column-0 ```mermaid or ```excalidraw fence renders as a vector diagram,
offline. Indented fences are left alone, so a fence quoted inside a list stays a code block.
Info-string options on the opening fence:
title="Auth flow"— accessible label for the rendered figurerender=false— leave this fence as a plain code block (the escape hatch when the source is what the reader needs to see)page=landscape/page=portrait— force or veto a landscape page for this diagram
A fence whose source fails to parse becomes a visible red diagnostic block carrying the error and an excerpt — never a silently missing figure. When that shows up, fix the diagram source rather than dropping the fence.
Images — scaled right, never truncated
A directive suffix on a markdown image tunes its placement:
{width=full}
{width=50%}
{page=landscape}
{page=portrait}width takes full, a percentage, or an absolute dimension (in, cm, mm, pt, px).
By default an image renders at its intrinsic size, capped at the content box and never
upscaled.
Wide, small-text images auto-promote to their own landscape page. The heuristic is deliberately
conservative — aspect ratio at least 1.8, intrinsic width over roughly 2.5x the content box,
and either diagram provenance or a diagram-ish word in the alt text — so it misses more often
than it fires. {page=landscape} forces promotion; {page=portrait} vetoes it.
Local images are inlined as data URIs and rasters wider than print resolution are downscaled. An image that is missing, not a regular file, or over 64MB degrades to a visible placeholder with a warning; one resolving outside the markdown's own directory is inlined but warned about, because an agent rendering untrusted markdown should not quietly embed a file from elsewhere on the machine into a shareable document.
Other formats — single-file HTML and Word
P='<PDF_BIN>'
"$P" generate readme.md out.html --to html # one self-contained file, no network refs
"$P" generate readme.md out.docx --to docx # content fidelity; diagrams become PNG--to is the output format. --format is something else entirely — an alias for
--page-size — so --format html asks for a page size named "html", not HTML output.
CI mode — fail loud on missing assets
P='<PDF_BIN>'
"$P" generate docs.md --strictMissing, unreadable, oversized, out-of-tree, and remote images become hard failures instead of warnings, so a broken asset path fails the build rather than shipping a placeholder.
Fast iteration via preview
P='<PDF_BIN>'
"$P" preview essay.mdRenders with print CSS and opens in browser. Skip the PDF round trip until you're ready.
Common flags
Output format:
--to pdf|html|docx What to produce (default: pdf)
Page layout:
--margins <dim> 1in (default) | 72pt | 2.54cm | 25mm
--page-size letter|a4|legal (alias --format — page SIZE, not --to)
Structure:
--cover Cover page (title, author, date)
--toc Clickable TOC with page numbers
--no-chapter-breaks Don't start a new page at every H1
Branding:
--watermark <text> Diagonal watermark ("DRAFT", "CONFIDENTIAL")
--header-template <html> Custom running header
--footer-template <html> Custom footer (mutex with --page-numbers)
--no-confidential Suppress the CONFIDENTIAL right-footer (on by default)
Output:
--page-numbers "N of M" footer (default on)
--tagged Accessible PDF (default on)
--outline PDF bookmarks from headings (default on)
--quiet Suppress progress on stderr
--verbose Per-stage timings
Images:
--strict Missing/remote images fail the run (CI mode)
Network:
--allow-network Fetch external images. Off by default
(blocks tracking pixels).
Metadata:
--title "..." Document title (defaults to first H1)
--author "..." Author for cover + PDF metadata
--date "..." Date for cover (defaults to today)When to run it
Watch for markdown-to-PDF intent. Any of these → run "$P" generate:
- "Can you make this markdown a PDF"
- "Export it as a PDF"
- "Turn this into a PDF"
- "I need a PDF of this"
- "Print this as a PDF for me"
If the user has a .md file open and says "make it look nice", propose "$P" generate --cover --toc and ask before running.
Output contract
stdout: /path/to/letter.pdf ← just the path, one line
stderr: Rendering HTML... ← progress (unless --quiet)
Generating PDF...
Done in 1.5s. 43 words · 22KB · /path/to/letter.pdf
exit code: 0 success / 1 bad args or unknown flag / 2 render error / 3 TOC page numbers failed / 4 binary unavailableCapture the path: PDF=$("$P" generate letter.md letter.pdf) — then use $PDF.
Debugging
- Blank output → check binary is executable:
ls -la "$P" - Fragmented text on copy-paste → remove fenced code blocks and regenerate
- Exit 3 with
--toc→ the TOC page numbers could not be filled (they kept moving after three prints, or the PDF had no destination for a heading); shorten the longest TOC entries or drop--toc - External image missing → the binary fetches external images only when
--allow-networkis set - Wrong text metrics or ▯ boxes where emoji should be (Linux, containers) → the print CSS
falls back to Liberation Sans and a system color-emoji font; install
fonts-liberationand a Noto color-emoji package, neither of which the vibestack installer provides
Capture Learnings
If you discovered a non-obvious make-pdf behavior, flag pattern, or conversion quirk during this session, log it for future sessions:
"${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-learnings-log" '{"skill":"make-pdf","type":"TYPE","key":"SHORT_KEY","insight":"DESCRIPTION","confidence":N,"source":"SOURCE","files":["path/to/relevant/file"]}'Types: pattern (reusable approach), pitfall (what NOT to do), tool
(binary behavior), operational (env/path/dependency quirk).
Only log genuine discoveries. A good test: would this save time in a future session?
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

