A technique for conditional inclusion of parts of a TeX document.
Let me describe to you the situation which I found myself in. I wanted to create some maths problems sheets, and needed a way to maintain a single document while rendering both an output which included the solutions and an output which didnβt. There is an obvious way to do this; just comment and uncomment the solutions each time you want to compile the relevant document, but this is a bit of a pain, especially when the document needs to go through many iterations. There is another solution; maintain each of the problem and solution sheets separately, but this is equally painful, since every single change will require another change to prevent differences between the documents.
I recently found a better way, and Iβll outline this method now.
The method Iβm now using involves symlinks. A symlink, short for symbolic link, is a file which points to another file. Strictly speaking, there are two kinds of symlink, hard and soft, with the former pointing exactly to the point in memory, and the latter pointing to the file location.
The idea of the method is to create a single master.tex
file, then make symlinks to this file, with specifically chosen names which we will use to conditionally render parts of the document. For example, we can create the master file, and two symlinked files with,
touch master.tex
ln -s master.tex problems.tex
ln -s master.tex solutions.tex
where the -s
specifies that the symlink should be soft.
From now, the only document which we need to alter is master.tex
, as the other files are symlinked to this file, and will βchangeβ accordingly.
As an example, consider the following master.tex
\documentclass{article}
\begin{document}
Q: What is the best way to learn mathematics?
A: Do loads of problems!
\end{document}
So, in the problems.pdf
which will be created on compilation of problems.tex
, we want only to see the question, and in solutions.pdf
, similarly created, we want to see everything. In order to achieve this result, we will use lualatex
to access, and condition on the filename.
In order to access the filename in lualatex
, we can make a \directlua
call, and access the arg
object, which contains a list of all the arguments passed to lualatex
. For example,
\documentclass{article}
\directlua{
if (arg[1] == 'solutions.tex') then
% Condition to go here.
end
}
\begin{document}
Q: What is the best way to learn mathematics?
A: Do loads of problems!
\end{document}
Now, we can conditionally include a specific statement if the filename is solutions.tex
. This specific statement should relate to an \if
which we have defined elsewhere in the document.
\documentclass{article}
\newif\ifsolution
\directlua{
if (arg[1] == 'solutions.tex') then
tex.print("\string\\solutiontrue")
end
}
\begin{document}
Q: What is the best way to learn mathematics?
\ifsolution
A: Do loads of problems!
\fi
\end{document}
Now, to obtain both of the .pdf
files which we were after, we can simply compile each of the symlinked files with lualatex
.
lualatex problems.tex
lualatex solutions.tex
I think this is pretty cool! We donβt need any external packages or dependencies; weβre only relying on the power of lualatex
, which youβre probably using anyway.
Maybe itβs not a common situation, but there are a wide variety of jobs which I find interesting and want to apply for. As a result of this, I canβt often use the same CV for every application. It wouldnβt really make sense to highlight the same things when applying for data analyst roles and linux engineer roles for example.
So the question becomes, how can one effectively maintain multiple CVs simultaneously. There are obviously many similarities between the CVs which I want to submit, and as such when I make a change to a common area, I would like this change to be seen in every CV. This is a perfect use case for the conditional rendering which I have outlined above.
I use the following directory structure,
βββ academic
βΒ Β βββ Samuel Ireson CV.pdf
βββ data
βΒ Β βββ Samuel Ireson CV.pdf
βββ general
βΒ Β βββ Samuel Ireson CV.pdf
βββ internship
βΒ Β βββ Samuel Ireson CV.pdf
βββ quant
βΒ Β βββ Samuel Ireson CV.pdf
βββ software
βΒ Β βββ Samuel Ireson CV.pdf
βββ Samuel Ireson CV.tex
βββ sections
Β Β βββ academic_skills.tex
.
.
.
Β Β βββ societies.tex
In this case, instead of conditioning on the filename, I pass an additional argument to lualatex
, and condition on that β like this.
% IFS
\newif\ifacademic
\newif\ifdata
\newif\ifgeneral
\newif\ifinternship
\newif\ifquant
\newif\ifsoftware
\directlua{
if (arg[2] == 'academic') then
tex.print("\string\\academictrue")
elseif (arg[2] == 'data') then
tex.print("\string\\datatrue")
elseif (arg[2] == 'general') then
tex.print("\string\\generaltrue")
elseif (arg[2] == 'internship') then
tex.print("\string\\internshiptrue")
elseif (arg[2] == 'quant') then
tex.print("\string\\quanttrue")
elseif (arg[2] == 'software') then
tex.print("\string\\softwaretrue")
end
}
Then, I use a Makefile
to compile the CV multiple times, each time passing a difference argument to lualatex
, and moving the .pdf
into a well-named directory to avoid over-writing. The exact Makefile
is,
INPUTS = Samuel\ Ireson\ CV.tex sections/*.tex
COMPILER = lualatex
MASTER = Samuel\ Ireson\ CV.tex
CVS = academic data general internship quant software
Samuel\ Ireson\ CV.pdf: $(INPUTS)
for dir in $(CVS); do \
mkdir -p $$dir; \
$(COMPILER) $(MASTER) $$dir; \
mv Samuel\ Ireson\ CV.pdf $$dir; \
done
I can run this whenever I want to re-compile all of the CVs.
Conditional rendering in tex
turns out to be more straightforward than I initially thought, and has loads of potential uses. Hope you enjoyed :)