diff options
Diffstat (limited to 'Master/bin/powerpc-darwin/texi2dvi')
-rwxr-xr-x | Master/bin/powerpc-darwin/texi2dvi | 2030 |
1 files changed, 1455 insertions, 575 deletions
diff --git a/Master/bin/powerpc-darwin/texi2dvi b/Master/bin/powerpc-darwin/texi2dvi index 18f6f59322b..4607be1949e 100755 --- a/Master/bin/powerpc-darwin/texi2dvi +++ b/Master/bin/powerpc-darwin/texi2dvi @@ -1,14 +1,14 @@ #! /bin/sh -# texi2dvi --- produce DVI (or PDF) files from Texinfo (or LaTeX) sources. -# $Id: texi2dvi,v 1.42 2005/02/11 13:35:14 karl Exp $ +# texi2dvi --- produce DVI (or PDF) files from Texinfo (or (La)TeX) sources. +# $Id: texi2dvi,v 1.122 2008/04/17 18:45:49 karl Exp $ # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, -# 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. +# the Free Software Foundation; either version 3 of the License, +# or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -16,9 +16,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, you can either send email to this -# program's maintainer or write to: The Free Software Foundation, -# Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA. +# along with this program. If not, see <http://www.gnu.org/licenses/>. # # Original author: Noah Friedman. # @@ -31,48 +29,106 @@ test -f /bin/ksh && test -z "$RUNNING_KSH" \ && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; } unset RUNNING_KSH +# No failure shall remain unpunished. +set -e + # This string is expanded by rcs automatically when this file is checked out. -rcs_revision='$Revision: 1.42 $' +rcs_revision='$Revision: 1.122 $' rcs_version=`set - $rcs_revision; echo $2` program=`echo $0 | sed -e 's!.*/!!'` -version="texi2dvi (GNU Texinfo 4.8) $rcs_version +version="texi2dvi (GNU Texinfo 4.12) $rcs_version + +Copyright (C) 2008 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. +" -Copyright (C) 2005 Free Software Foundation, Inc. -There is NO warranty. You may redistribute this software -under the terms of the GNU General Public License. -For more information about these matters, see the files named COPYING." +build_mode=${TEXI2DVI_BUILD_MODE:-local} +build_dir=${TEXI2DVI_BUILD_DIRECTORY:-.} usage="Usage: $program [OPTION]... FILE... -Run each Texinfo or LaTeX FILE through TeX in turn until all +Run each Texinfo or (La)TeX FILE through TeX in turn until all cross-references are resolved, building all indices. The directory containing each FILE is searched for included files. The suffix of FILE -is used to determine its language (LaTeX or Texinfo). +is used to determine its language ((La)TeX or Texinfo). To process +(e)plain TeX files, set the environment variable LATEX=tex. + +In order to make texi2dvi a drop-in replacement of TeX/LaTeX in AUC-TeX, +the FILE may also be composed of the following simple TeX commands. + \`\\input{FILE}' the actual file to compile + \`\\nonstopmode' same as --batch Makeinfo is used to perform Texinfo macro expansion before running TeX when needed. -Operation modes: +General options: -b, --batch no interaction - -c, --clean remove all auxiliary files -D, --debug turn on shell debugging (set -x) -h, --help display this help and exit successfully -o, --output=OFILE leave output in OFILE (implies --clean); - Only one input FILE may be specified in this case + only one input FILE may be specified in this case -q, --quiet no output unless errors (implies --batch) -s, --silent same as --quiet -v, --version display version information and exit successfully -V, --verbose report on what is done TeX tuning: - -@ use @input instead of \input; for preloaded Texinfo - -e, -E, --expand force macro expansion using makeinfo - -I DIR search DIR for Texinfo files - -l, --language=LANG specify the LANG of FILE (LaTeX or Texinfo) - -p, --pdf use pdftex or pdflatex for processing - -r, --recode call recode before TeX to translate input characters - -t, --command=CMD insert CMD in copy of input file - or --texinfo=CMD multiple values accumulate + -@ use @input instead of \input for preloaded Texinfo + --dvi output a DVI file [default] + -e, -E, --expand force macro expansion using makeinfo + -I DIR search DIR for Texinfo files + -l, --language=LANG specify the LANG of FILE (LaTeX or Texinfo) + --no-line-error do not pass --file-line-error to TeX + -p, --pdf use pdftex or pdflatex for processing + -r, --recode call recode before TeX to translate input + --recode-from=ENC recode from ENC to the @documentencoding + --src-specials pass --src-specials to TeX + -t, --command=CMD insert CMD in copy of input file + or --texinfo=CMD multiple values accumulate + --translate-file=FILE use given charset translation file for TeX + +Build modes: + --build=MODE specify the treatment of auxiliary files [$build_mode] + --tidy same as --build=tidy + -c, --clean same as --build=clean + --build-dir=DIR specify where the tidy compilation is performed; + implies --tidy; + defaults to TEXI2DVI_BUILD_DIRECTORY [$build_dir] + --mostly-clean remove the auxiliary files and directories + but not the output + +The MODE specifies where the TeX compilation takes place, and, as a +consequence, how auxiliary files are treated. The build mode +can also be set using the environment variable TEXI2DVI_BUILD_MODE. + +Valid MODEs are: + \`local' compile in the current directory, leaving all the auxiliary + files around. This is the traditional TeX use. + \`tidy' compile in a local *.t2d directory, where the auxiliary files + are left. Output files are copied back to the original file. + \`clean' same as \`tidy', but remove the auxiliary directory afterwards. + Every compilation therefore requires the full cycle. + +Using the \`tidy' mode brings several advantages: + - the current directory is not cluttered with plethora of temporary files. + - clutter can be even reduced using --build-dir=dir: all the *.t2d + directories are stored there. + - clutter can be reduced to zero using, e.g., --build-dir=/tmp/\$USER.t2d + or --build-dir=\$HOME/.t2d. + - the output file is updated after every succesful TeX run, for + sake of concurrent visualization of the output. In a \`local' build + the viewer stops during the whole TeX run. + - if the compilation fails, the previous state of the output file + is preserved. + - PDF and DVI compilation are kept in separate subdirectories + preventing any possibility of auxiliary file incompatibility. + +On the other hand, because \`tidy' compilation takes place in another +directory, occasionally TeX won't be able to find some files (e.g., when +using \\graphicspath): in that case use -I to specify the additional +directories to consider. The values of the BIBTEX, LATEX (or PDFLATEX), MAKEINDEX, MAKEINFO, TEX (or PDFTEX), TEXINDEX, and THUMBPDF environment variables are used @@ -86,30 +142,48 @@ Texinfo home page: http://www.gnu.org/software/texinfo/" # Initialize variables for option overriding and otherwise. # Don't use `unset' since old bourne shells don't have this command. # Instead, assign them an empty value. -batch=false # eval for batch mode -clean= -debug= -escape='\' +action=compile +batch=false # true for batch mode +debug=false +escape="\\" expand= # t for expansion via makeinfo -miincludes= # makeinfo include path -oformat=dvi +includes= +line_error=true # Pass --file-line-error to TeX. +no_line_error=false # absolutely do not pass --file-line-error to TeX oname= # --output -quiet= # by default let the tools' message be displayed +out_lang=dvi +quiet=false # by default let the tools' message be displayed recode=false set_language= +src_specials= textra= # Extra TeX commands to insert in the input file. -textra_cmd= # sed command to insert TEXTRA where appropriate -tmpdir=${TMPDIR:-/tmp}/t2d$$ # avoid collisions on 8.3 filesystems. -txincludes= # TEXINPUTS extensions, with trailing colon txiprereq=19990129 # minimum texinfo.tex version with macro expansion -verb=false # echo for verbose mode +verb=false # true for verbose mode +translate_file= # name of charset translation file +recode_from= # if not empty, recode from this encoding to @documentencoding orig_pwd=`pwd` +# We have to initialize IFS to space tab newline since we save and +# restore IFS and apparently POSIX allows stupid/broken behavior with +# empty-but-set IFS. +# http://lists.gnu.org/archive/html/automake-patches/2006-05/msg00008.html +# We need space, tab and new line, in precisely that order. And don't leave +# trailing blanks. +space=' ' +tab=' ' +newline=' +' +IFS="$space$tab$newline" + +# In case someone pedantic insists on using grep -E. +: ${EGREP=egrep} + # Systems which define $COMSPEC or $ComSpec use semicolons to separate -# directories in TEXINPUTS -- except for Cygwin, where COMSPEC might be -# inherited, but : is used. -if test -n "$COMSPEC$ComSpec" && uname | grep -iv cygwin >/dev/null; then +# directories in TEXINPUTS -- except for Cygwin et al., where COMSPEC +# might be inherited, but : is used. +if test -n "$COMSPEC$ComSpec" \ + && uname | $EGREP -iv 'cygwin|mingw|djgpp' >/dev/null; then path_sep=";" else path_sep=":" @@ -118,37 +192,129 @@ fi # Pacify verbose cds. CDPATH=${ZSH_VERSION+.}$path_sep -# In case someone crazy insists on using grep -E. -: ${EGREP=egrep} +# If $TEX is set to a directory, don't use it. +test -n "$TEX" && test -d "$TEX" && unset TEX -# return true if program $1 is somewhere in PATH, else false. +# +## --------------------- ## +## Auxiliary functions. ## +## --------------------- ## + +# In case `local' is not supported by the shell, provide a function +# that simulates it by simply performing the assignments. This means +# that we must not expect `local' to work, i.e., we must not (i) rely +# on it during recursion, and (ii) have two local declarations of the +# same variable. (ii) is easy to check statically, and our test suite +# does make sure there is never twice a static local declaration of a +# variable. (i) cannot be checked easily, so just be careful. # -findprog () +# Note that since we might use a function simulating `local', we can +# no longer rely on the fact that no IFS-splitting is performed. So, +# while +# +# foo=$bar +# +# is fine (no IFS-splitting), never write +# +# local foo=$bar +# +# but rather +# +# local foo="$bar" +( + foo=bar + test_local () { + local foo=foo + } + test_local + test $foo = bar +) || local () { + case $1 in + *=*) eval "$1";; + esac +} + + +# cd_orig +# ------- +# Return to the original directory. +cd_orig () { - foundprog=false + # In case $orig_pwd is on a different drive (for DOS). + cd / - saveIFS=$IFS + # Return to the original directory so that + # - the next file is processed in correct conditions + # - the temporary file can be removed + cd "$orig_pwd" || exit 1 +} + +# func_dirname FILE +# ----------------- +# Return the directory part of FILE. +func_dirname () +{ + dirname "$1" 2>/dev/null \ + || { echo "$1" | sed 's!/[^/]*$!!;s!^$!.!'; } +} + + +# absolute NAME -> ABS-NAME +# ------------------------- +# Return an absolute path to NAME. +absolute () +{ + case $1 in + [\\/]* | ?:[\\/]*) + # Absolute paths don't need to be expanded. + echo "$1" + ;; + *) local slashes + slashes=`echo "$1" | sed -n 's,.*[^/]\(/*\)$,\1,p'` + local rel + rel=$orig_pwd/`func_dirname "$1"` + if test -d "$rel"; then + (cd "$rel" 2>/dev/null && + local n + n=`pwd`/`basename "$1"`"$slashes" + echo "$n") + else + error 1 "not a directory: $rel" + fi + ;; + esac +} + + +# findprog PROG +# ------------- +# Return true if PROG is somewhere in PATH, else false. +findprog () +{ + local saveIFS="$IFS" IFS=$path_sep # break path components at the path separator for dir in $PATH; do - # use test -x rather than test -f for DJGPP, where test -x checks - # for .exe. But test -x will also return true for directories, so - # explicitly ignore those. - if test -x "$dir/$1" && test ! -d "$dir/$1"; then - foundprog=true - break - - # But on cygwin, test -x foo will not find foo.exe. So also check - # for that. - elif test -x "$dir/$1.exe"; then - foundprog=true - break + IFS=$saveIFS + # The basic test for an executable is `test -f $f && test -x $f'. + # (`test -x' is not enough, because it can also be true for directories.) + # We have to try this both for $1 and $1.exe. + # + # Note: On Cygwin and DJGPP, `test -x' also looks for .exe. On Cygwin, + # also `test -f' has this enhancement, bot not on DJGPP. (Both are + # design decisions, so there is little chance to make them consistent.) + # Thusly, it seems to be difficult to make use of these enhancements. + # + if { test -f "$dir/$1" && test -x "$dir/$1"; } || + { test -f "$dir/$1.exe" && test -x "$dir/$1.exe"; }; then + return 0 fi done - IFS=$saveIFS - $foundprog + return 1 } -# Report some information. +# report LINE1 LINE2... +# --------------------- +# Report some information on stderr. report () { for i in "$@" @@ -157,30 +323,1083 @@ report () done } +# verbose WORD1 WORD2 +# ------------------- # Report some verbose information. verbose () { - $verb >&2 "$0: $@" + if $verb; then + echo >&2 "$0: $@" + fi } -# Report an error and exit with failure. -fatal () +# run COMMAND-LINE +# ---------------- +# Run the COMMAND-LINE verbosely, and catching errors as failures. +run () { - s=$1 + verbose "Running $@" + "$@" 2>&5 1>&2 || + error 1 "$1 failed" +} + + +# error EXIT_STATUS LINE1 LINE2... +# -------------------------------- +# Report an error and exit with failure if EXIT_STATUS is non null. +error () +{ + local s="$1" shift report "$@" - exit $s + if test "$s" != 0; then + exit $s + fi +} + +# ensure_dir DIR1 DIR2... +# ----------------------- +# Make sure the directories exist. +ensure_dir () +{ + for dir + do + test -d "$dir" \ + || mkdir "$dir" \ + || error 1 "cannot create directory: $dir" + done +} + + +## ---------------- ## +## Handling lists. ## +## ---------------- ## + + +# list_append LIST-NAME ELEM +# -------------------------- +# Set LIST-NAME to its former contents, with ELEM appended. +list_append () +{ + local la_l="$1" + shift + eval set X \$$la_l "$@" + shift + eval $la_l=\""$@"\" +} + +# list_prefix LIST-NAME SEP -> STRING +# ----------------------------------- +# Return a string that is composed of the LIST-NAME with each item +# preceded by SEP. +list_prefix () +{ + local lp_p="$2" + eval set X \$$1 + shift + local lp_res + for i + do + lp_res="$lp_res \"$lp_p\" \"$i\"" + done + echo "$lp_res" } +# list_infix LIST-NAME SEP -> STRING +# ---------------------------------- +# Same as list_prefix, but a separator. +list_infix () +{ + eval set X \$$1 + shift + local la_IFS="$IFS" + IFS=$path_sep + echo "$*" + IFS=$la_IFS +} + +# list_dir_to_abs LIST-NAME +# ------------------------- +# Convert the list to using only absolute dir names. +# Currently unused, but should replace absolute_filenames some day. +list_dir_to_abs () +{ + local ld_l="$1" + eval set X \$$ld_l + shift + local ld_res + for dir + do + dir=`absolute "$dir"` + test -d "$dir" || continue + ld_res="$ld_res \"$dir\"" + done + set X $ld_res; shift + eval $ld_l=\"$@\" +} + + +## ------------------------------ ## +## Language auxiliary functions. ## +## ------------------------------ ## + +# out_lang_tex +# ------------ +# Return the tex output language (DVI or PDF) for $OUT_LANG. +out_lang_tex () +{ + case $out_lang in + dvi | ps | dvipdf ) echo dvi;; + pdf ) echo $out_lang;; + html | info | text ) echo $out_lang;; + *) error 1 "$0: invalid out_lang: $1";; + esac +} + + +# out_lang_ext +# ------------ +# Return the extension for $OUT_LANG. +out_lang_ext () +{ + case $out_lang in + dvipdf ) echo pdf;; + dvi | html | info | pdf | ps | text ) echo $out_lang;; + *) error 1 "$0: invalid out_lang: $1";; + esac +} + + +## ------------------------- ## +## TeX auxiliary functions. ## +## ------------------------- ## + # Save TEXINPUTS so we can construct a new TEXINPUTS path for each file. # Likewise for bibtex and makeindex. -tex_envvars="BIBINPUTS BSTINPUTS INDEXSTYLE TEXINPUTS" +tex_envvars="BIBINPUTS BSTINPUTS DVIPSHEADERS INDEXSTYLE MFINPUTS MPINPUTS \ +TEXINPUTS TFMFONTS" for var in $tex_envvars; do eval ${var}_orig=\$$var export $var done +# absolute_filenames TEX-PATH -> TEX-PATH +# --------------------------------------- +# Convert relative paths to absolute paths, so we can run in another +# directory (e.g., in tidy build mode, or during the macro-support +# detection). +# +# Empty path components are meaningful to tex. We rewrite them +# as `EMPTY' so they don't get lost when we split on $path_sep. +# Hopefully no one will have an actual directory named EMPTY. +absolute_filenames () +{ + local replace_empty="-e 's/^$path_sep/EMPTY$path_sep/g' \ + -e 's/$path_sep\$/${path_sep}EMPTY/g' \ + -e 's/$path_sep$path_sep/${path_sep}EMPTY:/g'" + local res + res=`echo "$1" | eval sed $replace_empty` + save_IFS=$IFS + IFS=$path_sep + set x $res; shift + res=. + for dir + do + case $dir in + EMPTY) + res=$res$path_sep + ;; + *) + if test -d $dir; then + res=$res$path_sep`absolute "$dir"` + fi + ;; + esac + done + echo "$res" +} + + +# output_base_name FILE +# --------------------- +# The name of FILE, possibly renamed to satisfy --output. +output_base_name () +{ + case $oname in + '') echo "$1";; + *) local out_noext + out_noext=`echo "$oname" | sed 's/\.[^.]*$//'` + local file_ext + file_ext=`echo "$1" | sed 's/^.*\.//'` + echo "$out_noext.$file_ext" + ;; + esac +} + + +# move_to_dest FILE... +# -------------------- +# Move FILE to the place where the user expects it. Truly move it, that +# is, it must not remain in its build location unless that is also the +# output location. (Otherwise it might appear as an extra file in make +# distcheck.) +# +# FILE can be the principal output (in which case -o directly applies), or +# an auxiliary file with the same base name. +move_to_dest () +{ + local dest + local destfile + local destdir + local destbase + local sourcedir + local sourcebase + + for file + do + case $tidy:$oname in + true:) dest=$orig_pwd;; + false:) dest=;; + *:*) dest=`output_base_name "$file"`;; + esac + if test ! -f "$file"; then + error 1 "no such file or directory: $file" + fi + if test -n "$dest"; then + # We need to know whether $dest is a directory. + if test -d "$dest"; then + destdir=$dest + destfile=$dest/$file + else + destdir="`dirname $dest`" + destfile=$dest + fi + # We want to compare the source location and the output location, + # and if they are different, do the move. But if they are the + # same, we must preserve the source. Since we can't assume + # stat(1) or test -ef is available, resort to comparing the + # directory names, canonicalized with pwd. We can't use cmp -s + # since the output file might not actually change from run to run; + # e.g., TeX DVI output is timestamped to only the nearest minute. + destdir=`cd $destdir && pwd` + destbase=`basename $destfile` + # + sourcedir=`dirname $file` + sourcedir=`cd $sourcedir && pwd` + sourcebase=`basename $file` + # + if test "$sourcedir/$sourcebase" != "$destdir/$destbase"; then + verbose "Moving $file to $destfile" + rm -f "$destfile" + mv "$file" "$destfile" + fi + fi + done +} + + +## --------------------- ## +## Managing xref files. ## +## --------------------- ## + +# aux_file_p FILE +# --------------- +# Return with success with FILE is an aux file. +aux_file_p () +{ + test -f "$1" || return 1 + case $1 in + *.aux) return 0;; + *) return 1;; + esac +} + +# bibaux_file_p FILE +# ------------------ +# Return with success with FILE is an aux file containing citation +# requests. +bibaux_file_p () +{ + test -s "$1" || return 1 + if (grep '^\\bibstyle[{]' "$1" \ + && grep '^\\bibdata[{]' "$1" \ + ## The following line is suspicious: fails when there + ## are citations in sub aux files. We need to be + ## smarter in this case. + ## && grep '^\\citation[{]' "$f" + ) >&6 2>&1; + then + return 0 + fi + return 1 +} + +# index_file_p FILE +# ----------------- +# Return with success with FILE is an index file. +# When index.sty is used, there is a space before the brace. +index_file_p () +{ + test -f "$1" || return 1 + case `sed '1q' "$1"` in + "\\entry{"*|"\\indexentry{"*|"\\indexentry {"*) return 0;; + *) return 1;; + esac +} + +# xref_file_p FILE +# ---------------- +# Return with success if FILE is an xref file (indexes, tables and lists). +xref_file_p () +{ + test -f "$1" || return 1 + # If the file is not suitable to be an index or xref file, don't + # process it. It's suitable if the first character is a + # backslash or right quote or at, as long as the first line isn't + # \input texinfo. + case `sed '1q' "$1"` in + "\\input texinfo"*) return 1;; + [\\''@]*) return 0;; + *) return 1;; + esac +} + + +# generated_files_get FILENAME-NOEXT [PREDICATE-FILTER] +# ----------------------------------------------------- +# Return the list of files generated by the TeX compilation of FILENAME-NOEXT. +generated_files_get () +{ + local filter=true + if test -n "$2"; then + filter=$2 + fi + + # Gather the files created by TeX. + ( + if test -f "$1.log"; then + sed -n -e "s,^\\\\openout.* = \`\\(.*\\)'\\.,\\1,p" "$1.log" + fi + echo "$1.log" + ) | + # Depending on these files, infer outputs from other tools. + while read file; do + echo $file + case $in_lang in + texinfo) + # texindex: texinfo.cp -> texinfo.cps + if index_file_p $file; then + echo ${file}s + fi + ;; + latex) + # bibtex: *.aux -> *.bbl and *.blg. + if aux_file_p $file; then + echo $file | sed 's/^\(.*\)\.aux$/\1.bbl/' + echo $file | sed 's/^\(.*\)\.aux$/\1.blg/' + fi + ;; + esac + done | + # Filter existing files matching the criterion. + # + # With an input file name containing a space, this produces a + # "command not found" message (and filtering is ineffective). + # The situation with a newline is presumably even worse. + while read file; do + if $filter "$file"; then + echo $file + fi + done | + sort | + # Some files are opened several times, e.g., listings.sty's *.vrb. + uniq +} + + +# xref_files_save +# --------------- +# Save the xref files. +xref_files_save () +{ + # Save copies of auxiliary files for later comparison. + xref_files_orig=`generated_files_get "$in_noext" xref_file_p` + if test -n "$xref_files_orig"; then + verbose "Backing up xref files: $xref_files_orig" + # The following line improves `cp $xref_files_orig "$work_bak"' + # by preserving the directory parts. Think of + # cp chap1/main.aux chap2/main.aux $work_bak. + tar cf - $xref_files_orig | (cd "$work_bak" && tar xf -) + fi +} + + +# xref_files_changed +# ------------------ +# Whether the xref files were changed since the previous run. +xref_files_changed () +{ + # LaTeX (and the package changebar) report in the LOG file if it + # should be rerun. This is needed for files included from + # subdirs, since texi2dvi does not try to compare xref files in + # subdirs. Performing xref files test is still good since LaTeX + # does not report changes in xref files. + if grep "Rerun to get" "$in_noext.log" >&6 2>&1; then + return 0 + fi + + # If old and new lists don't at least have the same file list, + # then one file or another has definitely changed. + xref_files_new=`generated_files_get "$in_noext" xref_file_p` + verbose "Original xref files = $xref_files_orig" + verbose "New xref files = $xref_files_new" + if test "x$xref_files_orig" != "x$xref_files_new"; then + return 0 + fi + + # Compare each file until we find a difference. + for this_file in $xref_files_new; do + verbose "Comparing xref file `echo $this_file | sed 's|\./||g'` ..." + # cmp -s returns nonzero exit status if files differ. + if cmp -s "$this_file" "$work_bak/$this_file"; then :; else + verbose "xref file `echo $this_file | sed 's|\./||g'` differed ..." + if $debug; then + diff -u "$work_bak/$this_file" "$this_file" + fi + return 0 + fi + done + + # No change. + return 1 +} + + + +## ----------------------- ## +## Running the TeX suite. ## +## ----------------------- ## + + + +# run_tex () +# ---------- +# Run TeX as "$tex $in_input", taking care of errors and logs. +run_tex () +{ + case $in_lang:`out_lang_tex` in + latex:dvi) tex=${LATEX:-latex};; + latex:pdf) tex=${PDFLATEX:-pdflatex};; + texinfo:dvi) + # MetaPost also uses the TEX environment variable. If the user + # has set TEX=latex for that reason, don't bomb out. + case $TEX in + *latex) tex=tex;; # don't bother trying to find etex + *) tex=$TEX + esac;; + texinfo:pdf) tex=$PDFTEX;; + + *) error 1 "$0: $out_lang not supported for $in_lang";; + esac + + # Beware of aux files in subdirectories that require the + # subdirectory to exist. + case $in_lang:$tidy in + latex:true) + sed -n 's|^[ ]*\\include{\(.*\)/.*}.*|\1|p' "$in_input" | + sort -u | + while read d + do + ensure_dir "$work_build/$d" + done + ;; + esac + + # Note that this will be used via an eval: quote properly. + local cmd="$tex" + + # If possible, make TeX report error locations in GNU format. + if test "${tex_help:+set}" != set; then + # Go to a temporary directory to try --help, since old versions that + # don't accept --help will generate a texput.log. + tex_help_dir=$t2ddir/tex_help + ensure_dir "$tex_help_dir" + tex_help=`cd "$tex_help_dir" >&6 && $tex --help </dev/null 2>&1` + fi + if $no_line_error; then :; else + # The mk program and perhaps others want to parse TeX's + # original error messages. + case $line_error:$tex_help in + true:*file-line-error*) cmd="$cmd --file-line-error";; + esac + fi + + # Tell TeX about TCX file, if specified. + test -n "$translate_file" && cmd="$cmd --translate-file=$translate_file" + + # Tell TeX to make source specials (for backtracking from output to + # source, given a sufficiently smart editor), if specifed. + test -n "$src_specials" && cmd="$cmd $src_specials" + + # Tell TeX to be batch if requested. + if $batch; then + # \batchmode does not show terminal output at all, so we don't + # want that. And even in batch mode, TeX insists on having input + # from the user. Close its stdin to make it impossible. + cmd="$cmd </dev/null '${escape}nonstopmode' '${escape}input'" + fi + + # we'd like to handle arbitrary input file names, such as a~b.tex. + # This isn't a general way to do it :), though it does work, kind of. + # cmd="$cmd '${escape}catcode126=12 \input '" + + # TeX's \input does not (easily or reliably) support whitespace + # characters or other special characters in file names. Our intensive + # use of absolute file names makes this worse: the enclosing directory + # names may include white spaces. Improve the situation using a + # symbolic link to the filename in the current directory, in tidy mode + # only. Do not alter in_input. + # + # The filename is almost always tokenized using plain TeX conventions + # (the exception would be if the user made a texinfo.fmt file). Not + # all the plain TeX special characters cause trouble, but there's no + # harm in making the link. + # + case $tidy:`func_dirname "$in_input"` in + true:*["$space$tab$newline\"#\$%\\^_{}"]*) + _run_tex_file_name=`basename "$in_input"` + if test ! -f "$_run_tex_file_name"; then + verbose ln -s "$in_input" + rm -f "$_run_tex_file_name" + ln -s "$_run_tex_file_name" + fi + cmd="$cmd '$_run_tex_file_name'" + ;; + + *) + cmd="$cmd '$in_input'" + ;; + esac + + verbose "$0: Running $cmd ..." + if eval "$cmd" >&5; then + case $out_lang in + dvi | pdf ) move_to_dest "$in_noext.$out_lang";; + esac + else + error 1 "$tex exited with bad status, quitting." + fi +} + +# run_bibtex () +# ------------- +# Run bibtex on current file. +# - If its input (AUX) exists. +# - If some citations are missing (LOG contains `Citation'). +# or the LOG complains of a missing .bbl +# +# Don't try to be too smart: +# +# 1. Running bibtex only if the bbl file exists and is older than +# the LaTeX file is wrong, since the document might include files +# that have changed. +# +# 3. Because there can be several AUX (if there are \include's), +# but a single LOG, looking for missing citations in LOG is +# easier, though we take the risk to match false messages. +run_bibtex () +{ + case $in_lang in + latex) bibtex=${BIBTEX:-bibtex};; + texinfo) return;; + esac + + # "Citation undefined" is for LaTeX, "Undefined citation" for btxmac.tex. + # The no .aux && \bibdata test is also for btxmac, in case it was the + # first run of a bibtex-using document. Otherwise, it's possible that + # bibtex would never be run. + if test -r "$in_noext.aux" \ + && test -r "$in_noext.log" \ + && (grep 'Warning:.*Citation.*undefined' "$in_noext.log" \ + || grep '.*Undefined citation' "$in_noext.log" \ + || grep 'No file .*\.bbl\.' "$in_noext.log") \ + || (grep 'No \.aux file' "$in_noext.log" \ + && grep '^\\bibdata' "$in_noext.aux") \ + >&6 2>&1; \ + then + for f in `generated_files_get "$in_noext" bibaux_file_p` + do + run $bibtex "$f" + done + fi +} + +# run_index () +# ------------ +# Run texindex (or makeindex) on current index files. If they already +# exist, and after running TeX a first time the index files don't +# change, then there's no reason to run TeX again. But we won't know +# that if the index files are out of date or nonexistent. +run_index () +{ + case $in_lang in + latex) texindex=${MAKEINDEX:-makeindex};; + texinfo) texindex=${TEXINDEX:-texindex};; + esac + index_files=`generated_files_get $in_noext index_file_p` + if test -n "$texindex" && test -n "$index_files"; then + run $texindex $index_files + fi +} + + +# run_thumbpdf () +# --------------- +run_thumbpdf () +{ + if test `out_lang_tex` = pdf \ + && test -r "$in_noext.log" \ + && grep 'thumbpdf\.sty' "$in_noext.log" >&6 2>&1; \ + then + thumbpdf=${THUMBPDF:-thumbpdf} + verbose "Running $thumbpdf $in_noext ..." + if $thumbpdf "$in_noext" >&5; then + run_tex + else + report "$thumbpdf exited with bad status." \ + "Ignoring its output." + fi + fi +} + + +# run_dvipdf FILE.dvi +# ------------------- +# Convert FILE.dvi to FILE.pdf. +run_dvipdf () +{ + # Find which dvi->pdf program is available. + if test -z "$dvipdf"; then + for i in "$DVIPDF" dvipdfmx dvipdfm dvipdf dvi2pdf dvitopdf; + do + if findprog $i; then + dvipdf=$i + fi + done + fi + # These tools have varying interfaces, some 'input output', others + # 'input -o output'. They all seem to accept 'input' only, + # outputting using the expected file name. + run $dvipdf "$1" + if test ! -f `echo "$1" | sed -e 's/\.dvi$/.pdf/'`; then + error 1 "$0: cannot find output file" + fi +} + +# run_tex_suite () +# ---------------- +# Run the TeX tools until a fix point is reached. +run_tex_suite () +{ + # Move to the working directory. + if $tidy; then + verbose "cd $work_build" + cd "$work_build" || exit 1 + fi + + # Count the number of cycles. + local cycle=0 + + while :; do + cycle=`expr $cycle + 1` + verbose "Cycle $cycle for $command_line_filename" + + xref_files_save + + # We run bibtex first, because I can see reasons for the indexes + # to change after bibtex is run, but I see no reason for the + # converse. + run_bibtex + run_index + run_core_conversion + + xref_files_changed || break + done + + # If we were using thumbpdf and producing PDF, then run thumbpdf + # and TeX one last time. + run_thumbpdf + + # Install the result if we didn't already (i.e., if the output is + # dvipdf or ps). + case $out_lang in + dvipdf) + run_dvipdf "$in_noext.`out_lang_tex`" + move_to_dest "$in_noext.`out_lang_ext`" + ;; + ps) + dvips -o "$in_noext.`out_lang_ext`" "$in_noext.`out_lang_tex`" + move_to_dest "$in_noext.`out_lang_ext`" + ;; + esac + + cd_orig +} + +## -------------------------------- ## +## TeX processing auxiliary tools. ## +## -------------------------------- ## + + +# A sed script that preprocesses Texinfo sources in order to keep the +# iftex sections only. We want to remove non TeX sections, and comment +# (with `@c texi2dvi') TeX sections so that makeinfo does not try to +# parse them. Nevertheless, while commenting TeX sections, don't +# comment @macro/@end macro so that makeinfo does propagate them. +# Unfortunately makeinfo --iftex --no-ifinfo doesn't work well enough +# (yet), makeinfo can't parse the TeX commands, so work around with sed. +# +comment_iftex=\ +'/^@tex/,/^@end tex/{ + s/^/@c texi2dvi/ +} +/^@iftex/,/^@end iftex/{ + s/^/@c texi2dvi/ + /^@c texi2dvi@macro/,/^@c texi2dvi@end macro/{ + s/^@c texi2dvi// + } +} +/^@ifnottex/,/^@end ifnottex/{ + s/^/@c (texi2dvi)/ +} +/^@ifinfo/,/^@end ifinfo/{ + /^@node/p + /^@menu/,/^@end menu/p + t + s/^/@c (texi2dvi)/ +} +s/^@ifnotinfo/@c texi2dvi@ifnotinfo/ +s/^@end ifnotinfo/@c texi2dvi@end ifnotinfo/' + +# Uncommenting is simple: Remove any leading `@c texi2dvi'. +uncomment_iftex='s/^@c texi2dvi//' + + +# run_makeinfo () +# --------------- +# Expand macro commands in the original source file using Makeinfo. +# Always use `end' footnote style, since the `separate' style +# generates different output (arguably this is a bug in -E). Discard +# main info output, the user asked to run TeX, not makeinfo. +run_makeinfo () +{ + test $in_lang == texinfo || + return 0 + + # Unless required by the user, makeinfo expansion is wanted only + # if texinfo.tex is too old. + if test "$expand" = t; then + makeinfo=${MAKEINFO:-makeinfo} + else + # Check if texinfo.tex performs macro expansion by looking for + # its version. The version is a date of the form YEAR-MO-DA. + # We don't need to use [0-9] to match the digits since anyway + # the comparison with $txiprereq, a number, will fail with non + # digits. + # Run in a temporary directory to avoid leaving files. + version_test_dir=$t2ddir/version_test + ensure_dir "$version_test_dir" + ( + cd "$version_test_dir" + echo '\input texinfo.tex @bye' >txiversion.tex + # Be sure that if tex wants to fail, it is not interactive: + # close stdin. + $TEX txiversion.tex </dev/null >txiversion.out 2>txiversion.err + ) + if test $? != 0; then + cat "$version_test_dir/txiversion.out" + cat "$version_test_dir/txiversion.err" >&2 + error 1 "texinfo.tex appears to be broken, quitting." + fi + eval `sed -n 's/^.*\[\(.*\)version \(....\)-\(..\)-\(..\).*$/txiformat=\1 txiversion="\2\3\4"/p' "$version_test_dir/txiversion.out"` + verbose "texinfo.tex preloaded as \`$txiformat', version is \`$txiversion' ..." + if test "$txiprereq" -le "$txiversion" >&6 2>&1; then + makeinfo= + else + makeinfo=${MAKEINFO:-makeinfo} + fi + # As long as we had to run TeX, offer the user this convenience: + if test "$txiformat" = Texinfo; then + escape=@ + fi + fi + + if test -n "$makeinfo"; then + # in_src: the file with macros expanded. + # Use the same basename to generate the same aux file names. + work_src=$workdir/src + ensure_dir "$work_src" + in_src=$work_src/$in_base + local miincludes + miincludes=`list_prefix includes -I` + verbose "Macro-expanding $command_line_filename to $in_src ..." + # eval $makeinfo because it might be defined as something complex + # (running missing) and then we end up with things like '"-I"', + # and "-I" (including the quotes) is not an option name. This + # happens with gettext 0.14.5, at least. + sed "$comment_iftex" "$command_line_filename" \ + | eval $makeinfo --footnote-style=end -I "$in_dir" $miincludes \ + -o /dev/null --macro-expand=- \ + | sed "$uncomment_iftex" >"$in_src" + # Continue only if everything succeeded. + if test $? -ne 0 \ + || test ! -r "$in_src"; then + verbose "Expansion failed, ignored..."; + else + in_input=$in_src + fi + fi +} + +# insert_commands () +# ------------------ +# Used most commonly for @finalout, @smallbook, etc. +insert_commands () +{ + local textra_cmd + case $in_lang in + latex) textra_cmd=1i;; + texinfo) textra_cmd='/^@setfilename/a';; + *) error 1 "internal error, unknown language: $in_lang";; + esac + + if test -n "$textra"; then + # _xtr. The file with the user's extra commands. + work_xtr=$workdir/xtr + in_xtr=$work_xtr/$in_base + ensure_dir "$work_xtr" + verbose "Inserting extra commands: $textra" + sed "$textra_cmd\\ +$textra" "$in_input" >"$in_xtr" + in_input=$in_xtr + fi +} + +# run_recode () +# ------------- +# If this is a Texinfo file with a specified input encoding, and +# recode is available, then recode to plain 7 bit Texinfo. +run_recode () +{ + local from + local to + + if test $in_lang = texinfo; then + pgm='s/^ *@documentencoding *\([^ ][^ ]*\) *$/\1/ + t found + d + :found + q' + encoding=`sed -e "$pgm" "$in_input"` + if $recode && test -n "$encoding" && findprog recode; then + if test -n "$recode_from"; then + from=$recode_from + to=$encoding + else + from=$encoding + to=$texinfo + fi + verbose "Recoding from $from to $to." + # _rcd. The Texinfo file recoded in 7bit. + work_rcd=$workdir/recode + in_rcd=$work_rcd/$in_base + ensure_dir "$work_rcd" + if recode "$encoding..$to" <"$in_input" >"$in_rcd" \ + && test -s "$in_rcd"; then + in_input=$in_rcd + else + verbose "Recoding failed, using original input." + fi + fi + fi +} + +# compute_language FILENAME +# ------------------------- +# Return the short string describing the language in which FILENAME +# is written: `texinfo' or `latex'. +compute_language () +{ + # If the user explicitly specified the language, use that. + # Otherwise, if the first line is \input texinfo, assume it's texinfo. + # Otherwise, guess from the file extension. + if test -n "$set_language"; then + echo $set_language + elif sed 1q "$1" | grep 'input texinfo' >&6; then + echo texinfo + else + # Get the type of the file (latex or texinfo) from the given language + # we just guessed, or from the file extension if not set yet. + case $1 in + *.ltx | *.tex | *.drv | *.dtx) echo latex;; + *) echo texinfo;; + esac + fi +} + + +# run_hevea (MODE) +# ---------------- +# Convert to HTML/INFO/TEXT. +# +# Don't pass `-noiso' to hevea: it's useless in HTML since anyway the +# charset is set to latin1, and troublesome in other modes since +# accented characters loose their accents. +# +# Don't pass `-o DEST' to hevea because in that case it leaves all its +# auxiliary files there too... Too bad, because it means we will need +# to handle images some day. +run_hevea () +{ + local hevea="${HEVEA:-hevea}" + local run_hevea="$hevea" + + case $1 in + html) ;; + text|info) run_hevea="$run_hevea -$1";; + *) error 1 "run_hevea: invalid argument: $1";; + esac + + # Compiling to the tmp directory enables to preserve a previous + # successful compilation. + run_hevea="$run_hevea -fix -O -o '$out_base'" + run_hevea="$run_hevea `list_prefix includes -I` -I '$orig_pwd' " + run_hevea="$run_hevea '$in_input'" + + if $debug; then + run_hevea="$run_hevea -v -v" + fi + + verbose "running $run_hevea" + if eval "$run_hevea" >&5; then + # hevea leaves trailing white spaces, this is annoying. + case $1 in text|info) + perl -pi -e 's/[ \t]+$//g' "$out_base"*;; + esac + case $1 in + html|text) move_to_dest "$out_base";; + info) # There can be foo.info-1, foo.info-2 etc. + move_to_dest "$out_base"*;; + esac + else + error 1 "$hevea exited with bad status, quitting." + fi +} + + +# run_core_conversion () +# ---------------------- +# Run the TeX (or HeVeA). +run_core_conversion () +{ + case $in_lang:`out_lang_tex` in + *:dvi|*:pdf) + run_tex;; + latex:html|latex:text|latex:info) + run_hevea $out_lang;; + *) + error 1 "invalid input/output combination: $in_lang/$out_lang";; + esac +} + + +# compile () +# ---------- +# Run the full compilation chain, from pre-processing to installation +# of the output at its expected location. +compile () +{ + # Source file might include additional sources. + # We want `.:$orig_pwd' before anything else. (We'll add `.:' later + # after all other directories have been turned into absolute paths.) + # `.' goes first to ensure that any old .aux, .cps, + # etc. files in ${directory} don't get used in preference to fresher + # files in `.'. Include orig_pwd in case we are in clean build mode, where + # we've cd'd to a temp directory. + txincludes=`list_infix includes $path_sep` + common="$orig_pwd$path_sep$in_dir$path_sep$txincludes$path_sep" + for var in $tex_envvars; do + eval val="\$common\$${var}_orig" + # Convert relative paths to absolute paths, so we can run in another + # directory (e.g., in clean build mode, or during the macro-support + # detection). + val=`absolute_filenames "$val"` + eval $var="\"$val\"" + export $var + eval verbose \"$var=\'\$${var}\'\" + done + + # --expand + run_makeinfo + + # --command, --texinfo + insert_commands + + # --recode + run_recode + + # Run until a fix point is reached. + run_tex_suite +} + + +# remove FILES +# ------------ +remove () +{ + verbose "Removing" "$@" + rm -rf "$@" +} + + +# mostly_clean +# ------------ +# Remove auxiliary files and directories. Changes the current directory. +mostly_clean () +{ + cd_orig + set X "$t2ddir" + shift + $tidy || { + local log="$work_build/$in_noext.log" + set X ${1+"$@"} "$log" `generated_files_get "$work_build/$in_noext"` + shift + } + remove ${1+"$@"} +} + + +# cleanup () +# ---------- +# Remove what should be removed according to options. +# Called at the end of each compilation cycle, and at the end of +# the script. Changes the current directory. +cleanup () +{ + case $build_mode in + local) cd_orig; remove "$t2ddir";; + clean) mostly_clean;; + tidy) ;; + esac +} + + + +## ---------------------- ## +## Command line parsing. ## +## ---------------------- ## + # Push a token among the arguments that will be used to notice when we # ended options/arguments parsing. # Use "set dummy ...; shift" rather than 'set - ..." because on @@ -209,41 +1428,53 @@ while test x"$1" != x"$arg_sep"; do case "$1" in -@ ) escape=@;; # Silently and without documentation accept -b and --b[atch] as synonyms. - -b | --b*) batch=true;; - -c | --c*) clean=t;; - -D | --d*) debug=t;; - -e | -E | --e*) expand=t;; - -h | --h*) echo "$usage"; exit 0;; + -b | --batch) batch=true;; + --build) shift; build_mode=$1;; + --build-dir) shift; build_dir=$1; build_mode=tidy;; + -c | --clean) build_mode=clean;; + -D | --debug) debug=true;; + --dvi) out_lang=dvi;; + --dvipdf) out_lang=dvipdf;; + -e | -E | --expand) expand=t;; + -h | --help) echo "$usage"; exit 0;; + --html) out_lang=html;; -I | --I*) shift - miincludes="$miincludes -I $1" - txincludes="$txincludes$1$path_sep" + # Use absolute dir names in the includes. + val=`absolute "$1"` + list_append includes "$val" ;; - -l | --l*) shift; set_language=$1;; - -o | --o*) + --info) out_lang=info;; + -l | --lang | --language) shift; set_language=$1;; + --mostly-clean) action=mostly-clean;; + --no-line-error) no_line_error=true;; + -o | --out | --output) shift - clean=t - case "$1" in - /* | ?:/*) oname=$1;; - *) oname="$orig_pwd/$1";; - esac;; - -p | --p*) oformat=pdf;; - -q | -s | --q* | --s*) quiet=t; batch=true;; - -r | --r*) recode=true;; - -t | --tex* | --com* ) shift; textra="$textra\\ + # Make it absolute, just in case we also have --clean, or whatever. + oname=`absolute "$1"`;; + -p | --pdf) out_lang=pdf;; + --ps) out_lang=ps;; + -q | -s | --quiet | --silent) quiet=true; batch=true;; + -r | --recode) recode=true;; + --recode-from) shift; recode=true; recode_from="$1";; + --src-specials) src_specials=--src-specials;; + -t | --texinfo | --command ) shift; textra="$textra\\ "`echo "$1" | sed 's/\\\\/\\\\\\\\/g'`;; + --text) out_lang=text;; + --translate-file ) shift; translate_file="$1";; + --tidy) build_mode=tidy;; -v | --vers*) echo "$version"; exit 0;; - -V | --verb*) verb=echo;; + -V | --verb*) verb=true;; --) # What remains are not options. shift while test x"$1" != x"$arg_sep"; do - set dummy ${1+"$@"} "$1"; shift - shift + set dummy ${1+"$@"} "$1"; shift + shift done break;; -*) - fatal 1 "Unknown or ambiguous option \`$1'." \ - "Try \`--help' for more information." + error 1 "Unknown or ambiguous option \`$1'." \ + "Try \`--help' for more information." ;; *) set dummy ${1+"$@"} "$1"; shift;; esac @@ -252,15 +1483,24 @@ done # Pop the token shift +# $tidy: compile in a t2d directory. +# $clean: remove all the aux files. +case $build_mode in + local) clean=false; tidy=false;; + tidy) clean=false; tidy=true;; + clean) clean=true; tidy=true;; + *) error 1 "invalid build mode: $build_mode";; +esac + # Interpret remaining command line args as filenames. case $# in 0) - fatal 2 "Missing file arguments." "Try \`--help' for more information." + error 2 "Missing file arguments." "Try \`--help' for more information." ;; 1) ;; *) if test -n "$oname"; then - fatal 2 "Can't use option \`--output' with more than one argument." + error 2 "Can't use option \`--output' with more than one argument." fi ;; esac @@ -298,151 +1538,6 @@ if test -z "$PDFTEX"; then fi -# Prepare the temporary directory. Remove it at exit, unless debugging. -if test -z "$debug"; then - trap "cd / && rm -rf $tmpdir" 0 1 2 15 -fi - -# Create the temporary directory with strict rights -(umask 077 && mkdir $tmpdir) || exit 1 - -# Prepare the tools we might need. This may be extra work in some -# cases, but improves the readability of the script. -utildir=$tmpdir/utils -mkdir $utildir || exit 1 - -# A sed script that preprocesses Texinfo sources in order to keep the -# iftex sections only. We want to remove non TeX sections, and comment -# (with `@c texi2dvi') TeX sections so that makeinfo does not try to -# parse them. Nevertheless, while commenting TeX sections, don't -# comment @macro/@end macro so that makeinfo does propagate them. -# Unfortunately makeinfo --iftex --no-ifinfo doesn't work well enough -# (yet), makeinfo can't parse the TeX commands, so work around with sed. -# -comment_iftex_sed=$utildir/comment.sed -cat <<EOF >$comment_iftex_sed -/^@tex/,/^@end tex/{ - s/^/@c texi2dvi/ -} -/^@iftex/,/^@end iftex/{ - s/^/@c texi2dvi/ - /^@c texi2dvi@macro/,/^@c texi2dvi@end macro/{ - s/^@c texi2dvi// - } -} -/^@ifnottex/,/^@end ifnottex/{ - s/^/@c (texi2dvi)/ -} -/^@ifinfo/,/^@end ifinfo/{ - /^@node/p - /^@menu/,/^@end menu/p - t - s/^/@c (texi2dvi)/ -} -s/^@ifnotinfo/@c texi2dvi@ifnotinfo/ -s/^@end ifnotinfo/@c texi2dvi@end ifnotinfo/ -EOF -# Uncommenting is simple: Remove any leading `@c texi2dvi'. -uncomment_iftex_sed=$utildir/uncomment.sed -cat <<EOF >$uncomment_iftex_sed -s/^@c texi2dvi// -EOF - -# Compute the list of xref files. -# Takes the filename (without extension) of which we look for xref -# files as argument. The index files must be reported last. -get_xref_files () -{ - # Get list of xref files (indexes, tables and lists). - # Find all files having root filename with a two-letter extension, - # saves the ones that are really Texinfo-related files. .?o? catches - # many files: .toc, .log, LaTeX tables and lists, FiXme's .lox, maybe more. - for this_file in "$1".?o? "$1".aux "$1".?? "$1".idx; do - # If file is empty, skip it. - test -s "$this_file" || continue - # If the file is not suitable to be an index or xref file, don't - # process it. It's suitable if the first character is a - # backslash or right quote or at, as long as the first line isn't - # \input texinfo. - first_character=`sed -n '1s/^\(.\).*$/\1/p;q' $this_file` - if (test "x$first_character" = "x\\" \ - && sed 1q $this_file | grep -v '^\\input *texinfo' >/dev/null) \ - || test "x$first_character" = "x'" \ - || test "x$first_character" = "x@"; then - xref_files="$xref_files ./$this_file" - fi - done - echo "$xref_files" -} - -# Convert relative paths to absolute paths, so we can run in another -# directory (e.g., in --clean mode, or during the macro-support detection.) -# -# Empty path components are meaningful to tex. We rewrite them -# as `EMPTY' so they don't get lost when we split on $path_sep. -# Hopefully no one will have an actual directory named EMPTY. -absolute_filenames () -{ - replace_empty="-e 's/^$path_sep/EMPTY$path_sep/g' \ - -e 's/$path_sep\$/${path_sep}EMPTY/g' \ - -e 's/$path_sep$path_sep/${path_sep}EMPTY:/g'" - _res=`echo "$1" | eval sed $replace_empty` - save_IFS=$IFS - IFS=$path_sep - set x $_res; shift - _res=. - for dir - do - case $dir in - EMPTY) - _res=$_res$path_sep - ;; - [\\/]* | ?:[\\/]*) # Absolute paths don't need to be expanded. - _res=$_res$path_sep$dir - ;; - *) - abs=`cd "$dir" && pwd` && _res=$_res$path_sep$abs - ;; - esac - done - echo "$_res" -} - - -# run_tex () -# ---------- -# Run TeX as "$tex $tex_args $filename_input", taking care of errors -# and logs. -run_tex () -{ - # Note that this will be used via an eval: quote properly. - cmd=$tex - - # If possible, make TeX report error locations in GNU format. - tex_args= - case $tex_help in - *file-line-error*) cmd="$cmd --file-line-error";; - esac - - # Tell TeX to be batch if requested. - if $batch; then - # \batchmode does not show terminal output at all, so we don't - # want that. And even in batch mode, TeX insists on having input - # from the user. Close its stdin to make it impossible. - cmd="$cmd </dev/null '${escape}nonstopmode' '${escape}input'" - fi - - cmd="$cmd '$filename_input'" - - verbose "Running $cmd ..." - if eval "$cmd" >&5; then :; else - test "$clean" = t \ - && cp "$filename_noext.log" "$orig_pwd" - fatal 1 "$tex exited with bad status, quitting." \ - "see $filename_noext.log for errors." - fi -} - # File descriptor usage: # 0 standard input # 1 standard output (--verbose messages) @@ -452,15 +1547,24 @@ run_tex () # 5 tools output (turned off by --quiet) # 6 tracing/debugging (set -x output, etc.) -# Tools' output. If quiet, discard, else redirect to the message flow. -if test "$quiet" = t; then + +# Main tools' output (TeX, etc.) that TeX users are used to seeing. +# +# If quiet, discard, else redirect to the message flow. +if $quiet; then exec 5>/dev/null else exec 5>&1 fi -# Enable tracing -if test "$debug" = t; then + +# Enable tracing, and auxiliary tools output. +# +# Should be used where you'd typically use /dev/null to throw output +# away. But sometimes it is convenient to see that output (e.g., from +# a grep) to aid debugging. Especially debugging at distance, via the +# user. +if $debug; then exec 6>&1 set -x else @@ -468,10 +1572,38 @@ else fi # -# TeXify files. -for command_line_filename in ${1+"$@"}; do - verbose "Processing $command_line_filename ..." +# input_file_name_decode +# ---------------------- +# Decode COMMAND_LINE_FILENAME, and compute: +# - COMMAND_LINE_FILENAME clean of TeX commands +# - IN_DIR +# The directory to the input file, possibly absolute if needed. +# - IN_DIR_ABS +# The absolute directory of the input file. +# - IN_BASE +# The input file base name (no directory part). +# - IN_NOEXT +# The input file name without extensions (nor directory part). +# - IN_INPUT +# Defaults to COMMAND_LINE_FILENAME, but might change if the +# input is preprocessed (recode etc.). With directory, possibly absolute. +input_file_name_decode () +{ + # See if we are run from within AUC-Tex, in which case we are + # passed `\input{FOO.tex}' or even `\nonstopmode\input{FOO.tex}'. + case $command_line_filename in + *\\nonstopmode*) + batch=true;; + esac + case $command_line_filename in + *\\input{*}*) + # Let AUC-TeX error parser deal with line numbers. + line_error=false + command_line_filename=`\ + expr X"$command_line_filename" : X'.*input{\([^}]*\)}'` + ;; + esac # If the COMMAND_LINE_FILENAME is not absolute (e.g., --debug.tex), # prepend `./' in order to avoid that the tools take it as an option. @@ -482,354 +1614,102 @@ for command_line_filename in ${1+"$@"}; do # though the user may be able to reenter a valid filename at the tex # prompt (assuming they're attending the terminal), this script won't # be able to find the right xref files and so forth. - if test ! -r "$command_line_filename"; then - report "Could not read $command_line_filename, skipping." - continue + test -r "$command_line_filename" || + error 1 "cannot read $command_line_filename, skipping." + + # Get the name of the current directory. + in_dir=`func_dirname "$command_line_filename"` + in_dir_abs=`absolute "$in_dir"` + # In a clean build, we `cd', so get an absolute file name. + if $tidy; then + in_dir=$in_dir_abs fi - # Get the name of the current directory. We want the full path - # because in clean mode we are in tmp, in which case a relative - # path has no meaning. - filename_dir=`echo $command_line_filename | sed 's!/[^/]*$!!;s!^$!.!'` - filename_dir=`cd "$filename_dir" >/dev/null && pwd` - # Strip directory part but leave extension. - filename_ext=`basename "$command_line_filename"` + in_base=`basename "$command_line_filename"` # Strip extension. - filename_noext=`echo "$filename_ext" | sed 's/\.[^.]*$//'` - ext=`echo "$filename_ext" | sed 's/^.*\.//'` - - # _src. Use same basename since we want to generate aux files with - # the same basename as the manual. If --expand, then output the - # macro-expanded file to here, else copy the original file. - tmpdir_src=$tmpdir/src - filename_src=$tmpdir_src/$filename_noext.$ext - - # _xtr. The file with the user's extra commands. - tmpdir_xtr=$tmpdir/xtr - filename_xtr=$tmpdir_xtr/$filename_noext.$ext - - # _rcd. The Texinfo file recoded in 7bit. - tmpdir_rcd=$tmpdir/rcd - filename_rcd=$tmpdir_rcd/$filename_noext.$ext - - # _bak. Copies of the previous xref files (another round is run if - # they differ from the new one). - tmpdir_bak=$tmpdir/bak - - # Make all those directories and give up if we can't succeed. - mkdir $tmpdir_src $tmpdir_xtr $tmpdir_rcd $tmpdir_bak || exit 1 + in_noext=`echo "$in_base" | sed 's/\.[^.]*$//'` - # Source file might include additional sources. - # We want `.:$orig_pwd' before anything else. (We'll add `.:' later - # after all other directories have been turned into absolute paths.) - # `.' goes first to ensure that any old .aux, .cps, - # etc. files in ${directory} don't get used in preference to fresher - # files in `.'. Include orig_pwd in case we are in clean mode, where - # we've cd'd to a temp directory. - common="$orig_pwd$path_sep$filename_dir$path_sep$txincludes" - for var in $tex_envvars; do - eval ${var}="\$common\$${var}_orig" - export $var - done + # The normalized file name to compile. Must always point to the + # file to actually compile (in case of recoding, macro-expansion etc.). + in_input=$in_dir/$in_base - # Convert relative paths to absolute paths, so we can run in another - # directory (e.g., in --clean mode, or during the macro-support detection.) - TEXINPUTS=`absolute_filenames "$TEXINPUTS"` - verbose "TEXINPUTS: $TEXINPUTS" - BIBINPUTS=`absolute_filenames "$BIBINPUTS"` - verbose "BIBINPUTS: $BIBINPUTS" - BSTINPUTS=`absolute_filenames "$BSTINPUTS"` - verbose "BSTINPUTS: $BSTINPUTS" - INDEXSTYLE=`absolute_filenames "$INDEXSTYLE"` - verbose "INDEXSTYLE: $INDEXSTYLE" - # If the user explicitly specified the language, use that. - # Otherwise, if the first line is \input texinfo, assume it's texinfo. - # Otherwise, guess from the file extension. - if test -n "$set_language"; then - language=$set_language - elif sed 1q "$command_line_filename" | grep 'input texinfo' >&6; then - language=texinfo + # Compute the output file name. + if test x"$oname" != x; then + out_name=$oname else - language= - fi - - # Get the type of the file (latex or texinfo) from the given language - # we just guessed, or from the file extension if not set yet. - case ${language:-$filename_ext} in - [lL]a[tT]e[xX] | *.ltx | *.tex) - # Assume a LaTeX file. LaTeX needs bibtex and uses latex for - # compilation. No makeinfo. - language=latex - bibtex=${BIBTEX:-bibtex} - makeinfo= # no point in running makeinfo on latex source. - texindex=${MAKEINDEX:-makeindex} - textra_cmd=1i - if test $oformat = dvi; then - tex=${LATEX:-latex} - else - tex=${PDFLATEX:-pdflatex} - fi - thumbpdf=${THUMBPDF:-thumbpdf} - ;; - - *) - # Assume a Texinfo file. Texinfo files need makeinfo, texindex and tex. - language=texinfo - bibtex= - texindex=${TEXINDEX:-texindex} - textra_cmd='/^@setfilename/a' - if test $oformat = dvi; then - # MetaPost also uses the TEX environment variable. If the user - # has set TEX=latex for that reason, don't bomb out. - if echo $TEX | grep 'latex$' >/dev/null; then - tex=tex # don't bother trying to find etex - else - tex=$TEX - fi - else - tex=$PDFTEX - fi - # Unless required by the user, makeinfo expansion is wanted only - # if texinfo.tex is too old. - if test "$expand" = t; then - makeinfo=${MAKEINFO:-makeinfo} - else - # Check if texinfo.tex performs macro expansion by looking for - # its version. The version is a date of the form YEAR-MO-DA. - # We don't need to use [0-9] to match the digits since anyway - # the comparison with $txiprereq, a number, will fail with non - # digits. - # Run in the tmpdir to avoid leaving files. - ( - cd $tmpdir - echo '\input texinfo.tex @bye' >txiversion.tex - # Be sure that if tex wants to fail, it is not interactive: - # close stdin. - $tex txiversion.tex </dev/null - ) >$tmpdir/txiversion.out 2>$tmpdir/txiversion.err - if test $? != 0; then - cat $tmpdir/txiversion.out - cat $tmpdir/txiversion.err >&2 - fatal 1 "texinfo.tex appears to be broken, quitting." - fi - eval `sed -n 's/^.*\[\(.*\)version \(....\)-\(..\)-\(..\).*$/txiformat=\1 txiversion="\2\3\4"/p' $tmpdir/txiversion.out` - verbose "texinfo.tex preloaded as \`$txiformat', version is \`$txiversion' ..." - if test "$txiprereq" -le "$txiversion" >/dev/null 2>&1; then - makeinfo= - else - makeinfo=${MAKEINFO:-makeinfo} - fi - # As long as we had to run TeX, offer the user this convenience: - test "$txiformat" = Texinfo && escape=@ - fi - thumbpdf=${THUMBPDF:-thumbpdf} - ;; - esac - - # Go to $tmpdir to try --help, since old versions that don't accept - # --help will generate a texput.log. - tex_help=`cd $tmpdir >/dev/null && $tex --help </dev/null 2>&1` - - # Expand macro commands in the original source file using Makeinfo. - # Always use `end' footnote style, since the `separate' style - # generates different output (arguably this is a bug in -E). - # Discard main info output, the user asked to run TeX, not makeinfo. - if test -n "$makeinfo"; then - verbose "Macro-expanding $command_line_filename to $filename_src ..." - sed -f $comment_iftex_sed "$command_line_filename" \ - | $makeinfo --footnote-style=end -I "$filename_dir" $miincludes \ - -o /dev/null --macro-expand=- \ - | sed -f $uncomment_iftex_sed >"$filename_src" - filename_input=$filename_src + out_name=$in_noext.`out_lang_ext` fi + out_dir=`func_dirname "$out_name"` + out_dir_abs=`absolute "$out_dir"` + out_base=`basename "$out_name"` + out_noext=`echo "$out_base" | sed 's/\.[^.]*$//'` +} - # If makeinfo failed (or was not even run), use the original file as input. - if test $? -ne 0 \ - || test ! -r "$filename_src"; then - verbose "Reverting to $command_line_filename ..." - filename_input=$filename_dir/$filename_ext - fi - # Used most commonly for @finalout, @smallbook, etc. - if test -n "$textra"; then - verbose "Inserting extra commands: $textra" - sed "$textra_cmd\\ -$textra" "$filename_input" >"$filename_xtr" - filename_input=$filename_xtr - fi +## -------------- ## +## TeXify files. ## +## -------------- ## - # If this is a Texinfo file with a specified input encoding, and - # recode is available, then recode to plain 7 bit Texinfo. - if test $language = texinfo; then - pgm='s/^ *@documentencoding *\([^ ][^ ]*\) *$/\1/ - t found - d - :found - q' - encoding=`sed -e "$pgm" "$filename_input"` - if $recode && test -n "$encoding" && findprog recode; then - verbose "Recoding from $encoding to Texinfo." - if recode "$encoding"..texinfo <"$filename_input" >"$filename_rcd" \ - && test -s "$filename_rcd"; then - filename_input=$filename_rcd - else - verbose "Recoding failed, using original input." - fi - fi - fi +for command_line_filename +do + verbose "Processing $command_line_filename ..." - # If clean mode was specified, then move to the temporary directory. - if test "$clean" = t; then - verbose "cd $tmpdir_src" - cd "$tmpdir_src" || exit 1 + input_file_name_decode + + # `texinfo' or `latex'? + in_lang=`compute_language "$command_line_filename"` + + # An auxiliary directory used for all the auxiliary tasks involved + # in compiling this document. + case $build_dir in + '' | . ) t2ddir=$out_noext.t2d ;; + *) # Avoid collisions between multiple occurrences of the same + # file. The sed expression is fragile if the cwd has + # active characters. + t2ddir=$build_dir/`echo "$out_dir_abs/$out_noext.t2d" | + sed "s,^$orig_pwd/,," | + sed 's,/,!,g'` + esac + # Remove it at exit if clean mode. + trap "cleanup" 0 1 2 15 + + ensure_dir "$build_dir" "$t2ddir" + + # We will change directory, better work with an absolute path... + t2ddir=`absolute "$t2ddir"` + # Sometimes there are incompatibilities between auxiliary files for + # DVI and PDF. The contents can also change whether we work on PDF + # and/or DVI. So keep separate spaces for each. + workdir=$t2ddir/`out_lang_tex` + ensure_dir "$workdir" + + # _build. In a tidy build, where the auxiliary files are output. + if $tidy; then + work_build=$workdir/build + else + work_build=. fi - while :; do # will break out of loop below - orig_xref_files=`get_xref_files "$filename_noext"` - - # Save copies of originals for later comparison. - if test -n "$orig_xref_files"; then - verbose "Backing up xref files: `echo $orig_xref_files | sed 's|\./||g'`" - cp $orig_xref_files $tmpdir_bak - fi - - # Run bibtex on current file. - # - If its input (AUX) exists. - # - If AUX contains both `\bibdata' and `\bibstyle'. - # - If some citations are missing (LOG contains `Citation'). - # or the LOG complains of a missing .bbl - # - # We run bibtex first, because I can see reasons for the indexes - # to change after bibtex is run, but I see no reason for the - # converse. - # - # Don't try to be too smart. Running bibtex only if the bbl file - # exists and is older than the LaTeX file is wrong, since the - # document might include files that have changed. Because there - # can be several AUX (if there are \include's), but a single LOG, - # looking for missing citations in LOG is easier, though we take - # the risk to match false messages. - if test -n "$bibtex" \ - && test -r "$filename_noext.aux" \ - && test -r "$filename_noext.log" \ - && (grep '^\\bibdata[{]' "$filename_noext.aux" \ - && grep '^\\bibstyle[{]' "$filename_noext.aux" \ - && (grep 'Warning:.*Citation.*undefined' "$filename_noext.log" \ - || grep 'No file .*\.bbl\.' "$filename_noext.log")) \ - >&6 2>&1; \ - then - verbose "Running $bibtex $filename_noext ..." - $bibtex "$filename_noext" >&5 || - fatal 1 "$bibtex exited with bad status, quitting." - fi - - # What we'll run texindex on -- exclude non-index files. - # Since we know index files are last, it is correct to remove everything - # before .aux and .?o?. But don't really do <anything>o<anything> - # -- don't match whitespace as <anything>. - # Otherwise, if orig_xref_files contains something like - # foo.xo foo.whatever - # the space after the o will get matched. - index_files=`echo "$orig_xref_files" \ - | sed "s!.*\.aux!!g; - s!./$filename_noext\.[^ ]o[^ ]!!g; - s/^[ ]*//;s/[ ]*$//"` - # Run texindex (or makeindex) on current index files. If they - # already exist, and after running TeX a first time the index - # files don't change, then there's no reason to run TeX again. - # But we won't know that if the index files are out of date or - # nonexistent. - if test -n "$texindex" && test -n "$index_files"; then - verbose "Running $texindex $index_files ..." - $texindex $index_files 2>&5 1>&2 || - fatal 1 "$texindex exited with bad status, quitting." - fi - - # Finally, run TeX. - run_tex - - # Decide if looping again is needed. - finished=t - - # LaTeX (and the package changebar) report in the LOG file if it - # should be rerun. This is needed for files included from - # subdirs, since texi2dvi does not try to compare xref files in - # subdirs. Performing xref files test is still good since LaTeX - # does not report changes in xref files. - if grep "Rerun to get" "$filename_noext.log" >&6 2>&1; then - finished= - fi - - # Check if xref files changed. - new_xref_files=`get_xref_files "$filename_noext"` - verbose "Original xref files = `echo $orig_xref_files | sed 's|\./||g'`" - verbose "New xref files = `echo $new_xref_files | sed 's|\./||g'`" - - # If old and new lists don't at least have the same file list, - # then one file or another has definitely changed. - test "x$orig_xref_files" != "x$new_xref_files" && finished= - - # File list is the same. We must compare each file until we find - # a difference. - if test -n "$finished"; then - for this_file in $new_xref_files; do - verbose "Comparing xref file `echo $this_file | sed 's|\./||g'` ..." - # cmp -s returns nonzero exit status if files differ. - if cmp -s "$this_file" "$tmpdir_bak/$this_file"; then :; else - # We only need to keep comparing until we find one that - # differs, because we'll have to run texindex & tex again no - # matter how many more there might be. - finished= - verbose "xref file `echo $this_file | sed 's|\./||g'` differed ..." - test "$debug" = t && diff -c "$tmpdir_bak/$this_file" "$this_file" - break - fi - done - fi - - # If finished, exit the loop, else rerun the loop. - test -n "$finished" && break - done # while :; - - # If we were using thumbpdf and producing PDF, then run thumbpdf - # and TeX one last time. - if test $oformat = pdf \ - && test -r "$filename_noext.log" \ - && grep 'thumbpdf\.sty' "$filename_noext.log" >&6 2>&1; \ - then - verbose "Running $thumbpdf $filename_noext ..." - $thumbpdf "$filename_noext" >&5 || - fatal 1 "$thumbpdf exited with bad status, quitting." - run_tex - fi + # _bak. Copies of the previous auxiliary files (another round is + # run if they differ from the new ones). + work_bak=$workdir/bak + # Make those directories. + ensure_dir "$work_build" "$work_bak" - # If we were in clean mode, compilation was in a tmp directory. - # Copy the DVI (or PDF) file into the directory where the compilation - # has been done. (The temp dir is about to get removed anyway.) - # We also return to the original directory so that - # - the next file is processed in correct conditions - # - the temporary file can be removed - if test -n "$clean"; then - if test -n "$oname"; then - dest=$oname - else - dest=$orig_pwd - fi - verbose "Copying $oformat file from `pwd` to $dest" - cp -p "./$filename_noext.$oformat" "$dest" - cd / # in case $orig_pwd is on a different drive (for DOS) - cd $orig_pwd || exit 1 - fi + case $action in + compile) + # Compile the document. + compile + cleanup + ;; - # Remove temporary files. - if test "x$debug" = "x"; then - verbose "Removing $tmpdir_src $tmpdir_xtr $tmpdir_bak ..." - cd / - rm -rf $tmpdir_src $tmpdir_xtr $tmpdir_bak - fi + mostly-clean) + mostly_clean + ;; + esac done verbose "done." |