# Passing parameters to a document

I compile most of my documents via Makefiles which take care of the bibliography, indexes, etc. Often I'd like to compile different versions from the same TeX file changing only small things (e.g. a beamer presentation plus a version with the handout option).

Is there any standard mechanism for passing parameters to the TeX file so that I can just type make handout to get the handout version in the above example?

I do this by using symlinks and testing the jobname. That is, I have a main (la)tex file and a bunch of symlinks to it. To find out which symlink was actually used, I examine the \jobname macro in my document and set certain parameters accordingly. In particular, if \jobname contains the string "handout", then the beamer class is called using the handout option. I do this by using a "wrapper" class which sets things up before calling the real class.

• I like that way for its unix-yness, but it seems comparatively complicated. Also this probably would not work on Windows (not that I use Windows, but other people do). – Caramdir Aug 11 '10 at 9:34
• @Caramdir: I felt it was more of a tex-y solution than a unix-y one since apart from the symlinks, everything is happening inside TeX. I thought that Windows had an idea of a symlink, and I'd be surprised if TeX didn't set the jobname accordingly. – Andrew Stacey Aug 11 '10 at 10:34
• By unix-y I meant that quite a lot of commands are actually symlinks on unix systems. For example latex and pdflatex are both just symlinks to pdftex in Tex Live. (My knowledge of the Windows filesystems mostly ends with FAT which didn't have real symlinks.) – Caramdir Aug 11 '10 at 10:47
• @Caramdir: I see. But I think that this solution is actually more robust than the others as it's almost pure TeX and doesn't rely on make files or shell scripts. It's also darn useful when you've got 30 lectures all with beamer, trans, and handout versions. – Andrew Stacey Aug 11 '10 at 11:04
• I am late to this party, but maybe I might point out that you can run latex --jobname=foo bar. No symlinks required. – Harald Hanche-Olsen Oct 25 '10 at 10:55

Here's a hacky way, probably this is the wrong way :).

Instead of passing a filename, you can pass a sequence of commands. So in particular, you could do something like

pdflatex "\def\ishandout{1} \input{foo.tex}"


which defines the macro \ishandout (to be 1) and then reads foo.tex. And then, inside foo.tex, you can check whether \ishandout is defined:

\ifdefined\ishandout
\documentclass[handout]{beamer}
\else
\documentclass{beamer}
\fi

• This would allow to emulate the ifdraft package when used with the word draft instead of handout, and specifying the appropriate lines inside the ifdefined, wouldn't it? Related question – Andrestand Oct 6 '14 at 14:52
• Best solution, all OS independent. – gustafbstrom Aug 10 '15 at 13:46
• Very nice solution, although having a foo-handout.tex that contains \def\ishandout{1} \input{foo.tex} in itself played out more nicely for me since I use latexmk. – Ayberk Özgür Aug 13 '15 at 14:50
• Will \ifdefined work on (for) any part of a (Xe)LaTeX document, or is it just for \documentclass{} options? – Nikos Alexandris Oct 10 '15 at 16:24
• Thank you! My standalone_verbatim.txt that renders text file given by \txtfile parameter offers nice "default usage" message, thanks to your answer! Here is source code for reference for other readers: gist.github.com/gwpl/5128cb3cd348c38492da59800b6ab3f2 – Grzegorz Wierzowiecki May 9 '16 at 20:47

I used to do it like in Neil Olver's answer, but found a better way:

pdflatex "\def\ishandout{1} \input{foo.tex}"


with a manual \ifdefined\ishandout statement, you can use:

pdflatex "\PassOptionsToClass{handout}{beamer}\input{foo}"


if you only want to set the a class option (use PassOptionsToPackage for package options).

In the case of beamer you can then also use the following statement in the main file:

\mode<handout>{%
<code>
}


if you want to use different settings in that mode.

• Interesting approach. I found PassOptionsToPackage in my ancient copy of Kopka and Daly, Third Edn, pg 334. It is however not that clear what this does. Does it override whatever option the package has, if an option is set? I tried it with the changes package. It seemed to work. K&D said I needed to use it with \RequirePackage, but I just used \usepackage{changes} and it still seemed to work. It there any documentation for this option online? – Faheem Mitha Aug 14 '11 at 18:07
• Never mind, a Google search comes up with some stuff. In particular, tex.ac.uk/cgi-bin/texfaq2html?label=optionclash seems quite helpful. – Faheem Mitha Aug 14 '11 at 18:19
• I'm unclear if this approach works with a arbitrary \newif\iffoo; \iffoo [...] \else [...] fi. What is the class or package in this case? – Faheem Mitha Aug 14 '11 at 18:59
• \PassOptionsToPackage passes the given options to the package if the package is loaded afterwards (and wasn't loaded beforehand). This solution is more of less beamer specific. It works only if the setting you want to pass to a document is a class or package option. – Martin Scharrer Aug 14 '11 at 19:11
• This solution hasn't been upvoted enough! Thanks, Martin. – jub0bs Nov 18 '13 at 16:37

Have the target in your Makefile clobber a file that is \input by your Latex document, which, say, sets or resets a \newif conditional.

For example, let the Makefile run echo "\handouttrue">flags.tex; latex manuscript on the handout goal. Then manuscript.tex might begin:

\newif\ifhandout
\input{flags}
\documentclass...


in document:

\ifhandout
...
\else
...
\fi

• This solution is so good and so underrated. – Alberto Nov 9 '20 at 13:46

LuaTeX anyone? Inside the document, you can access the command line arguments through the arg table:

%luaargs.tex
\documentclass{article}

\begin{document}

Document args were:

\begin{description}

\directlua{
if not (arg == nil) then
for i,v in pairs(arg) do
tex.print("\string\\item[" .. i .. "]" .. v)
end
end
}

\end{description}
\end{document}


The result of:

lualatex luaargs.tex foo bar bam biz


Is:

• You should consider using something like tex.tprint({ "\string\\item["}, {-2, i}, {"]"}, {-2, v}) for the print routine, as funny command line arguments result in funny output. - I know that this doesn't affect the (nice) given solution. – topskip May 23 '11 at 13:06

LATEX         := pdflatex -output-format dvi
PDFLATEX      := pdflatex

LATEX_ARGS    := -interaction=nonstopmode -halt-on-error
PDFLATEX_ARGS := $(LATEX_ARGS) TEX_RUNS := 2 SRC_BASE_NAME := parametrized_doc SRC :=$(SRC_BASE_NAME).tex

# cf. GNU Make Manual (“Syntax of Functions”) and
# <https://stackoverflow.com/questions/28615974/wildcard-to-variable-to-comma-joined-string>
space :=
space += # $(space) is a space comma := , # Function that converts a space-separated list into a comma-separated list comma-separate =$(subst ${space},${comma},$(strip$(1)))

# Macro that expands to a Make rule for a parametrized document using the
# l3keys LaTeX3 module for parameters and \jobname for the output file name.
#
# $(1): variant name #$(2): space-separated list of options to pass to l3keys (we can't
#       conveniently use the comma separator, because we'll expand this macro
#       with Make's $(call ...) function which separates arguments with # commas, precisely; therefore, we replace spaces with commas for l3keys). define customPDF =$(1): $$(SRC_BASE_NAME)-(1).pdf$$(SRC_BASE_NAME)-$(1).pdf: $$(SRC) for i in$$$$(seq 1$$(TEX_RUNS)); do \ $$(PDFLATEX) --jobname=$$(SRC_BASE_NAME)-$(1) \
$$(PDFLATEX_ARGS) '\newcommand{\MyDocParams}{' \ '(call comma-separate,(2)) }' '\input{$$<}'; \
done
endef

$(eval$(call customPDF,screen, outputType=screen fullScreen=false))
$(eval$(call customPDF,fullscreen, outputType=screen fullScreen=true))
$(eval$(call customPDF,print, outputType=paper))

# Write a specific rule for this file (as opposed to a pattern rule starting
# with %.dvi: %.tex), because the suitable $(TEX_RUNS) value depends on the # document, in general.$(SRC_BASE_NAME).dvi: $(SRC) for i in $$(seq 1 (TEX_RUNS)); do \ (LATEX) (LATEX_ARGS) '\input{<}'; \ done %.ps: %.dvi dvips -o '@' '<' dvi: (SRC_BASE_NAME).dvi ps: (SRC_BASE_NAME).ps clean: for ext in dvi ps pdf out aux log idx ind ilg toc bbl blg bcf run.xml; \ do rm -f "(SRC_BASE_NAME).$$ext"; \ \ for variant in$(VARIANTS); do                                     \
rm -f "$(SRC_BASE_NAME)-$$variant.$$ext"; \ done \ done rm -f missfont.log # Stuff from preview-latex for ext in fmt ini log; do \ rm -f "prv_$(SRC_BASE_NAME).$$ext"; \ done rm -rf auctex-auto '(SRC_BASE_NAME).prv' _region_.prv for ext in tex pdf log; do \ rm -f "_region_.$$ext"; \
done

.PHONY: all clean screen fullscreen print dvi ps


Finally, here is an expanded version of the same .tex file that actually adapts the layout based on the options passed using the mechanism just described. It uses the KOMA-Script scrartcl class, but obviously this has nothing to do with the parameters handling discussed here. I have removed most of the comments that were already in the “minimal example”, so if you find something unclear, look at the above LaTeX code and you should find what you are looking for. :-)

\documentclass[12pt]{scrartcl}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{textcomp}
\usepackage{expl3}
\usepackage{xparse}
\usepackage{blindtext}
\usepackage[english]{babel}
\usepackage[final,babel]{microtype}

\usepackage{scrlayer-scrpage}   % used to customize headers and footers

\newif\ifMyScreenOutput
\newif\ifMyFullScreenOutput

\ExplSyntaxOn

\bool_new:N \g_MyDocParams_screenOutput_bool
\bool_new:N \g_MyDocParams_fullScreen_bool

\msg_new:nnnn { MyDocParams } { unknown-choice-for-option }
{
Invalid~value~for~option~\exp_not:n {'#1'}:~\exp_not:n {'#3'}~
(valid~choices~are~\exp_not:n {#2})
}
{ You~may~optionally~put~a~more~verbose~message~here. }

\keys_define:nn { MyDocParams }
{
outputType .choice:,
outputType / paper .code:n = {
\bool_gset_false:N \g_MyDocParams_screenOutput_bool },
outputType / screen .code:n = {
\bool_gset_true:N \g_MyDocParams_screenOutput_bool },
outputType .initial:n = { paper },
outputType / unknown .code:n = {
\msg_error:nnxxx { MyDocParams } { unknown-choice-for-option }
{ outputType }                 % name of the choice key
{ 'paper'~and~'screen' }       % valid choices
{ \exp_not:n {#1} }            % invalid choice given
},

fullScreen .bool_gset:N = \g_MyDocParams_fullScreen_bool,
fullScreen .initial:n = { false },
% Used when the key is passed with no value
fullScreen .default:n = { true }
}

% The option values may be set from the command line by means of the
% \MyDocParams macro. If nothing is passed this way, the defaults come from
% the 'outputType .initial:n' and 'fullScreen .initial:n' settings above,
% but they could also be set here in the definition of \MyDocParams.
\providecommand{\MyDocParams}{}

% This is where keys are set from the point of view of l3keys.
\keys_set:no { MyDocParams } { \MyDocParams }

% Finally, convert our LaTeX3 booleans to \ifFooBar TeX conditionals.
\bool_if:NT \g_MyDocParams_screenOutput_bool
{ \MyScreenOutputtrue }
\bool_if:NT \g_MyDocParams_fullScreen_bool
{ \MyFullScreenOutputtrue }

\ExplSyntaxOff

% Customize the layout and colors depending on the selected output type.
\ifMyScreenOutput
% Useful if you choose a two-sided layout for paper output (e.g., with the
% scrbook class) but want to override it here in order to have a one-sided
% layout for screen output.
\KOMAoptions{twoside=false}

\usepackage[svgnames]{xcolor}
\pagecolor{yellow!9!white}

% Let's choose a \textwidth containing a suitable number of characters for
% convenient reading, and a \textheight such that if a page is filled with
% “normal text” in the document font without any space between paragraphs,
% then no vertical stretching nor shrinking is needed to fill the type area
% (technique explained in the typearea/KOMA-Script documentation).
\newlength{\MyTextWidthGoal}
\newlength{\MyTextHeightGoal}
\settowidth{\MyTextWidthGoal}{% 67 characters, incl. spaces and punctuation
{\normalfont                % (recommended range is between 60 and 70)
In this document, we'll show that in spite of its original syntax, }}
\setlength{\MyTextHeightGoal}{\topskip}

\ifMyFullScreenOutput
\addtolength{\MyTextHeightGoal}{14\baselineskip} % 15 lines
% Aspect ratio is 16:9 in this case
\usepackage[papersize={17cm,9.5625cm},
width=\MyTextWidthGoal,height=\MyTextHeightGoal]{geometry}
\else
% 55 lines (very tall!). I want this for screen reading as in a web
% browser---without being disturbed by page separations.
\usepackage[papersize={17cm,31.5cm},
width=\MyTextWidthGoal,height=\MyTextHeightGoal]{geometry}
\fi

% I want empty headers and footers for screen output (these are commands
% from KOMA-Script's scrlayer-scrpage package).
\ofoot*{} \cfoot*{} \ifoot*{}
\else
% Paper output: just use typearea's automatic calculations, they work great!
\KOMAoptions{paper=A4,BCOR=0mm,DIV=calc}
\fi

\ifMyScreenOutput
% Also available: filecolor, menucolor, runcolor
citecolor=DarkRed}
\ifMyFullScreenOutput
\hypersetup{pdfpagemode=FullScreen}
\fi
\else
\hypersetup{allcolors=black}  % for print; other possibility: 'hidelinks'
\fi

% Define a few convenient document-level commands using the LaTeX3 framework.
\ExplSyntaxOn

% Insert a URL with optional link text. In print mode, if the link text is
% provided, then the URL is put inside a footnote tied to the link text.
%
% #1: URL (prefix any '%' or '#' characters with a backaslash)
% #2: link text (optional)
\NewDocumentCommand \myHref { m o }
{
\IfValueTF {#2}
{ % The link text was provided (#2)
\bool_if:nTF { \g_MyDocParams_screenOutput_bool }
{ \href {#1} {#2} }
{ #2 \footnote { \url {#1} } }
}
{ % No link text provided
\url {#1}
}
}

% Typeset a LaTeX3 package name
\NewDocumentCommand \liiiPkg { m }
{
\texttt {#1}
}

\ExplSyntaxOff

\begin{document}
\title{Gnus, gnats and armadillos}%
\subtitle{Their life in relation to the universe}%
\author{Joe R.~User}%
\date{}%
\maketitle

In this article, we are going to make a reference to
\autoref{sec:test-section} just to show the link color. And also add a pointer
to the very useful
\myHref{https://ctan.org/pkg/l3kernel}[\liiiPkg{l3kernel} documentation]
for people interested in \LaTeX3 programming. The \LaTeX3 source code
repository can be found on GitHub: \myHref{https://github.com/latex3/latex3}.

\section{This is a test section\label{sec:test-section}}

\blindtext                      % text that belongs to the section

\Blinddocument
\end{document}


Sample outputs for the print, screen and fullscreen variants

Print

Screen

Fullscreen

Detail on the differing handling of hyperlinks implemented in \myHref:

Print

Screen

Fullscreen
For this part of the document, it is identical to the screen variant, except that the page is shorter and thus the first paragraph doesn't entirely fit on the first page. Thus, I'm not including the screenshot in order to spare some bandwidth.

Notes:

• I used LaTeX3 to parse the key/value pairs, but of course one could do something similar with xkeyval in pure LaTeX2e;
• I implemented the fullscreen variant mainly to see what the result would look like with \hypersetup{pdfpagemode=FullScreen}; however, for real presentations, specialized packages such as beamer and pdfscreen should be considered too;
• Since I'm using the outputType and fullScreen logic in several documents of mine, to avoid redundancy I've moved all this logic to a little package I called parmoutput.sty (for “parametrizable output”). In this setup, options can be passed in several ways:

• with \PassOptionsToPackage{outputType=screen,...}{parmoutput}, which is convenient from the Makefile or any batch file controlling the compilation (this works because I use \ProcessKeysOptions from l3keys2e in parmoutput.sty, see here for explanations);
• with \usepackage[outputType=screen,...]{parmoutput} if I want the format choice to be written in the document itself;
• with \ParmOutputSetup{outputType=screen,...}: the same, but allows one to select these options later in the document, possibly in several steps (conceptually similar to hyperref's \hypersetup command).

Currently, parmoutput.sty can be found here, but I can't guarantee the URL will remain stable (I don't guarantee its API will be stable either, yet).

• I'm just starting with LaTeX3, so please forgive any mistakes in this area. :-)

I found myself wanting to declare some rather long macros, including spaces and all that. The following approach worked best for me:

\read 16 to \file
\read 16 to \fname
\documentclass{ blah }
\begin{document}
\section{\fname}
\input \file
\end{document}


which is then called from my makefile with

( echo "mychapter" ; echo "This is about something" ) | pdflatex mainfile.tex


Summary: let TeX/LaTeX read macros from standard input, supply those interactively or through a script or whatever.