Workflow: LaTeX
Work environement
I use Visual Studio Code with the extension LaTeX Workshop. Most modern TeX processors have similar capabilities (syntax detection, bracket matching, synctex between source and pdf,…), but I prefer VSCode because I can use one program for everything.
As the TeX distribution I use TeXlive. If you’re on Ubuntu, like me, make sure to not install texlive using apt
, as that version will probably be very outdated. See for example this guide for how to install the right version.
Advanced: GitHub Actions
Hosting the git repository allows to run some post-processing of the files, or “continuous integration” in the jargon, using GitHub Actions. When certain events are triggered in the repo (for example, pushing or publishing a tag), GitHub Actions executes the instructions stored in the .yaml
files inside the folder .github/workflows
.
I have a GitHub action that compiles a TeX file to pdf and also prepares a .zip
file ready to upload to arXiv. To install the action, you only have to copy it in the folder and change the filename in line 5 to the name of your main .tex
(it has to be located in the base directory of the repo). To execute it, you have to create and push a tag with
git tag -a versionnumber
git push --tags
After a couple of minutes, the .pdf
and .zip
files will be available at the “Releases” section of the GitHub repo page.
Advanced/optional: Docker
An alternative to install texlive in your computer is to use a pre-compiled version in the form of a Docker image. You can obtain the image with the command
docker pull texlive/texlive
This will take some time. You only have to run this command every time you want a new version of texlive. A new image is released every week, but it is reasonable to update just every couple of months.
Now we want to create a docker volume to store permanently the files, and populate it with the contents of your current folder containing the .tex
files:
docker volume create myvol
docker run --rm -v "$(pwd)":/data -v myvol/app ubuntu cp -r /data /app
Now, the .tex
files can be compiled with
docker run --rm -v myvol:/app -w /app/data texlive/texlive latexmk -f -pdf myfile.tex
When the processing finishes, you can check that the files are generated by mounting the volume
docker run --rm --name temp_ubuntu -it -v myvol -w /app/data ubuntu
and doing a ls
inside the container. You will see the .pdf
, and also all the auxiliary .aux
, .out
, .bib
, etc. This is very useful if you want to keep them to speed up the compiling (for example, try to compile again, latexmk
knows that everything is up-to-date), but don’t want them polluting your folders.
To retrieve the .pdf
, without stopping the container, open a new terminal and execute the command
docker cp temp_ubuntu:/app/data/myfile.pdf .
Docker with VSCode remotes
Working with containers (or rather, inside containers) is much easier with VSCode and the Docker extension. Once that you have pulled texlive and created a volume, launch an interactive texlive container with
docker run -i --rm --name latex -v myvol:/app -w /app/data texlive/texlive
Now click the button in the bottom-left corner of VSCode (the >< symbol), and select “Attach to running container…” A new VSCode window will open, this time with the contents of the container. You can work inside the container as in a normal folder, editing files, viewing PDFs, using extensions… In particular, you can clone the git repository and sync all the files.
If you don’t want to remember all these commands, you can store them as VSCode tasks. Copy this file to .vscode/tasks.json
in your directory (don’t forget to add it to .gitignore
), and launch the tasks with Ctr+Shift+P > “Tasks: Run Tasks”.
Project structure
The LaTeX project files should live in their own directory, with no code or anything else. The directory should correspond to its own git repo.
The base directory should only contain LaTeX source files (.tex
, .bib
, .sty
or .cls
), and the configuration files for git and GitHub. Figures & cia should be organized in folder(s). The products of LaTeX’s compilation, including .pdf
files, shouldn’t be tracked by git. This is achieved by a .gitignore
file in the base directory:
*.pdf
!figures/*.pdf
*.aux
*.log
*.out
*.bbl
The first line excludes all .pdf
files in the repo, but the second line makes an exception for the .pdf
files in the figures
folder (should add a similar exception for each folder). The rest of the lines exclude some of the usual files produced by the compilation. There are many more, depending on your packages and editor, so make sure to add all of them.
The plots generated by matplotlib
or other plotting packages should be saved, if possible, as .pgf
files, which is a TeX graphic format that can be used by including \usepackage{pgf}
at the preamble of the main file, and then
\resizebox{0.45\textwidth}{!}{\input{figures/myplot.pgf}}
where you want to insert the plot. For certain plots, for example scatter plots with many points, a .pgf
takes too much to compile. In those cases, if possible, use a .pdf
. Non-vectorial formats like .png
or jpg
should be the last option.
Subfiles
For large projects, it’s better to keep each chapter or section in a separate file. The package subfiles
allows for the compilation of both the whole document and each individual chapter file, inheriting the preamble of the parent file.
In the parent file, add \usepackage{subfiles}
in the preamble, and \subfile{mychapter.tex}
wherever you want to insert the chapter. In the chapter files, start with \documentclass[myparent.tex]{subfiles}
, and write \begin{document}
and \end{document}
around your TeX code as usual. Chapter files don’t need a preamble before \begin{document}
, they use the same as its parent. Now you can compile the parent file to get the complete document, or each chapter individually.
If you want some part of the text to be different depending on the file being compiled as the whole document or as a standalone chapter, use the command
\ifSubfilesClassLoaded{
This text is only visible when compiled as an individual chapter.
}{
This text is only visible when compiled as the whole document.
}
This is useful, for example, if you want to include the bibliography at the end of individual chapters.
Packages and newcommands
I personally prefer having all the \usepackage
’s at the preamble of the main file. Another option is to collect them in a mypackages.sty
file, and then load them with a single \usepackage{mypackages}
at the preamble. In any case, each package has to be followed by a %-comment with a brief description, in order to make sure that the package is needed.
\newcommand
’s are very useful to define common complex combinations. They should never be used to re-define primitive LaTeX commands (for example, don’t define \be
and \ee
to redefine \begin{equation}
and \end{equation}
, it reduces legibility and you can achieve a similar performance using autocompletion in you editor).
Commands should be defined in a mycommands.sty
file (or even better, in several .sty
files), and loaded with \usepackage{mycommands}
. Also, if possible, document them with %-comments.