Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
    
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 at 8:35
add comment

10 Answers

up vote 10 down vote accepted

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.

share|improve this answer
    
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
2  
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
1  
@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
show 8 more comments

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
share|improve this answer
2  
This is a good solution! –  Will Robertson Aug 31 '10 at 9:01
add comment

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...
share|improve this answer
add comment

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

share|improve this answer
1  
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
add comment

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

Instead of:

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.

share|improve this answer
    
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
    
Well, that happened to be the case for one of the two options I'm using. I'm now thinking about the other. Thanks. –  Faheem Mitha Aug 14 '11 at 19:16
show 2 more comments

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:

List of args passed to LuaLaTeX

share|improve this answer
    
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
add comment

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.

share|improve this answer
    
... which is the same trick Charles Stewart just posted ... –  Taco Hoekwater Aug 10 '10 at 18:41
add comment

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
\endinput\expandafter\expandafter\expandafter\ReadCommandLineArg\fi

\documentclass{article}
\begin{document}
Hello, \CommandLineArg, I am pleased to greet you.
\end{document}
share|improve this answer
add comment

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.

share|improve this answer
add comment

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
\askforoverwritefalse
\generate{\file{\jobname.tex}{\from{\jobname.dtx}{source}}
          \file{\jobname_slides.tex}{\from{\jobname.dtx}{metadata,slides}}
          \file{\jobname_lp.tex}{\from{\jobname.dtx}{metadata,article}}          
          \file{\jobname_handout.tex}{\from{\jobname.dtx}{metadata,slides,handout}}        
          \file{\jobname_ws.tex}{\from{\jobname.dtx}{metadata,worksheet}}
          \file{\jobname_ws-sol.tex}{\from{\jobname.dtx}{metadata,worksheet,solutions}}
}
\endbatchfile
%</driver>
%<*metadata>
\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}
%</metadata>
\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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.