Tuesday, August 19, 2008

Building MATLAB images from Makefiles

Recently I beefed up my LaTeX Makefiles to make image generation more automatic. These implicit rules have worked very well for me (note that the indentation is done with TABS — that's important).
%.pdf : %.eps
epstopdf $*.eps

%.eps : %.m
matlab -nosplash -nodesktop -r "$*;quit"

%.eps : %.png
convert -density $(RESOLUTION) $*.png $*.eps

%.eps : %.jpg
convert -density $(RESOLUTION) $*.jpg $*.eps

%.eps : %.dvi
dvips $* -D $(RESOLUTION) -E -o $*.eps

%.dvi : %.tex
latex -interaction=nonstopmode $*.tex
rm -f $*.log
rm -f $*.aux
That if, if I need a file called FILENAME.eps or FILENAME.pdf, the Makefile will look for FILENAME.m, FILENAME.png, FILENAME.jpg, or FILENAME.tex. Depending on which one it finds, it will run the appropriate command to generate the image I need. Note that I define RESOLUTION=1500 in the top of my Makefile.

I want to point out the MATLAB build line:
matlab -nosplash -nodesktop -r "$*;quit"
That handy line starts up as little of MATLAB as possible and runs a script that contains something like:
% First, generate a figure somehow

% Next, setup the figure's print proportions
set( gcf, 'PaperType', 'usletter', ...
'PaperOrientation', 'portrait', ...
'PaperPosition', [0.0 3.5 11 3.5] );

% Finally, save the figure as a (color) EPS
saveas( gcf, 'FILENAME.eps', 'epsc2' );
After the script finishes, MATLAB exits. It won't get started on any subsequent makes so long as the script file doesn't change or the image isn't deleted.

Getting back to the more general case, up high in my Makefile, I have something like
BASETEXIMAGES=$(shell perl -ne \
'/\\includegraphics\s*(?:\[.*?\]|)\s*{\s*(.*?)\s*}/ \
&& do { print "$$1 " \
if (-e "$${1}.tex" || \
-e "$${1}.png" || \
-e "$${1}.jpg" || \
-e "$${1}.m"); };' *.tex)
TEXIMAGES=$(addsuffix .eps,$(BASETEXIMAGES))
and a little later I make $(TEXIMAGES) a dependency for my document (or something equivalent to that).

Those lines have saved me a lot of time, and I'm pretty happy about them.

No comments: