Setting the stage
Picture it. You’re finally in that type of course that allows you to put whatever you want on your cheatsheet for the exam, no requirement to have handwritten it on your tablet or (god forbid) using a physical pen on a physical piece of paper, just free reign to type all of it up and copy-paste images to your heart’s content. As an engineering student, such a scenario appears rarely, but when it does, it is oh-so-sweet.
Except… when the opportunity does arise, it’s usually for a course where the lecture content rivals some textbooks in just the sheer amount of concepts covered (typically 1k+ slides over the course of a semester, with each slide as dense and filled to the brim with testable content as any other). Which leads to the question: what’s the best way of writing out everything you can reasonably put down on a single sheet of paper (double-sided, of course)?
The answer is surprisingly simple. But to get there, there’s 3 things we need to consider: the medium (how to write your cheatsheet), the message (what to write on it), and the machine (how to print it such that everything remains readable).
Oh, and if you’re looking to take a peek at what exactly we’re going to learn how to make, well, here’s an example in it’s full glory:
![Full page view of cheatsheet](/_astro/01-fullpage.DkN8IckZ_Z27Jh3q.webp)
![Zoomed in view of cheatsheet](/_astro/01-zoomed.BcxBZ4XA_Z97qM2.webp)
Alas, putting together a behemoth of a cheatsheet like this one takes a while. It’s an intricate process that involves making a number of decisions, the first of which is selecting the best tool for the job.
The Medium
Picking the tool of choice for writing your cheatsheet.
This really just boils down to picking one of two choices: taking a WYSIWYG editor approach (word processors the likes of Microsoft Word and Google Docs) or a programmatic approach using a typesetting engine (normally one would just use LaTeX, but the newcomer Typst engine shows a lot of promise and as we’ll see later on, is a hidden gem for making all the granular changes needed for a cheatsheet).
There are some third-party alternatives like Cribr and a handful of side projects posted on Github, but they lack the fine-grained customizability that is sorely needed for making your cheatsheet pixel-perfect (including setting fractional font sizes, word and line spacing, character kerning, and most notably image placement).
The cream of the crop is Typst, and here’s why you should be using it instead of some of the other options at your disposal.
Google Docs/Microsoft Word
I’ve successfully used Google Docs to make a slightly but not that dense cheatsheet for an operating systems course in the past (which, as any computer science or engineering student can tell you, has oodles of terminology and concepts that you need to remember), and while it was decent to some degree, it’s lacking in a lot of ways (almost all of which are remedied by Typst). Here’s just a few of why you shouldn’t be using Google Docs for your cheatsheet:
- It gets real slow when word count gets real high, especially in Google Docs.
- Zooming in/out to parse through really small text is a hassle, especially when it comes to finding specific words or phrases amongst an ocean of text.
- Making document-wide changes to text formatting (like changing the highlight colour of all bolded text) is at best a finnicky modification of document styles and at worst a completely manual endeavour involving lots of copy-pasting (and trust me, trying to use the format painter with paragraphs of teeny-tiny text without accidentally modifying anything you don’t want to modify is a lesson in pure frustration).
- It’s really hard to plan out how to organize content (tables would be the ideal way of grouping text together, if they weren’t so finicky to adjust), and moving content from one place to another requires so much reshuffling that it makes you question whether the whole thing is even worth it in the first place (and it is, just not if you’re doing in Google Docs).
- Adding, updating, and removing images is an exercise in frustration and a reminder of how true to life that one meme is (about Word spazzing out your delicately edited formatting for the entire document when you slightly move an image by 1 mm).
So the WYSIWYG editor approach just isn’t going to cut it for making all the small changes you’re going to need to make for your awe-inspiring cheatsheet. Which leads us to the programmatic approach, and the obvious choice, LaTeX.
LaTeX
Look, I love LaTeX as much as the next guy, but there’s a couple of key pain points with LaTeX that make it suboptimal compared to Typst. Specifically…
- It’s slow to render when there’s a whole lot of text (and frustratingly, will need to render the entire document even if all you do is change a single word).
- Anything and everything requires a metric ton of boilerplate syntax (typing out backslashes and curly brackets is the last thing I want to do 1k words in).
- It’s practically impossible for the layperson to reasonably extend LaTeX code beyond something simple like shorthand functions for formatting text (which is most people just use templates built by people who’ve spent a lot of time on them).
On that last point, I took a quick search on Github1 for any LaTeX cheatsheet templates that might be a suitable starting point for something more complex. And… yeah, while it might pass for a cheatsheet for Vim commands, it’s wholly inadequate for dealing with the sheer amount of content in your average university course, and is really a microcosm of the whole boilerplate and limited (practical) extensibility issues surrounding the use of LaTeX for making a cheatsheet. I mean, just look at that code 😔.
A decent-looking LaTeX cheatsheet, albeit one that isn’t necessarily the best use of space and is an absolute *pain* to edit in LaTeX.
![Front page: sample LaTeX cheatsheet](/_astro/latexsheet-0.C071EJcj_1BaB5P.webp)
![Back page: sample LaTeX cheatsheet](/_astro/latexsheet-1.rOReMirB_ZdAeUs.webp)
Source: https://wch.github.io/latexsheet
112 collapsed lines
\documentclass[10pt,landscape]{article}\usepackage{multicol}\usepackage{calc}\usepackage{ifthen}\usepackage[landscape]{geometry}\usepackage{hyperref}
% To make this come out properly in landscape mode, do one of the following% 1.% pdflatex latexsheet.tex%% 2.% latex latexsheet.tex% dvips -P pdf -t landscape latexsheet.dvi% ps2pdf latexsheet.ps
% If you're reading this, be prepared for confusion. Making this was% a learning experience for me, and it shows. Much of the placement% was hacked in; if you make it better, let me know...
% 2008-04% Changed page margin code to use the geometry package. Also added code for% conditional page margins, depending on paper size. Thanks to Uwe Ziegenhagen% for the suggestions.
% 2006-08% Made changes based on suggestions from Gene Cooperman. <gene at ccs.neu.edu>
% To Do:% \listoffigures \listoftables% \setcounter{secnumdepth}{0}
% This sets page margins to .5 inch if using letter paper, and to 1cm% if using A4 paper. (This probably isn't strictly necessary.)% If using another size paper, use default 1cm margins.\ifthenelse{\lengthtest { \paperwidth = 11in}} { \geometry{top=.5in,left=.5in,right=.5in,bottom=.5in} } {\ifthenelse{ \lengthtest{ \paperwidth = 297mm}} {\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} } {\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} } }
% Turn off header and footer\pagestyle{empty}
% Redefine section commands to use less space\makeatletter\renewcommand{\section}{\@startsection{section}{1}{0mm}% {-1ex plus -.5ex minus -.2ex}% {0.5ex plus .2ex}%x {\normalfont\large\bfseries}}\renewcommand{\subsection}{\@startsection{subsection}{2}{0mm}% {-1explus -.5ex minus -.2ex}% {0.5ex plus .2ex}% {\normalfont\normalsize\bfseries}}\renewcommand{\subsubsection}{\@startsection{subsubsection}{3}{0mm}% {-1ex plus -.5ex minus -.2ex}% {1ex plus .2ex}% {\normalfont\small\bfseries}}\makeatother
% Define BibTeX command\def\BibTeX{{\rm B\kern-.05em{\sc i\kern-.025em b}\kern-.08em T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}}
% Don't print section numbers\setcounter{secnumdepth}{0}
\setlength{\parindent}{0pt}\setlength{\parskip}{0pt plus 0.5ex}
% -----------------------------------------------------------------------
\begin{document}
\raggedright\footnotesize\begin{multicols}{3}
% multicol parameters% These lengths are set only within the two main columns%\setlength{\columnseprule}{0.25pt}\setlength{\premulticols}{1pt}\setlength{\postmulticols}{1pt}\setlength{\multicolsep}{1pt}\setlength{\columnsep}{2pt}
\begin{center} \Large{\textbf{\LaTeXe\ Cheat Sheet}} \\\end{center}
\section{Document classes}\begin{tabular}{@{}ll@{}}\verb!book! & Default is two-sided. \\\verb!report! & No \verb!\part! divisions. \\\verb!article! & No \verb!\part! or \verb!\chapter! divisions. \\\verb!letter! & Letter (?). \\\verb!slides! & Large sans-serif font.\end{tabular}
Used at the very beginning of a document:\verb!\documentclass{!\textit{class}\verb!}!. Use\verb!\begin{document}! to start contents and \verb!\end{document}! toend the document.
\subsection{Common \texttt{documentclass} options}\newlength{\MyLen}\settowidth{\MyLen}{\texttt{letterpaper}/\texttt{a4paper} \ }\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}\texttt{10pt}/\texttt{11pt}/\texttt{12pt} & Font size. \\\texttt{letterpaper}/\texttt{a4paper} & Paper size. \\\texttt{twocolumn} & Use two columns. \\\texttt{twoside} & Set margins for two-sided. \\\texttt{landscape} & Landscape orientation. Must use \texttt{dvips -t landscape}. \\\texttt{draft} & Double-space lines.\end{tabular}
Usage:\verb!\documentclass[!\textit{opt,opt}\verb!]{!\textit{class}\verb!}!.
\subsection{Packages}\settowidth{\MyLen}{\texttt{multicol} }\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}%\begin{tabular}{@{}ll@{}}\texttt{fullpage} & Use 1 inch margins. \\\texttt{anysize} & Set margins: \verb!\marginsize{!\textit{l}% \verb!}{!\textit{r}\verb!}{!\textit{t}% \verb!}{!\textit{b}\verb!}!. \\\texttt{multicol} & Use $n$ columns: \verb!\begin{multicols}{!$n$\verb!}!. \\\texttt{latexsym} & Use \LaTeX\ symbol font. \\\texttt{graphicx} & Show image: \verb!\includegraphics[width=!% \textit{x}\verb!]{!% \textit{file}\verb!}!. \\\texttt{url} & Insert URL: \verb!\url{!% \textit{http://\ldots}% \verb!}!.\end{tabular}
Use before \verb!\begin{document}!.Usage: \verb!\usepackage{!\textit{package}\verb!}!
598 collapsed lines
\subsection{Title}\settowidth{\MyLen}{\texttt{.author.text.} }\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}\verb!\author{!\textit{text}\verb!}! & Author of document. \\\verb!\title{!\textit{text}\verb!}! & Title of document. \\\verb!\date{!\textit{text}\verb!}! & Date. \\\end{tabular}
These commands go before \verb!\begin{document}!. The declaration\verb!\maketitle! goes at the top of the document.
\subsection{Miscellaneous}\settowidth{\MyLen}{\texttt{.pagestyle.empty.} }\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}\verb!\pagestyle{empty}! & Empty header, footer and no page numbers. \\\verb!\tableofcontents! & Add a table of contents here. \\
\end{tabular}
\section{Document structure}\begin{multicols}{2}\verb!\part{!\textit{title}\verb!}! \\\verb!\chapter{!\textit{title}\verb!}! \\\verb!\section{!\textit{title}\verb!}! \\\verb!\subsection{!\textit{title}\verb!}! \\\verb!\subsubsection{!\textit{title}\verb!}! \\\verb!\paragraph{!\textit{title}\verb!}! \\\verb!\subparagraph{!\textit{title}\verb!}!\end{multicols}{\raggedrightUse \verb!\setcounter{secnumdepth}{!$x$\verb!}! suppresses headingnumbers of depth $>x$, where \verb!chapter! has depth 0.Use a \texttt{*}, as in \verb!\section*{!\textit{title}\verb!}!,to not number a particular item---these items will also not appearin the table of contents.}
\subsection{Text environments}\settowidth{\MyLen}{\texttt{.begin.quotation.}}\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}\verb!\begin{comment}! & Comment (not printed). Requires \texttt{verbatim} package. \\\verb!\begin{quote}! & Indented quotation block. \\\verb!\begin{quotation}! & Like \texttt{quote} with indented paragraphs. \\\verb!\begin{verse}! & Quotation block for verse.\end{tabular}
\subsection{Lists}\settowidth{\MyLen}{\texttt{.begin.description.}}\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}\verb!\begin{enumerate}! & Numbered list. \\\verb!\begin{itemize}! & Bulleted list. \\\verb!\begin{description}! & Description list. \\\verb!\item! \textit{text} & Add an item. \\\verb!\item[!\textit{x}\verb!]! \textit{text} & Use \textit{x} instead of normal bullet or number. Required for descriptions. \\\end{tabular}
\subsection{References}\settowidth{\MyLen}{\texttt{.pageref.marker..}}\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}\verb!\label{!\textit{marker}\verb!}! & Set a marker for cross-reference, often of the form \verb!\label{sec:item}!. \\\verb!\ref{!\textit{marker}\verb!}! & Give section/body number of marker. \\\verb!\pageref{!\textit{marker}\verb!}! & Give page number of marker. \\\verb!\footnote{!\textit{text}\verb!}! & Print footnote at bottom of page. \\\end{tabular}
\subsection{Floating bodies}\settowidth{\MyLen}{\texttt{.begin.equation..place.}}\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}\verb!\begin{table}[!\textit{place}\verb!]! & Add numbered table. \\\verb!\begin{figure}[!\textit{place}\verb!]! & Add numbered figure. \\\verb!\begin{equation}[!\textit{place}\verb!]! & Add numbered equation. \\\verb!\caption{!\textit{text}\verb!}! & Caption for the body. \\\end{tabular}
The \textit{place} is a list valid placements for the body. \texttt{t}=top,\texttt{h}=here, \texttt{b}=bottom, \texttt{p}=separate page, \texttt{!}=place even if ugly. Captions and label markers should be within the environment.
%---------------------------------------------------------------------------
\section{Text properties}
\subsection{Font face}\newcommand{\FontCmd}[3]{\PBS\verb!\#1{!\textit{text}\verb!}! \> % \verb!{\#2 !\textit{text}\verb!}! \> % \#1{#3}}\begin{tabular}{@{}l@{}l@{}l@{}}\textit{Command} & \textit{Declaration} & \textit{Effect} \\\verb!\textrm{!\textit{text}\verb!}! & % \verb!{\rmfamily !\textit{text}\verb!}! & % \textrm{Roman family} \\\verb!\textsf{!\textit{text}\verb!}! & % \verb!{\sffamily !\textit{text}\verb!}! & % \textsf{Sans serif family} \\\verb!\texttt{!\textit{text}\verb!}! & % \verb!{\ttfamily !\textit{text}\verb!}! & % \texttt{Typewriter family} \\\verb!\textmd{!\textit{text}\verb!}! & % \verb!{\mdseries !\textit{text}\verb!}! & % \textmd{Medium series} \\\verb!\textbf{!\textit{text}\verb!}! & % \verb!{\bfseries !\textit{text}\verb!}! & % \textbf{Bold series} \\\verb!\textup{!\textit{text}\verb!}! & % \verb!{\upshape !\textit{text}\verb!}! & % \textup{Upright shape} \\\verb!\textit{!\textit{text}\verb!}! & % \verb!{\itshape !\textit{text}\verb!}! & % \textit{Italic shape} \\\verb!\textsl{!\textit{text}\verb!}! & % \verb!{\slshape !\textit{text}\verb!}! & % \textsl{Slanted shape} \\\verb!\textsc{!\textit{text}\verb!}! & % \verb!{\scshape !\textit{text}\verb!}! & % \textsc{Small Caps shape} \\\verb!\emph{!\textit{text}\verb!}! & % \verb!{\em !\textit{text}\verb!}! & % \emph{Emphasized} \\\verb!\textnormal{!\textit{text}\verb!}! & % \verb!{\normalfont !\textit{text}\verb!}! & % \textnormal{Document font} \\\verb!\underline{!\textit{text}\verb!}! & % & % \underline{Underline}\end{tabular}
The command (t\textit{tt}t) form handles spacing better than thedeclaration (t{\itshape tt}t) form.
\subsection{Font size}\setlength{\columnsep}{14pt} % Need to move columns apart a little\begin{multicols}{2}\begin{tabbing}\verb!\footnotesize! \= \kill\verb!\tiny! \> \tiny{tiny} \\\verb!\scriptsize! \> \scriptsize{scriptsize} \\\verb!\footnotesize! \> \footnotesize{footnotesize} \\\verb!\small! \> \small{small} \\\verb!\normalsize! \> \normalsize{normalsize} \\\verb!\large! \> \large{large} \\\verb!\Large! \= \Large{Large} \\ % Tab hack for new column\verb!\LARGE! \> \LARGE{LARGE} \\\verb!\huge! \> \huge{huge} \\\verb!\Huge! \> \Huge{Huge}\end{tabbing}\end{multicols}\setlength{\columnsep}{1pt} % Set column separation back
These are declarations and should be used in the form\verb!{\small! \ldots\verb!}!, or without braces to affect the entiredocument.
\subsection{Verbatim text}
\settowidth{\MyLen}{\texttt{.begin.verbatim..} }\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}\verb@\begin{verbatim}@ & Verbatim environment. \\\verb@\begin{verbatim*}@ & Spaces are shown as \verb*@ @. \\\verb@\verb!text!@ & Text between the delimiting characters (in this case % `\texttt{!}') is verbatim.\end{tabular}
\subsection{Justification}\begin{tabular}{@{}ll@{}}\textit{Environment} & \textit{Declaration} \\\verb!\begin{center}! & \verb!\centering! \\\verb!\begin{flushleft}! & \verb!\raggedright! \\\verb!\begin{flushright}! & \verb!\raggedleft! \\\end{tabular}
\subsection{Miscellaneous}\verb!\linespread{!$x$\verb!}! changes the line spacing by themultiplier $x$.
\section{Text-mode symbols}
\subsection{Symbols}\begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{2em}}l@{\hspace{1em}}l@{\hspace{2em}}l@{\hspace{1em}}l@{\hspace{2em}}l@{\hspace{1em}}l@{}}\& & \verb!\&! &\_ & \verb!\_! &\ldots & \verb!\ldots! &\textbullet & \verb!\textbullet! \\\$ & \verb!\$! &\^{} & \verb!\^{}! &\textbar & \verb!\textbar! &\textbackslash & \verb!\textbackslash! \\\% & \verb!\%! &\~{} & \verb!\~{}! &\# & \verb!\#! &\S & \verb!\S! \\\end{tabular}
\subsection{Accents}\begin{tabular}{@{}l@{\ }l|l@{\ }l|l@{\ }l|l@{\ }l|l@{\ }l@{}}\`o & \verb!\`o! &\'o & \verb!\'o! &\^o & \verb!\^o! &\~o & \verb!\~o! &\=o & \verb!\=o! \\\.o & \verb!\.o! &\"o & \verb!\"o! &\c o & \verb!\c o! &\v o & \verb!\v o! &\H o & \verb!\H o! \\\c c & \verb!\c c! &\d o & \verb!\d o! &\b o & \verb!\b o! &\t oo & \verb!\t oo! &\oe & \verb!\oe! \\\OE & \verb!\OE! &\ae & \verb!\ae! &\AE & \verb!\AE! &\aa & \verb!\aa! &\AA & \verb!\AA! \\\o & \verb!\o! &\O & \verb!\O! &\l & \verb!\l! &\L & \verb!\L! &\i & \verb!\i! \\\j & \verb!\j! &!` & \verb!~`! &?` & \verb!?`! &\end{tabular}
\subsection{Delimiters}\begin{tabular}{@{}l@{\ }ll@{\ }ll@{\ }ll@{\ }ll@{\ }ll@{\ }l@{}}` & \verb!`! &`` & \verb!``! &\{ & \verb!\{! &\lbrack & \verb![! &( & \verb!(! &\textless & \verb!\textless! \\' & \verb!'! &'' & \verb!''! &\} & \verb!\}! &\rbrack & \verb!]! &) & \verb!)! &\textgreater & \verb!\textgreater! \\\end{tabular}
\subsection{Dashes}\begin{tabular}{@{}llll@{}}\textit{Name} & \textit{Source} & \textit{Example} & \textit{Usage} \\hyphen & \verb!-! & X-ray & In words. \\en-dash & \verb!--! & 1--5 & Between numbers. \\em-dash & \verb!---! & Yes---or no? & Punctuation.\end{tabular}
\subsection{Line and page breaks}\settowidth{\MyLen}{\texttt{.pagebreak} }\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}\verb!\\! & Begin new line without new paragraph. \\\verb!\\*! & Prohibit pagebreak after linebreak. \\\verb!\kill! & Don't print current line. \\\verb!\pagebreak! & Start new page. \\\verb!\noindent! & Do not indent current line.\end{tabular}
\subsection{Miscellaneous}\settowidth{\MyLen}{\texttt{.rule.w..h.} }\begin{tabular}{@{}p{\the\MyLen}% @{}p{\linewidth-\the\MyLen}@{}}\verb!\today! & \today. \\\verb!$\sim$! & Prints $\sim$ instead of \verb!\~{}!, which makes \~{}. \\\verb!~! & Space, disallow linebreak (\verb!W.J.~Clinton!). \\\verb!\@.! & Indicate that the \verb!.! ends a sentence when following an uppercase letter. \\\verb!\hspace{!$l$\verb!}! & Horizontal space of length $l$ (Ex: $l=\mathtt{20pt}$). \\\verb!\vspace{!$l$\verb!}! & Vertical space of length $l$. \\\verb!\rule{!$w$\verb!}{!$h$\verb!}! & Line of width $w$ and height $h$. \\\end{tabular}
\section{Tabular environments}
\subsection{\texttt{tabbing} environment}\begin{tabular}{@{}l@{\hspace{1.5ex}}l@{\hspace{10ex}}l@{\hspace{1.5ex}}l@{}}\verb!\=! & Set tab stop. &\verb!\>! & Go to tab stop.\end{tabular}
Tab stops can be set on ``invisible'' lines with \verb!\kill!at the end of the line. Normally \verb!\\! is used to separate lines.
\subsection{\texttt{tabular} environment}\verb!\begin{array}[!\textit{pos}\verb!]{!\textit{cols}\verb!}! \\\verb!\begin{tabular}[!\textit{pos}\verb!]{!\textit{cols}\verb!}! \\\verb!\begin{tabular*}{!\textit{width}\verb!}[!\textit{pos}\verb!]{!\textit{cols}\verb!}!
\subsubsection{\texttt{tabular} column specification}\settowidth{\MyLen}{\texttt{p}\{\textit{width}\} \ }\begin{tabular}{@{}p{\the\MyLen}@{}p{\linewidth-\the\MyLen}@{}}\texttt{l} & Left-justified column. \\\texttt{c} & Centered column. \\\texttt{r} & Right-justified column. \\\verb!p{!\textit{width}\verb!}! & Same as % \verb!\parbox[t]{!\textit{width}\verb!}!. \\\verb!@{!\textit{decl}\verb!}! & Insert \textit{decl} instead of inter-column space. \\\verb!|! & Inserts a vertical line between columns.\end{tabular}
\subsubsection{\texttt{tabular} elements}\settowidth{\MyLen}{\texttt{.cline.x-y..}}\begin{tabular}{@{}p{\the\MyLen}@{}p{\linewidth-\the\MyLen}@{}}\verb!\hline! & Horizontal line between rows. \\\verb!\cline{!$x$\verb!-!$y$\verb!}! & Horizontal line across columns $x$ through $y$. \\\verb!\multicolumn{!\textit{n}\verb!}{!\textit{cols}\verb!}{!\textit{text}\verb!}! \\ & A cell that spans \textit{n} columns, with \textit{cols} column specification.\end{tabular}
\section{Math mode}For inline math, use \verb!\(...\)! or \verb!$...$!.For displayed math, use \verb!\[...\]! or \verb!\begin{equation}!.
\begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{2em}}l@{\hspace{1em}}l@{}}Superscript$^{x}$ &\verb!^{x}! &Subscript$_{x}$ &\verb!_{x}! \\$\frac{x}{y}$ &\verb!\frac{x}{y}! &$\sum_{k=1}^n$ &\verb!\sum_{k=1}^n! \\$\sqrt[n]{x}$ &\verb!\sqrt[n]{x}! &$\prod_{k=1}^n$ &\verb!\prod_{k=1}^n! \\\end{tabular}
\subsection{Math-mode symbols}
% The ordering of these symbols is slightly odd. This is because I had to put all the% long pieces of text in the same column (the right) for it all to fit properly.% Otherwise, it wouldn't be possible to fit four columns of symbols here.
\begin{tabular}{@{}l@{\hspace{1ex}}l@{\hspace{1em}}l@{\hspace{1ex}}l@{\hspace{1em}}l@{\hspace{1ex}} l@{\hspace{1em}}l@{\hspace{1ex}}l@{}}$\leq$ & \verb!\leq! &$\geq$ & \verb!\geq! &$\neq$ & \verb!\neq! &$\approx$ & \verb!\approx! \\$\times$ & \verb!\times! &$\div$ & \verb!\div! &$\pm$ & \verb!\pm! &$\cdot$ & \verb!\cdot! \\$^{\circ}$ & \verb!^{\circ}! &$\circ$ & \verb!\circ! &$\prime$ & \verb!\prime! &$\cdots$ & \verb!\cdots! \\$\infty$ & \verb!\infty! &$\neg$ & \verb!\neg! &$\wedge$ & \verb!\wedge! &$\vee$ & \verb!\vee! \\$\supset$ & \verb!\supset! &$\forall$ & \verb!\forall! &$\in$ & \verb!\in! &$\rightarrow$ & \verb!\rightarrow! \\$\subset$ & \verb!\subset! &$\exists$ & \verb!\exists! &$\notin$ & \verb!\notin! &$\Rightarrow$ & \verb!\Rightarrow! \\$\cup$ & \verb!\cup! &$\cap$ & \verb!\cap! &$\mid$ & \verb!\mid! &$\Leftrightarrow$ & \verb!\Leftrightarrow! \\$\dot a$ & \verb!\dot a! &$\hat a$ & \verb!\hat a! &$\bar a$ & \verb!\bar a! &$\tilde a$ & \verb!\tilde a! \\
$\alpha$ & \verb!\alpha! &$\beta$ & \verb!\beta! &$\gamma$ & \verb!\gamma! &$\delta$ & \verb!\delta! \\$\epsilon$ & \verb!\epsilon! &$\zeta$ & \verb!\zeta! &$\eta$ & \verb!\eta! &$\varepsilon$ & \verb!\varepsilon! \\$\theta$ & \verb!\theta! &$\iota$ & \verb!\iota! &$\kappa$ & \verb!\kappa! &$\vartheta$ & \verb!\vartheta! \\$\lambda$ & \verb!\lambda! &$\mu$ & \verb!\mu! &$\nu$ & \verb!\nu! &$\xi$ & \verb!\xi! \\$\pi$ & \verb!\pi! &$\rho$ & \verb!\rho! &$\sigma$ & \verb!\sigma! &$\tau$ & \verb!\tau! \\$\upsilon$ & \verb!\upsilon! &$\phi$ & \verb!\phi! &$\chi$ & \verb!\chi! &$\psi$ & \verb!\psi! \\$\omega$ & \verb!\omega! &$\Gamma$ & \verb!\Gamma! &$\Delta$ & \verb!\Delta! &$\Theta$ & \verb!\Theta! \\$\Lambda$ & \verb!\Lambda! &$\Xi$ & \verb!\Xi! &$\Pi$ & \verb!\Pi! &$\Sigma$ & \verb!\Sigma! \\$\Upsilon$ & \verb!\Upsilon! &$\Phi$ & \verb!\Phi! &$\Psi$ & \verb!\Psi! &$\Omega$ & \verb!\Omega!\end{tabular}\footnotesize
%\subsection{Special symbols}%\begin{tabular}{@{}ll@{}}%$^{\circ}$ & \verb!^{\circ}! Ex: $22^{\circ}\mathrm{C}$: \verb!$22^{\circ}\mathrm{C}$!.%\end{tabular}
\section{Bibliography and citations}When using \BibTeX, you need to run \texttt{latex}, \texttt{bibtex},and \texttt{latex} twice more to resolve dependencies.
\subsection{Citation types}\settowidth{\MyLen}{\texttt{.shortciteN.key..}}\begin{tabular}{@{}p{\the\MyLen}@{}p{\linewidth-\the\MyLen}@{}}\verb!\cite{!\textit{key}\verb!}! & Full author list and year. (Watson and Crick 1953) \\\verb!\citeA{!\textit{key}\verb!}! & Full author list. (Watson and Crick) \\\verb!\citeN{!\textit{key}\verb!}! & Full author list and year. Watson and Crick (1953) \\\verb!\shortcite{!\textit{key}\verb!}! & Abbreviated author list and year. ? \\\verb!\shortciteA{!\textit{key}\verb!}! & Abbreviated author list. ? \\\verb!\shortciteN{!\textit{key}\verb!}! & Abbreviated author list and year. ? \\\verb!\citeyear{!\textit{key}\verb!}! & Cite year only. (1953) \\\end{tabular}
All the above have an \texttt{NP} variant without parentheses;Ex. \verb!\citeNP!.
\subsection{\BibTeX\ entry types}\settowidth{\MyLen}{\texttt{.mastersthesis.}}\begin{tabular}{@{}p{\the\MyLen}@{}p{\linewidth-\the\MyLen}@{}}\verb!@article! & Journal or magazine article. \\\verb!@book! & Book with publisher. \\\verb!@booklet! & Book without publisher. \\\verb!@conference! & Article in conference proceedings. \\\verb!@inbook! & A part of a book and/or range of pages. \\\verb!@incollection! & A part of book with its own title. \\%\verb!@manual! & Technical documentation. \\%\verb!@mastersthesis! & Master's thesis. \\\verb!@misc! & If nothing else fits. \\\verb!@phdthesis! & PhD. thesis. \\\verb!@proceedings! & Proceedings of a conference. \\\verb!@techreport! & Tech report, usually numbered in series. \\\verb!@unpublished! & Unpublished. \\\end{tabular}
\subsection{\BibTeX\ fields}\settowidth{\MyLen}{\texttt{organization.}}\begin{tabular}{@{}p{\the\MyLen}@{}p{\linewidth-\the\MyLen}@{}}\verb!address! & Address of publisher. Not necessary for major publishers. \\\verb!author! & Names of authors, of format .... \\\verb!booktitle! & Title of book when part of it is cited. \\\verb!chapter! & Chapter or section number. \\\verb!edition! & Edition of a book. \\\verb!editor! & Names of editors. \\\verb!institution! & Sponsoring institution of tech.\ report. \\\verb!journal! & Journal name. \\\verb!key! & Used for cross ref.\ when no author. \\\verb!month! & Month published. Use 3-letter abbreviation. \\\verb!note! & Any additional information. \\\verb!number! & Number of journal or magazine. \\\verb!organization! & Organization that sponsors a conference. \\\verb!pages! & Page range (\verb!2,6,9--12!). \\\verb!publisher! & Publisher's name. \\\verb!school! & Name of school (for thesis). \\\verb!series! & Name of series of books. \\\verb!title! & Title of work. \\\verb!type! & Type of tech.\ report, ex. ``Research Note''. \\\verb!volume! & Volume of a journal or book. \\\verb!year! & Year of publication. \\\end{tabular}Not all fields need to be filled. See example below.
\subsection{Common \BibTeX\ style files}\begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{3em}}l@{\hspace{1em}}l@{}}\verb!abbrv! & Standard &\verb!abstract! & \texttt{alpha} with abstract \\\verb!alpha! & Standard &\verb!apa! & APA \\\verb!plain! & Standard &\verb!unsrt! & Unsorted \\\end{tabular}
The \LaTeX\ document should have the following two lines just before\verb!\end{document}!, where \verb!bibfile.bib! is the name of the\BibTeX\ file.\begin{verbatim}\bibliographystyle{plain}\bibliography{bibfile}\end{verbatim}
\subsection{\BibTeX\ example}The \BibTeX\ database goes in a file called\textit{file}\texttt{.bib}, which is processed with \verb!bibtex file!.\begin{verbatim}@String{N = {Na\-ture}}@Article{WC:1953, author = {James Watson and Francis Crick}, title = {A structure for Deoxyribose Nucleic Acid}, journal = N, volume = {171}, pages = {737}, year = 1953}\end{verbatim}
\section{Sample \LaTeX\ document}\begin{verbatim}\documentclass[11pt]{article}\usepackage{fullpage}\title{Template}\author{Name}\begin{document}\maketitle
\section{section}\subsection*{subsection without number}text \textbf{bold text} text. Some math: $2+2=5$\subsection{subsection}text \emph{emphasized text} text. \cite{WC:1953}discovered the structure of DNA.
A table:\begin{table}[!th]\begin{tabular}{|l|c|r|}\hlinefirst & row & data \\second & row & data \\\hline\end{tabular}\caption{This is the caption}\label{ex:table}\end{table}
The table is numbered \ref{ex:table}.\end{document}\end{verbatim}
\rule{0.3\linewidth}{0.25pt}\scriptsize
Copyright \copyright\ 2014 Winston Chang
\href{http://wch.github.io/latexsheet/}{http://wch.github.io/latexsheet/}
\end{multicols}\end{document}
Typst (the ideal typesetting engine)
Typst is a new markup-based typesetting system that is designed to be as powerful as LaTeX while being much easier to learn and use (literally, just take a look at it’s GitHub: github.com/typst/typst). It’s so damn good that it absolutely deserves it’s own post, but for now we’ll leave that for another day. What’s important to note is that it’s so much easier to write virtually anything in Typst than in LaTeX, and it solves almost all of the pain points in the other tools mentioned above, including:
- Incremental compilation, which means that editing content updates in documents/previews instantly (rather than having wait between 1 and many seconds for LaTeX to compile, or for Google Docs/Microsoft Word to stop lagging).
- Easy extensibility: Typst has batteries-included functions for creating tables, drawing lines, setting colours for text and highlighted text (even gradient support is built-in), and so much more. Even the documentation for Typst is amazing, with examples to showcase how to use each of the different functions and how different arguments can affect the output (meanwhile, you pretty much have to learn how to use the intricate features of Google Docs/Microsoft Word by playing around with buttons, and I’m not even sure where you can get the core LaTeX documentation; latex-project.org/help/documentation is so complicated that it’s rather unhelpful, and the Overleaf docs at overleaf.com/learn are nice for beginners but woefully lack the complexity needed for more advanced documents).
- Similar to LaTeX, Typst supports importing third-party extensions and files built by other people (they’re even importable into your current document in the same way, using a single line with an
#import ...
statement rather than\usepackage{...}
).
- Similar to LaTeX, Typst supports importing third-party extensions and files built by other people (they’re even importable into your current document in the same way, using a single line with an
Another key characteristic of Typst is that you don’t need any complicated template with tens of lines of boilerplate code to start off writing your cheatsheet so that you have some modicum of structure to follow; you can just start of with something simple (e.g. a single table with a single row and column that fills the entire page) and then build on top of it (e.g. adding more rows and columns that are dynamically sized, with optional adjustments such that some rows/columns can be larger/smaller than others, such that the single table remains filling the entire page with no additional modifications required).
And what’s brilliant about all of this, is that the Typst team have been generous enough to build a fully functional web application (typst.app) to only store your Typst project files, but also edit them with dynamically updating previews and all sorts of bits and bobs to make your Typst writing experience oh-so-sweet (probably my favourite feature is the ability to not only click on some text or box in the output PDF preview and be immediately directed to the line of Typst markup that’s generating that specific output but also, with a line of code selected, jump and zoom in directly to the specific page and portion of the generated PDF that the markup is creating; remember this for later, because it comes in incredibly handy when you’re writing text at a size that’s on par with some smaller species of ants). typst.app is to Typst as overleaf.com is to LaTeX (except the Typst web app is so much better than Overleaf that the folks over at Overleaf actually copied their “new” landing page design to mimic Typst’s, which I’m not too surprised about given just how much better Typst is to use).
![Landing page: Typst](/_astro/02-typst.CJeQhYXR_Z14jWgH.webp)
![Landing page: Overleaf](/_astro/02-overleaf.Ch5k2fwu_NoW4V.webp)
It’s awe-inspiring to think of just how powerful Typst is given how easy it is to use as well, making it a fantastic option not just for writing cheatsheets but for replacing LaTeX for a ridiculous number of purposes (as for myself, I now exclusively use Typst to typeset pretty much any PDF requiring math notation, which at the time of writing is pretty much just relegated to homework assignments for calculus/algorithms/data structures/database design courses). But we’re here to figure out how to write a kickass cheatsheet, so let’s get to it.
A reminder
Now, something that I’d like to point out before we dive into the meat of how exactly we can use Typst to make our denser-than-osmium cheatsheet is that this isn’t the only good way of writing a cheatsheet. By all means, you should use whatever you’re comfortable with to type it out, especially if your goal is to write something that’s good enough instead of something that’s incredibly dense (and may also might require a wee bit more squinting than some would prefer). What I’m investigating here is a way pushing the maximum readable word count in a typed-up cheatsheet to the very limit, which is why breaking down what makes one methodology or tool suboptimal for that purpose compared to another is so important.
The Message
Figuring out how to organize content on your cheatsheet.
So, here we are. We’ve got Typst down as our writing utencil of choice, and for the purposes of this scenario, let’s suppose we’re writing a cheatsheet for a computer security course (which is just as well, because I’ve got a raw text file just full to the brim of all the different concepts and terminology we’re going to want to put on our cheatsheet).
We’ve got our tool; now we have to figure out how to use it. And in order to do that, there’s a couple of important things we need to keep in mind.
How to Make Tiny Text Readable
1. Uniformity means readability
As someone who’s been writing cheatsheets over half a decade now, I’ve made this mistake far too many times in the name of trying to minimize how much white space I leave on my cheatsheets, and almost every time it makes them a complete mess and terribly difficult to parse (which as you can imagine is not ideal in an exam setting where you need to find very specific bits of information in a time constrained environment).
For a good example at what not to do, consider my cheatsheet (below) for an introductory digital logics course from my second year of university. I can hardly distinguish the different groups of concepts amongst all the differently sized blocks of diagrams mixed in with text, and I was the one who wrote the entire darn thing, I can only imagine how you, dear reader, must feel looking at this spagetthi gobble of a cheatsheet.
![My cheatsheet for an introductory digital logics course, which is a complete mess of different sized blocks of diagrams mixed in with text.](/_astro/03-ece241.lostDGXe_ZO1h91.webp)
How do we maintain uniformity with incredibly tiny text? Well, for starters, stick with a consistent method of structuring your content. The best way of doing this, regardless of whether you’re using some typesetting engine or a text editor, is with a table. Ideally, a single table that fills up the entire page (so you don’t have to deal with all the spacing headaches trying to properly sandwich together multiple tables of different sizes onto the same 8.5x11 inch sheet of paper) with consistently sized rows and columns. In addition, go with justified or centre-aligned text instead of left/right-aligned (having straight edges for text boxes is a lot easier to read than text boxes with jagged edges that have no easily parseable pattern)
One thing to note: it’s ok to break uniformity and have something really stick out on your cheatsheet (if it’s really that important, or maybe if you ran out of time and just need to put something onto paper), just know that when nearly everything breaks uniformity, there isn’t really any uniformity to be had there (we just call that a mess).
And if you’re going to be using tables, there’s another important principle that I like to prescribe.
2. It’s easier to read up-down than left-right
Which means you should have small widths for columns, such that all you need to do is move your eyes straight down from a single horizontal position such that vertical-only movements enable you to parse through an entire column easily (trust me, this saves a lot of eye strain compared to having to read left to right and then down and back to start on the left every few lines).
Group related content together
- Highlight terms while leaving their definitions as plain text so that you can look into a sea of text and quickly see whether the term you’re looking for is even present at all first.
- Break up multi-layered content by using multiple levels of formatting for your headings, subheadings, definitions, sub-definitions, and so on.
- Also have separate fonts for important terms, plaintext, and special text (e.g. code, math); ensure that all work well at small scales (adjustments to character and word spacing can luckily be made by Typst, which means all you need to do is focus on readability; you can fit more characters of a thin font in the same space of whitespace compared to a wider font, so keep that in mind and maybe don’t select something as wide as Stint Ultra Expanded):
- Also have separate fonts for important terms, plaintext, and special text (e.g. code, math); ensure that all work well at small scales (adjustments to character and word spacing can luckily be made by Typst, which means all you need to do is focus on readability; you can fit more characters of a thin font in the same space of whitespace compared to a wider font, so keep that in mind and maybe don’t select something as wide as Stint Ultra Expanded):
- Have some method of clearly separating unrelated content (that minimizes use of whitespace, like a dotted line).
Other things to keep in mind
Convert JPGs to SVGs (which are better than PNGs since you can easily edit them to remove backgrounds or non-essential elements from slides so that you’re left with the most important details that remain readable at small sizes).
Implementing it in Typst
To see the whole project in action, take a look at typst.app/project/rbJ15a29M2OcglqKcAuWkM 2. But for an overview of how each individual part of the Typst project works together, continue on reading below.
📁cheatsheet/├── 📁fonts/├── 📁images/├── aidsheet.typ├── content.typ└── lazy.typ
The project structure for the cheatsheet, with the main content split into 2 separate files (content.typ and lazy.typ; the latter file is for when I got, as it is written, lazy and simply began copy-pasting text from lecture slides) and the content formatting specified within the aidsheet.typ file.
First order of business before we get to the task of structuring our content: the page layout.
Programmability is one of Typst’s strong suits, and so it’s good practice to set variables for your cheatsheet’s document formatting properties (e.g. line spacing, image width, font size) because it can enable making minor document-wide changes down the road a whole lot easier. Of course, you’ll notice that I don’t do this all the time in my code below (and that’s largely because I wrote this cheatsheet under the time crunch of studying for 2 exams in 2 days, which meant that many a corner had to be cut to get it done).
...
#import "content.typ": *#import "lazy.typ": *
#set page( paper: "us-letter", margin: (
top: 0.2in, bottom: 0.1in, left: 0.2in, right: 0.2in ))
...
...
#let img_width = 70%#let font_size = 3.6pt#let line_spacing = 0.2em#let main_color = purple.lighten(20%).transparentize(20%)
...
Add another couple hundred lines of formatting code (using alias for headers, bolded text, math, highlights, and more), along with a couple thousand lines of actual cheatsheet content, and you find yourself staring at what can only be described as a marvel of modern (text) engineering.
The Machine
Making sure readability and formatting are maintained on the journey from page to paper.
Black and white printers are better than color printers, because it’s a lot easier to find a BW printer with a high enough DPI for printing readable size 2-3pt text.
You’ll notice I don’t talk much about colour in this post, and this is exactly why. Yt’s pretty much ideal to go for super high contrast black-white text styles instead of greys bc a lot of BW printers actually just reduce the number of dots printed using the small ultra black ink to make gray show up on paper (which as you can imagine is not ideal for maximizing the resolution of text and images at a small scale; this has burned me in the past a couple of times, and I have learnt to stay away from it ever since)
I’ve also found that a DPI of 1200 is the sweet spot for getting really high quality prints out; while a smaller DPI could technically remain readable, I’d recommend going up in font size by a half point or two just to make your cheatsheet a bit easier to read (if you have to use a magnifying glass to read content, then you’re not exactly making things easier for yourself, which is the entire point behind this whole compressing a textbook into a single sheet of paper).
The Result
What it looks like all put together.
Is it readable in real life? Quite so.
In fact, you know what I kept thinking during the exam that I used this cheatsheet in?
I think I could’ve gone with a smaller font.
Footnotes
-
Searched for LaTeX cheatsheet templates at github.com/search?q=cheat+sheet+template&type=repositories ↩
-
Note that there are some minute differences between the code linked here and the overview below for clarity purposes. ↩