To generate multiple versions of a document from the same source file,
we can use \jobname
and
conditionals (\ifthenelse
from ifthen
or \iftoggle
from
etoolbox
) to output version-specific text or layouts.
Example Use Cases: Conference paper submission vs. conference paper camera ready, conference proceedings vs. an extended tech report, short résumé vs. long curriculum vitae.
Rather than modify the source .tex
each time to specify whether LaTeX should
generate version A or B (or even worse, having to maintain multiple source
files with overlapping or duplicated content), we could always generate both
simultaneously.
prerequisites
latexmk
: used to automate compilation of our documentsmake
implementation
In this example, we will generate multiple output PDFs, short.pdf
and
long.pdf
from the singular source file named source.tex
.
We’ll use the ifthen
package as it is part of the
ACM list of accepted LaTeX packages;
we could also use the etoolbox
package (but not covered here).
source.tex
:
\documentclass{article}
\usepackage{ifthen}
\newboolean{long}
\setboolean{long}{false}
\newboolean{short}
\setboolean{short}{false}
% The crux of this tutorial!
%
% Here we set the appropriate boolean toggles based on what is passed to
% `-jobname=` (in this example, either `short` or `long`).
%
\ifthenelse{\equal{\jobname}{\detokenize{long}}}
{\setboolean{long}{true}
\setboolean{short}{false}}
{\setboolean{long}{false}
\setboolean{short}{true}}
% I prefer to create and set multiple toggles, and then check each
% toggle individually rather than keeping track of what the state
% would be if the condition is false.
%
% It's easy if we only have two document options (`short` or `long`),
% but gets a bit more complex if we have multiple combinations of
% options (e.g., `anonymized`, `draft`, etc.).
%
\newcommand{\ifthen}[2]{\ifthenelse{\boolean{#1}}{#2}{}}
\begin{document}
Hello world!
\ifthenelse
{\boolean{long}}
{This text only appears in the \textbf{long} version.}{}
\ifthenelse
{\boolean{short}}
{This text only appears in the \textbf{short} version.}{}
\ifthenelse
{\NOT \boolean{short}}
{This text only appears in the version that is \emph{not} short}{}
% We could also use boolean operators:
%
% \ifthenelse{\boolean{long} \AND \boolean{anonymized}}{[...]}{[...]}
% \ifthenelse{\NOT \boolean{short}}{[...]}{[...]}
%
% But I prefer to nest the conditionals.
%
% A shortcut with some caveats. See the macro definition above.
\ifthen{long}{This text also only appears in the \textbf{long} version.}
\end{document}
compiling via -jobname
To compile, we pass short
or long
to the -jobname=
parameter to
latexmk
:
latexmk -pdf -jobname=short source.tex
Here is an example Makefile
that will generate multiple output PDFs
simultaneously:
.PHONY: all pdf FORCE_MAKE
all pdf:: short.pdf long.pdf
%.pdf: source.tex FORCE_MAKE
latexmk -pdf -jobname=$(basename $@) $<
clean::
latexmk -pdf -C $*
compiling via symlinks
As an alternative to explicitly setting -jobname=
, you can
create symbolic links (symlinks) for each version, based on this
StackOverflow answer:
ln -s source.tex short.tex
ln -s source.tex long.tex
The Makefile
then looks like:
.PHONY: all pdf FORCE_MAKE
all pdf:: short.pdf long.pdf
%.pdf: %.tex FORCE_MAKE
latexmk -pdf $<
clean::
latexmk -pdf -C $*
example output
short.pdf:
long.pdf: