Tectonic PDF generation
SkillDocs & knowledgeGenerate PDFs from LaTeX (.tex) or Markdown (.md) using Tectonic, a self-contained TeX engine. Use whenever the user wants a PDF, whether converting markdown, compiling existing LaTeX, writing a document from scratch (reports, resumes, letters, CVs), or live-rebuilding while the user edits. Trigger on words like "make a PDF", "convert to PDF", "render this markdown", "compile this tex", "latex", "tectonic", "typeset" — even when the tool is never named.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Tectonic PDF generation skill
What this skill tells your AI
The instructions your AI receives, as published by nmdra/dotfiles in .agents/skills/tectonic-pdf/SKILL.md and read by ahel’s review.
Tectonic is a self-contained XeTeX-based TeX engine installed at /usr/bin/tectonic (v0.17). Unlike a full TeX Live install, it downloads packages ("bundles") on demand to a per-user cache on first use, so the first compile of any document may take a minute while the bundle downloads; subsequent compiles take seconds. It runs multiple passes automatically (cross-references, TOC, bibtex-style reruns), so you never need to compile twice.
Tectonic cannot parse Markdown itself — it compiles (La)TeX only. Markdown must be converted to LaTeX first (see "Markdown → PDF" below).
Choose your workflow
| Input | Workflow |
|---|---|
.tex file(s) the user has | Compile directly (Workflow A) |
.md / markdown content | Convert to LaTeX, then compile (Workflow B) |
| No file — user describes a document | Write the LaTeX yourself (Workflow C) |
| User wants to keep editing / iterate | Add -X watch (Workflow D) |
Workflow A: Compile existing LaTeX
tectonic -X compile main.tex
Produces main.pdf next to main.tex. Useful flags:
--outdir DIR— put output elsewhere--keep-logs— keep the.logfile (invaluable for debugging, see Troubleshooting)--synctex— SyncTeX data for editor source-linking-p, --print— show the engine's chatter (warnings, overfull boxes)--reruns N— force extra engine passes
If the project uses multiple .tex files with \input/\include, compile the root file only — Tectonic resolves the includes automatically.
Workflow B: Markdown → PDF
- Convert the markdown to LaTeX (see conversion rules below).
- Compile with Workflow A.
If pandoc is installed, it is a faster path: pandoc input.md -o output.pdf --pdf-engine=tectonic. Check with which pandoc — on systems where it's absent (it is on this machine), do the conversion manually.
Never hand the markdown file to tectonic itself; it will fail.
Workflow C: Writing a document from scratch
For a single-file document, write a complete standalone .tex file. Minimal skeleton:
\documentclass[11pt]{article}
\usepackage[margin=1in]{geometry}
\usepackage{hyperref}
\title{...}
\author{...}
\begin{document}
\maketitle
...content...
\end{document}
For a multi-file project (or when the user wants a repeatable structure), scaffold a project:
tectonic -X new mydoc # creates mydoc/ with src/index.tex, src/_preamble.tex, src/_postamble.tex, Tectonic.toml
cd mydoc && tectonic -X build
Project output goes to build/default/default.pdf, NOT the project root — tell the user where it landed. Edit src/index.tex for content, src/_preamble.tex for the preamble. The template splits the document into preamble/content/postamble, so keep \documentclass and \begin{document} in the preamble file and \end{document} in the postamble.
Workflow D: Live rebuilding
cd mydoc && tectonic -X watch # rebuilds on every file change
tectonic -X watch -x "build --keep-logs" # custom build command via -x/--exec
Great when the user is iterating on a document. Tell them to leave it running.
Markdown → LaTeX conversion rules
Convert every markdown construct; don't leave any plain markdown syntax in the .tex.
| Markdown | LaTeX |
|---|---|
# H1 … ###### H6 | \section{...} … \subparagraph{...} (or \subsection etc. — use article's sectioning, skipping H1 if it's the title) |
**bold** | \textbf{...} |
*italic* / _italic_ | \textit{...} |
`code` | \texttt{...} |
Inline links [text](url) | \href{url}{text} (needs \usepackage{hyperref}) |
Images  | \includegraphics[width=\linewidth]{path} (needs \usepackage{graphicx}) |
Unordered lists - item / * item | \begin{itemize} \item ... \end{itemize} |
Ordered lists 1. item | \begin{enumerate} \item ... \end{enumerate} |
| Nested lists | Nested itemize/enumerate environments |
Fenced code blocks ```lang | \begin{lstlisting}[language=lang] ... \end{lstlisting} (needs \usepackage{listings}); or verbatim for no syntax highlighting |
| Tables | tabular or tabularx (needs \usepackage{tabularx} for wrapped columns) |
Blockquote > text | \begin{quote} ... \end{quote} |
Horizontal rule --- | \hrule or \noindent\rule{\linewidth}{0.4pt} |
Math $...$ / $$...$$ | Leave as-is — tectonic handles $...$ and \[...\] natively |
Pitfalls to watch for:
- Escape special characters:
% # & _ { } $(and~ ^ \where needed) must be escaped with a backslash in text, or the compile fails. The markdown source itself is the best place to catch these. Braces inside\texttt{...}count too:\texttt{\{"apiVersion": "v1", \ldots\}}. - Emoji do not render (❌ ✅ 👉 live outside Latin Modern's glyph set): replace them with plain words,
$\rightarrow$, or colored status text in the.tex(keep them in the.mdif it doubles as an Obsidian note). - Long inline
\texttt{...}strings overflow the line ("Overfull \hbox"): wrap the paragraph in\begin{sloppypar}...\end{sloppypar}. - Wrap long table cells: use
tabularxwith anXcolumn instead oftabular, or content overflows the page. - Page geometry: add
\usepackage[margin=1in]{geometry}so pages don't use TeX's cramped default margins. - Code blocks with
#or_: insidelstlisting, no escaping is needed — don't escape inside verbatim environments.
LaTeX writing guidance
- Engine is XeTeX: UTF-8/Unicode text works natively (em-dashes, accented letters, curly quotes, CJK with a suitable font via
fontspec). - Packages verified to work with the default bundle:
geometry,listings,tabularx,array,caption,hyperref,graphicx,xcolor,tcolorbox,titlesec,fancyhdr,tikz,float,parskip,sourceserifpro,sourcesanspro,sourcecodepro. Don't be shy about using them — Tectonic fetches them automatically. - Prefer
articleclass for reports/notes;letter/custom for letters;amsart/amsmathfor math-heavy docs. - Compile after every meaningful change so errors surface early and the user sees progress.
Visual design: O'Reilly-style boxes & color
Study notes and reports read much better with colored callout boxes and a consistent palette — the classic "O'Reilly book" look: a light box, colored left bar, and a small attached label tag (TIP / NOTE / WARNING / IMPORTANT / CLARIFICATION). Users ask for this as "tips and clarification boxes", "colored boxes", "like O'Reilly books" — treat those phrases as styling requests.
-
Fonts: O'Reilly's Thesis family (TheSerif/TheSans/TheSansMono) is commercial; the free analogues that compile in tectonic are Adobe's Source Serif Pro (body), Source Sans Pro (headings), Source Code Pro (code) —
\usepackage[default]{sourceserifpro}etc., with the[default]on the serif package only. Seereferences/oreilly-style.md(Fonts section) for the exact snippet. -
House style: practical rules from the official O'Reilly style guide (captions sentence-case without trailing period, italic emphasis, list punctuation, serial comma, code line length) are in
references/oreilly-house-style.md— apply them to study-note text when the user wants an "O'Reilly-like" document. -
Color maps to meaning: green = TIP, blue = NOTE, red = WARNING, orange = IMPORTANT, purple = CLARIFICATION (clarification boxes answer "why not just…?" questions). A teal primary + warm accent for headings is a safe palette.
-
tcolorboxneeds\tcbuselibrary{skins};xcolorneeds thetableoption (\usepackage[table]{xcolor}— plain xcolor has no\rowcolorsfor alternating table rows). Loadhyperreflast. -
Copy the exact working preamble from
references/oreilly-style.md— theattach boxed titledefinitions and the part-banner format are fiddly and were debugged once already; do not improvise them from memory. -
TikZ (
\usetikzlibrary{arrows.meta, positioning}) is in the bundle — draw stack/layer diagrams, handshakes, and box-and-arrow figures with it instead of ASCII art. Patterns live in the same reference file.
Images in the PDF
- XeTeX cannot include
.webp(or.gif) images directly — convert to PNG first:magick in.webp -resize "1600>" -background white -flatten out.png(flatten renders transparency on white; the resize keeps the PDF size sane). - Embed as
\begin{figure}[H] \centering \includegraphics[width=0.8\linewidth]{...} \caption{...} \end{figure}— thefloatpackage's[H]keeps figures where the text references them. - Caption from what the image actually shows: look at the image (vision pass) before writing the caption; never invent captions for images you have not seen.
- Escape underscores in filenames inside captions:
\texttt{authorized\_keys}.
Visual QA before delivery
A compile that succeeds can still ship broken pages. Before declaring done:
pdfinfo <input>.pdf | grep Pages— sanity-check the page count.grep "^!" <input>.logandgrep "Overfull" <input>.log— zero errors; overfull boxes are fixable cosmetics.- Render sampled pages (
pdftoppm -png -r 60 -f N -l N <input>.pdf /tmp/pg) and inspect them with a vision pass: title page, one figure-heavy page, one box-heavy page. - Cross-check any suspicious text with
pdftotext— vision reads of small print misreport (a 60-dpi read of "Symmetric Key Exchange" once came back as "Diffie-Hellman Key Exchange"); the extracted text is ground truth. - After a font swap,
pdffonts <input>.pdf— every family you loaded must appear in the list (plus math fonts).
Troubleshooting
! Undefined control sequence.at\rowcolors— xcolor needs thetableoption (see Visual design).- Boxes split across a page boundary — tcolorbox
breakablelets a box break mid-content across pages, which reads as a broken layout. Dropbreakableso boxes are atomic: one that does not fit moves whole to the next page (the default LaTeX behavior, same as floats). Add\raggedbottomso leftover space collects at the page bottom instead of stretching gaps. Tables withtable[H]never split; longlstlistingblocks can — wrap them in aminipageif one lands on a break. ! LaTeX Error: Missing \begin{document}pointing at a\titleformat{\part}[display]line — the optional trailing[after-code]argument executes in the preamble and breaks the build; drop it (keep the top rule in the before-code) and use\vskip(not\vspace) inside\titleformatarguments.- Overfull
\hboxwarnings — long inline\texttt{...}: wrap the paragraph insloppypar(see Markdown→LaTeX pitfalls); hairline overfulls after a font swap:\emergencystretch=2em(see Fonts inreferences/oreilly-style.md). [default]on\usepackage{sourcesanspro}makes the whole document sans — put[default]on the serif package only (Fonts section ofreferences/oreilly-style.md).- Fonts don't embed (or whole PDF falls back to one family) — after a font swap,
pdffontsmust list every family you loaded (see Visual QA step 5 and the Fonts section ofreferences/oreilly-style.md). - "the XeTeX engine had an unrecoverable error" — this opaque message is the engine halting; the real cause is in the log. Recompile with
--keep-logs, then read<input>.logand search for the first line starting with!(e.g.! Undefined control sequence.) plus the surrounding context — it shows the offending line. Fix that and recompile. - First run is slow / downloads — normal; Tectonic downloads
tlextrasetc. once.-C, --only-cacheduses only cached resources (useful offline). - Wrong output location — single-file compile puts the PDF next to the input; project builds put it in
build/default/. Check both before telling the user nothing was produced. - Warnings are normal — overfull
\hboxwarnings, undefined-reference warnings on the first pass are cosmetic. Onlyerror:lines matter. - Verify the PDF exists (
ls -la *.pdf) after compiling, and open it withxdg-open/openif the user wants a preview.
Signals
- GitHub stars
- 27
- Forks
- 1
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
tectonic-pdf- Source
- github.com/nmdra/dotfiles