LaTeX Documents skill for Claude Code
Clean builds, resolved citations, no ?? in the PDF. Claude sets up LaTeX projects that build with one latexmk command: a sane preamble with packages in the right order, biblatex with biber, booktabs tables, siunitx units, and cleveref cross-references. After each build a bundled log parser lists errors by line, undefined references and citations, and wide overfull boxes, so fixes target causes instead of rerunning and hoping.
- name
latex-documents - size211 lines · ≈2,100 tokens
- files2
- licenseMIT
- updated
What Claude sees before loading it
This description is the only part of the skill that sits in context all the time. Claude reads it to decide when to load the full playbook below.
description: Writes and builds LaTeX papers, theses, and reports that compile cleanly — project structure, engine choice (pdfLaTeX vs LuaLaTeX), latexmk builds with .latexmkrc, biblatex with biber bibliographies, figures and booktabs tables, cross-references with cleveref, siunitx units, and reading the log to fix errors, undefined references, and overfull boxes. Use when the user works with .tex or .bib files, asks for a LaTeX paper or report template, hits a compile error, has citations showing as question marks, or needs a journal or university class configured. Try asking
- Set up a LaTeX paper template with biblatex, figures and cleveref
- My citations show up as question marks — fix the bibliography build
- Clean up the overfull hbox warnings in my thesis before submission
Use it when
- Starting a LaTeX paper, report, or thesis
- A .tex build fails or citations and references show ?? or bold keys
- Configuring latexmk, biber, or a journal class
- Polishing tables, figures, and layout warnings before submission
Skip it when
- The source is Markdown and LaTeX is only the PDF engine — use markdown-publishing instead
- The goal is improving the prose rather than the build — use technical-writing instead
How to check the result
A clean latexmk build from scratch exits zero and the log summary shows no errors, no undefined references or citations, and no overfull boxes above the agreed width.
The common mistake it prevents
Placing the label before the caption in a figure or table, so every reference silently points at the section number instead of the figure.
Done well means: the document builds from a clean checkout with one command, the log has no errors, no undefined references or citations, and no overfull boxes worth fixing; structure lives in sectioning and labels rather than manual numbering; and you read the log rather than guessing from the PDF.
Toolchain
| Need | Choice |
|---|---|
| Default engine for new documents | LuaLaTeX (Unicode, system/OpenType fonts via fontspec) |
| Journal/arXiv template requires it, or fastest builds | pdfLaTeX |
| Build orchestration | latexmk (reruns LaTeX/biber until references settle) |
| Bibliography | biblatex + biber (unless the journal class mandates BibTeX .bst styles) |
| Single-binary alternative | Tectonic (auto-downloads packages; good for CI) |
| Distribution | TeX Live 2025+ (full scheme avoids missing packages) or MacTeX; texlive/texlive Docker image in CI |
Check what is installed: latexmk -v, lualatex --version, biber --version,
kpsewhich biblatex.sty (prints a path if the package exists).
Project layout
paper/
├── main.tex
├── .latexmkrc
├── refs.bib
├── sections/ intro.tex method.tex results.tex
├── figures/ architecture.pdf latency.pdf
└── build/ (generated; gitignored)
.gitignore: build/, *.aux, *.log, *.bbl, *.bcf, *.blg, *.fdb_latexmk,
*.fls, *.out, *.run.xml, *.synctex.gz, *.toc.
Minimal dependable preamble (LuaLaTeX)
\documentclass[11pt,a4paper]{article}
\usepackage{fontspec} % LuaLaTeX/XeLaTeX only; pdfLaTeX: \usepackage[T1]{fontenc}
\usepackage[english]{babel}
\usepackage{microtype}
\usepackage{amsmath,amssymb}
\usepackage{graphicx}
\usepackage{booktabs}
\usepackage{siunitx}
\usepackage[style=authoryear,backend=biber,maxcitenames=2]{biblatex}
\addbibresource{refs.bib}
\usepackage[hidelinks]{hyperref} % load late
\usepackage[capitalise,noabbrev]{cleveref} % after hyperref
\graphicspath{{figures/}}
\title{Reducing Tail Latency in Queue-Backed APIs}
\author{Jane Doe}
\date{\today}
\begin{document}
\maketitle
\begin{abstract}
...
\end{abstract}
\input{sections/intro}
\input{sections/method}
\printbibliography
\end{document}
Package order rules: hyperref near the end; cleveref after hyperref; fontspec
never with pdfLaTeX; do not load inputenc on LuaLaTeX (UTF-8 is native; pdfLaTeX has
defaulted to UTF-8 since 2018 too).
Build with latexmk
.latexmkrc:
$pdf_mode = 4; # 1 = pdflatex, 4 = lualatex, 5 = xelatex
$out_dir = 'build';
$bibtex_use = 2; # run biber/bibtex as needed; delete .bbl on clean
@default_files = ('main.tex');
set_tex_cmds('-interaction=nonstopmode -halt-on-error -file-line-error -synctex=1 %O %S');
latexmk # build using .latexmkrc
latexmk -pvc # rebuild on save (preview continuously)
latexmk -c # remove auxiliary files, keep PDF
latexmk -C # remove everything generated, including PDF
latexmk -lualatex -interaction=nonstopmode -halt-on-error main.tex # without an rc file
After every build, summarize the log:
python3 scripts/latex_log_summary.py build/main.log
python3 scripts/latex_log_summary.py build/main.log --boxes 5
Standard library only. It lists errors with file:line, missing files, undefined references and citations, overfull boxes above a width threshold, badness-10000 underfull boxes, font and missing-character warnings, and whether a rerun is pending. Exit code 1 when errors, missing files, or undefined refs/citations remain.
Bibliography (biblatex + biber)
@article{dean2013tail,
author = {Dean, Jeffrey and Barroso, Luiz Andr{\'e}},
title = {The Tail at Scale},
journal = {Communications of the ACM},
volume = {56}, number = {2}, pages = {74--80}, year = {2013},
doi = {10.1145/2408776.2408794}
}
- Cite with
\textcite{dean2013tail}(narrative) and\parencite{...}(parenthetical);\autocitefollows the style’s default. - Styles:
authoryear,numeric-comp,ieee(viabiblatex-ieee),apa(viabiblatex-apa, requires\DeclareLanguageMappingonly on old versions). - Protect capitalization in titles with braces:
{GPU},{Kubernetes}. - Use
--for page ranges, full author names inLast, First and Last, Firstform. - Citations print as bold keys or
[?]: biber did not run or failed. Checkbuild/main.blg, confirmbackend=biber, and that keys match exactly (case-sensitive). - Never fabricate references. If the user asks for citations, use only sources they provide or that you can verify, and flag any entry you could not confirm.
Figures and tables
\begin{figure}[tbp]
\centering
\includegraphics[width=0.8\linewidth]{latency}
\caption{p99 latency before and after admission control.}
\label{fig:latency}
\end{figure}
\begin{table}[tbp]
\centering
\caption{Latency by configuration.}
\label{tab:latency}
\begin{tabular}{l S[table-format=3.1] S[table-format=3.1]}
\toprule
Configuration & {p50 (\unit{\milli\second})} & {p99 (\unit{\milli\second})} \\
\midrule
Baseline & 12.4 & 310.0 \\
Admission & 11.9 & 84.2 \\
\bottomrule
\end{tabular}
\end{table}
\labelafter\caption, or references point at the section number.- Vector figures as PDF (matplotlib
savefig("x.pdf")), photos as PNG/JPEG. Omit the extension in\includegraphicsso the engine picks the best available. - Refer with
\cref{fig:latency}→ “Figure 3”; never hard-code numbers. - No vertical rules in tables;
booktabsrules only.siunitxScolumns align decimals; wrap non-numeric header cells in braces. - Units:
\qty{3.2}{\milli\second},\num{12345}(siunitx v3 syntax;\SIis the old form). - Floats drifting far away: use
[tbp], reduce float size, or\FloatBarrier(placeins); avoid[H]except for short documents.
Fixing common errors
| Log message | Usual cause and fix |
|---|---|
Undefined control sequence at l.N | Typo or missing package for that command; check the line shown |
File 'x.sty' not found | Package not installed: tlmgr install x (TeX Live) or install the full scheme |
Missing $ inserted | Math character (_, ^, &) in text; escape as \_ or wrap in $...$ |
Misplaced alignment tab character & | & in text; use \& |
Runaway argument / File ended while scanning | Unbalanced braces; check the start of the reported paragraph |
There's no line here to end | \\ in vertical mode (after a blank line); remove it, use paragraph spacing |
Option clash for package x | Loaded twice with different options; load once, or pass via \PassOptionsToPackage before the class |
Missing character: There is no ü in font | pdfLaTeX without T1 fontenc, or font lacks glyph; switch to LuaLaTeX with a Unicode font |
Citations [?] / references ?? | Rerun needed or biber failed; run latexmk, read .blg |
-halt-on-error stops at the first error, which is the one to fix; later errors are often
consequences.
Overfull boxes
Fix ones wider than ~1–2 pt in final output. Options in order: let microtype work;
rephrase; allow hyphenation of a long word (\hyphenation{data-base}); break URLs with
\url{} (hyperref) or xurl; for code use listings/minted with breaklines. Do not
blanket-set \sloppy for the whole document.
Gotchas
- Journal classes (IEEEtran, acmart, elsarticle, llncs) dictate bibliography tooling and
fonts; follow their templates instead of the preamble above, and do not add
geometryor font changes they forbid. - arXiv uses pdfLaTeX by default and requires the
.bblfor BibTeX; for biblatex, include the.bblproduced by a matching biber version or switch to BibTeX for submission. - Spaces after macros:
\LaTeX isswallows the space; write\LaTeX{} is. - Quotes: use
``text''or\enquote{}(csquotes), never straight". - Non-breaking space before references and citations:
Figure~\ref{...}(cleveref handles this for you).
Verification
latexmk -C && latexmkbuilds from scratch with exit code 0.scripts/latex_log_summary.pyreports zero errors, zero undefined references and citations, and no overfull boxes above the agreed threshold.- Spot-check the PDF: table of contents, figure/table numbering, bibliography entries, and links resolve.
Bundled files
Loaded only when a step in the skill needs them. Review them here before installing.
scripts/latex_log_summary.py
#!/usr/bin/env python3
"""Summarize a LaTeX .log file: errors with line numbers, undefined references and
citations, missing files, overfull/underfull boxes, font and package warnings, and
whether a rerun is still needed.
Standard library only (Python 3.10+).
Usage:
python3 latex_log_summary.py build/main.log
python3 latex_log_summary.py build/main.log --boxes 5 # report overfull boxes wider than 5pt
Exit codes: 0 = no errors and no undefined refs/citations, 1 = problems found, 2 = cannot read log.
"""
import argparse
import re
import sys
ERR = re.compile(r"^(?:! (?P<msg>.+)|(?P<file>[^:\s]+\.\w+):(?P<line>\d+): (?P<msg2>.+))$")
UNDEF_REF = re.compile(r"LaTeX Warning: Reference `([^']+)' on page \d+ undefined")
UNDEF_CIT = re.compile(r"(?:LaTeX|Package natbib) Warning: Citation `([^']+)'.* undefined")
BIBLATEX_UNDEF = re.compile(r"Package biblatex Warning: The following entry could not be found")
MISSING = re.compile(r"(?:LaTeX Error: File `([^']+)' not found|! LaTeX Error: Unknown graphics extension)")
OVERFULL = re.compile(r"^Overfull \\hbox \(([\d.]+)pt too wide\).*?lines? (\d+)")
UNDERFULL = re.compile(r"^Underfull \\[hv]box \(badness (\d+)\).*?lines? (\d+)")
RERUN = re.compile(r"(Rerun to get|Label\(s\) may have changed|Please \(re\)run Biber|Please rerun LaTeX)")
FONT = re.compile(r"(LaTeX Font Warning: .+|Missing character: There is no .+)")
LINE_NO = re.compile(r"^l\.(\d+)")
def main() -> int:
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
ap.add_argument("log")
ap.add_argument("--boxes", type=float, default=1.0, help="min overfull width in pt to report (default 1.0)")
args = ap.parse_args()
try:
# TeX wraps log lines at 79 chars; join wrapped lines conservatively for matching
raw = open(args.log, encoding="utf-8", errors="replace").read()
except OSError as exc:
print(f"error: {exc}", file=sys.stderr)
return 2
lines = raw.splitlines()
errors, refs, cites, missing, overfull, underfull, fonts = [], set(), set(), set(), [], [], set()
rerun = False
for i, line in enumerate(lines):
m = ERR.match(line)
if m:
msg = m.group("msg") or m.group("msg2")
where = f"{m.group('file')}:{m.group('line')}" if m.group("file") else ""
if not where:
for nxt in lines[i + 1:i + 8]:
lm = LINE_NO.match(nxt)
if lm:
where = f"line {lm.group(1)}"
break
errors.append(f"{where} {msg}".strip())
if (m := UNDEF_REF.search(line)):
refs.add(m.group(1))
if (m := UNDEF_CIT.search(line)):
cites.add(m.group(1))
if BIBLATEX_UNDEF.search(line):
nxt = lines[i + 1] if i + 1 < len(lines) else ""
key = re.search(r"'([^']+)'", nxt)
cites.add(key.group(1) if key else "(see log)")
if (m := MISSING.search(line)):
missing.add(m.group(1) or line.strip())
if (m := OVERFULL.match(line)) and float(m.group(1)) >= args.boxes:
overfull.append((float(m.group(1)), int(m.group(2))))
if (m := UNDERFULL.match(line)) and int(m.group(1)) >= 10000:
underfull.append(int(m.group(2)))
if RERUN.search(line):
rerun = True
if (m := FONT.search(line)):
fonts.add(m.group(1)[:120])
print(f"{args.log}")
print(f" errors: {len(errors)}")
for e in errors[:25]:
print(f" ! {e}")
if missing:
print(f" missing files: {sorted(missing)}")
if refs:
print(f" undefined references ({len(refs)}): {sorted(refs)[:30]}")
if cites:
print(f" undefined citations ({len(cites)}): {sorted(cites)[:30]}")
if overfull:
worst = sorted(overfull, reverse=True)[:15]
print(f" overfull hboxes >= {args.boxes}pt ({len(overfull)}): " +
", ".join(f"{w:.1f}pt@line {ln}" for w, ln in worst))
if underfull:
print(f" underfull boxes at badness 10000 ({len(underfull)}): lines {underfull[:15]}")
if fonts:
print(" font warnings:")
for f in sorted(fonts)[:10]:
print(f" - {f}")
if rerun:
print(" rerun needed: yes (latexmk normally handles this; run it again or check for oscillating labels)")
problems = bool(errors or refs or cites or missing)
print(" status: " + ("PROBLEMS" if problems else "clean (warnings above are cosmetic)"))
return 1 if problems else 0
if __name__ == "__main__":
sys.exit(main())
About this skill
Written and maintained by the Claude Skills editors to the same editorial standard as every skill in the directory: a selective trigger, a real workflow, known pitfalls and a verification step. First published , last updated . MIT licensed.