# 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?

-
There doesn't seem to be a standard way and all the solution here are perfectly fine. I chose Charles' answer as accepted because it is the most cross-platform way. Even if make is not available it is quite easy to do that by hand. – Caramdir Aug 11 '10 at 9:38
This is similar to another question, so some of the answers there might be useful – Norman Gray Aug 12 '10 at 14:30
similar question in tex.stackexchange.com/questions/170542/… – meduz Apr 14 '14 at 8:35

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. – Loop Space 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
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
@Andrew: I tried that of course. It wouldn't accept it. That stupid rule about not enough characters changed. – Faheem Mitha May 22 '11 at 17:50

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 is a good solution! – Will Robertson Aug 31 '10 at 9:01
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

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\handout
\input{flags}
\documentclass...

-

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. – Jubobs Nov 18 '13 at 16:37

Just for fun: instead of giving the arguments on the command-line before the filename, we can do the opposite. This allows a more natural syntax for arguments (which don't have to be TeX code like \def\flag{1}). Used as pdflatex file argument. The file is opened, \CommandLineArg is not yet defined, so TeX sees \endinput, and decides to stop reading that file at the end of the current line. The \expandafter expand the \fi, and expand beyond the end of the file (which has occured because of \endinput), to avoid some 'runaway argument' error. Then the file is input again with the flag set. In this second reading, \ifdefined is true, and \endinput is never read, so TeX happily continues with the main part of the file.

\def\ReadCommandLineArg#1 {%
\def\CommandLineArg{#1}%
\input{\jobname}}
\unless\ifdefined\CommandLineArg

\documentclass{article}
\begin{document}
Hello, \CommandLineArg, I am pleased to greet you.
\end{document}

-
It works, and it can even handle more command line options, but it is not easy to understand or manipulate (not straightforward for people who are less familiar with LaTeX) – Eran Marom Aug 5 '14 at 12:29

I know that your question is focused on LaTeX. I just want to mention that ConTeXt provides such an option. You can use

context --mode=handout filename


to enable handout mode. See ConTeXt wiki for details

-
You are right, I'm most interested in a solution for LaTeX. But it is useful to know that it can easily be done with ConTeXt. I guess at some point I should take a closer look at ConTeXt. – Caramdir Aug 10 '10 at 17:41

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

What ConTeXt does is, in simplified form, something like this:

# Makefile rule
handout:
echo "\\RequirePackage[handout]{beamer}" > myfile-options.tex
echo "\\endinput" >> myfile-options.tex
pdflatex myfile
rm myfile-options.tex


Where myfile.tex (loads a document class that ...) starts with

\InputIfFileExists{\jobname-options.tex}


You can then adjust the Makefile rule to put whatever you like in the options file.

-
... which is the same trick Charles Stewart just posted ... – Taco Hoekwater Aug 10 '10 at 18:41

If you are using Rubber to compile your documents, the following solution seems to work very well:

• Put almost everything in main.tex.

• Create files like slides.tex, handout.tex, etc. These are short files contain the parts that are different between the two versions, followed by \input{main}. For example, they may contain \documentclass with different options. Or they may load a different set of packages. Or they may define the same macro in two different ways, etc. These files may also contain rubber directives in comments.

• Then I can simply run rubber -Wall slides.tex handout.tex and I will have up-to-date versions of both slides.pdf and handout.pdf. Or just rubber -Wall handout.tex if I don't need the slides.

You don't need to do any scripting or write complicated Makefiles. In many cases, you don't even need to use any \if... commands. Instead of defining a flag and doing something depending on the flag in main.tex, you can do the right thing directly in slides.tex and handout.tex. For example:

• slides.tex:

\documentclass{beamer}
\input{main}

• handout.tex:

\documentclass[handout]{beamer}
\input{main}


You can also re-use these files in different projects; just drop in a different main.tex.

-

My solution is a bit unique: docstrip. Instead of my master file being a .tex file, it's a docstrip file with .dtx extension. The header for each file is the docstrip \generate command, and the rest of the file uses docstrip's %<tag> mechanism to conditionally include/exclude stuff. For example (sorry, this isn't very minimal):

%<*driver>
\input docstrip.tex
\newwrite\configfile
\immediate\openout\configfile=config.def
\immediate\write\configfile{\string\def\string\rootjobname{\jobname}}
\immediate\closeout\configfile
\generate{\file{\jobname.tex}{\from{\jobname.dtx}{source}}
}
\endbatchfile
%</driver>
\input config.def
\let\oldrootjobname=\rootjobname
% Change these!
\def\longtitle{Section 3.7 \\ Indeterminate Forms and L'H\^opital's Rule}
\def\shorttitle{L'H\^opital's Rule}
\def\longcoursename{V63.0121.002.2010Su, Calculus I}
\def\shortcoursename{V63.0121, Calculus I}
\author{\longcoursename}
%<*slides>
\documentclass[ignorenonframetext,
%<handout>handout
]{beamer}
\usepackage[tikz,beamerpresentation]{V63-0121-2010Su}
\author[\shortcoursename]{\longcoursename}
\title[\shorttitle]{\longtitle}
%<*handout>
\usepackage{pgfpages}
\usepackage{handoutWithNotes}
\pgfpagesuselayout{3 on 1 with notes}[letterpaper]
%</handout>
%</slides>
%<*article>
\documentclass{article}
\usepackage{beamerarticle}
\usepackage[tikz,
]{V63-0121-2010Su}
\title{\longtitle}
%</article>
%<*worksheet>
\documentclass{article}
\title{\longtitle}
\usepackage[worksheet,tikz,
%<solutions>solutions,
]{V63-0121-2010Su}
\author{\shortcoursename}
\date{Summer 2010}
%</worksheet>
%<*source>
\date{June 7, 2010}
% ... beamer slides ...
\end{document}
%</source>
%<*article>
\usepackage{beamerarticle}
\setjobnamebeamerversion{\rootjobname_slides}
%</article>
%<*slides|article>
\input{\rootjobname_\secnum.tex}
%</slides|article>
%<*worksheet>
\begin{document}
\maketitle
% worksheet material ...
\end{document}
%</worksheet>


If you tex or latex the file foo.dtx, the individual files foo_slides.tex, foo_handout.tex, foo_lp.tex (for lesson plan, my personal notes), foo_ws.tex (worksheet), foo_ws-sol.tex (worksheet solutions) are all generated. Then you tex or latex whichever of these you want to produce.

Advantages of this method are that copying and reusing the file in the next semester involve copying a single file and editing. It's as portable as any .tex file—no extra utility or scripting language needed. The produced files don't have to be compiled with anything other than tex either. You get one document:one file which makes it easier to know what's in a document by its file name.

Disadvantages are that it's kinda crufty, and some people may not like running TeX on two files every time they want to preview something they are editing. With TeXShop this is actually pretty easy because you can open files for preview, which means you only see the pdf and not the source. So I edit the .dtx file, open the derivative .tex file for preview, and typeset the .dtx and derivative .pdf in a single sequence of keys. Works for me.

-

I did something with a very naive approach, reading what is suggested here I definitively have to change my code. Anyway, if someone is interested here it is:

https://github.com/rvelseg/MuDoVLaGM

it uses mainly make, and sed to comment and uncomment fragments of a main document.

-
The comment package might be useful too for your approach. – Caramdir Oct 17 '14 at 5:50