So as promised in the comments, here is my current setup for image-heavy documents using TikZ and similar (the below uses TikZ, circuitikz
, includes SVGs, plots created with Python and possibly other images):
I maintain a shared preamble for all standalone
TeX creations (like those of TikZ and circuitikz
images) to sync stuff like font sizes and other stuff related to design. Additionally there is a shared preamble for every TikZ picture and a shared one for the circuitikz
stuff.
For my latest work the shared preamble only includes
\documentclass[tikz]{standalone}
the one dedicated to all ordinary TikZ pictures is in fact empty and the one for all the circuitikz
images contains
\usepackage[european,straightvoltages]{circuitikz}
For every image I can now create a file which contains only a \begin{document}
and \end{document}
and the contents in between (additional preamble material for that file could be added here, too). circuitikz
image code is saved as img/<filename>.circuit
, ordinary TikZ pictures as img/<filename>.tikz
.
The next thing to setup is a Makefile for the main document and another Makefile for all those images.
The main Makefile for my latest project looks like this:
# User defined variables {{{
##########################################
# engine to be used
TEX = pdflatex
# flags for that engine
FLAGS = -halt-on-error -8bit
# relative path to included TeX-files
TEXF = ./tex
# relative path to included TeX-files containing only preamble stuff
PREF = ./preamble
# relative path to img folder containing tikz and circuit files
IMGF = ./img
##########################################
# }}}
# Automatically defined variables {{{
##########################################
FILE = $(wildcard ./*.tex)
SFILES = $(wildcard $(TEXF)/*.tex)
PREAMB = $(wildcard $(PREF)/*.tex)
PREAMB += $(wildcard $(PREF)/*.sty)
PREAMB += $(wildcard ./*.sty)
NAME = $(FILE:%.tex=%)
OUT = $(NAME).pdf
FMT = $(NAME).fmt
##########################################
# }}}
# default target {{{
## the name 'quick' maybe misleading! 'all' might be faster if $(FILE) hasn't
## changed. 'quick' is for quickly running TeX assuming that you know what
## you're doing
quick: $(FMT) img
$(TEX) $(FLAGS) -fmt="$(NAME)" $(FILE)
#$(TEX) $(FLAGS) $(FILE);
# }}}
all: img $(OUT) #bib
$(OUT): $(FILE) $(SFILES) $(PREAMB)# {{{
$(TEX) $(FLAGS) $(FILE);
$(TEX) $(FLAGS) $(NAME).tex > /dev/null;
$(TEX) $(FLAGS) $(NAME).tex > /dev/null;
# }}}
$(FMT): $(FILE) $(PREAMB)# {{{
$(TEX) -ini -enc -jobname="$(NAME)" "&$(TEX)" mylatexformat.ltx """$(FILE)"""
# }}}
img: # {{{
cd $(IMGF); make -j4
# }}}
.PHONY: clean cleantex cleansubfoldertex quick all img clean_img
clean: cleantex cleansubfoldertex clean_img
cleantex: # {{{
-rm $(shell find $(NAME)\.* | grep -Ev '\.tex$$' | grep -Ev '\.sty$$' | grep -Ev '\.bib$$')
# }}}
cleansubfoldertex: # {{{
-cd $(TEXF); rm $(shell cd $(TEXF); find * | grep -v tex);
# }}}
clean_img: # {{{
-cd $(IMGF); make clean
# }}}
This Makefile has the default target quick, which will build a custom format if something in ./preamble/
or the main file has changed, call the Makefile for the images with the option -j4
which means that that Makefile can run 4 processes in parallel and build the PDF. It assumes that there is only one file with the file extension .tex
which is the main file of the project.
The other targets are:
all
: running TeX three times (and building the images if necessary)
clean
: calling cleantex
, cleansubfoldertex
and clean_img
cleantex
: delete every file having the same name as the main file, except those having the file extensions .tex
, .sty
and .bib
cleansubfoldertex
: delete all files in ./tex/
except those containing tex
in their names or file extension
clean_img
: call the img Makefile with clean
The second Makefile should be placed in the ./img/
sub folder. It defines the rules to build the different image file types.
# User defined variables {{{
##########################################
# engine to use for everything that needs TeX
TEX = pdflatex
# flags for the TeX engine
TFLAG = -halt-on-error
# Python call
PY = python
# flags for python
PFLAG =
# inkscape call (used for conversion of svg to pdf)
INK = inkscape
# flags for inkscape
IFLAG = --without-gui
# output option for inkscape
IOOPT = --export-pdf=
# relative path to included TeX-files containing preamble stuff
# circuit related preamble
CPREAMB = circuit_preamble.tex
# tikz related preamble
TPREAMB = tikz_preamble.tex
# shared preamble
MPREAMB = ct_preamble.tex
# a configuration file for python
PYCONF = custom_rcParams.py
# file extensions of different files
# for the tikz pictures
TIKZ = tikz
# for circuitikz pictures
CIRC = circuit
# for plots created by python
PYPL = plot.py
# for svg files
SVG = svg
##########################################
# }}}
# Automatically defined variables {{{
##########################################
CFILES = $(wildcard ./*.$(CIRC))
PFILES = $(wildcard ./*.$(PYPL))
SFILES = $(wildcard ./*.$(SVG))
TFILES = $(wildcard ./*.$(TIKZ))
COUT = $(CFILES:%.$(CIRC)=%.$(CIRC).pdf)
POUT = $(PFILES:%.$(PYPL)=%.$(PYPL).pdf)
SOUT = $(SFILES:%.$(SVG)=%.$(SVG).pdf)
TOUT = $(TFILES:%.$(TIKZ)=%.$(TIKZ).pdf)
##########################################
# }}}
all: circuit pypl svg tikz
circuit: $(COUT)
pypl: $(POUT)
svg: $(SOUT)
tikz: $(TOUT)
%.$(CIRC).pdf: %.$(CIRC) $(CPREAMB) $(MPREAMB)
$(TEX) $(TFLAG) -jobname="$<" "\input{$(MPREAMB)}\input{$(CPREAMB)}\input{$<}"
-rm $<.aux
-rm $<.log
%.$(TIKZ).pdf: %.$(TIKZ) $(TPREAMB) $(MPREAMB)
$(TEX) $(TFLAG) -jobname="$<" "\input{$(MPREAMB)}\input{$(TPREAMB)}\input{$<}"
-rm $<.aux
-rm $<.log
%.$(PYPL).pdf: %.$(PYPL) $(PYCONF)
$(PY) $(PFLAG) $<
%.$(SVG).pdf: %.$(SVG)
$(INK) $(IFLAG) $< $(IOOPT)"$<.pdf"
.PHONY: all circuit pypl svg tikz clean clean_tikz clean_circuit clean_pypl clean_svg
clean: clean_tikz clean_circuit clean_pypl clean_svg
clean_circuit:
-rm $(COUT)
clean_tikz:
-rm $(TOUT)
clean_pypl:
-rm $(POUT)
clean_svg:
-rm $(SOUT)
All the PDFs created by it have the naming scheme <filename>.<type>.pdf
, so every TikZ picture which's source was named <filename>.tikz
will create a PDF named <filename>.tikz.pdf
. This way the clean
target knows which PDFs can be removed and you can distinguish the files and use different \includegraphics
options based on the filename.
One important thing left to do is setting up graphicx
to recognize those image files as PDFs. This is done with
\usepackage[]{graphicx}
\DeclareGraphicsRule{.circuit.pdf}{pdf}{*}{}
\DeclareGraphicsRule{.tikz.pdf}{pdf}{*}{}
\DeclareGraphicsRule{.plot.py.pdf}{pdf}{*}{}
\DeclareGraphicsRule{.svg.pdf}{pdf}{*}{}
Now you can include your TikZ picture with \includegraphics{img/<filename>.tikz.pdf}
.
Running make
in the directory of your main file should build everything necessary for your finished PDF.
The overall approach keeps a clean structure with distinctive names for different types of content.
Possible speed gains
The above method builds really quick, as it parallelizes as much as possible (if you have many cores in your machine, you can change the -j4
option to more processes). Further speed gains could be achieved with building formats for the TikZ and circuitikz
files.
Stuff to add
The project I used this on was a formulary for an exam, so I didn't need any bibliography or index. These should be added to the main Makefile if you need those (and shouldn't be too hard to do).
standalone
class for creatingTikZ
pictures ('cause so I can see more details and so on), but your way of doing TeX (or writing your thesis) isn't bad. I can tell only for me: I would do it exactly that way (but I wouldn't use an externalTikZ
editor for creating pictures, as you mentioned it is better to use thestandalone
package …).\include
for those pictures? That is not good, as\include
does a\clearpage
,\input
seems like the reasonable thing to do for pictures (if they shouldn't be made standalone).