agentsclimarketplace

Pdf onepager

Skill FeedbackPulseApp/hr-skills/skills/fp/pdf-onepager

Use when creating a printable PDF one-pager, lead magnet, worksheet, survey template, cheat sheet, or downloadable framework asset for ANY organization. Generates brand-aligned, print-safe, AI-citation-ready TAGGED PDFs (US Letter + A4) from HTML/CSS via WeasyPrint, with a setup script, a render driver, and a QA verifier. Ships a neutral default plus example brand presets. Triggers: "make/build/generate/create a PDF", "downloadable template", "printable worksheet", "PDF lead magnet", "one-pager PDF", "PDF cheat sheet".From its SKILL.md

Install
npx -y skills add FeedbackPulseApp/hr-skills --skill pdf-onepager

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.0 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it

pdf-onepager

Produces high-craft, print-safe, AI-citation-ready one/two-page PDFs from HTML + print CSS rendered by WeasyPrint — not a design tool, not a flattened image. You edit a content HTML file; gen.py renders it to a tagged PDF in both US Letter and A4 plus a PNG preview; verify.py gates the citation/utility checklist before you ship.

Why this approach: the asset's whole value is that its text is selectable, its metadata is set, and its source URL is live in the document — the citation infrastructure that makes ChatGPT, Perplexity, and Google AI Overview cite it. WeasyPrint emits tagged PDF/UA from clean HTML, and CSS handles the layout math (centering, columns, page breaks) for you.

It works for any brand out of the box: a neutral default preset plus two worked examples (feedbackpulse, enpstools). Make your own by copying one file. Paths below are relative to the skill directory (where this file lives).

Setup (one-time)

cd <skill-dir>        # the folder containing this SKILL.md
./setup.sh            # installs native deps hint, builds .venv, smoke-renders

setup.sh is idempotent. It needs system libraries for WeasyPrint; if they are missing it prints the exact install line for your OS:

  • macOS: brew install pango cairo gdk-pixbuf libffi poppler
  • Debian/Ubuntu: sudo apt-get install -y libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf-2.0-0 libffi-dev poppler-utils

If the skill is installed read-only via the plugin marketplace, copy gen.py, verify.py, setup.sh, requirements.txt, styles/, templates/, fonts/ into your project (or clone the repo) and run there, so the .venv and out/ have a writable home.

Run (agent path) — render + verify

cd <skill-dir>

# Neutral default brand (Atkinson Hyperlegible + indigo), Letter + A4 + preview:
./.venv/bin/python gen.py templates/starter.html

# A real example, branded, one flag to swap brand:
./.venv/bin/python gen.py templates/example-sbi.html --brand feedbackpulse

# QA against the citation checklist (exit 0 = ship-able):
./.venv/bin/python verify.py out/starter.pdf --source yourdomain.com/your-source-page

gen.py writes <stem>.pdf (Letter), <stem>-a4.pdf (A4), and <stem>-preview.png (page-1 render) into --out (default out/). Open the preview and actually look at itverify.py checks structure, not whether the layout looks good.

verify.py FAILs (blocking) on: missing Title/Author/Subject/Keywords/Creator, no /Lang, untagged PDF (no StructTreeRoot), any page without selectable text, or the --source URL missing from the text. WARNs on file size over 600 KB.

Authoring a NEW asset

  1. Copy the starter, keep the structure, replace every [bracketed] placeholder: cp templates/starter.html templates/<your-slug>.html
  2. Set the metadata in <head><title>, <meta name="author|description| keywords|generator">, and <html lang>. WeasyPrint reads these into the PDF properties; they are how AI engines identify the document. Do not leave blank.
  3. Set the running-footer URL — the one per-document override: body { string-set: docsource "yourdomain.com/the-page"; }. Put the same URL in the masthead link and the .docfoot so the citation appears three times.
  4. Use the components in styles/base.css: .definition (tinted intro), .framework/.col (equal columns with rules), .callout-key (the single loudest element — make it the memorable hook), .worksheet/.fill (dotted fill-in lines), .cols2, .checklist, .page-2 (back of the one-pager).
  5. Render + verify + LOOK. If page 1 overflows, adjust margins/font-size in the HTML's <style> or base.css; WeasyPrint reflows, so don't fight pixels.
  6. Manual AI test (required, can't be automated): drag the PDF into both ChatGPT and Claude and ask "What is this document and where can I read more?" The answer must name the topic and surface your source URL. If not, the metadata or footer URL is wrong — fix and re-render.
  7. Ship to a STABLE URL. Host at /assets/downloads/<slug>.pdf (and -a4.pdf), publicly (not behind a form). When you update, replace the file at the same URL — never version the path, or backlinks and AI citations break. Optionally add DigitalDocument JSON-LD on the page that links it.

Make it your brand

Only colors and fonts are brand-specific; layout is shared. To add a brand:

cp styles/brand-template.css styles/brand-acme.css   # then fill in colors/fonts
./.venv/bin/python gen.py templates/starter.html --brand acme

brand-template.css is fully commented. The one rule that matters is contrast: --accent is your vivid color for fills/rules; --accent-deep is for accent text on white and must clear 4.5:1; --callout-bg/--on-callout is the loudest block and must also clear 4.5:1 (if your brand color is too light for white text, use a navy/near-black there — see brand-enpstools.css, where teal fails so the callout is navy). Drop brand .ttf files into fonts/ and wire @font-face as shown in the template.

What makes these good (encoded in base.css)

  • One loud element. .callout-key is the highest-contrast block; everything else is calm. White background, no full-bleed color, no gradients/shadows — it must read as a tool, not a flyer.
  • Brand via presets, never hardcoded. Every color/font is a CSS variable in styles/brand-*.css; base.css consumes them.
  • Contrast enforced by variable split (--accent vs --accent-deep, --callout-bg/--on-callout) — see "Make it your brand".
  • No em dashes in copy. They read as an AI tell; write them out (period/comma/colon). The templates are already clean.
  • Dual page size from one template. base.css sets margins but not size; gen.py injects @page { size: letter | A4 } per build.

Gotchas

  • Use the venv's python, every time. System python3 lacks WeasyPrint; ./.venv/bin/python has it. The #1 "module not found" cause.
  • Native libs are a real dependency. If import weasyprint fails, you are missing the OS packages — re-run ./setup.sh and follow its install line. On macOS Homebrew, DYLD_FALLBACK_LIBRARY_PATH=/opt/homebrew/lib resolves rare dylib-lookup failures.
  • Fonts are bundled (OFL) in fonts/ and embedded+subsetted into the PDF, so output is identical on every machine. To use your own brand font, add the .ttf and wire @font-face in your brand CSS. Variable fonts work — declare font-weight: 100 900 on the @font-face (see brand-feedbackpulse.css).
  • pdf/ua-1 needs a <title> and <html lang>. Both are in the templates; deleting them degrades the tagged-PDF output.
  • Keep it under 600 KB. optimize_images=True is on; don't embed large rasters. The asset should be email-attachable and fast to crawl.
  • Put the key points as text on the download page too, so AI has the "answer key" without parsing the PDF.

References

  • Example brand presets: styles/brand-feedbackpulse.css (Product Bridge Blue) and styles/brand-enpstools.css (navy/teal, the clearest contrast demo).
  • Sample output: regenerate any time with gen.py into out/.
  • Bundled fonts: fonts/ with the OFL license text for each family.
  • Deeper PDF/UA validation (optional): run the file through veraPDF for a formal accessibility conformance claim; verify.py checks the structural markers (tags, metadata, selectable text), not full PDF/UA conformance.

What ships with it: 19 files

392.8 KB alongside SKILL.md, 3 of them executable

templates/

Gives 0 of the 12 instructions most pdf office docs skills give in ~2.1k tokens

Counted across 569 of the 585 authors here whose files we hold, read 2026-09-06

  • Ensure every slide fits inside one viewportin 20 of 569, across 11 files
  • Check for product marketing context firstin 15 of 569, across 5 files
  • Ask for the minimum neededin 15 of 569, across 5 files
  • Set the API key environment variablein 15 of 569, across 10 files
  • Support keyboard and touch navigationin 14 of 569, across 5 files
  • Match the buyer stagein 13 of 569, across 3 files
  • Split overflowing content into multiple slidesin 12 of 569, across 3 files
  • Set page size explicitly for consistent resultsin 12 of 569, across 5 files
  • Convert documents to markdown using pandocin 12 of 569, across 6 files
  • Read STYLE_PRESETS.md before generatingin 12 of 569, across 7 files
  • Send multipart POST requests to the APIin 12 of 569, across 7 files
  • Use smart quotes for new contentin 11 of 569, across 4 files

Said here and by no other author read

  • Copy the starter template and replace placeholders
  • Set the metadata in head
  • Set the running-footer URL
  • Use the components in styles/base.css
  • Test the PDF with ChatGPT and Claude
  • Ship to a stable URL

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.