3

Suppose I have a LaTeX repo, which contains main file and lots of image files, also in LaTeX format (with tikz inside). I would like to achieve multiple goals:

  1. Separate compilation. All images can be compiled separately to their own pdf, and then included into main document.
  2. No meaningless recompilations - if the image source did not change, it is not recompiled.
  3. No hacks. (shell escape included)
  4. One command. It must compile all images which were changed and then compile the main file.
  5. Portability. The solution should work both on Windows and Linux

As I see it, I need a build system, some simple version of cmake. The question is, is there any?

Update #1:

Tried latexmk, as comments suggest. So, there are two possible ways to solve my problem:

  1. Use custom dependencies feature. In my case it looks like this:
add_cus_dep('tex', 'pdf', 1, 'texinclude2pdf');
sub texinclude2pdf {
  system("pdflatex -synctex=1 -aux-directory \"$aux_dir\" -output-directory \"$out_dir/images\" \"$_[0].tex\"");
}

This solution has several problems:

  • It reacts to all *.pdf includes in the main document.
  • It does not allow to specify search directory for tex image files
  • It is a script inside config file - why even use latexmk then?
  • This script uses "system" command - it is no better than shell escape.
  1. Use @default_files:
@default_files = ();
push @default_files, 'images/picture1.tex';
push @default_files, 'main.tex';

That works much better, but it does not allow to specify custom output directory (which is build/images) for image tex inputs.

6
  • 4
    There's arara -- see github.com/islandoftex/arara --, which may be worth looking at. That said, why not use an actual build system, like cmake itself?
    – chsk
    Apr 12, 2021 at 14:08
  • 1
    Oh, and lest I forget: welcome to TeX.SE!
    – chsk
    Apr 12, 2021 at 14:09
  • 1
    Seems like tikz-externalize should be sufficient? See the manual Section 111 Externalizing Graphics on page 1178.
    – Marijn
    Apr 12, 2021 at 14:12
  • 4
    I suggest trying latexmk. It was explicitly designed to satisfy all your requirements. It's part of both TeXLive and MiKTeX distributions. Under TeXLive, run texdoc latexmk to see the documentation. Do I understand correctly that most/all of the tikz stuff is in the image files, not in the main document? If so, see the section Custom Dependencies that starts at about p. 44 of the documentation. Apr 12, 2021 at 14:55
  • 1
    Addition to @chsk's comment: You can search for questions with the arara tag: tex.stackexchange.com/questions/tagged/arara Apr 25, 2021 at 0:13

1 Answer 1

1

I do like do use Docker+Make (or any build automation tool) to achieve this.

  1. Separate compilation. We compile figures separately in a separate Docker container, and the document itself in another. The document will be compiled with latexmk (or however you want really) if needed.
  2. No meaningless recompilations. We use GNU Make to achieve this. Figures will be rebuilt if their code changed.
  3. No hacks. OK, you got me here.
  4. One command. make figures render.
  5. Portability. Docker is of course portable, and GNU Make should be but ymmv.

See How to annoy your co-authors: a Gitlab CI pipeline for LaTeX for how to achieve this - including building using Gitlab CI. Using Gitlab CI here has the advantage of increasing portability.

build system

A minimal example

The directory structure is

.
├── Makefile
├── images
│   ├── Makefile
│   └── image1.tex
└── main.tex

where the first Makefile contains

all: main.pdf

.PHONY: images
main.pdf: images

images:
    docker run -it --rm -w /data/ -v`pwd`:/data  martisak/texlive:2022 -- sh -c "make -C images"

%.pdf: %.tex
    docker run --rm -w /data/ -v`pwd`:/data martisak/texlive:2022 -- sh -c "latexmk -pdf $<"

clean:
    -make -C images clean
    latexmk -CA
    -rm -rf build

and images/Makefile contains

IMAGES_DIR = ../images
BUILD_DIR = ../build/images

IMAGES_TEX_FILES = $(wildcard $(IMAGES_DIR)/*.tex)
IMAGES_PDF_FILES = $(patsubst $(IMAGES_DIR)/%.tex, $(BUILD_DIR)/%.pdf, $(IMAGES_TEX_FILES))

.PHONY: all clean

all: $(IMAGES_PDF_FILES)

$(BUILD_DIR)/%.pdf: $(IMAGES_DIR)/%.tex
    @mkdir -p $(BUILD_DIR)
    latexmk -pdf -output-directory=$(BUILD_DIR) $<

clean:
    latexmk -CA

For completeness, images/image1.tex is

\documentclass[tikz, border=2pt]{standalone}

\begin{document}

\begin{tikzpicture}
  \draw (0,0) circle (1);
  \fill (0,0) circle (2pt);
\end{tikzpicture}

\end{document}

and main.tex:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\title{An example}
\begin{document}

\begin{figure}[htbp]
    \centering
    \includegraphics[width=0.5\textwidth]{build/images/image1.pdf}
    \caption{caption}
    \label{fig:label}
\end{figure}

\end{document}

You can omit the Docker-container if you wish, and run latexmk directly.

Start compilation with make.

3
  • 1
    I feel like this comes down to "Q: I would like a build system". "A: Try a build automation tool." It seems like you've hidden all of the interesting stuff in the Makefile, which isn't part of your posted answer.
    – Teepeemm
    Aug 22, 2023 at 13:55
  • @Teepeemm Valid point, I will create a simple example and edit. Aug 22, 2023 at 14:06
  • 1
    Wow, thanks! I did something similar in my repos. I wrap main build system latexmk with make, which also orchestrates images compilation as well as manages containers. github.com/rudenkornk/latex_experiments Aug 24, 2023 at 17:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .