#!/bin/sh
#
# $Id: latex-mk.in,v 1.22 2004/05/29 12:46:07 dan Exp $
#
# Copyright (c) 2002, 2003, 2004 Dan McMahill
# All rights reserved.
#
# This code is derived from software written by Dan McMahill
#
# 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. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#        This product includes software developed by Dan McMahill
#  4. 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 AUTHOR ``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 AUTHOR 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.
#

VERSION=1.3

MAXITERS=${MAXITERS:-5}
LATEX=${LATEX:-latex}
LATEX_FLAGS=${LATEX_FLAGS:-}
PDFLATEX=${PDFLATEX:-pdflatex}
PDFLATEX_FLAGS=${PDFLATEX_FLAGS:-}
BIBTEX=${BIBTEX:-bibtex}
BIBTEX_FLAGS=${BIBTEX_FLAGS:-}
LATEX_MK_LOG=${LOG:-latex-mk.log}

# list of files to monitor.  If they change, we will rerun 
# LaTeX again.  These are all suffixes of ${NAME}
monitor_files="lof lot toc"

sep="------------------------------------"

ignore_errors=no
debug=no
do_clean=no

while test -n "$1"
do
	case "$1"
	in

	--clean)
		do_clean=yes
		shift
		;;
		
	--debug)
		debug=yes
		echo "$0:  Enabling debug mode"
		shift
		;;
		
	-h|--help)
		echo "latex-mk.  This is a wrapper script used by the LaTeX-Mk"
		echo "makefile system for LaTeX documents.  Its purpose is to"
		echo "run LaTeX the appropriate number of times to resolve all"
		echo "references and page changes associated with resolving"
		echo "references."
		exit 0
		;;

	--ignore-errors)
		ignore_errors=yes
		shift
		;;

	--pdflatex)
		LATEX=$PDFLATEX
		LATEX_FLAGS=$PDFLATEX_FLAGS
		shift
		;;

	--version)
		echo "latex-mk version $VERSION"
		exit 0
		;;

	-*)
		echo "unknown option: $1"
		exit 1
		;;

	*)
		break
		;;

	esac
done

INFILE=$1

if test "X$debug" = "Xyes" ; then
	echo "$0 debug: command line INFILE=$INFILE"
fi

if test -z "$INFILE" ; then
	echo "$0:   You must specify an input file"
	exit 1
fi

if test ! -f "${INFILE}" ; then
    INFILE=${INFILE}.tex
fi
if test ! -f "${INFILE}" ; then
	echo "$0:   Neither ${INFILE} nor ${INFILE}.tex exists"
	exit 1
fi
if test "X$debug" = "Xyes" ; then
	echo "$0 debug: processed INFILE=$INFILE"
fi

NAME=`basename ${INFILE} .tex`

if test "X$debug" = "Xyes" ; then
	echo "$0 debug: NAME=$NAME"
fi

if [ "X$do_clean" = "Xyes" ]; then
	echo "$0: Cleaning for project: ${NAME}"
	if [ -f $LATEX_MK_LOG ]; then
		rm -f $LATEX_MK_LOG
	fi
	# clean up any of the .old versions of files we were
	# monitoring
	for sfx in $monitor_files ; do
		if [ -f ${NAME}.${sfx}.old ]; then
			rm -f ${NAME}.${sfx}.old
		fi
	done
	exit 0
fi

cnt=0
bibcnt=0

while test $cnt -lt $MAXITERS ; do
	if test "X$debug" = "Xyes" ; then echo "$0 debug: cnt=$cnt" ; fi

	# run latex.  If it fails, manually remove the .dvi file since
	# latex won't.  This will confuse 'make' because on the next
	# invocation, the .dvi file will appear to be up to date already.
	( ( ( $LATEX $LATEX_FLAGS $INFILE 2>&1 ; echo $? >&4) | tee $LATEX_MK_LOG 1>&3) 4>&1 |  (read a; exit $a)) 3>&1
	if test $? -ne 0 -a "$ignore_errors" != "yes"  ; then
		echo "$sep" 
		echo "$0:  Error:  LaTeX failed" 
		echo "$sep"
		rm -f ${NAME}.dvi ${NAME}.pdf
		rm -f $LATEX_MK_LOG
		exit 1
	fi

	# if we need to run bibtex, we should end up with something like this:
	#LaTeX Warning: Citation `foo' on page 1 undefined on input line 2
	# and
	#LaTeX Warning: There were undefined references.
	#
	# After bibtex is run, we will get one more latex run that has a citation
	# complaint so we allow one more complaint from latex before declaring
	# that there is a problem with the citations.  Just in case someone
	# wants to keep running latex and viewing/printing the results with these
	# errors present, provide a way to override this.
	#
	# Evidently, we may also simply get the following complaint:
	#
	# No file foo.bbl
	#
	# instead of the above warning.  This can happen if you only have
	# something line \nocite{*} in your document instead of \cite{x}

	needbib=`grep "Citation.*undefined" $LATEX_MK_LOG`
	if test -z "$needbib" ; then
	    echo "Checking for missing .bbl files in latex log ..."
	    needbib=`grep "No file.*\.bbl" $LATEX_MK_LOG`
	fi
	if test -n "$needbib" ; then
		if test $bibcnt -eq 0 ; then
			echo "$sep"
			echo "$0:  Running bibtex to resolve citations"
			echo "$sep"
			bibtex_ran=yes
			$BIBTEX $BIBTEX_FLAGS $NAME
			if test $? -ne 0 -a "$ignore_errors" != "yes" ; then
				echo "$sep" 
				echo "$0:  Error:  BibTeX failed" 
				echo "$sep"
				rm -f ${NAME}.dvi ${NAME}.pdf
				rm -f $LATEX_MK_LOG
				exit 1
			fi
			# run the post-bibtex hook if its been defined
			if test "X$POST_BIBTEX_HOOK" != "X" ; then
			    if test -x $POST_BIBTEX_HOOK ; then
				$POST_BIBTEX_HOOK $NAME
				rc=$?
				if test $rc -ne 0 ; then
				    echo "$POST_BIBTEX_HOOK $NAME failed"
				    rm -f ${NAME}.dvi ${NAME}.pdf
				    rm -f $LATEX_MK_LOG
				    exit $rc
				fi
			    fi
			fi
		elif test $bibcnt -eq 1 ; then
			echo "$sep"
			echo "$0:  BibTeX has already been run, but LaTeX is still reporting"
			echo "    $needbib."
			echo "    Trying LaTeX one more time...."
			echo "$sep"
		elif test -n "$IGNORE_CITATION_WARNS" ; then
			echo "$sep"
			echo "$0:  WARNING:  BibTeX has already been run, but LaTeX is still reporting"
			echo "$0:  $needbib"
			echo "$0:  You have set the IGNORE_CITATION_WARNS variable to override this, but"
			echo "$0:  you probably do have an error in your citations."
			echo "$sep"
		else
			echo "$sep"
			echo "$0:  Error:  BibTeX has already been run, but LaTeX is still reporting"
			echo "$0:  $needbib"
			echo "$sep"
			rm -f $LATEX_MK_LOG
			if test "$ignore_errors" = "yes" ; then exit 0 ; else exit 1 ; fi
		fi
		bibcnt=`expr $bibcnt + 1`
	fi

	# Examine the list of figures, list of tables, table of contents, etc
	# files because when these change, we need to re-run latex, but
	# sometimes latex does not tell us this.
	changed_file=""
	for sfx in $monitor_files ; do
		echo "Checking for ${NAME}.${sfx} ..."
		if [ -f ${NAME}.${sfx} ]; then
			if [ ! -f ${NAME}.${sfx}.old ]; then
				echo "${NAME}.${sfx} is new.  LaTeX needs to be re-run"
				changed_file="$changed_file ${NAME}.${sfx}"
			elif cmp -s ${NAME}.${sfx}.old ${NAME}.${sfx} ; then
				echo "no change"
			else
				echo "${NAME}.${sfx} has changed.  LaTeX needs to be re-run"
				changed_file="$changed_file ${NAME}.${sfx}"
			fi
			cp -p ${NAME}.${sfx} ${NAME}.${sfx}.old
		fi
	done

	#LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right
	rerun=`grep "Rerun to get" $LATEX_MK_LOG`
	if test -z "$rerun" -a -z "$needbib" -a -z "$changed_file" ; then
		break;
	fi
	echo "$sep"
	echo "$0:   LaTeX references have changed, another latex run is needed"
	echo "$sep"
	cnt=`expr $cnt + 1`
	if test "X$debug" = "Xyes" ; then echo "$0 debug: incremented cnt=$cnt" ; fi
done

#LaTeX Warning: There were undefined references.
undefined=`grep "There were undefined references" $LATEX_MK_LOG`
if test -n "$undefined" ; then
	echo "$sep"
	echo "$0:  There were undefined references.  Please correct this."
	echo "$0:  I have already made $cnt passes."
	#LaTeX Warning: Reference `tab:fuse_table' on page 3 undefined on input line 82.
	grep "Reference.*on page.*undefined" $LATEX_MK_LOG
	echo "$sep"
fi

#LaTeX Warning: There were multiply-defined labels.
mult=`grep "multiply-defined labels" $LATEX_MK_LOG`
if test -n "$mult" ; then
	echo "$sep"
	echo "$0:  There were multiply defined labels."
	echo "$0:  You may wish to correct this"
	#LaTeX Warning: Label `fig:myfig' multiply defined.
	grep "multiply defined" $LATEX_MK_LOG
	echo "$sep"
fi

if test $cnt -eq $MAXITERS ; then
	echo "$sep"
	echo "$0:   Failed to get LaTeX to converge after $MAXITERS tries"
	echo "$0:   Please fix the document or try again if you think it"
	echo "$0:   should be ok"
	echo "$sep"
	rm -f $LATEX_MK_LOG
	if test "$ignore_errors" = "yes" ; then exit 0 ; else exit 1 ; fi
fi

rm -f $LATEX_MK_LOG
exit 0

