#!/bin/sh -e 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, PDF or HINT format from a set of C/WEB programs included in the 'TeX Live' source tree. Options are (--long options only with Linux-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=[(hi|pdf|xe)]tex -v, --validpdf Use correct number of entries in NOS node Public domain. Originally written by Andreas Scherer, 2020. HELP } LONGOPTS=changes,files:,help,new,outdir:,pdftocfront,tex:,validpdf SHRTOPTS=cf:hno:pt:v CHANGES= # 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' or 'hitex' or 'luatex' VALID=false # give 'pdftex' a chance to produce valid output # Extra material for editorial improvements # published in https://ctan.org/pkg/pwebmac (editorsnote.tex etc.), # https://github.com/ascherer/web (cosmetics for HiTeX and PDFTeX), # and https://github.com/ascherer/mplibdir (cosmetics for MetaPost) LOCALSTUFF=/opt/github/web # 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 twill" WEBINPUTS=$KNUTHWARE//: FILES="$FILES common ctangle cweave ctwill refsort twinx ctie tie hitex \ mp mpost mpmath mpmathbinary mpmathdecimal mpmathdouble mpstrings tfmin" 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 && true # keep going 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='-changes'; 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 ;; -v | --validpdf ) VALID=true; shift ;; -- ) shift; break ;; * ) usage; exit 1 ;; esac done CWEAVE='cweave -f +lX +bph' CTWILL='ctwill -f +lpdf +bph' HITEX='hitex --compress' PAX='pax -wvzf' EXT=pdf # default extension for 'knuth-pdf' SED_I='sed -i' # non-GNU-sed requires an extra '' argument for '-i' option. # Prevent '#1)' from showing up in the PDF bookmarks/outlines: PURGE_OUTLINES='s/\\(\([0-9a-z]\)[0-9a-z]*)/\\9{\1}/g' # Sorting order of new material from TEX.CH and ENCTEX2.CH SORT_NOS='s/\(ump \)\(a couple\)/\1\\(a)\2/ s/\(ump \)\(constants\)/\1\\(c)\2/ s/\(ump \)\(enc\)/\1\\(e)\2/ s/\(ump \)\(ML\)/\1\\(m)\2/' WEAVE=weave XETEX=xetex case "$TEX" in hitex ) # HINT format CTWILL="$CTWILL +P" TEX="$HITEX" EXT=hnt # default extension for 'knuth-hint' PDFTOCFRONT=false # use 'hintview -h' to start with TOC page VALID=false ;; # HiTeX has no command-line option '--shell-escape' pdftex | luatex ) # actually only necessary for 'pwebmac.tex' VALID=true ;; * ) # plain TeX and XeTeX use different approaches [ tex = "$TEX" ] && XETEX="$XETEX --no-pdf" # XeTeX's extended DVI format VALID=false ;; esac # Valid PDF output from 'pdftex' and 'luatex': In 'pwebmac.tex' set '\countNOS' # to the actual number of @<named modules@>, not the number of all sections. if $VALID then NEW=true # PDF output requires 'pwebmac.tex' TEX="$TEX --shell-escape" fi # Use alternative TeX macros more suited for PDF output. [ -n "$CHANGES" ] && NEW=true $NEW && WEAVE="$WEAVE -p" # Loop over WEB and CWEB programs we want to get formatted for f in $FILES do f=$(basename $f .web) # Prepare local C/WEB sources case $f in vftovp ) # FIX: Sorting order of named sections sed -e 's/\(Compute the \)\(|activity\)/\1\\9{a}\2/ /\\def\\(/d' -e $PURGE_OUTLINES $KNUTHWARE/$f.web > $f.web ;; # ) pdftex ) # Fix several 'Overfull \hbox'es tie -m $f.web $f.web $LOCALSTUFF/$f.ch ;; hitex | mp | mpost | mpmath* | mpstrings | tfmin ) # Beautifications for HiTeX and MetaPost tie -m $f.w $f.w $LOCALSTUFF/$f.ch $SED_I -e $PURGE_OUTLINES -e '/\\def\\(/d' $f.w ;; # ) weave | twill ) # Fix non-constant factor if [ "$HITEX" = "$TEX" ] && [ ! -f weave.web ] then sed -e 's/\\the\\hsize/460pt/' \ $KNUTHWARE/weave.web > weave.web fi ;; esac # Run C/WEAVE on the C/WEB sources w/o changes if [ -n "$CHANGES" ] then case $f in # These are changes in and of themselves ctwill | twill | glue | hitex | mp | mpost | \ mpmath* | mpstrings | tfmin ) continue ;; # 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 mf | pdftex | xetex ) WEBINPUTS=.:$KNUTHWARE/../../Work//:$WEBINPUTS: \ $WEAVE $f $f-final ;; tex ) sed -e "$SORT_NOS" $KNUTHWARE/$f.web > $f.web sed -e "$SORT_NOS" $KNUTHWARE/../../Work/texk/web2c/$f-final.ch > $f-final.ch WEBINPUTS=.:$WEBINPUTS $WEAVE $f $f-final ;; # FIX: Sorting order of new @<Define...@> sections vftovp ) WEBINPUTS=.:$WEBINPUTS $WEAVE $f $f $SED_I -e $PURGE_OUTLINES $f.tex ;; # all other WEB codes have singular changefiles * ) $WEAVE $f $f ;; esac # only document changed modules/sections $SED_I -e '/\\let\\maybe/s/\\iftrue/\\iffalse/' $f.tex else # -z $CHANGES case $f in ctwill ) # apply tons of editorial changes to 'ctwill.w' [ "$HITEX" = "$TEX" ] && ctie -m $f.w cweave.w $f-w2c.ch $f-hint.ch || ctie -m $f.w cweave.w $f-w2c.ch $f-mini.ch $CTWILL $f # prime the pump $CTWILL $f ;; # get decent answers c* | refsort | twinx | tie ) $CWEAVE $f ;; hitex | mp | mpost | mpmath* | mpstrings | tfmin ) CWEBINPUTS=.: $CWEAVE $f ;; twill ) WEBINPUTS=.:$WEBINPUTS \ tie -c $f.ch weave.web weave.ch weav-$f.ch && $WEAVE weave $f $f ;; pdftex | weave | vftovp ) WEBINPUTS=.:$WEBINPUTS $WEAVE $f ;; * ) $WEAVE $f ;; esac fi # $CHANGES case $f in # amend '\N' redefinition for PDF outlines in Metafont and TeX # (also pdfTeX and XeTeX); 'pwebmac' redefines the headers. mf | tex | pdftex | xetex ) $NEW && $SED_I -e \ 's/\\outer\\def\\N.*{/&%/ /\\outer\\def\\N/a\ \\ifpdf{\\makeoutlinetoks{[#2] #3}\\outlinedone}\\fi s/\\def\\rhead/\\gtitle=/ /\\gtitle=/a\ \\MN#1.\\vfill\\eject % begin starred section s/{\\the\\pageno}/&{\\the\\toksE}/ /\\edef\\next/a\ \\ifpdflua\\relax\\else\ \\ifpdf\\special{pdf: outline 0 << /Title (\\the\\toksE) /Dest\ [ @thispage /FitH @ypos ] >>}\\fi\\fi /\\def\\(/d' -e $PURGE_OUTLINES $f.tex ;; # )} esac # mf | tex | pdftex | xetex # 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 [ -z "$CHANGES" ] && $SED_I -e '71,78d' $f.tex ;; # FIX: 'glue.web' obviously uses an old 'webmac.tex'. glue ) $SED_I -e 's/titlefalse/titletrue/ /\\def\\title{GLUE}/a\ \\pageno=\\contentspagenumber \\advance\\pageno by1\\relax' $f.tex ;; # FIX: GFtoDVI uses 'Metafont' in a module name; # this should appear correctly in the bookmarks, too. # FIX: Metafont uses '\over' in several module names; # this should appear correctly in the bookmarks, too. # FIX: typo in MF.WEB. gftodvi | mf ) $NEW && $SED_I -e '/\\def\\MF/a\ \\ifpdf\ \\sanitizecommand\\MF{Metafont}\ \\sanitizecommand\\over{\/}\ \\sanitizecommand\\langle{<}\ \\sanitizecommand\\rangle{>}\ \\fi' -e 's/a ano/ano/' $f.tex ;; # FIX: MFT uses '\pb' in several module names; # this should appear correctly in the bookmarks, too. mft ) $NEW && $SED_I -e '/\\def\\pb/a\ \\ifpdf\\sanitizecommand\\pb{\|...\|}\\fi' $f.tex ;; # FIX: pdfTeX uses '\pdfTeX' in section names; these should # appear correctly in the bookmarks, too. pdftex ) $NEW && $SED_I -e '/\\def\\pdfeTeX{pdf\\eTeX}/a\ \\ifpdf\ \\sanitizecommand\\pdfTeX{pdfTeX}\ \\sanitizecommand\\eTeX{e-TeX}\ \\sanitizecommand\\over{\/}\ \\fi' $f.tex ;; # FIX: weave uses '\max' in name of module 173; this should # appear correctly in the bookmarks, too. weave | twill ) $NEW && $SED_I -e '/\\def\\({}/a\ \\ifpdf\\sanitizecommand\\max{max}\\fi' $f.tex ;; # ) # FIX: purge obsolete macros from XeTeX. # FIX: XeTeX uses '\pdfTeX' from section 114, which is not # changed and thus 'disappears'; repeat in preamble. # FIX: apply '\sanitizecommand' for bookmarks. xetex ) $SED_I -e '/\\input xewebmac/d /\\let\\maybe/i\ \\def\\pdfTeX{pdf\\TeX}' $f.tex $NEW && $SED_I -e '/\\def\\pdfTeX/a\ \\ifpdf\\sanitizecommand\\pdfTeX{pdfTeX}\\fi /\\def\\eTeX/a\ \\ifpdf\ \\sanitizecommand\\eTeX{e-TeX}\ \\sanitizecommand\\over{\/}\ \\fi' $f.tex ;; esac # timestamp on table-of-contents page or the first page case $f in tex | pdftex | xetex | hitex | mf | mp ) $NEW && $SED_I -e '/\\def\\title{/i\ \\datethis\ \\emergencystretch=.1\\hsize' $f.tex ;; # } common | ctangle | cweave | ctie | tie ) $SED_I -e '/\\def\\botofcontents/i\ \\datethis' $f.tex ;; bibtex | patgen | tangle | weave | twill | \ mpost | mpmath* | mpstrings | tfmin ) $NEW && $SED_I -e '/\\def\\title{/i\ \\datecontentspage\ ' $f.tex ;; # } { {{ { * ) $NEW && $SED_I -e '/\\def\\botofcontents/d s/ \\centerline{\(\\hsize\)/\\def\\covernote{\1/ s/\(Publishing Company.}}\)}/\1\n\\datecontentspage/ s/\(Mathematical Society.}}\)}/\1\n\\datecontentspage/' $f.tex ;; esac # shift table-of-contents pages to the front in PDF if $PDFTOCFRONT && echo $f | grep -v -q -E 'ctwill|hitex' then $SED_I -e '0,/\\N[1{]/s/\\N[1{]/\\input pdfwebtocfront\n\n&/' $f.tex # }} fi if [ -n "$CHANGES" ] || [ twill = "$f" ] then # We add an Editor's Note and the list of changed # sections on the ToC page. [ -f editorsnote.tex ] || cp $LOCALSTUFF/editorsnote.tex . case $f in mf ) $SED_I -e '/\\datethis/i\ \\input editorsnote.tex\ \\def\\datethis{\\def\\startsection{\\leftline{\\sc\\today\\ at \\hours}\ \\medskip\\editorsnote\\readchanges\\bigskip\ \\let\\startsection=\\stsec\\stsec}}' $f.tex ;; # TeX and XeTeX grow significantly for TeX Live # so there's enough room on the last ToC page. pdftex | tex | xetex ) $SED_I -e '/\\datethis/d s/\(\\def\\botofcontents\).*/\1{\\hsize6.5in\\vskip 0pt plus 1filll/ /\\def\\botofcontents/i\ \\input editorsnote.tex /\\def\\botofcontents/a\ \\editorsnote\\readchanges\\medskip\\noindent\\sc\\today\\ at \\hours} /\\input pdfwebtocfront/a\ \ \\def\\tocpages{2}' $f.tex ;; bibtex | patgen | tangle | weave | twill | \ refsort | twinx ) $SED_I -e 's/\\date.*/\\datecontentspage/ /\\datecontentspage/i\ \\input editorsnote\ \\def\\covernote{\\vbox{\\editorsnote\\readchanges\\par}}' $f.tex ;; common | ctangle | cweave | ctie | tie ) # {{ $SED_I -e '/\\def\\covernote/i\ \\input editorsnote.tex s/^}}/\\bigskip\\editorsnote\\readchanges\\par&/' $f.tex ;; * ) $SED_I -e '/\\def\\title{/i\ \\input editorsnote.tex s/\\vbox{\\ninerm/&\\editorsnote\\readchanges\\medskip/' $f.tex ;; # }} esac fi # $CHANGES # Run TeX on the woven C/WEB programs case $f in ctwill ) # gives two different outcomes if [ "$HITEX" = "$TEX" ] # sort mini-indexes then # directly in the TeX file ( ctwill-proofsort < $f.tex ) 1<> $f.tex else # in the TeX-created .ref file $TEX $f ctwill-refsort < $f.ref > $f.sref fi $TEX $f ;; * ) # run TeX twice if $PDFTOCFRONT || [ -n "$CHANGES" ] then [ xetex = $f ] && $XETEX $f || $TEX $f fi # only XeTeX can process XETEX.WEB [ xetex = $f ] && $XETEX $f || $TEX $f ;; esac done # create tarballs w/o changes for publication if ( $PDFTOCFRONT || [ "$HITEX" = "$TEX" ] ) && ! $FILESELECT then export TEXINPUTS=.:$(kpsewhich --var-value=TEXMFDIST)//:$KNUTHWARE// # Prepare 'webman' with section links and bookmarks. rm -f webman.tex f=$(kpsewhich -engine tex webman) [ -z "$CHANGES" ] && tie -m webman.tex $f $LOCALSTUFF/webman-outlines.ch || tie -m webman.tex $f $LOCALSTUFF/webman-outlines.ch \ $LOCALSTUFF/webman-changes.ch $TEX webman if [ -z "$CHANGES" ] then touch pages.tex # let 'manmac' produce output at all $TEX -jobname=errorlog $LOCALSTUFF/Xerrorlog.tex for f in one two three four five six seven eight nine ten \ eleven twelve do $TEX -jobname errata.$f errata.$f done $TEX errata $PAX "$OUTDIR/errata.tar.gz" -s ,^,errata/, err*.$EXT && true $PAX "$OUTDIR/hitex.tar.gz" -s ,^,hitex/, hitex.$EXT && true $PAX "$OUTDIR/mp.tar.gz" -s ,^,mp/, mp.$EXT mpost.$EXT && true # Finally, build the remaining documents # * TeX and Metafont test routines # * WEB and CWEB manuals rm -f trapman.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 trapman.tex $f $LOCALSTUFF/trapman.ch # Prepare 'cwebman' with footnotes describing the extended CWEB. f=$(kpsewhich -engine tex cwebman) tie -m cwebman.tex $f cwebman-w2c.ch for f in tripman trapman cwebman do $TEX $f done $PAX "$OUTDIR/mf.tar.gz" -s ,^,mf/, mf.$EXT trapman.$EXT && true $PAX "$OUTDIR/tex.tar.gz" -s ,^,tex/, \ glue.$EXT tex.$EXT tripman.$EXT && true $PAX "$OUTDIR/web.tar.gz" -s ,^,web/, \ webman.$EXT tangle.$EXT weave.$EXT twill.$EXT && true $PAX "$OUTDIR/cweb.tar.gz" -s ,^,cweb/, \ cwebman.$EXT common.$EXT ctangle.$EXT cweave.$EXT \ ctwill.$EXT refsort.$EXT twinx.$EXT && true else # -n $CHANGES for f in *.$EXT do case $f in *$CHANGES.$EXT ) rm -f $f; continue ;; esac mv $f $(basename $f .$EXT)$CHANGES.$EXT && true done [ "$HITEX" = "$TEX" ] && mv -f xetex.pdf xetex$CHANGES.pdf $PAX "$OUTDIR/mf$CHANGES.tar.gz" -s ,^,mf/, mf$CHANGES.$EXT && true $PAX "$OUTDIR/tex$CHANGES.tar.gz" -s ,^,tex/, tex$CHANGES.$EXT && true $PAX "$OUTDIR/web$CHANGES.tar.gz" -s ,^,web/, \ webman$CHANGES.$EXT \ tangle$CHANGES.$EXT weave$CHANGES.$EXT && true $PAX "$OUTDIR/cweb$CHANGES.tar.gz" -s ,^,cweb/, \ common$CHANGES.$EXT ctangle$CHANGES.$EXT \ cweave$CHANGES.$EXT refsort$CHANGES.$EXT \ twinx$CHANGES.$EXT && true fi # $CHANGES $PAX "$OUTDIR/etc$CHANGES.tar.gz" -s ,^,etc/, \ vftovp$CHANGES.$EXT vptovf$CHANGES.$EXT && true $PAX "$OUTDIR/mfware$CHANGES.tar.gz" -s ,^,mfware/, \ gftodvi$CHANGES.$EXT gftopk$CHANGES.$EXT \ gftype$CHANGES.$EXT mft$CHANGES.$EXT && true $PAX "$OUTDIR/texware$CHANGES.tar.gz" -s ,^,texware/, \ dvitype$CHANGES.$EXT pltotf$CHANGES.$EXT \ pooltype$CHANGES.$EXT tftopl$CHANGES.$EXT && true $PAX "$OUTDIR/other$CHANGES.tar.gz" -s ,^,other/, \ dvicopy$CHANGES.$EXT patgen$CHANGES.$EXT \ pktogf$CHANGES.$EXT pktype$CHANGES.$EXT && true [ "$HITEX" = "$TEX" ] || { $PAX "$OUTDIR/xetex$CHANGES.tar.gz" -s ,^,xetex/, \ xetex$CHANGES.pdf && true ; } for f in bibtex pdftex ctie tie do $PAX "$OUTDIR/$f$CHANGES.tar.gz" -s ,^,$f/, $f$CHANGES.$EXT && true done # Notes to self: # (1) Create a user-friendly central entrypoint with # (a) pandoc index.md -o index.pdf # (b) pandoc index.md -s -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 (42/53 and 34/54) with either of # (a) pax -wzf knuth-pdf.tar.gz knuth-pdf # (a') pax -wzf knuth-hint.tar.gz knuth-hint # (b) zip -r knuth-pdf.zip knuth-pdf # (b') zip -r knuth-hint.zip knuth-hint fi exit 0