Tokenization stage
The general rule is that spaces after control words (\par
, for instance) are ignored, while after control symbols (\!
, for instance) are retained; spaces at the beginning of a line are ignored altogether. Consecutive spaces are transformed into one space token but two consecutive end-of-lines become a \par
(this statement is not fully correct, but not too incorrect for the purposes of this answer).
After the tokenization stage
There is an obvious intermix between tokenization stage and subsequent processing. In what follows "space" will mean "space token" and I won't care about spaces that have already disappeared, such as those after a control word).
It's now important to know that spaces in the input don't always produce spacing in the output. To understand why, it's necessary to learn some theory.
TeX is always in one of three modes: horizontal, vertical or math.
(The above paragraph tells a lie, strictly speaking: there is a circumstance in which it's not in one of these modes, but it's irrelevant for the discussion.)
Under normal circumstances spaces do not produce output in vertical and math mode (let's not discuss the very special settings that make them appear).
It's quite easy to tell when TeX enters math mode: as soon as it sees $
or $$
(which, in LaTeX parlance, are, respectively \(
and all the display math environments, initiated by \[
, \begin{equation}
, \begin{align}
and so on). It exits math mode, returning to the previous mode when it sees the closing $
or $$
(with similar remarks as before for LaTeX).
Roughly speaking, TeX is in vertical mode at the start of a job or after a \par
or when it's beginning a \vbox
or \vtop
or \vcenter
; these are started, in LaTeX, by \parbox
and \begin{minipage}
. However, spaces in vertical and math mode are not suppressed: they are there, but produce no output. This is a cause for some misunderstandings. TeX starts horizontal mode when it sees a character to be typeset, \noindent
, \indent
or some other commands, notably \leavevmode
(this is not an exhaustive list) or when it's starting an \hbox
(for LaTeX it's \mbox
, \makebox
, \fbox
, \colorbox
, ... or the lrbox
environment). In horizontal mode every space that's not absorbed by other rules (see later) produces output.
When TeX is absorbing the preamble of a LaTeX document it is in vertical mode. But a definition such as
\newcommand{\foo}{
bar
}
will produce spaces in the output: the above is equivalent to
\newcommand{\foo}{ bar }
If \foo
is seen at the beginning of a paragraph, the first space will not produce output (TeX is still in vertical mode), but the second will, as the b
will trigger horizontal mode. Conversely
\newcommand{\baz}[1]{\parbox{10cm}{
#1
}}
won't show spurious spaces. The first one, before #1
does nothing because it's seen in vertical mode; the final one, after #1
is suppressed because of the final implicit \par
that ends the \parbox
.
A definition such as
\newcommand{\myop}{
\overset{t }{=}
}
will not need %
to protect end-of-lines (translated into spaces), because it will be used in math mode (or will give an error anyway).
The most important (but easy) rule that should be considered is that tokens in the body of a definition are simply stored and not executed (they can be expanded in a \edef
or \xdef
, but still not executed). The execution is performed (after expansion) when the defined macro is used. The execution of a space token in vertical or math mode does nothing, in horizontal mode it produces a spacing in the output.
Numbers and dimensions
There is a place where space tokens have a peculiar behavior. When TeX is looking for a number or a dimension in order to perform an assignment or when expanding \number
and \romannumeral
, it expands tokens until an unexpandable token appears or a space token is found. In this case, the space is swallowed as part of the process.
This is one aspect to be kept in mind when writing macros. Let's see an example: we want to make a "monthly to-do list". Just a \parbox
with twelve lines labelled by year and month; a loop seems the best approach, with the year given as argument:
\documentclass{article}
\newcount\monthlycount
\newcommand{\monthlytodo}[1]{\par%
\fbox{%
\parbox{10cm}{%
\monthlycount=1%
\loop\ifnum\monthlycount<13%
#1--\number\monthlycount\hrulefill\par%
\advance\monthlycount by 1%
\repeat%
}%
}%
}
\begin{document}
\monthlytodo{2013}
\end{document}
Try it; this will surprise you with
! TeX capacity exceeded, sorry [main memory size=3000000].
Oh, boy! We've made sure that no spurious spaces were inserted by our macro! Why is TeX betraying us? Simple: the input can be written equivalently as
\loop\ifnum\monthlycount<13#1--\number\monthlycount
and #1
is replaced by 2013. So our loop checks whether the current value of \monthlycount
is less than 132013 and stores tokens for the \parbox
until TeX runs out of memory.
Let's try an amended version:
\newcommand{\monthlytodo}[1]{\par
\fbox{%
\parbox{10cm}{
\monthlycount=1
\loop\ifnum\monthlycount<13
#1--\number\monthlycount\hrulefill\par
\advance\monthlycount by 1
\repeat
}%
}%
}
Look, ma! No spurious spaces!
Exercise 1 Why some lines end with %
and other lines don't? We now know that %
is harmful after 13
(and also after the 1
in the preceding line).
Technicality: space tokens are looked for but then swallowed also after keywords (such as by
in the example and the unit names mm
, pt
and so on). There are also a few other places, but this answer is already too long. I'll show only how some of the problems can arise also when using LaTeX functions in this context:
\newcounter{monthlycount}
\newcommand{\monthlytodo}[1]{\par
\fbox{%
\parbox{10cm}{
\setcounter{monthlycount}{1}
\loop\ifnum\value{monthlycount}<13
#1--\arabic{monthlycount}\hrulefill\par
\stepcounter{monthlycount}
\repeat
}%
}%
}
Exercise 2 Why isn't %
necessary in lines 4–9 of the code above?
Best Answer
You can't change the name of the output files/the name of the .pdf file during the TeX run/LaTeX run.
The reason is:
The output files are created anew and opened for writing right at the beginning of the TeX run/LaTeX run.
(E.g., the .log file is created anew and opened for writing right after starting the tex-executable or latex-executable. E.g., the .pdf file is created anew and opened for writing when shipping out the very first page of the document. )
The output files (and thus also the .pdf file) are left open for writing until the end of the TeX run/LaTeX run.
With most computer platforms you can't change the name of a file while that file is open for writing.
But with most TeX-platforms you can run tex-binaries/executables with command line options.
One of these options is the option
-jobname
.If you have the main .tex-file
foo.tex
and compile it by running latex from the command line aspdflatex --jobname=bar foo.tex
, you won't get the output files
foo.aux
,foo.log
andfoo.pdf
, etc, but you will get output filesbar.aux
,bar.log
andbar.pdf
, etc.Also the primitive
\jobname
won't deliver the phrasefoo
in this case but will deliver the phrasebar
.You can't use a macro for changing the names of output files during the LaTeX run but you can go the other direction:
Create a macro which examines whether the expansion of
\jobname
contains some specific phrase and forks accordingly. Be aware that\jobname
spits out explicit space tokens of category code 10(space) and explicit character tokens of category code 12(other).Example:
Save the following example as
test.tex
:Compiling from the command line via
pdflatex test.tex
yieldstest.pdf
which looks like this:Compiling from the command line via
pdflatex --jobname=test_sol test.tex
yieldstest_sol.pdf
which looks like this:Another approach could be:
File
test_sol.tex
:File
test.tex
:Compiling
test_sol.tex
yieldstest_sol.pdf
:Compiling
test.tex
yieldstest.pdf
:A variation on this approach can be having
test.tex
create the filetest_sol.tex
for you automatically in case it does not exist:When you save the example below as
test.tex
and compile it, you will get a filetest.pdf
which contains the text without solutions. You also get a filetest_sol.tex
. If you compile that, it will—via\input
—importtest.tex
in a way wheresol
-environments are included. Thus you get a filetest_sol.pdf
which does also contain solutions:Yet another approach could be using something like the docstrip package. The purpose of the docstrip package is copying files of tex-source-code with having comments removed. It provides means for conditional inclusion of code into the copies.
E.g. if you save the following example as
test.tex
and compile it, you don't get a .pdf file but you get two new text files.One of these text files is named
test_nosol.tex
and its content is:The other of these text files is named
test_sol.tex
and its content is: