7  \(\LaTeX\)

Motivation and Scope

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-gui

We can instead use brew install --cask mactex to include an alternative GUI.

  • Ubuntu:
sudo apt install texlive-full
  • Arch Linux:
sudo pacman -Syu texlive-meta

You 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:

\documentclass{article}

\begin{document}
Hello, world!
\end{document}

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
% !TEX program = lualatex
\documentclass{article}
\usepackage{emoji}

\begin{document}
Hello, world! \emoji{cowboy-hat-face} 
\end{document}

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.tex with 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.pdf into VS Code to create a split view
  • Replace cowboy-hat-face with mushroom, 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:

.gitignore
# LaTeX output
*.pdf

# LaTeX temporary files
*.aux
*.bbl
*.blg
*.log
*.out
*.synctex.gz

# LuaLaTeX temporary files
*.fdb_latexmk
*luamml-mathml.html

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.gz file to navigate instantly between the PDF and underlying code. If we Cmd/Ctrl + Click on a paragraph in the PDF, the cursor will jump to the corresponding line of code in our .tex file. 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
\documentclass{article}

\begin{document}
The most beautiful equation is $e^{i \pi + 1 = 0$.
\end{document}
Problems (click to expand)
Missing } inserted. LaTeX [Ln 5, Col 1]
We forgot to close our brackets in the superscript! The code should read e^{i \pi}.
main.tex
\documentclass{article}

\begin{document}
There are two distinct square roots of every positive real, 
by which we mean that x^2 = r has two solutions whenever r > 0.
\end{document}
Problems (click to expand)
Missing $ inserted. LaTeX [Ln 5, Col 1]
Missing $ inserted. LaTeX [Ln 6, Col 1]
The superscript \(x^2\) can only be rendered in math mode! This example is particularly important, because the compiler missed another error: we forgot to use $ delimiters around “\(r > 0\)”, which would have caused it to render as simply “r > 0”.
main.tex
\documentclass{article}

\begin{document}
Let $f: X \to Y$ and fix $y \in Y$. We set 
\[ f^{-1}(\{y\}) \coloneqq \{ x \in X \mid f(x) = y \}, \]
which is called the \emph{fiber} of $f$ over $y$.
\end{document}
Problems (click to expand)
Undefined control sequence. LaTeX [Ln 5, Col 18]
This error is harder to diagnose: to use \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.

Warning

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 unnumbered
macros.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


  1. 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).↩︎