Submitting with TikZ-Feynman
Posted on Mon 26 January 2015One of TikZ-Feynman’s strengths is its simple syntax which is only possible by having vertex positioned automatically by graph drawing algorithms which are implement in the Lua scripting language. As a result, LuaTeX is required to compile documents that use TikZ-Feynman. Although LuaTeX is intended to supplant pdfTeX, the latter remains the standard when it comes to submitting to journals and the arXiv. Fortunately, there is a way to both use TikZ-Feynman and still submit to journals as long as they use a version of TikZ released after 2013.
Note: Since TikZ-Feynman was released recently, it will not yet be installed on most TeX distributions and I provide instructions at the bottom of this post detailing how it can be bundled easily. Regarding arXiv in particular, they have not updated their LaTeX packages in the past five years. As a result, they are using a version of TikZ that is incompatible with TikZ-Feynman. Hopefully this will be fixed in the next few months.
There exists a large class of graph drawing algorithms which automatically determine the placement of vertices in a graph. Simple graph drawing algorithms can be implemented in pure TeX but they are not powerful enough to be produce Feynman diagrams; on the other hand, more complex force-based algorithms quickly become too complex to be practical to implement purely in TeX. In order to implement these more complex graph drawing algorithms into PGF/TikZ, Jannis Pohlmann used the Lua_ scripting language1 which has native support provided through the LuaTeX engine.
Although LuaTeX is now considered stable and has been shipped with every TeXLive distribution since 2009, they have not reached version 1.0 yet. As a result, most journals are reluctant to use LuaTeX and the arXiv does not support LuaTeX either. Hopefully this will all change when LuaTeX reaches version 1.0 but until then, submitting to these journals or the arXiv can still be achieved by externalizing the diagrams.
If you just want to know what you need to add to the preamble to make it work,
here is the code (for Linux and probably OS X). You will need to initially
compile with -shell-escape
and when submitting to the arXiv or a journal,
make sure to include every .pdf
and .md5
file inside the pgf-img
directory on submission. For more details as to how this works, read on.
1 2 3 4 5 6 7 8 9 | %% After having loaded `tikz` or `tikz-feynman`
\usetikzlibrary{external}
\immediate\write18{mkdir -p pgf-img}
\tikzexternalize[
prefix=pgf-img/,
system call={
lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname="\image" "\texsource" || rm "\image.pdf"
},
]
|
Note that errors relating to a particular image will be stored inside that
images’ .log
file inside the pgf-img
subdirectory (usually, just look
for any .log
file which doesn’t have an accompanying .pdf
).
The Basics
TikZ diagrams can become very complex which can result in very long compilation times. To alleviate this, Feuersänger developed the externalization library (§50, PGF/TikZ manual) which compiles the diagrams separately. In particular, this library can used to to ensure that the LuaTeX engine is used regardless of what is generating the initial document. The most minimal way to load the externalization library is as follows:
1 2 | \usetikzlibrary{external} %% Load the `external` library
\tikzexternalize %% Activate externalization
|
By default, the externalization library uses the same TeX engine to generate diagrams as the one used to generate the main document. We can override this by specifying the system call to use:
1 2 3 4 5 6 | \usetikzlibrary{external} %% Load the `external` library
\tikzexternalize[ %% Activate externalization
system call={ %% Use lualatex in system call
lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname="\image" "\texsource"
},
]
|
This is the minimal configuration that will ensure TikZ-Feynman works, even if you don’t compile with the LuaTeX engine. The disadvantage now is that the directory will be cluttered with four new file for each diagram. Combined with all the other temporary files TeX generates, it can become quite cumbersome. (For example, the documentation for TikZ-Feynman contains over 60 diagrams which will result in over 240 additional files!)
To make the clutter more manageable, we can make sure that the externalization
library places all these extra files in a subdirectory. Let’s call that
pgf-img
since it will contain all images powered by PGF. To ensure that the
externalization library places files inside pgf-img
, we need to prefix each
filename with pgf-img/
.
In addition to prefixing the filenames, we also need to make sure that the
pgf-img
directory exists beforehand, and ideally this should also be
automated. Fortunately, TeX actually allows system calls directly from the file
through the \write18
command. This will require -shell-escape
to be
used with pdflatex
or whatever program you are compiling the master TeX file with.
1 2 3 4 5 6 7 8 | \usetikzlibrary{external} %% Load the `external` library
\immediate\write18{mkdir -p pgf-img} %% Create `pgf-img` directory
\tikzexternalize[ %% Activate externalization
prefix=pgf-img/, %% Avoid cluttering the directory
system call={ %% Use lualatex in system call
lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname="\image" "\texsource"
},
]
|
At this stage, the above snippet of code will work most of the time but
occasionally you’ll find that it fails to compile—-usually after the
previous build was aborted. This is due to the PDF from the previous run being
left in a corrupt state and then subsequent runs trying and failing to read the
corrupt PDF. The fix for this is the delete the corrupt PDF file whenever
something goes wrong. In sh
, it is possible to run a program if the
previous one failed by using the OR operator ||
(you may have to scroll to
view the change):
1 2 3 4 5 6 7 8 | \usetikzlibrary{external} %% Load the `external` library
\immediate\write18{mkdir -p pgf-img} %% Create `pgf-img` directory
\tikzexternalize[ %% Activate externalization
prefix=pgf-img/, %% Avoid cluttering the directory
system call={ %% Use lualatex in system call
lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname="\image" "\texsource" || rm "\image.pdf"
},
]
|
When you call you TeX engine of preference, you should see that LuaLaTeX is
invoked whenever it encounters a TikZ picture. The pgf-img
directory will
be populated with a .dpth
, .log
, .md5
and .pdf
file for each
picture. The .pdf
contains the generated picture and the .md5
contains
a hash that is used to check whether the PDF needs to be regenerated (and if it
is missing, the PDF is always regenerated); the other two extensions are only
temporary files.
When submitting the source file, you will have to include the .md5
and
.pdf
files so when they compile your document, their system will simply
import the pre-generated .pdf
instead of trying to generate them again.
Speeding It Up
Each time a TikZ picture is encountered, LuaLaTeX is dispatched to generate the PDF. To do this, LuaLaTeX load all the packages in your preamble, the fonts your document uses and various other system files which significantly lengthen how much time it takes to compile the master document if it has to generate new pictures. Fortunately, subsequent runs will be faster and in many cases this is not an issue.
There is no getting around the load time of LuaLaTeX (which only becomes an issue when it needs to be loaded many times), so the only way to speed up compilation is to run LuaLaTeX in parallel. The externalization library has, as one of its options, the possibility of creating a makefile which needs to be executed separately and parallelizing a makefile is really easy. First we need to instruct the externalization library to generate this makefile:
1 2 3 4 5 6 7 8 9 | \usetikzlibrary{external} %% Load the `external` library
\immediate\write18{mkdir -p pgf-img} %% Create `pgf-img` directory
\tikzexternalize[ %% Activate externalization
prefix=pgf-img/, %% Avoid cluttering the directory
mode=list and make, %% Generate a makefile to run later
system call={ %% Use lualatex in system call
lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname="\image" "\texsource" || rm "\image.pdf"
},
]
|
After processing the master TeX file, a new <name>.makefile
is generated and
can be executed with:
1 | make -j 4 -f <name>.makefile
|
The -j 4
option instructs make
to run at most four tasks in parallel and
-f
tells make
which file to read (by default, it searches for
./makefile
or ./Makefile
).
Finally, I use LatexMk in order to compile TeX files because it will
automatically run all the extra steps for bibliographies, indices, and for
changed references. By default, it isn’t configured to handle TikZ’s
makefiles by this can be fixed by adding the following to ~/.latexmkrc
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # Adapted from http://tex.stackexchange.com/a/145878/26980
# Add a few files to cleanup
push @generated_exts, 'figlist', 'ist', 'makefile', 'unq';
# On the initial run, %tikzexternalflag is set to an empty list (when
# it reads this .latexmkrc).
#
# %tikzexternalflag is then set after successfully running make.
our %tikzexternalflag = ();
$pdflatex = 'internal tikzpdflatex -shell-escape -synctex=1 %O %S %B';
sub tikzpdflatex {
our %externalflag;
my $n = scalar(@_);
my @args = @_[0 .. $n - 2];
my $base = $_[$n - 1];
system 'lualatex', @args;
# Exit with error on failure
if ($? != 0) {
return $?
}
if ( !defined $externalflag->{$base} ) {
$externalflag->{$base} = 1;
if ( -e "$base.makefile" ) {
system ("$make -j5 -f $base.makefile");
}
}
return $?;
}
|
Depending on your computer and your preferences, you may wish to replace
'lualatex'
with whatever engine you prefer on line 18; and you may wish to
replace -j5
on line 27 with a smaller number if you computer has fewer cores
(I have it set to be one more than the number of cores I have).
To compile the document, you now need to run latexmk <name>.tex
once and
everything should work fine.2_
Bundling TikZ-Feynman
If the journal your are submitting to is using a version of TikZ released after 2013 and they are only missing TikZ-Feynman, then you can quite easily bundle TikZ-Feynman along with your submission. Firstly, you will need to obtain the appropriate version from Github and copy the needed files to the same directory as your TeX master file. This can be all achieved with:
1 2 3 | wget https://github.com/JP-Ellis/tikz-feynman/archive/v1.0.0.tar.gz -O - | tar -xz
mv tikz-feynman-1.0.0/*.code.tex tikz-feynman-1.0.0/*.sty tikz-feynman-1.0.0/*.lua .
rm -rvf tikz-feynman-1.0.0
|
Next, you need to prepare your submission to journal as usual and make sure that
all images in pgf-img/
are up to date. Assuming that your master file
consists of only TeX files, then you can create a tarball with everything in it with:
1 | tar -cavf submission.tar *.tex *.sty pgf-img/
|
Of course if you have extra dependencies, you will need to adapt the above command to suit your needs.
The arXiv, unfortunately, has not updated their LaTeX packages in the past five years and they are using a version of TikZ that is incompatible with TikZ-Feynman. They have announced an upgrade, but until that is complete, submission to the arXiv with TikZ-Feynman will require you to ask permission to submit the PDF only.
-
J. Pohlmann, Configurable graph drawing algorithms for the TikZ graphics description language, Masters thesis (Institute of Theoretical Computer Science, Universität zu Lübeck, Lübeck, Germany, 2011). ↩
-
Note that on the very first run, LatexMk won’t actually recompile the master TeX file after having generated the pictures. This occurs only on the very first run. ↩