latex-pdf — Professional LaTeX PDF Typesetting Guide
The goal is not "it compiles", but that a reader picks up the PDF and feels it is professional. Delivery is based on content and actual page appearance; a successful compilation only proves the compilation finished, not that visual acceptance can be bypassed.
Table of Contents
- Core Philosophy
- Engine Selection
- Compilation Strategy
- Readability Principles
- Workflow
- Common Pitfalls Quick Reference
Core Philosophy
Typesetting follows two inspection goals and does not depend on another skill to function.
① Typesetting serves reading — every typesetting decision answers "Does this help the reader understand better?" If removing a setting does not change the reading experience, it does not need to exist.
② Restraint equals professionalism — remove all visual elements that do not convey information. Decorative lines, shading, colored boxes — most should be deleted. Professional typesetting "looks effortless", while amateur typesetting often "looks like a lot of effort but is messy".
See readability-principles for a detailed mapping of principles.
Engine Selection
Choosing the wrong engine is the most common mistake, especially using pdflatex for Chinese content.
Has Chinese/Japanese/Korean?
├─ Yes → xelatex (+ ctex package)
│ (lualatex works too, but compiles slower)
└─ No → Need system fonts?
├─ Yes → xelatex or lualatex (+ fontspec)
└─ No → pdflatex (fastest, most compatible)
For new CJK documents, prefer XeLaTeX or LuaLaTeX and verify actual font support. Do not unnecessarily replace an existing working pdfLaTeX/CJK template; fandol is not suitable for ordinary pdfLaTeX paths.
| Engine | Advantages | Disadvantages | Use Cases |
|---|---|---|---|
pdflatex | Fastest, most stable, widest ecosystem | No native Unicode, cannot use system fonts | Pure English documents |
xelatex | Native Unicode, system fonts, CJK friendly | Slower | Default for Chinese documents |
lualatex | Most powerful font handling, can embed Lua | Slowest | Advanced typesetting needs |
Compilation Strategy
First, check source and execution boundaries
Before compilation, statically check the .tex, included .sty/.cls files, build configuration, and attachment paths. Watch for file read/write, external commands, and Lua execution capabilities. Static checks are not proof of safety. For untrusted projects, use an isolated environment that has no private files, no network, and restricted write, runtime, and resource limits; if no suitable isolation is available, stop compilation and report, do not try running in a personal environment.
Disable shell-escape by default; do not automatically enable it for minted or external graphics. Use latexmk with -norc to avoid automatically loading system, user, or project rc files; review other build scripts and external helper programs separately. Installation, network access for packages, or environment modification must be within existing authorization; if not covered, obtain approval first.
Use a suitable compilation chain
For existing projects, use the applicable build method; when multiple compilation passes and bibliography processing are needed, latexmk can be used. The examples below apply only to already-checked inputs and run in the allowed working directory:
# xelatex document (Chinese default)
latexmk -norc -xelatex -latexoption=-no-shell-escape -interaction=nonstopmode -halt-on-error main.tex
# pdflatex document
latexmk -norc -pdf -latexoption=-no-shell-escape -interaction=nonstopmode -halt-on-error main.tex
# Clean auxiliary files
latexmk -norc -c
Parameter Explanation:
-interaction=nonstopmode: Does not pause for input on errors (necessary for script environments)-halt-on-error: Stops at the first error, making it easier to locate problems
biber (bibliography)
When bibliographies are needed, check the biber/BibTeX that latexmk plans to call and the inputs, then allow execution after verification; do not treat automatic detection as additional permission to execute.
Readability Principles
Below is a summary of core principles; see readability-principles for detailed mappings and code examples.
Page geometry
Target 50-75 characters per line (66 is ideal; TeX default matches this closely).
\usepackage{geometry}
\geometry{a4paper, margin=2.5cm}
% Each Chinese character is approximately 2x the width of an English character; 35 Chinese chars/line ≈ 70 English chars/line
Tables
For regular data tables, prefer the booktabs style without vertical lines; if the user, journal, or institutional template requires a different format, preserve that specification:
\usepackage{booktabs}
\begin{tabular}{lrr}
\toprule
Metric & 2024 & 2025 \\
\midrule
Revenue & 120 & 150 \\
\bottomrule
\end{tabular}
booktabs is designed without vertical lines — adding them breaks the horizontal line spacing; this is not a bug, it's a feature.
Spacing system
Choose one paragraph separation method, do not mix:
% Option A: first-line indent (academic documents, ctex default)
\setlength{\parindent}{2em}
% Option B: paragraph spacing (technical documents, reports)
\setlength{\parindent}{0pt}
\setlength{\parskip}{0.5\baselineskip}
Fonts
Use serif fonts for body text (comfortable for reading) and monospaced fonts for code. For xelatex/lualatex, use fontspec to set system fonts:
\usepackage{fontspec}
\setmainfont{TeX Gyre Termes}[Ligatures=TeX]
\setmonofont{TeX Gyre Cursor}
microtype
An almost free quality improvement — character protrusion makes the body text more uniform:
\usepackage{microtype}
% Note: Under xelatex, only protrusion works (no font expansion), but it is still worth loading
Widows/Orphans
Prevent a single line of a paragraph from appearing alone at the page top or bottom:
\widowpenalty=10000
\clubpenalty=10000
Code highlighting
Use listings by default (no external dependencies). minted offers higher quality but requires Python + Pygments/latexminted:
\usepackage{listings}
\usepackage{xcolor}
\lstset{
basicstyle=\ttfamily\small,
keywordstyle=\color{blue!70!black},
commentstyle=\color{gray},
stringstyle=\color{green!50!black},
numbers=left,
numberstyle=\tiny\color{gray},
frame=none,
breaklines=true,
showstringspaces=false,
}
Workflow
For someone using this workflow for the first time.
Step 0: Environment check
Only check when local compilation is needed and existing tool information is insufficient. First read the detection script, confirm it calls trusted PATH programs and complies with existing permissions; it only reports, does not install or modify settings.
Resolve skill_root from the absolute parent directory of the SKILL.md actually read this time; do not assume the current working directory is the skill directory, then run:
bash "$skill_root/scripts/check_latex_env.sh"
Report missing components and detection failures separately. Only install dependencies that are actually required for the task and have been authorized; if not authorized, report the gap or existing alternatives. For detailed steps, read environment check guide as needed.
Step 1: Understand requirements
Confirm:
- Document type: Paper / Report / Resume / Slides / General
- Language: Chinese / English / Mixed
- Audience: Academic / Business / Technical / General
- Special needs: Bibliography / Code blocks / Math formulas / Data charts
Step 2: Engine selection
Use the engine selection decision tree above. Chinese → xelatex is the most common choice.
Step 3: Generate .tex
Apply the readability principles, following the standard loading order template in package-guide.
Step 4: Compile
latexmk -norc -xelatex -latexoption=-no-shell-escape -interaction=nonstopmode -halt-on-error main.tex
Step 5: Check log
Open main.log, search for Warning and Overfull/Underfull:
- Overfull hbox → Locate overflowing text, formulas, or column widths; check the actual page and fix locally; do not mask the issue with a global
\sloppy - Underfull hbox → Lines too loose, usually harmless
- Font shape warning → Font shape unavailable, check fontspec settings
- Undefined references → Need another compilation pass (latexmk should handle this automatically)
Fix warnings that affect delivery, such as missing glyphs, unresolved references, and visible overflow; for harmless warnings or those constrained by the template, explain the rationale; do not force all warnings to zero.
Step 6: Actual page inspection and delivery
Render or open the actual PDF, check page count, missing glyphs, cropping, tables/formulas/code, links, bookmarks, and relevant accessibility requirements; verify font embedding and selectable text as needed. After fixes, recompile and review affected pages. If rendering is not possible, explicitly mark "visual inspection not performed"; do not equate compilation success with page inspection acceptance.
Output the actually generated and verified files:
- PDF — final deliverable
- .tex source files and required local resources — retain reproducible entry point, actual commands, compilation results, and unverified items.
evals/evals.json is evaluation data, not run instructions; read it only when testing this skill itself.
Common Pitfalls Quick Reference
When encountering problems, consult by type:
| Problem Type | Reference File | Common Symptoms |
|---|---|---|
| Compilation errors | common-pitfalls §Top 10 Compilation Errors | Undefined control sequence, Missing $, hangs |
| Encoding/Characters | common-pitfalls §Encoding and Characters | Non-ASCII errors, smart quotes, Chinese punctuation spacing |
| Floats | common-pitfalls §Floats | Figures/tables move to end of document |
| Tables | common-pitfalls §Tables | Column width overflow, page breaks |
| Fonts | common-pitfalls §Fonts | System font not found, CJK not working |
| Package conflicts | package-guide §Package Conflict Matrix | Option clash, functional anomalies |
| Loading order | package-guide §Loading Order Rules | Bookmark corruption, broken links |
| Typesetting quality | readability-principles | Document looks "amateur" |
| Environment issues | environment-check | Command not found, permission errors |
| ctex fonts | environment-check §Common Environment Issues §6 | fontset 'fandol' is unavailable |
Quick Diagnosis Checklist
When compilation fails, troubleshoot in this order:
- ✅ Used the correct engine? (Chinese → xelatex)
- ✅ Used
latexmk? (Handles multi-pass compilation and biber automatically) - ✅ Used
-interaction=nonstopmode? (Won't get stuck in interactive mode) - ✅ Package loading order complies with the actual constraints of the current document class and packages? (Usually hyperref late, cleveref after)
- ✅ Every
\begin{...}has a matching\end{...}? - ✅ Every
{has a matching}? - ✅ Image paths correct? (
\graphicspathsets search paths) - ✅ All packages installed? (Check with
kpsewhich <pkg>.sty) - ✅ For Chinese documents, used ctex with the correct
fontset? - ✅ Check the end of the log — LaTeX error messages usually point to the actual problem line