7 \(\LaTeX\)
Motivation and Scope
- Say words about Section 7.4.4 for the seasoned users
- Also advertise Section 7.5
WYSISWG (or not)
- Microsoft Word, Google Docs, or Notion
- Problematic at scale—issues with complexity and technical content
- Philosophy of a markup language (plaintext plays nicely with git)
- Focus on content, not layout
- Math as code; compiled document
- Precision, consistency, portability
Mathematical Writing
Another important domain of hidden curriculum, which recieves only cursory mention throughout this book, is the skill of writing mathematics. This would require a whole other book unto itself. For now, we refer the reader to many wonderful articles written by thoughtful mathematicians, e.g., “A Guide to Writing Mathematics” and the much more exhaustive A Primer of Mathematical Writing (Krantz 2017).
Core Concepts
Separation of Content and Presentation
“Not making enough use—or (sadly all too frequently) not making hardly any use—of the opportunities afforded by LaTeX to separate the content of a document from its visual appearance. In particular, too many attempts to engage in visual formatting at early to intermediate stages of writing a working paper, a technical note, or whatever.”
— Mico, “What are the most common mistakes that beginners of (La)TeX and Friends make?”
- The fundamental philosophy
- You write the logic, the compiler designs the page).
The Ecosystem
- Distributions (TeX Live)
- Engines (pdflatex)
- Packages (
amsmath)
The Compiler Pipeline
- Multiple passes
Getting Started
We begin by mentioning Overleaf, which is a fantastic and popular online \(\LaTeX\) editor that enjoys a growing number of features (including collaborative editing) and a free account tier. Consistent with the posture of this guide, we avoid recommending cloud-based tools: a mathematician who does all their work on Overleaf risks losing decades of material if they are locked out of their account. Instead, this tutorial makes use of the tools we have already established, which run locally on your machine. Remember that one of the great advantages of \(\TeX\) and its derivatives, as mark-up languages stored in plaintext, is their boundless portability. Tools that we have already mentioned, such as Git (Chapter 4), provide a robust alternative for collaboration and versioning.
Setup
As a reminder, you should never edit \(\LaTeX\) files (.tex, .bib, etc.) with a word processor. This section is written with VSCode as the default editor in mind, as discussed in Chapter 5, and assumes use of one of the package managers described in Chapter 3 accessed via a terminal emulator (see Chapter 2).
Installation
You can install TeX Live with one of the following CLI commands:
macOS:
brew install --cask mactex-no-guiWe can instead use brew install --cask mactex to include an alternative GUI.
- Ubuntu:
sudo apt install texlive-full- Arch Linux:
sudo pacman -Syu texlive-metaYou can also run tex --version to confirm that you are up to date.
Manual Compilation
Next, we need a simple file to test our compilers:
If we save this as main.tex and navigate to the enclosing directory in a terminal (see Section 2.3.1 if you need a refresher), then we can compile the document using the command: pdflatex main.tex. This will produce a rather boring file called main.pdf, as per our code, in the same directory.
There are several ways to improve this state of affairs. Firstly, for more complex projects, \(\LaTeX\) requires multiple runs (“compilation passes”) because of how it proccesses documents and auxiliary files. If we want cross-references, labels, lists, tags, bibiographies, page numbers, and so on—and we do!—then we’ll need to run the previous command (and others) many times. Applications like Latexmk and IDEs like TeXshop and Overleaf automatically detect these warnings and run the compiler as many times as necessary, until the document converges. So, we can already improve on the above command by instead running latexmk --pdf main.tex.
IDE Extension
Next we’ll set up LaTeX Workshop for VS Code, which is found by clicking on the Extensions tab (or ⇧⌘X on macOS and Shift+Ctrl+X on Linux/Windows). Once configured, we can simply click Build to compile a project (without needing to recall CLI commands). Indeed, the default behavior1 is for Save (⌘S on macOS, Ctrl+S on Linux/Windows) to trigger an auto build using the default (first) recipe.
Now, there are numerous \(\LaTeX\) engines we can use to generate documents. Here we will focus on LuaLaTeX—which uses Unicode (UTF-8) natively and supports OpenType/TrueType fonts, but is slower—given some of our goals to come later in the chapter. With some compilers, we can use directives to indicate the engine we want, like this:
main.tex
The emoji package will not work with the default compiler (pdfLaTeX) but, by including the % !TEX program = lualatex directive, we instruct LaTeX Workshop’s Latexmk-based recipe to switch engines when compiling the document. Try the following:
- Open your
main.texwith VS Code - Update it to match the file above
- Open VS Code’s Panel (⌘J on macOS, Ctrl+J on Linux/Windows) and ensure LaTeX Compiler is selected (this is optional—just so you can see what the recipe is doing!)
- Save the file, triggering an auto-build
- Drag the resulting
main.pdfinto VS Code to create a split view - Replace
cowboy-hat-facewithmushroom, then save again to see the live update!
Taking this further, we can change the default recipe so that all our documents compile using LuaLaTeX, even without the aforementioned directives, in the Settings (recall Section 5.3.3):
settings.json
{
// previous settings go here
"latex-workshop.latex.recipe.default": "latexmk (lualatex)"
}Ignoring Auxiliary Files
When you compile a \(\LaTeX\) document, a number of auxiliary files (ending in .aux, .log, and so on) will also be generated. These arise because of the multi-pass nature of the compilation: the purpose of these files is to keep track of equations and labels in your document, so it can number them correctly on the next pass. These files are not a sign that you’ve done something wrong, but we should avoid committing them to version control. The resulting PDFs, being binary files, are also inappropriate to commit!
Let’s teach Git to ignore them:
Anatomy of a Document
Preamble and Body
Writing Mathematics
Diagrams
SyncTeX
To write: One of the most magical moments is realizing the PDF and the code are linked. Something like: “LaTeX Workshop can use the
*.synctex.gzfile to navigate instantly between the PDF and underlying code. If weCmd/Ctrl + Clickon a paragraph in the PDF, the cursor will jump to the corresponding line of code in our.texfile. When the document grows to 50 pages, this feature is extremely valuable!”
Debugging
All the above is fine when we have nice, correctly formatted \(\LaTeX\), but things become more difficult during the messy process of writing something new (a homework assignment, a paper, and so on). Below are three block of code, each of which suffers from an error that will prevent compilation.
Try running each of these by pasting them over the contents of your main.tex file and saving. We can see detailed error reports in the Output field of VS Code’s Panel, but the Problems tab gives a much more readable summary of what has gone wrong.
main.tex
Problems (click to expand)
Missing } inserted. LaTeX [Ln 5, Col 1]e^{i \pi}.
main.tex
Problems (click to expand)
Missing $ inserted. LaTeX [Ln 5, Col 1]
Missing $ inserted. LaTeX [Ln 6, Col 1]main.tex
Problems (click to expand)
Undefined control sequence. LaTeX [Ln 5, Col 18]\coloneqq (which renders as \(\coloneqq\), meaning “the left hand side is defined as the right hand side”), we need to include a package like mathtools!
Note that, in all cases, LaTeX Workshop attempts to provide an approximate location (in terms of line and column numbers) of the offending error. In general, it is advisable to always start correcting errors from the top down, since something as simple as a misplaed bracket may cause cascading error flags in otherwise functional code.
Some IDEs, like Overleaf, will attempt to produce PDF outputs even if your code has important errors, which can lead to the bad practice of ignoring flags that might be contributing to underlying problems which are difficult to percieve from only the output PDF. Just because the document compiles does not mean the code is semantically correct!
Should we say more?
Best Practices
Semantic vs Visual Formatting
Coming soon
Semantic Mathematics
Coming soon (make sure to talk about DeclareMathOperator)
Don’t Repeat Yourself
Coming soon
- Include that nifty collaboration macro everyone loves
Accessibility
You can confirm that your favorite packages are compatible with the LaTeX Tagging Project by checking the tagging status list.
Sample Document
Explain this!
example.tex
% ======================================================================
% PDF ACCESSIBILITY/TAGGING (Must come before \documentclass)
% ======================================================================
% This block enables the LaTeX tagging project, embedding a hidden
% structural tree so screen readers understand what is text, math, etc.
% This also declares PDF/UA accessibility compliance and the language.
\DocumentMetadata{
testphase={phase-III, math, table, list}, % Structural tagging
pdfversion=1.7, % Requires a modern format
pdfstandard=ua-1, % Marks as UA-1 compliant
lang=en-US % Records the language
}
\documentclass[11pt, letterpaper]{article}
% ======================================================================
% DOCUMENT CONFIGURATION (Helps with reusing templates)
% ======================================================================
\newcommand{\coursename}{Math 232}
\newcommand{\assignmentnumber}{2}
\newcommand{\myname}{Claudio Gómez-Gonzáles}
% ======================================================================
% CORE MATH & TYPESETTING PACKAGES
% ======================================================================
\usepackage{amsmath, amssymb, amsthm}
\usepackage{mathtools} % Should come before unicode-math!
\usepackage{unicode-math}
\usepackage{emoji}
% ======================================================================
% HYPERLINKS & DOCUMENT METADATA
% ======================================================================
% Makes references clickable, sets the PDF file's title/author metadata,
% and improves navigation in PDF readers.
\usepackage[
colorlinks=true,
linkcolor=red,
urlcolor=blue,
pdftitle={\coursename: Homework \assignmentnumber},
pdfauthor={\myname},
pdfdisplaydoctitle=true % Forces PDF readers to display the title
]{hyperref}
% cleveref enhances cross-referencing features, determining types
\usepackage[capitalize, nameinlink]{cleveref}
% ======================================================================
% ENVIRONMENTS & MACROS
% ======================================================================
\theoremstyle{definition} % Sets a global (non-italic) style
% Creates a "Theorem" environment type, then also a "Definition" type
% with a shared counter. We also create an independent "Problem" type.
\newtheorem{theorem}{Theorem}
\newtheorem{definition}[theorem]{Definition}
\newtheorem{problem}{Problem}
% Custom macros for commonly-used expressions
\newcommand{\Rb}{\mathbb{R}}
\DeclareMathOperator{\Span}{span}
\DeclareMathOperator{\Img}{img}
% ======================================================================
% DOCUMENT CONTENT
% ======================================================================
\title{\coursename: Homework \assignmentnumber}
\author{\myname}
\date{\today}
\begin{document}
\maketitle
\section*{Kernels}
\begin{problem}
Let $V$ and $W$ be vector spaces, and let $T: V \to W$ be a linear transformation.
Prove that $\ker(T)$ is a subspace of $V$.
\end{problem}
\begin{proof}
Let $v_1, v_2 \in \ker(T)$ and $a, b \in \Rb$.
We will show $a v_1 + b v_2 \in \ker(T)$.
By the definition of kernel, we know $T(v_1) = 0$ and $T(v_2) = 0$.
We compute:
\begin{align}
T(a v_1 + b v_2) &= T(a v_1) + T(b v_2) \label{eq:additivity} \\
&= a T(v_1) + b T(v_2) \label{eq:homogeneity} \\
&= 0 \nonumber,
\end{align}
where \cref{eq:additivity} uses additivity and \cref{eq:homogeneity} uses homogeneity of $T$.
Therefore, by definition, we see that $a v_1 + b v_2 \in \ker(T).$
% Add some personal flair, instead of that boring old tombstone
\renewcommand{\qedsymbol}{\emoji{cowboy-hat-face}}
\end{proof}
\end{document}verapdf
Write this! What do we need to say?
verapdf --format html --flavour ua1 main.pdf > main.html
A Working Project
We conclude by constructing a working project for a course (Math 236) that allows us to adhere to the principle of separating content and formatting, while also establishing a course-wide environment that prevents us from having to define macros or stylistic choices on the fly. Along the way, we’ll integrate what we’ve learned about implementing accessibility best practices! The directory structure will be as follows:
math236/
├── main.tex
├── macros.tex
├── homework.sty
├── content/
│ ├── hw0.tex
│ ├── hw1.tex
│ ├── hw2.tex
│ └── ...
├── README.md
├── .gitignore
└── .git/After creating (recall Section 2.3.2) the directory itself and the content/ subdirectory, you can initialize the git repository (Section 4.3.2), configure the .gitignore as in Section 7.3.1.4, and prepare the first few files:
homework.sty
\ProvidesPackage{homework}[2026/04/13 Homework Style]
\RequirePackage{amsmath, amsthm}
\RequirePackage{mathtools}
\RequirePackage{unicode-math}
\RequirePackage{emoji}
\RequirePackage{geometry}
\geometry{margin=1in}
\RequirePackage[
colorlinks=true,
linkcolor=red,
urlcolor=blue
]{hyperref}
\RequirePackage[capitalize, nameinlink]{cleveref}
\theoremstyle{definition}
\newtheorem{problem}{Problem}
\newtheorem*{solution}{Solution} % Solutions are unnumberedmacros.tex
% blackboard Letters
\newcommand{\Ab}{\mathbb{A}}
\newcommand{\Cb}{\mathbb{C}}
\newcommand{\Nb}{\mathbb{N}}
\newcommand{\Qb}{\mathbb{Q}}
\newcommand{\Rb}{\mathbb{R}}
\newcommand{\Zb}{\mathbb{Z}}
% functions
\DeclareMathOperator{\id}{I}
\newcommand{\into}{\hookrightarrow}
\newcommand{\onto}{\twoheadrightarrow}
\newcommand{\bijectto}{\xrightarrow{\sim}}
% linear algebra
\DeclareMathOperator{\Mat}{Mat}
% number theory
\DeclareMathOperator{\lcm}{lcm}main.tex
\DocumentMetadata{
testphase={phase-III, math, table, list},
pdfversion=1.7,
pdfstandard=ua-1,
lang=en-US
}
\documentclass[11pt, letterpaper]{article}
\newcommand{\assignmentnumber}{0} % determines what content we compile
\newcommand{\coursename}{Math 236}
\newcommand{\myname}{Xóchitl}
\usepackage{homework}
\input{macros}
\hypersetup{
pdftitle={\coursename: Homework \assignmentnumber},
pdfauthor={\myname},
pdfdisplaydoctitle=true
}
\title{\coursename: Homework \assignmentnumber}
\author{\myname}
\date{\today}
\begin{document}
\maketitle
% automatically load correct file
\input{content/hw\assignmentnumber}
\end{document}Look through these files carefully, being attentive to the few comments which indicate its use!
From here, all we need to do is open the entire project in VS Code, create hw0.tex, and start doing our Homework! Try compiling the following:
hw0.tex
\begin{problem}\label{exr:bezout-calculation}
Compute $d \coloneqq \gcd(42,30)$, then express $d = 42x + 30y$ for $x, y \in \Zb$.
\end{problem}
\begin{solution}
First we employ the Euclidean algorithm:
\[
42 = 1 \cdot 30 + 12, \quad
30 = 2 \cdot 12 + 6, \quad \text{and} \quad
12 = 2 \cdot 6.
\]
Now we back-substitute to express $6$ as a linear combination of $42$ and $30$.
From the second equation:
\[ 6 = 30 - 2 \cdot 12. \]
From the first equation, solve for $12$:
\[ 12 = 42 - 1 \cdot 30. \]
Substitute this expression for $12$ into the equation for $6$:
\begin{align*}
6 & = 30 - 2 \cdot (42 - 1 \cdot 30) \\
& = 30 - 2 \cdot 42 + 2 \cdot 30 \\
& = (-2) \cdot 42 + 3 \cdot 30.
\end{align*}
\end{solution}
\begin{problem}
Show that, for any $n \geq 12$, there is some $a, b \in \Nb$ such that $n = 4a + 5b$.
\end{problem}
\begin{proof}
For given $n$, we write $P(n)$ for the desired statement.
Unlike \cref{exr:bezout-calculation}, we proceed by strong induction rather than B\'ezout's identity.
We employ four base cases:
\[
12 = 4 \cdot 3 + 5 \cdot 0, \quad
13 = 4 \cdot 2 + 5 \cdot 1, \quad
14 = 4 \cdot 1 + 5 \cdot 2, \quad \text{and} \quad
15 = 4 \cdot 0 + 5 \cdot 3.
\]
For the inductive step, we note that if $n = 4a+5b$, then $n+4 = 4(a+1) + 5b$, and so
\[ P(n) \implies P(n+4). \]
Therefore, our base cases give rise to $P(n)$ for all $n \geq 12$.
\end{proof}FINISH
We can confirm this under the Extension settings:
"latex-workshop.latex.autoBuild.run": "onFileChange"means that an auto build is triggered each time time we Save (or an outside program edits the file).↩︎