#!/bin/sh

PROG=$(basename $0)

usage ()
{
	cat << HELP
Usage: $PROG [options]

Test driver for 'pwebmac.tex' in combination with various TeX engines.
Produce TeX output in DVI or PDF from a set of C/WEB programs included
in the 'TeX Live' source tree.

Options are (--long options only with GNU getopt):
	-c, --changes		Apply change file to C/WEB source
	-f, --files STRING	Process only subset of C/WEB programs
	-h, --help		Print this help message and exit
	-n, --new		Use 'pwebmac' instead of 'webmac'
	-o, --outdir ARG	Create tarballs in path ARG
	-p, --pdftocfront	Place TOC page at the front (PDF only)
	-t, --tex ARG		Use TeX variant ARG={tex,pdftex,xetex}

Public domain.  Originally written by Andreas Scherer, 2020.
HELP
}

LONGOPTS=changes,files:,help,new,outdir:,pdftocfront,tex:
SHRTOPTS=cf:hno:pt:

CHANGES=false # apply changefile to C/WEB source
FILESELECT=false # user-defined '--files' selection
NEW=false # '\input pwebmac' instead of '\input webmac' for PDF et al.
OUTDIR=. # path where the resulting tarballs are placed
PDFTOCFRONT=false # push table-of-contents to front of PDF output
TEX=tex # or 'pdftex' or 'xetex'

# Initial list of C/WEB sources to process, overridable with option '-f':
KNUTHWHERE=$(locate /bibtex.web)
if [ -z "$KNUTHWHERE" ]
then echo "$PROG: Can't locate the TeX Live source tree!" >&2; exit 1
fi
KNUTHWARE=$(dirname $KNUTHWHERE)

FILES="$KNUTHWARE/*.web pdftex.web xetex.web"
WEBINPUTS=$KNUTHWARE//:

FILES="$FILES common ctangle cweave ctwill refsort twinx ctie tie"
CWEBINPUTS=$KNUTHWARE//:

KNUTHWHERE=$(locate /glue.web)
if [ -n "$KNUTHWHERE" ]
then
	FILES="$FILES $KNUTHWHERE"
	WEBINPUTS=$(dirname $KNUTHWHERE):$KNUTHWARE//:
fi

export WEBINPUTS CWEBINPUTS

getopt -T >/dev/null

if [ $? -eq 4 ] # Check for Linux-getopt with extensions
then OPTS=$(getopt -n $PROG -o $SHRTOPTS -l $LONGOPTS -- "$@")
else OPTS=$(getopt $SHRTOPTS $*)
fi

if [ $? -eq 0 ] # Check return code from getopt
then eval set -- $OPTS
else echo "Failed to parse options." >&2; exit 1
fi

while true
do
	case "$1" in
		-c | --changes ) CHANGES=true; shift ;;
		-f | --files ) FILES="$2"; FILESELECT=true; shift 2 ;;
		-h | --help ) usage; exit 0 ;;
		-n | --new ) NEW=true; shift ;;
		-o | --outdir ) OUTDIR="$2"; shift 2 ;;
		-p | --pdftocfront ) PDFTOCFRONT=true; shift ;;
		-t | --tex ) TEX=$2; shift 2 ;;
		-- ) shift; break ;;
		* ) usage; exit 1 ;;
	esac
done

CWEAVE="cweave -f +lX"
CTWILL="ctwill -f +lpdf"
PAX="pax -wvzf"
SED_I="sed -i" # non-GNU-sed requires an extra '' argument for '-i' option.

# WEB and CWEB programs we want to get formatted
for f in $FILES
do
	f=$(basename $f .web)

	if [ ctwill = $f ]
	then
		# apply tons of editorial changes to 'ctwill.w'
		ctie -m $f.w cweave.w $f-w2c.ch $f-mini.ch
		cp -an $KNUTHWARE/cwebdir/*.bux .
		$CTWILL $f # prime the pump
		$CTWILL $f # get decent answers

	elif [ glue = $f ]
	then
		weave $f # no 'glue.ch' at this time

	elif $CHANGES
	then
		case $f in
			# CWEB programs have individual changefiles
			common ) $CWEAVE $f comm-w2c ;;
			ctangle ) $CWEAVE $f ctang-w2c ;;
			cweave ) $CWEAVE $f cweav-w2c ;;
			refsort | twinx ) $CWEAVE $f $f ;;
			ctie ) $CWEAVE $f $f-k ;;
			tie ) $CWEAVE $f $f-w2c ;;

			# main WEB programs have complex change files
			tex | mf | pdftex | xetex )
				WEBINPUTS=$KNUTHWARE/../../Work//:$WEBINPUTS: \
				weave $f $f-final ;;

			# all other WEB codes have singular changefiles
			* ) weave $f $f ;;
		esac

		# FIX: XeTeX uses '\pdfTeX' from section 114, which is not
		# changed and thus 'disappears'; repeat in preamble.
		if [ xetex = $f ]
		then
			$SED_I -e "s/\(\\\\let\\\\maybe\)/\\\\def\\\\pdfTeX{pdf\\\\TeX}\n\1/" \
				$f.tex
		fi

		# only document changed modules/sections
		$SED_I -e "s/\(\\\\let\\\\maybe=\)\\\\iftrue/\1\\\\iffalse/" \
			$f.tex
	else
		case $f in
			c* | refsort | twinx | tie ) $CWEAVE $f ;;
			* ) weave $f ;;
		esac
	fi

	if $NEW
	then
		# use extended WEB macros for TeX Live PDF documentation
		$SED_I -e "1 s/\\\\input webmac/\\\\input pwebmac/" $f.tex

		# timestamp on table-of-contents page or the first page
		case $f in
			# do nothing for CWEB programs
			c* | refsort | twinx | tie ) ;;

			bibtex | patgen | tangle | weave )
				$SED_I -e "s/\(\\\\def\\\\title\)/\\\\datecontentspage\n\1/" $f.tex ;;

			mf | tex | pdftex | xetex )
				$SED_I -e "s/\(\\\\def\\\\botofcontents\)/\\\\datethis\n\1/" $f.tex

				# amend '\N' redefinition for PDF outlines in
				# Metafont and TeX (also pdfTeX and XeTeX)
				# 'pwebmac' defines headers differently
				$SED_I -e "s/\(\\\\outer\\\\def\\\\N.*{\)/\1%/" \
					 -e "s/\\\\def\\\\rhead\(.*}\)/\\\\gtitle=\1\\\\MN#1.\\\\vfill\\\\eject/" \
					 $f.tex

				# active links in PDF outlines/bookmarks
				cat > texmf-pdf.patch << FI
  \ifacro{\toksF={}\makeoutlinetoks{[#2] #3}\outlinedone\outlinedone}\fi
FI
				$SED_I -e "/\\\\outer\\\\def\\\\N/ {
					r texmf-pdf.patch
					}" $f.tex

				cat > texmf-pdf.patch << FI
  \ifpdf\special{pdf: outline 0 << /Title (\the\toksE) /Dest
    [ @thispage /FitH @ypos ] >>}\fi
FI
				$SED_I -e "/  \\\\edef\\\\next/ {
					r texmf-pdf.patch
					}" $f.tex
				rm texmf-pdf.patch ;;

			* ) $SED_I -e "s/\(\\\\def\\\\botofcontents\)/%\1/" \
				-e "s/  \\\\centerline{\(\\\\hsize\)/\\\\def\\\\covernote{\1/" \
				-e "s/\(Publishing Company.}}\)}/\1\n\\\\datecontentspage/" \
				-e "s/\(trademark of the American Mathematical Society.}}\)}/\1\n\\\\datecontentspage/" \
				$f.tex ;;
		esac
	fi

	# special treatment for individual C/WEB programs
	case $f in
		# replace former convention to indicate "not a title
		# page" to include page headers for table-of-contents;
		# purge conflict between bibtex.web and webmac.tex
		# 'E' no longer free to be active character
		# fix table-of-contents page for bibtex
		# FIX: don't wait for Oren Patashnik.
		bibtex ) $SED_I -e "s/\\\\def\\\\titlepage{F}/\\\\titletrue/" $f.tex
			if ! $CHANGES
			then
				$SED_I -e "71,78d" $f.tex
			fi ;;

		# FIX: 'glue.web' obviously uses an old 'webmac.tex'.
		glue ) $SED_I -e "s/\(\\\\def\\\\title{GLUE}\)/\1\n\\\\pageno=\\\\contentspagenumber \\\\advance\\\\pageno by1\\\\relax/" \
			-e "s/titlefalse/titletrue/" $f.tex ;;

		# FIX: pdfTeX uses '\pdfTeX' in section names; these should
		# appear correctly in the bookmarks, too.
		pdftex )
			if $NEW && [ tex != $TEX ]
			then
				$SED_I -e "s/\(\\\\def\\\\pdfTeX{pdf\\\\TeX}\)/\1 \\\\sanitizecommand\\\\pdfTeX{pdfTeX}\\\\sanitizecommand\\\\eTeX{e-TeX}/" \
					$f.tex
			fi ;;

		# FIX: purge obsolete macros from XeTeX.
		xetex ) $SED_I -e "/\\\\input xewebmac/d" $f.tex ;;
	esac

	# shift table-of-contents pages to the front in PDF
	if $PDFTOCFRONT && [ ctwill != $f ]
	then
		$SED_I -e "0,/\\\\N[1{]/s/\(\\\\N[1{]\)/\\\\input pdfwebtocfront\n\n\1/" \
			$f.tex

		# only XeTeX can process XETEX.WEB
		if [ xetex = $f ]
		then $f $f # run TeX twice
		else $TEX $f # run TeX twice
		fi

		# run TEX.WEB three times to fix table-of-contents
		if [ tex = $f ]
		then $TEX $f
		fi
	fi

	# only XeTeX can process XETEX.WEB
	if [ xetex = $f ]
	then $f $f
	elif [ refsort = $f ]
	then $TEX -interaction nonstopmode $f
	else $TEX $f
	fi

	if [ ctwill = $f ]
	then
		# sort mini-indexes
		ctwill-refsort < $f.ref > $f.sref
		$TEX $f
	fi
done

if $PDFTOCFRONT && ! $FILESELECT
then
	# create tarballs w/o changes for publication
	if $CHANGES
	then
		for f in *.pdf
		do
			case $f in
				*-changes.pdf ) rm -f $f; continue ;;
			esac
			mv $f $(basename $f .pdf)-changes.pdf
		done
		$PAX "$OUTDIR/etc-changes.tar.gz" -s ,^,etc/, \
			vftovp-changes.pdf vptovf-changes.pdf
		$PAX "$OUTDIR/mf-changes.tar.gz" -s ,^,mf/, \
			mf-changes.pdf
		$PAX "$OUTDIR/mfware-changes.tar.gz" -s ,^,mfware/, \
			gftodvi-changes.pdf gftopk-changes.pdf \
			gftype-changes.pdf mft-changes.pdf
		$PAX "$OUTDIR/tex-changes.tar.gz" -s ,^,tex/, \
			tex-changes.pdf
		$PAX "$OUTDIR/texware-changes.tar.gz" -s ,^,texware/, \
			dvitype-changes.pdf pltotf-changes.pdf \
			pooltype-changes.pdf tftopl-changes.pdf
		$PAX "$OUTDIR/web-changes.tar.gz" -s ,^,web/, \
			tangle-changes.pdf weave-changes.pdf
		$PAX "$OUTDIR/bibtex-changes.tar.gz" -s ,^,bibtex/, \
			bibtex-changes.pdf
		$PAX "$OUTDIR/other-changes.tar.gz" -s ,^,other/, \
			dvicopy-changes.pdf patgen-changes.pdf \
			pktogf-changes.pdf pktype-changes.pdf
		$PAX "$OUTDIR/pdftex-changes.tar.gz" -s ,^,pdftex/, \
			pdftex-changes.pdf
		$PAX "$OUTDIR/xetex-changes.tar.gz" -s ,^,xetex/, \
			xetex-changes.pdf
		$PAX "$OUTDIR/ctie-changes.tar.gz" -s ,^,ctie/, \
			ctie-changes.pdf
		$PAX "$OUTDIR/tie-changes.tar.gz" -s ,^,tie/, \
			tie-changes.pdf
		$PAX "$OUTDIR/cweb-changes.tar.gz" -s ,^,cweb/, \
			common-changes.pdf ctangle-changes.pdf \
			cweave-changes.pdf refsort-changes.pdf \
			twinx-changes.pdf
	else
		# Finally, build the remaining documents
		# * TeX and Metafont test routines
		# * WEB and CWEB manuals
		export TEXINPUTS=.:$(kpsewhich --var-value=TEXMFDIST)//:$KNUTHWARE//

		rm -f trapman.tex webman.tex cwebman.tex

		# FIX: Prepare 'trapman' for automatic processing; several
		# input files are renamed in TeX Live (in fact, there are
		# additional files for MetaPost).
		f=$(kpsewhich -engine tex trapman)
		tie -m $(basename $f) $f /opt/github/web/$(basename $f .tex).ch

		# Prepare 'webman' with section links and bookmarks.
		f=$(kpsewhich -engine tex webman)
		tie -m $(basename $f) $f /opt/github/web/$(basename $f .tex).ch

		# Prepare 'cwebman' with footnotes describing the extended CWEB.
		f=$(kpsewhich -engine tex cwebman)
		tie -m $(basename $f) $f $(basename $f .tex)-w2c.ch

		touch pages.tex # let 'manmac' produce output at all

		for f in tripman trapman webman cwebman
		do
			$TEX $f
		done

		$TEX -jobname=errorlog /opt/github/web/Xerrorlog.tex

		for f in one two three four five six seven eight nine ten \
			eleven twelve
		do
			$TEX errata.$f
			mv errata.pdf errata.$f.pdf
		done

		$TEX errata

		$PAX "$OUTDIR/errata.tar.gz" -s ,^,errata/, \
			errorlog.pdf errata.*.pdf errata.pdf
		$PAX "$OUTDIR/etc.tar.gz" -s ,^,etc/, vftovp.pdf vptovf.pdf
		$PAX "$OUTDIR/mf.tar.gz" -s ,^,mf/, mf.pdf trapman.pdf
		$PAX "$OUTDIR/mfware.tar.gz" -s ,^,mfware/, \
			gftodvi.pdf gftopk.pdf gftype.pdf mft.pdf
		$PAX "$OUTDIR/tex.tar.gz" -s ,^,tex/, \
			glue.pdf tex.pdf tripman.pdf
		$PAX "$OUTDIR/texware.tar.gz" -s ,^,texware/, \
			dvitype.pdf pltotf.pdf pooltype.pdf tftopl.pdf
		$PAX "$OUTDIR/web.tar.gz" -s ,^,web/, \
			webman.pdf tangle.pdf weave.pdf
		$PAX "$OUTDIR/bibtex.tar.gz" -s ,^,bibtex/, bibtex.pdf
		$PAX "$OUTDIR/other.tar.gz" -s ,^,other/, \
			dvicopy.pdf patgen.pdf pktogf.pdf pktype.pdf
		$PAX "$OUTDIR/pdftex.tar.gz" -s ,^,pdftex/, pdftex.pdf
		$PAX "$OUTDIR/xetex.tar.gz" -s ,^,xetex/, xetex.pdf
		$PAX "$OUTDIR/ctie.tar.gz" -s ,^,ctie/, ctie.pdf
		$PAX "$OUTDIR/tie.tar.gz" -s ,^,tie/, tie.pdf
		$PAX "$OUTDIR/cweb.tar.gz" -s ,^,cweb/, \
			cwebman.pdf common.pdf ctangle.pdf cweave.pdf \
			ctwill.pdf refsort.pdf twinx.pdf
	fi

	# Notes to self:
	# (1) Create a user-friendly central entrypoint with
	#     (a) pandoc index.md -o index.pdf
	#     (b) pandoc index.md -o index.tex;
	#         pandoc index.tex -s -o index.html;
	#         rm index.tex
	# (2) Prepare a super-tarball from all the contents of these
	#     individual tarballs (27/31) with either of
	#     (a) pax -wzf knuth-pdf.tar.gz knuth-pdf
	#     (b) zip -r knuth-pdf.zip knuth-pdf
fi

exit 0
