Friday, January 15, 2010

Creating .pdf and .eps files from xfig drawings in batch

So I've been using xfig a lot recently, and I thought I would share a little of what I've discovered. In case you didn't know, xfig is a simple drawing utility that comes with most linux distributions. Its open-source so you can also get ports to Mac and Windows (I prefer to use the cygwin version of it).

As you can see its pretty "old school", but its perfect for making simple figures. If you want to make vector graphics, then I'd suggest something like Inkscape. The only problem I've ever had with xfig is creating .pdf or .eps from the command line. I've figured out how to do that using the fig2dev program, which comes with xfig. The man page for it is pretty complete, but here's a small example of how to create both a .pdf and .eps file.

For .pdf you do:

$ fig2dev -L pdftex -p portrait fig/figure1.fig > fig/figure1.pdf

Where -L pdftex, tells fig2dev to create a latex compatible pdf drawing in portrait mode. If you prefer landscape mode, then just remove the -p portrait option.

For a .eps you do:

$ fig2dev -L eps fig/figure1.fig > fig/figure1.eps

Pretty straight forward what everything means, but it should be pointed out that .eps files and .pdf files behave differently regarding orientation. Without the -p portrait parameter, the .pdf generated file is rotated 90 degrees compared with the .eps version.


In order to use this with my LaTeX files, I created a make file that first checks to see if the .fig files have been updated, and then generates new .pdf or .eps files depending on the type of paper (.ps or .pdf) I'm generating. Here's a copy of it:


$ cat Makefile
PAPER=file_name

BIB_DB=${PAPER}.bib
TEX=latex

BIBTEX=bibtex

FIG=fig/figure.fig \
fig/figure1.fig \
fig/figure2.fig \
fig/figure3.fig

all: ${PAPER}.ps

${PAPER}.ps: ${PAPER}.tex ${PAPER}.bbl ${FIG:%.fig=%.eps}
        ${TEX} ${PAPER}.tex
        ${TEX} ${PAPER}.tex
        dvips -o ${PAPER}.ps ${PAPER}.dvi

${PAPER}.pdf : TEX = pdflatex
${PAPER}.pdf : ${PAPER}.tex ${PAPER}.bbl ${FIG:%.fig=%.pdf}
        ${TEX} ${PAPER}.tex
        ${TEX} ${PAPER}.tex

${PAPER}.bbl : ${PAPER}.aux ${BIB_STYLE} ${BIB_ABBR} ${BIB_DB} ${PAPER}.tex
        ${BIBTEX} ${PAPER}

${PAPER}.aux : ${PAPER}.tex ${FIG:%.fig=%.pdf}
        ${TEX} ${PAPER}.tex

fig/%.pdf: fig/%.fig
        fig2dev -L pdftex -p portrait $^ > $@

fig/%.eps: fig/%.fig
        fig2dev -L eps $^ > $@

pdf: ${PAPER}.pdf

clean: distclean
        rm -rf ${PAPER}.pdf ${PAPER}.ps ${PAPER}.dvi ${FIG:%.fig=%.eps} ${FIG:%.fig=%.pdf}

distclean:
        rm -rf *~ *.aux *.bbl *.blg *.log *.mpx mpx*.dvi mpxerr.tex thumb* *.core *.out ${PAPER}-dvi.dvi ${PAPER}.[0-9]* \
        ${PAPER}-dvi.tex ${PDFMPFIGURES}

The lines to pay attention to are the:

${PAPER}.ps: ${PAPER}.tex ${PAPER}.bbl ${FIG:%.fig=%.eps}

and the

${PAPER}.pdf : ${PAPER}.tex ${PAPER}.bbl ${FIG:%.fig=%.pdf}

Where I've added the dependency ${FIG:%.fig=%.pdf} which expends the list of figures and replaces .fig with .pdf for each figures name.

The generic targets:

fig/%.pdf: fig/%.fig

and

fig/%.eps: fig/%.fig

To create a .pdf or .eps file in the fig directory there is a .fig file of the same name. The command is executed on the $^ variable, which stands for the name of the dependency (fig/%.fig), and the $@ variable, which stands for the target (fig/%.pdf or fig/%.eps)

No comments:

Post a Comment