In this answer I will explain how does "precompiled preamble" works, how to use it in PDFLaTeX/XeLaTeX/LuaLaTeX, as well as some pitfalls.
Normally just follow the instruction suffices. However if something goes wrong, knowing what is going on under the hood helps you to diagnose the issue.
How to use mylatexformat
? [basic instruction]
Say, you have a normal LaTeX document a.tex
:
\documentclass{article}
\usepackage{amsmath}
\begin{document}
\begin{align*}
1+2 &= 3
\end{align*}
\end{document}
Assume a.tex
does not contain space, or special character such as %#{}~
.
First you execute pdftex -ini -jobname=b "&pdflatex" mylatexformat.ltx a.tex
. This will generate b.fmt
. (the file name is specified by -jobname
, if not specified default to mylatexformat.fmt
)
Then you execute pdftex "&b" a.tex
. This will generate a.pdf
as usual.
Remark on reading mylatexformat
package documentation
-ini
and -initialize
is the same thing.
- Its instruction on writing
"""abc.tex"""
on the command-line is for Windows only, on Linux/Bash you need
"\"abc.tex\""
. (basically pass the file name wrapped in one layer of double quote to TeX)
- If the first line of
a.tex
is %&b
, then the 2nd command you don't need to explicitly specify "&b"
on the command-line,
anything such as pdftex a.tex
or pdflatex a.tex
will suffice. Nevertheless this method does not work with LuaTeX.
How to use mylatexformat
? [advanced instruction]
Use XeLaTeX/LuaLaTeX instead of PDFLaTeX
Replace pdftex
with xetex
or luahbtex
respectively. Furthermore you need to replace the preloaded format name &pdflatex
with &xelatex
or &lualatex
.
You can tell that xelatex
and lualatex
executable are just xetex
and luahbtex
with xelatex.fmt
and lualatex.fmt
formats preloaded by seeing what it prints out at the beginning.
Furthermore note that first-line %&b
(as written in package documentation) will not work in LuaTeX.
For example:
% a.tex
\documentclass{article}
\usepackage{amsmath}
\csname endofdump\endcsname
\usepackage{unicode-math} % incompatible with precompiled preamble, see below
\begin{document}
\begin{align*}
1+2 &= 3
\end{align*}
\end{document}
Then in the shell:
luahbtex -ini -jobname=b "&lualatex" mylatexformat.ltx a.tex
luahbtex "&b" a.tex
This only speed up by a small amount, in my experience for an almost-empty document it is 0.6s → 0.4s.
Do not precompile the whole preamble
If some part of the preamble either:
- changes frequently (so you don't want to include into the format), or
- relies on
\jobname
(for example \usepackage{currfile}
, or pythontex
), or
- is incompatible with TeX format, such as
\usepackage{unicode-math}
or \usepackage{fontspec}
, (see "two other classes of things that can not be dumped." in David Carlisle's answer)
- For some reason for LuaLaTeX even
tikz
is incompatible.
- I don't see any easy way to easily tell what package is compatible and what is not, you will just have to try including/excluding it.
then you must exclude it from the preamble.
To do that use \csname endofdump\endcsname
(the spelling must be exactly like that) -- see mylatexformat
documentation for
more details. Using this instead of \endofdump
makes sure the file is compilable (the line is simply ignored) if mylatexformat
/precompiled preamble is not used (i.e. the file is compiled the normal way).
What is precompiled preamble/format?
Basically, it is just using TeX's INITeX feature to speed up processing of a fixed preamble part.
TeX supports generating formats that can be loaded later.
Refer to TeX by Topic chapter 33 "TeX and the Outside World" for some details.
(Reading TeXbook might be a bit confusing, just keep in mind that typing anything on the command-line is equivalent to typing it on the **
first line in the TeX prompt.)
In short:
A format file (usually with extension .fmt) is a compact dump of TEX’s internal structures. Loading a format file takes a considerably shorter time than would be needed for loading the font information and the macros that constitute the format.
So you can "define some commands, dump the internal state to a file", then when you "load" that file it's "as if" the commands have been defined similar to at the time how the format was dumped.
For an example:
% preamble.tex
\documentclass{article}
\usepackage{amsmath}
\dump
% a.tex
\begin{document}
\begin{align*}
1+2 &= 3
\end{align*}
\end{document}
In the shell execute pdftex -ini "&pdflatex" preamble.tex
, this will
- start with the existing
pdflatex.fmt
format (might be at /var/lib/texmf/web2c/pdftex/pdflatex.fmt
depends on operating system etc.)
- execute from file
preamble.tex
- when
\dump
is executed generates file preamble.fmt
.
The -ini
is needed to enable the \dump
command.
After that if pdftex "&preamble" a.tex
is executed (this means "execute a.tex
with preloaded format preamble.fmt
") it will generate a.pdf
with the correct content. (For an analogue, pdftex "&pdflatex" a.tex
is equivalent to pdflatex a.tex
)
What does mylatexformat
package do?
As you can see above, it's rather inconvenient to have to split the file into separate preamble.tex
.
So mylatexformat
allow you to put them in the same file and it will automatically detect the split between the preamble and the main file.
How does mylatexformat
work (regarding the command-line)?
There's 2 steps -- generating the format, and using the format.
In the first step, apart from -jobname
, the command-line is:
pdftex -ini "&pdflatex" mylatexformat.ltx a.tex
Because of historical reasons, it's made such that (almost) anything put on the command-line is equivalent to typing it to the first
line of **
prompt. So you can also run pdftex -ini
then on **
prompt type in &pdflatex mylatexformat.ltx a.tex
, both are equivalent.
Most of this is familiar. Recall that pdftex -ini "&pdflatex" mylatexformat.ltx
will start with preloaded format pdflatex.fmt
and execute content of file mylatexformat.ltx
. However, the additional a.tex
will be put on the input stream.
At the very end of mylatexformat.ltx
, after redefining \begin
etc. there's
%% Trick lookahead to allow mylatex.ltx and the document filename to be
%% given on the same command line. (initex &latex mylatex.ltx {abc.tex})
\expandafter\input\endinput%
\endinput
so effectively (some TeX programming knowledge is needed) \input a.tex
is executed. See also wipet's answer.
That's why it's useful to pass another pair of quotes in the command-line.
For other details of the implementation (how it separates the preamble from the document) read the documentation.
\include
many chapters you can use\includeonly
in your master file (book.tex
) to compile just the chapters you are editing at the moment.\include
and\includeonly
works only with separating the file's content on different pages. But for your final compilation you can change those\includeonly
back to\input
s. • Also related:mylatexformat
\newcommand
. Withmylatexformat
you can compile files with the same preamble, the files must have a\begin{document}
and\end{document}
book
document intopreamble.tex
andbook.tex
? Also, what is the exact wording of the error message?