Build Scripts for LaTeX-BibTeX-XFig-GnuPlot Combo
posted at April 28, 2012 with tags latex

Over the past 8 years, I needed to compile LaTeX documents for this or that reason. As time passed, I enhanced them with BibTeX, XFig, and Gnuplot. Further, I generally needed to produce PDF files validated by IEEE PDF eXpress. Here, I share some scripts I developed during the road to ease the pain.

First, note that there is a certain directory structure I stick to.

  • / – LaTeX (.tex) and BibTeX (.bib) files are placed here.
  • /constants.tex – LaTeX file for constants (variables, definitions, commands, etc.) shared between LaTeX and XFig files.
  • / – Compiles the whole project.
  • /figs – XFig (.fig), Gnuplot (.gnu), and EPS (.eps) files go here.
  • /figs/
  • /figs/ – Compiles the XFig and Gnuplot into EPS format.

Below is the entry point, / (Make sure you have latex, bibtex, dvips, and pspdf commands available.)


usage() {
    echo "Usage: $0 <BASENAME> <LATEX|BIBTEX|CLEAN>"
    exit 1

[ $# -ne 2 ] && usage

set -e
set -x

latex() {
    /usr/bin/latex --halt-on-error $1

make_bibtex() {
    latex $1 && \
	bibtex $1 && \
	latex $1 && \
	latex $1

make_latex() {
    cd figs && ./ && cd .. && \
    latex $1 && \
    dvips -Ppdf -G0 -ta4 $1.dvi -o && \
    ps2pdf \
	-dCompatibilityLevel=1.4 \
	-dPDFSETTINGS=/prepress \
	$ $1.pdf

make_clean() {
    rm -f \
	$1.aux \
	$1.bbl \
	$1.blg \
	$1.dvi \
	$1.log \
	$1.pdf \

case $ACTION in
    latex) make_latex $BASENAME;;
    bibtex) make_bibtex $BASENAME;;
    clean) make_clean $BASENAME;;
    *) usage;;

In /, I follow LaTeX->DVI->PostScript->PDF path. The main reason for the preference of this path over LaTeX->PDF is to properly process scalable EPS figures produced by XFig. (Personally, I hate to see broken figures in published articles.)

Next, here goes /figs/ script. (Per see, gnuplot is required during execution.)


set -e
set -x

get_modify_time() {
    if [ -e "$1" ]; then
	DT=$(stat "$1" | grep ^Modify: | sed 's/^Modify: //g')
	date -d "$DT" +%s
	echo 0

find -name "*.fig" | \
while read FIG; do
    BAS=$(basename "$FIG" | sed 's/\.fig$//g')

    # See if EPS needs to be updated.
    T_FIG=$(get_modify_time "$FIG")
    T_EPS=$(get_modify_time "$EPS")
    [ $T_FIG -gt $T_EPS ] && ./ $BAS

    # Remove backup, if there is any.
    rm -f "$BAK"

find -name "*.gnu" | \
while read GNU; do
    BAS=$(basename "$GNU" | sed 's/\.gnu$//g')

    # See if EPS needs to be updated.
    T_GNU=$(get_modify_time "$GNU")
    T_EPS=$(get_modify_time "$EPS")
    if [ $T_GNU -gt $T_EPS ]; then
	gnuplot $GNU

exit 0

Nothing fancy in /figs/ First, we process .fig files; second, we process .gnu files.

Finally, below goes /figs/ script. (Make fig2dev, pdflatex, pdf2ps commands ready. Note that /figs/ requires /constants.tex for shared LaTeX variables.)


set -x

if [ ${#@} -ne 1 ]; then
    echo "Usage: $0 <BASENAME>"
    exit 1


cat <<EOF >$BASENAME.tex

fig2dev -L pdftex $BASENAME.fig ${BASENAME}_fig.pdf && \
fig2dev -L pstex_t -p ${BASENAME}_fig.pdf $BASENAME.fig ${BASENAME}_fig.pdf_t && \
pdflatex $BASENAME && \
pdf2ps $BASENAME.pdf $BASENAME.eps

rm -f \
    ${BASENAME}_fig.pdf \
    ${BASENAME}_fig.pdf_t \
    $BASENAME.aux \
    $BASENAME.pdf \
    $BASENAME.log \

exit $RET

After all these fuss, the whole project boils down to

./ paper bibtex
./ paper latex

and you are ready to go.

Scripts need a little bit more cleaning and they are probably not the most correct ones. Anyway, they served well until now, and I hope they would for you as well.