Skip to content
Back to skills

Render Paper

BSecurity

Compile a LaTeX paper (ACM/IEEE/arXiv) to PDF and render its pages to high-DPI PNGs for mobile/on-screen review. Use whenever asked to "render / compile / show / screenshot" a .tex paper, or to produce phone-readable page images of a draft (e.g. ACM/IEEE workshop submissions). Encodes the toolchain + the gotchas already hit (font-expansion crash, filecontents bib, bibtex cycle).

  • 7 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 26, 2026
researchpythonrustgoshellbashnodegit

Works with

  • terminal

Security analysis

B77/100
  • highPerforms destructive filesystem operations
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 9 files and shows the line behind each finding

Scanned October 7, 2026

npx -y skills add zernie/paperlint --skill render-paper --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Render Paper?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Render Paper
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/zernie-render-paper/badge)](https://www.skillsdirectory.com/skills/zernie-render-paper)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: render-paper
description: Compile a LaTeX paper (ACM/IEEE/arXiv) to PDF and render its pages to high-DPI PNGs for mobile/on-screen review. Use whenever asked to "render / compile / show / screenshot" a .tex paper, or to produce phone-readable page images of a draft (e.g. ACM/IEEE workshop submissions). Encodes the toolchain + the gotchas already hit (font-expansion crash, filecontents bib, bibtex cycle).
allowed-tools: [Read, Write, Edit, Grep, Glob, Bash, SendUserFile]
---

<!-- vigiles:sha256:ff8dca1e1be3977e compiled from skills/render-paper/SKILL.md.spec.ts -->

# render-paper — .tex → PDF → readable page PNGs

Turns a LaTeX source into (a) a compiled PDF and (b) per-page PNG images crisp enough to read
the font on a phone. Encodes the exact toolchain and the failures already debugged, so it works
first try.

## 🔴 This is a COMMAND, not a stage

You run it twenty times a day. It has no position in the pipeline and nothing waits its turn to reach
it: **any `.tex` edit is the trigger** — render, then eyeball pages 1–2 before believing
anything you say about the paper. Scorecard row **`render`** (in the CONTINUOUS section of
`paper-pipeline`) records the last render and its page count; that page count is the hard input the
`tighten-paper` structure gate is blocked on, which is the only sense in which anything "comes after"
this.

*It used to carry a number in a stage list, which made a compile look like a milestone you pass once.
That list was replaced on 2026-08-03; nothing about the toolchain below changed.*

## Toolchain (one command, not a checklist)
- **Compiler:** TeX Live, installed by paperlint with exactly the packages the venue profiles declare:
  ```
  npx paperlint toolchain            # into ~/.cache/paperlint/texlive (PAPERLINT_TEXLIVE_DIR overrides); idempotent
  npx paperlint toolchain --check    # report what is missing, change nothing
  ```
  Measured 2026-09-24: 3 min from an empty directory, 269 MB, TeX Live 2026, 47 packages verified
  by `kpsewhich` against the files each profile names. The last line it prints is `bin: <dir>` —
  put that directory first on PATH before calling `pdflatex` or `check-render.sh` by hand.

  🔴 The package list lives in the venue profiles (`presets/*.jsonc` in the package, the
  `tex` block; `tex-base.jsonc` for every paper) and nowhere else. A new venue that needs a new
  package gets it there — never in a script, never here. A TeX Live without `libertine` builds an
  acmart paper GREEN in Computer Modern; that is why the files are checked, not the exit code.
- **Reading the PDF** needs nothing installed: `paperlint build` and `extract-pdf-facts.mjs` use pdf.js,
  which comes with paperlint. Page size, columns and font sizes come from banal (HotCRP's page-geometry
  script), which `npx paperlint toolchain` installs and which runs on pdf.js output — it needs `perl`,
  and no poppler. Without banal those facts are `null` and the build says so.
- **Renderer:** `pip install --quiet pymupdf` (system rasterizers and ghostscript are often missing or
  404 on apt here; pymupdf is reliable). No `playwright install`, no external fetches.

## Compile (full bibtex cycle — needed or citations show as `[?]`)
```
npx paperlint build <paper-dir>
```
It picks a TeX Live that has every package the venue declares (paperlint's own, else one on PATH),
runs pdflatex and bibtex until the references settle, fails on an undefined `\ref`/`\cite`
through `paper-guards.tex`, then measures the PDF into `_build/paper.facts.json` (fonts, Type 3,
the last page's column heights). It judges nothing: a venue that needs a balanced last page turns
on the optional lint rule `pdf/last-page-balance` (see `docs/optional-rules.md` in the package). Without a
terminal and without a qualifying TeX Live it stops with one line naming `npx paperlint toolchain`.
Check the last log anyway: `grep -iE "Fatal|Output written" ` and
`grep -ciE "Undefined control|Citation.*undefined|Reference.*undefined"` (must be 0).

### MECHANICAL RENDER GATE (run this — do not just eyeball)
Eyeballing a page or two misses `Overfull \hbox` defects on later pages (text/tables bleeding
past the column into the margin — the #1 "wtf, formatting is broken" bug). LaTeX reports every one
in the `.log`; **`check-render.sh` parses them so it's a checked fact, not a hope:**
```
bash .claude/skills/render-paper/check-render.sh <paper-dir> [texbasename=paper] [threshold_pt=5]
```
It compiles, then FAILS (exit 1) on: any `Overfull \hbox` ≥ threshold (visible overflow), any
`Overfull \vbox`, or any undefined reference/citation/control-sequence. **A paper is not "renders
clean" until this exits 0.** Common fixes when it fails:
- **Long `\texttt{...}` / literal commands / URLs overflowing** → wrap in `\seqsplit{}`, or use
  `\url{}` (breakable), or a `p{width}`/`>{\ttfamily\small}p{width}` table column instead of `l`,
  or shrink the block with `\small`/`\footnotesize`.
- **Wide table** → `\small` + fixed-width `p{}` columns so cells wrap; or `\resizebox{\columnwidth}{!}{...}`.
- Re-run the gate until PASS.

## KNOWN GOTCHAS (already hit — apply proactively)
1. **`pdfTeX error (font expansion): auto expansion is only possible with scalable fonts`** — acmart +
   microtype want Libertine outlines that `texlive-fonts-recommended` may lack. Fix: add
   `\microtypesetup{expansion=false}` in the preamble (after `\documentclass`). This is the #1 crash.
2. **`Undefined control sequence \lesssim` / `\gtrsim`** — need `amssymb`; either `\usepackage{amssymb}`
   or replace with `\le`/`\ge`.
3. **Bibliography via embedded `\begin{filecontents*}[overwrite]{refs.bib}...`** before
   `\documentclass` works and keeps the paper one-file; still run the full bibtex cycle above.
   ⚠️ **The block IS the source of truth — it `overwrite`s `refs.bib` on every build.** Editing `refs.bib`
   directly does nothing (regenerated away); fix citations INSIDE the filecontents block in the `.tex`.
   Consider `.gitignore`-ing the generated `refs.bib` so it can't drift from the block.
4. **Double-blind:** ACM uses `\documentclass[sigconf,review,anonymous]{acmart}`; keep author
   `Anonymous Author(s)` for the review PDF.
5. **`.gitignore`** the build junk (`*.aux *.log *.out *.bbl *.blg`); keep `paper.pdf` if you want it
   version-controlled, else ignore it too.
6. **Multi-token shell commands in `\texttt{}` break at their internal space** — `\texttt{rm -rf}` can wrap
   as `rm` ⏎ `-rf`, which reads as broken typesetting. This is a LEGAL break, so it raises **no** Overfull
   warning and the render gate is blind to it. Fix: non-breaking ties — `\texttt{rm~-rf~/}` (or wrap in
   `\mbox{}`). The space *before an argument* (`rm~-rf node\_modules`) stays breakable — only tie the
   command tokens. `check-render.sh` now greps for a literal space inside `\texttt{…}` and warns.
7. **Page-limit / body-end: trust the RENDERED References-start page, NOT `\newlabel{tmpbodyend}` in the
   `.aux`.** The aux label lags one compile (it reflects the *previous* build's pagination), so it triggers
   false page-limit alarms — this session it read "p11" while the body genuinely ended on p10. To check the
   body length: open the built PDF, find the page where the `\section*{References}`/`REFERENCES` heading
   first appears (that page = last body page). `python3 -c "import fitz;d=fitz.open('paper.pdf');[print('refs p',i+1) for i in range(d.page_count) if 'REFERENCES' in d[i].get_text()][:1]"`. Never gate a page-limit decision on the aux value.

## Render pages to PNGs
```
python3 -c "import fitz; d=fitz.open('paper.pdf'); \
  [d[i].get_pixmap(dpi=200).save(f'/<scratch>/p{i+1}.png') for i in range(d.page_count)]; \
  print('rendered', d.page_count)"
```
- **DPI 200** = phone-readable (zoomable); use 150 for quick previews, 300 for print-check.
- Write PNGs to the session scratchpad, not the repo.
- **The mechanical gate above (`check-render.sh`) is the primary defense** for text/table overflow and
  undefined refs — run it first, on the whole document, and get it to PASS.
- **Then eyeball EVERY page** (not just 1–2) for the defects the log CANNOT flag: **figure-internal
  label collisions** (TikZ/pgfplots nodes overlapping axis labels or each other — e.g. a legend
  landing on an axis tick), color/legibility, misaligned sub-figures. These do not raise an Overfull
  warning, so a human scan of each figure is still required. Fix and re-render until clean.

## Deliver
- Send the PNGs with `SendUserFile` (`display: render`) so the user can read on phone; caption what
  changed since the last render. Send the PDF too (`display: attach`) if they want the file.

## Compose with
- `paper-adversarial-review` / `pc-panel-review` (incl. its venue-fit mode) — review the rendered draft.

Files in this skill

  • SKILL.md10.2 KB
  • SKILL.md.spec.ts11 KB
  • check-render.sh24.3 KB
  • checkers-requirements.txt3.3 KB
  • ensure-checkers.sh3.9 KB
  • extract-pdf-facts.harness.mjs5.6 KB
  • extract-pdf-facts.mjs6.5 KB
  • render-paper.eval.mjs900 B
  • render-paper.harness.mjs15.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.