#!/bin/sh
#
# llatex - Loop LaTeX
#
# This program serves as a wrapper around LaTeX and BibTeX.  It will run
# latex (and if necessary bibtex) multiple times to deal with warnings
# such as undefined references or labels having changed.
#
# If you want to use pdflatex instead of latex, set the LLATEX environment
# variable to pdflatex (export LLATEX=pdflatex or setenv LLATEX pdflatex)
#
# Version: $Revision: 1.7 $
#
# Copyright (c) 2007, Eric Breck
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
# 1 Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
# 
# 2 Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
# 
# 3 The name of the author may not be used to endorse or promote products
#   derived from this software without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# set the LLATEX environment variable to use pdflatex instead

if [ -z "$LLATEX" ]; then LLATEX=latex; fi
BIBTEX=bibtex

HELP=0
VERBOSE=0

while getopts hv a
do
  case $a in
    h) HELP=1;;
    v) VERBOSE=1;;
  esac
done
shift `expr $OPTIND - 1`

if [ $HELP -eq 1 ]
then
  echo "Usage: $0 [-v] filestem"
  echo " where your LaTeX file is filestem.tex"
  echo " set LLATEX to pdflatex to use that instead of latex"
  exit 0
fi

if [ $# -ne 1 ]; then echo Must call this script with one parameter; exit; fi

arg=$1
arg=`echo $arg | sed 's/\.tex$//'`

spew=$arg.spew

if [ $VERBOSE -eq 1 ]; then echo "stem: $arg"; echo "spew file: $spew"; fi

rm -f $arg.aux $arg.bbl $arg.log $arg.dvi $arg.pdf $arg.spew $arg.blg $arg.out $arg.spew.* $arg.aux.prev

if [ $VERBOSE -eq 1 ]; then echo -n "Running latex... "; fi
echo -n '' | $LLATEX $arg >$spew
if [ $? -ne 0 ]; then cat $spew; echo '*** Error running latex ***' ; exit; fi
if [ $VERBOSE -eq 1 ]; then cp $spew $spew.0; echo "Output in $spew.0"; fi


if grep 'LaTeX Warning: Citation .* undefined' $spew > /dev/null
then
  if [ $VERBOSE -eq 1 ]; then echo -n "Running bibtex... "; fi
  $BIBTEX $arg > $spew
  if [ $? -ne 0 ]; then cat $spew; echo '*** Error running bibtex ***' ; exit; fi
  if [ $VERBOSE -eq 1 ]; then cp $spew $spew.1; echo "Output in $spew.1"; fi
  if [ $VERBOSE -eq 1 ]; then echo -n "Running latex... "; fi
  cp $arg.aux $arg.aux.prev
  echo -n '' | $LLATEX $arg > $spew
  if [ $? -ne 0 ]; then cat $spew; echo '*** Error running latex ***' ; exit; fi
  if [ $VERBOSE -eq 1 ]; then cp $spew $spew.2; echo "Output in $spew.2"; fi
else
  if [ $VERBOSE -eq 1 ]; then echo "Not running BibTeX"; fi
fi

counter=1

# As long as the counter < 10, and as long as either LaTeX thinks it needs
# to continue, or if the .aux is changing, keep running.
while ( grep 'LaTeX Warning: Label(s) may have changed' $spew > /dev/null || ! diff $arg.aux $arg.aux.prev > /dev/null )  && [ $counter -lt 10 ] ; do
  if [ $VERBOSE -eq 1 ]; then echo -n "Running latex... "; fi
  cp $arg.aux $arg.aux.prev
  echo -n '' | $LLATEX $arg > $spew
  if [ $? -ne 0 ]; then cat $spew; echo '*** Error running latex ***' ; exit; fi
  if [ $VERBOSE -eq 1 ]; then 
    n=`expr $counter + 2`
    cp $spew $spew.$n
    echo "Output in $spew.$n"
  fi
  counter=`expr $counter + 1`
done 

if grep 'LaTeX Warning' $spew; then
  echo Processed $arg, but warnings remain
else
  echo Successfully processed $arg
fi

rm -f $spew $arg.aux.prev
