[TxMt] smart Latex typesetting

Charilaos Skiadas cskiadas at uchicago.edu
Thu May 18 23:53:40 UTC 2006


I wanted to elaborate a bit on Jeroen's explanation for those not  
very familiar with the "more obsure" TeXnical commands. But first,  
let me bring to everyone's attention the \includeonly command. Say  
you have in your master document:

\include{chapter1}
\include{chapter2}
\include{chapter3}

and you have typeset them once, and hence the .aux files with the  
reference and counter information have been created. Then you want to  
only work on chapter 3. You can add the command:
\includeonly{chapter3}
before those includes, and then, when you typeset, only chapter 3  
gets typeset, BUT the .aux files from the other chapters are being  
used. In other words, this will STILL be typeset as "chapter 3",  
instead of becoming "chapter 1", keeping things just a bit more neat.  
So one way to arrange things is to have the command as:

\includeonly{
chapter1,
chapter2,
chapter3,
}

and then to comment out some of these lines depending on what  
chapters you want typeset.


Ok, on to Jeroen's explanation, which basically answers the question:  
"How to have a file that can be typeset normally, but that when  
include'd into other documents it will compile just fine." The  
question is in essence: How can I make the header and footer stuff of  
a document conditional as to whether the document is included or not.  
The idea is to create two extra files, a header.tex and a footer.tex.  
The header should have the following:

\providecommand{\setflag}{\newif \ifwhole \wholefalse}
\setflag
\ifwhole\else
   \documentclass[11pt,a4paper,twoside,openright]{report}
%  your header stuff here, usepackages etc
\begin{document}
\fi

We'll explain what all this does in a minute. Then the footer should  
contain:

\ifwhole\else
   \end{document}
\fi

Finally, your individual "chapter" files should have the following form:

\input{header.tex}
% your chapter text here
\input{footer.tex}

while your master document should have the form:

\input{header.tex}
\renewcommand{\setflag}{\newif \ifwhole
\wholetrue}
% your chapter includes here:
\include{chapter1}
\include{chapter2}
...
\renewcommand{\setflag}{\newif \ifwhole
\wholefalse}
\input{footer.tex}


Ok, now you are set. Let's explain what has happened here:

Let's start with the text in header.tex. The first line tells TeX to  
provide the command \setflag with definition {\newif\ifwhole 
\wholefalse}. \providecommand checks to see if the command is already  
present, and if it is not it creates it. When we compile this chapter  
file directly, this is the first command encountered, so it hasn't  
been created yet, so it gets created. the second line then executes it.

Ok, so what does \setflag do? It runs the commands \newif\ifwhole 
\wholefalse.
\newif is a TeX primitive. What it does is kind of complicated: It  
takes one argument, which should be of the form \iffoo. In this case  
it is \ifwhole (we could also have written this as \newif{\ifwhole}).  
So, when \newif\iffoo is run, the result is that three new commands  
are being defined. Two of these commands are \footrue and \foofalse,  
and they just set some "magical variable" to true or false  
respectively. The third new command is the command \iffoo, which is  
an "if" command an returns true or false depending on whether  
\footrue or \foofalse is the last command executed.

In out case, after the triple \ifwhole,\wholetrue,\wholefalse has  
been defined, our program runs \wholefalse. So this means that when  
\ifwhole gets called in the next line, it will return true.

Ok, let's move to this next line now. TeX "if" clauses have exactly  
this syntax:
\ifclause
%  stuff that happens when \ifclause is true
\else
%  stuff that happens when \ifclause is false
\fi

In our case, \ifwhole is now false, hence the entire \else block gets  
executed, and we get our header, and later on our footer, hence the  
document can be compiled.

Now let's see what happens when we are in our master document. Then  
we again include the header in the same way. Then we have the  
\renewcommand that redefines the \setflag command to be returning  
\wholetrue when executed. then we go on to include the various  
chapters. When header.tex in loaded in them, the \providecommand will  
not do anything since \setflag has already been defined, hence its  
definition with \wholetrue is the one that will be used. This now  
means that the \ifwhole test succeeds, hence the \else part is not  
executed, so the header data (and similarly the footer data) does not  
get inserted again (avoiding the disaster that would arise if it did).

Finally, after all the chapters have been included, we redefine the  
command again to make sure that the footer gets inserted. (I guess  
you could have directly used \end{document} in the master file  
instead of trying to include the footer file.)

One little question that might have arisen is why I used \input  
instead of \include. The reason is that by design (don't ask me why,  
I don't know) you cannot have nested \include's, while you could have  
nested \input's. The difference between the \input'ed files and the  
\include'd files is that the \include'd files generate their own .aux  
files, while the \input'ed files don't. I am guessing pdfsync might  
also not work with \input'ed files, but I haven't tested this.

Sorry for the long post, I hope it was interesting to some people.

Haris





More information about the textmate mailing list