Commit | Line | Data |
---|---|---|
d60d9f65 SS |
1 | #! /bin/sh |
2 | # texi2dvi --- smartly produce DVI files from texinfo sources | |
d60d9f65 | 3 | # $Id$ |
c862e87b JM |
4 | # |
5 | # Copyright (C) 1992, 93, 94, 95, 96, 97, 98 Free Software Foundation, Inc. | |
6 | # | |
d60d9f65 SS |
7 | # This program is free software; you can redistribute it and/or modify |
8 | # it under the terms of the GNU General Public License as published by | |
9 | # the Free Software Foundation; either version 2, or (at your option) | |
10 | # any later version. | |
11 | # | |
12 | # This program is distributed in the hope that it will be useful, | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | # GNU General Public License for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU General Public License | |
18 | # along with this program; if not, you can either send email to this | |
19 | # program's maintainer or write to: The Free Software Foundation, | |
20 | # Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA. | |
c862e87b | 21 | # |
d60d9f65 | 22 | # Commentary: |
c862e87b JM |
23 | # |
24 | # Author: Noah Friedman <friedman@gnu.org> | |
25 | # | |
26 | # Please send bug reports, etc. to bug-texinfo@gnu.org. | |
d60d9f65 SS |
27 | # If possible, please send a copy of the output of the script called with |
28 | # the `--debug' option when making a bug report. | |
c862e87b | 29 | # |
d60d9f65 SS |
30 | # In the interest of general portability, some common bourne shell |
31 | # constructs were avoided because they weren't guaranteed to be available | |
32 | # in some earlier implementations. I've tried to make this program as | |
33 | # portable as possible. Welcome to unix, where the lowest common | |
34 | # denominator is rapidly diminishing. | |
35 | # | |
c862e87b | 36 | # Among the more interesting lossages I noticed among Bourne shells: |
d60d9f65 SS |
37 | # * No shell functions. |
38 | # * No `unset' builtin. | |
39 | # * `shift' cannot take a numeric argument, and signals an error if | |
40 | # there are no arguments to shift. | |
c862e87b | 41 | # |
d60d9f65 SS |
42 | # Code: |
43 | ||
44 | # Name by which this script was invoked. | |
45 | progname=`echo "$0" | sed -e 's/[^\/]*\///g'` | |
46 | ||
47 | # This string is expanded by rcs automatically when this file is checked out. | |
48 | rcs_revision='$Revision$' | |
49 | version=`set - $rcs_revision; echo $2` | |
50 | ||
51 | # To prevent hairy quoting and escaping later. | |
52 | bq='`' | |
53 | eq="'" | |
54 | ||
c862e87b JM |
55 | usage="Usage: $0 [OPTION]... FILE... |
56 | Run a Texinfo document through TeX. | |
d60d9f65 | 57 | |
c862e87b JM |
58 | Options: |
59 | -b, --batch No interaction (\nonstopmode in TeX). | |
60 | -c, --clean Remove all auxiliary files. | |
d60d9f65 | 61 | -D, --debug Turn on shell debugging ($bq${bq}set -x$eq$eq). |
c862e87b JM |
62 | -t, --texinfo CMD Insert CMD after @setfilename before running TeX. |
63 | --verbose Report on what is done. | |
64 | -h, --help Display this help and exit. | |
65 | -v, --version Display version information and exit. | |
d60d9f65 | 66 | |
c862e87b JM |
67 | The values of the TEX, TEXINDEX, and MAKEINFO environment variables are |
68 | used to run those commands, if they are set. | |
69 | ||
70 | Email bug reports to bug-texinfo@gnu.org." | |
d60d9f65 SS |
71 | |
72 | # Initialize variables. | |
73 | # Don't use `unset' since old bourne shells don't have this command. | |
74 | # Instead, assign them an empty value. | |
c862e87b JM |
75 | # Some of these, like TEX and TEXINDEX, may be inherited from the environment. |
76 | backup_extension=.bak # these files get deleted if all goes well. | |
77 | batch= | |
78 | clean= | |
d60d9f65 SS |
79 | debug= |
80 | orig_pwd="`pwd`" | |
c862e87b JM |
81 | textra= |
82 | verbose=false | |
83 | makeinfo="${MAKEINFO-makeinfo}" | |
d60d9f65 SS |
84 | texindex="${TEXINDEX-texindex}" |
85 | tex="${TEX-tex}" | |
86 | ||
c862e87b | 87 | # Save this so we can construct a new TEXINPUTS path for each file. |
d60d9f65 SS |
88 | TEXINPUTS_orig="$TEXINPUTS" |
89 | export TEXINPUTS | |
90 | ||
91 | # Parse command line arguments. | |
92 | # Make sure that all wildcarded options are long enough to be unambiguous. | |
93 | # It's a good idea to document the full long option name in each case. | |
94 | # Long options which take arguments will need a `*' appended to the | |
95 | # canonical name to match the value appended after the `=' character. | |
c862e87b JM |
96 | while :; do |
97 | test $# -eq 0 && break | |
98 | ||
d60d9f65 | 99 | case "$1" in |
c862e87b JM |
100 | -b | --batch | --b* ) batch=t; shift ;; |
101 | -c | --clean | --c* ) clean=t; shift ;; | |
102 | -D | --debug | --d* ) debug=t; shift ;; | |
103 | -h | --help | --h* ) echo "$usage"; exit 0 ;; | |
104 | # OK, we should do real option parsing here, but be lazy for now. | |
105 | -t | --texinfo | --t*) shift; textra="$textra $1"; shift ;; | |
106 | -v | --vers* ) | |
107 | echo "$progname (GNU Texinfo 3.12) $version" | |
108 | echo "Copyright (C) 1998 Free Software Foundation, Inc. | |
109 | There is NO warranty. You may redistribute this software | |
110 | under the terms of the GNU General Public License. | |
111 | For more information about these matters, see the files named COPYING." | |
112 | exit 0 ;; | |
113 | --verb* ) verbose=echo; shift ;; | |
d60d9f65 SS |
114 | -- ) # Stop option processing |
115 | shift | |
c862e87b | 116 | break ;; |
d60d9f65 SS |
117 | -* ) |
118 | case "$1" in | |
119 | --*=* ) arg=`echo "$1" | sed -e 's/=.*//'` ;; | |
120 | * ) arg="$1" ;; | |
121 | esac | |
122 | exec 1>&2 | |
c862e87b JM |
123 | echo "$progname: Unknown or ambiguous option $bq$arg$eq." |
124 | echo "$progname: Try $bq--help$eq for more information." | |
125 | exit 1 ;; | |
126 | * ) break ;; | |
d60d9f65 SS |
127 | esac |
128 | done | |
129 | ||
130 | # See if there are any command line args left (which will be interpreted as | |
c862e87b JM |
131 | # filename arguments). |
132 | if test $# -eq 0; then | |
133 | exec 1>&2 | |
134 | echo "$progname: At least one file name is required as an argument." | |
135 | echo "$progname: Try $bq--help$eq for more information." | |
136 | exit 2 | |
137 | fi | |
138 | ||
139 | test "$debug" = t && set -x | |
d60d9f65 SS |
140 | |
141 | # Texify files | |
c862e87b JM |
142 | for command_line_filename in ${1+"$@"}; do |
143 | $verbose "Processing $command_line_filename ..." | |
144 | ||
145 | # See if file exists. If it doesn't we're in trouble since, even | |
146 | # though the user may be able to reenter a valid filename at the tex | |
147 | # prompt (assuming they're attending the terminal), this script won't | |
148 | # be able to find the right index files and so forth. | |
149 | if test ! -r "${command_line_filename}"; then | |
150 | echo "$0: Could not read ${command_line_filename}." >&2 | |
151 | continue | |
152 | fi | |
153 | ||
154 | # Roughly equivalent to `dirname ...`, but more portable | |
155 | directory="`echo ${command_line_filename} | sed 's/\/[^\/]*$//'`" | |
156 | filename_texi="`basename ${command_line_filename}`" | |
157 | # Strip off the last extension part (probably .texinfo or .texi) | |
158 | filename_noext="`echo ${filename_texi} | sed 's/\.[^.]*$//'`" | |
159 | ||
160 | # Use same basename since we want to generate aux files with the same | |
161 | # basename as the manual. Use extension .texi for the temp file so | |
162 | # that TeX will ignore it. Thus, we must use a subdirectory. | |
163 | # | |
164 | # Output the macro-expanded file to here. The vastly abbreviated | |
165 | # temporary directory name is so we don't have collisions on 8.3 or | |
166 | # 14-character filesystems. | |
167 | tmp_dir=${TMPDIR-/tmp}/txi2d.$$ | |
168 | filename_tmp=$tmp_dir/$filename_noext.texi | |
169 | # Output the file with the user's extra commands to here. | |
170 | tmp_dir2=${tmp_dir}.2 | |
171 | filename_tmp2=$tmp_dir2/$filename_noext.texi | |
172 | mkdir $tmp_dir $tmp_dir2 | |
173 | # Always remove the temporary directories. | |
174 | trap "rm -rf $tmp_dir $tmp_dir2" 1 2 15 | |
175 | ||
176 | # If directory and file are the same, then it's probably because there's | |
177 | # no pathname component. Set dirname to `.', the current directory. | |
178 | if test "z${directory}" = "z${command_line_filename}"; then | |
179 | directory=. | |
180 | fi | |
181 | ||
182 | # Source file might @include additional texinfo sources. Put `.' and | |
183 | # directory where source file(s) reside in TEXINPUTS before anything | |
184 | # else. `.' goes first to ensure that any old .aux, .cps, etc. files in | |
185 | # ${directory} don't get used in preference to fresher files in `.'. | |
186 | TEXINPUTS=".:${directory}:${TEXINPUTS_orig}" | |
187 | ||
188 | # Expand macro commands in the original source file using Makeinfo; | |
189 | # the macro syntax bfox implemented is impossible to implement in TeX. | |
190 | # Always use `end' footnote style, since the `separate' style | |
191 | # generates different output (arguably this is a bug in -E). | |
192 | # Discard main info output, the user asked to run TeX, not makeinfo. | |
193 | # Redirect output to /dev/null to throw away `Making info file...' msg. | |
194 | $verbose "Macro-expanding $command_line_filename to $filename_tmp ..." | |
195 | $makeinfo --footnote-style=end -E $filename_tmp -o /dev/null \ | |
196 | $command_line_filename >/dev/null | |
197 | ||
198 | # But if there were no macros, or makeinfo failed for some reason, | |
199 | # just use the original file. (It shouldn't make any difference, but | |
200 | # let's be safe.) | |
201 | if test $? -ne 0 || cmp -s $filename_tmp $command_line_filename; then | |
202 | $verbose "Reverting to $command_line_filename ..." | |
203 | cp -p $command_line_filename $filename_tmp | |
204 | fi | |
205 | filename_input=$filename_tmp | |
206 | dirname_input=$tmp_dir | |
207 | ||
208 | # Used most commonly for @finalout, @smallbook, etc. | |
209 | if test -n "$textra"; then | |
210 | $verbose "Inserting extra commands: $textra." | |
211 | sed '/^@setfilename/a\ | |
212 | '"$textra" $filename_input >$filename_tmp2 | |
213 | filename_input=$filename_tmp2 | |
214 | dirname_input=$tmp_dir2 | |
215 | fi | |
216 | ||
217 | # If clean mode was specified, then move to the temporary directory. | |
218 | if test "$clean" = t; then | |
219 | $verbose "cd $dirname_input" | |
220 | cd $dirname_input || exit 1 | |
221 | filename_input=`basename $filename_input` | |
222 | fi | |
223 | ||
224 | while true; do # will break out of loop below | |
225 | # "Unset" variables that might have values from previous iterations and | |
226 | # which won't be completely reset later. | |
227 | definite_index_files= | |
228 | ||
229 | # Find all files having root filename with a two-letter extension, | |
230 | # determine whether they're really index files, and save them. Foo.aux | |
231 | # is actually the cross-references file, but we need to keep track of | |
232 | # that too. | |
233 | possible_index_files="`eval echo ${filename_noext}.?? ${filename_noext}.aux`" | |
234 | for this_file in ${possible_index_files}; do | |
d60d9f65 | 235 | # If file is empty, forget it. |
c862e87b | 236 | test -s "${this_file}" || continue |
d60d9f65 | 237 | |
c862e87b JM |
238 | # Examine first character of file. If it's not suitable to be an |
239 | # index or xref file, don't process it. | |
d60d9f65 | 240 | first_character="`sed -n '1s/^\(.\).*$/\1/p;q' ${this_file}`" |
c862e87b JM |
241 | if test "x${first_character}" = "x\\" \ |
242 | || test "x${first_character}" = "x'"; then | |
243 | definite_index_files="${definite_index_files} ${this_file}" | |
d60d9f65 | 244 | fi |
c862e87b JM |
245 | done |
246 | orig_index_files="${definite_index_files}" | |
247 | orig_index_files_sans_aux="`echo ${definite_index_files} \ | |
248 | | sed 's/'${filename_noext}'\.aux//; | |
249 | s/^[ ]*//;s/[ ]*$//;'`" | |
250 | ||
251 | # Now save copies of original index files so we have some means of | |
252 | # comparison later. | |
253 | $verbose "Backing up current index files: $orig_index_files ..." | |
254 | for index_file_to_save in ${orig_index_files}; do | |
255 | cp "${index_file_to_save}" "${index_file_to_save}${backup_extension}" | |
256 | done | |
257 | ||
258 | # Run texindex on current index files. If they already exist, and | |
259 | # after running TeX a first time the index files don't change, then | |
260 | # there's no reason to run TeX again. But we won't know that if the | |
261 | # index files are out of date or nonexistent. | |
262 | if test -n "${orig_index_files_sans_aux}"; then | |
263 | $verbose "Running $texindex $orig_index_files_sans_aux ..." | |
d60d9f65 | 264 | ${texindex} ${orig_index_files_sans_aux} |
c862e87b JM |
265 | fi |
266 | ||
267 | # Finally, run TeX. | |
268 | if test "$batch" = t; then | |
269 | tex_mode='\nonstopmode' | |
270 | else | |
271 | tex_mode= | |
272 | fi | |
273 | $verbose "Running $tex $filename_input ..." | |
274 | cmd="$tex $tex_mode \\input $filename_input" | |
275 | $cmd | |
276 | ||
277 | # Check if index files changed. | |
278 | # | |
279 | definite_index_files= | |
280 | # Get list of new index files. | |
281 | possible_index_files="`eval echo ${filename_noext}.?? ${filename_noext}.aux`" | |
282 | for this_file in ${possible_index_files}; do | |
283 | # If file is empty, forget it. | |
284 | test -s "${this_file}" || continue | |
285 | ||
286 | # Examine first character of file. If it's not a backslash or | |
287 | # single quote, then it's definitely not an index or xref file. | |
288 | # (Will have to check for @ when we switch to Texinfo syntax in | |
289 | # all these files...) | |
290 | first_character="`sed -n '1s/^\(.\).*$/\1/p;q' ${this_file}`" | |
291 | if test "x${first_character}" = "x\\" \ | |
292 | || test "x${first_character}" = "x'"; then | |
293 | definite_index_files="${definite_index_files} ${this_file}" | |
294 | fi | |
295 | done | |
296 | new_index_files="${definite_index_files}" | |
297 | new_index_files_sans_aux="`echo ${definite_index_files} \ | |
298 | | sed 's/'${filename_noext}'\.aux//; | |
299 | s/^[ ]*//;s/[ ]*$//;'`" | |
300 | ||
301 | # If old and new list don't at least have the same file list, then one | |
302 | # file or another has definitely changed. | |
303 | $verbose "Original index files =$orig_index_files" | |
304 | $verbose "New index files =$new_index_files" | |
305 | if test "z${orig_index_files}" != "z${new_index_files}"; then | |
306 | index_files_changed_p=t | |
307 | else | |
308 | # File list is the same. We must compare each file until we find a | |
309 | # difference. | |
310 | index_files_changed_p= | |
311 | for this_file in ${new_index_files}; do | |
312 | $verbose "Comparing index file $this_file ..." | |
313 | # cmp -s will return nonzero exit status if files differ. | |
314 | cmp -s "${this_file}" "${this_file}${backup_extension}" | |
315 | if test $? -ne 0; then | |
316 | # We only need to keep comparing until we find *one* that | |
317 | # differs, because we'll have to run texindex & tex no | |
318 | # matter what. | |
319 | index_files_changed_p=t | |
320 | $verbose "Index file $this_file differed:" | |
321 | test $verbose = echo \ | |
322 | && diff -c "${this_file}${backup_extension}" "${this_file}" | |
323 | break | |
324 | fi | |
d60d9f65 | 325 | done |
c862e87b | 326 | fi |
d60d9f65 | 327 | |
c862e87b JM |
328 | # If index files have changed since TeX has been run, or if the aux |
329 | # file wasn't present originally, run texindex and TeX again. | |
330 | if test "${index_files_changed_p}"; then :; else | |
331 | # Nothing changed. We're done with TeX. | |
332 | break | |
333 | fi | |
334 | done | |
335 | ||
336 | # If we were in clean mode, compilation was in a tmp directory. | |
337 | # Copy the DVI file into the directory where the compilation | |
338 | # has been done. (The temp dir is about to get removed anyway.) | |
339 | # We also return to the original directory so that | |
340 | # - the next file is processed in correct conditions | |
341 | # - the temporary file can be removed | |
342 | if test -n "$clean"; then | |
343 | $verbose "Copying DVI file from `pwd` to $orig_pwd" | |
344 | cp -p $filename_noext.dvi $orig_pwd | |
345 | cd $orig_pwd || exit 1 | |
346 | fi | |
347 | ||
348 | # Generate list of files to delete, then call rm once with the entire | |
349 | # list. This is significantly faster than multiple executions of rm. | |
350 | file_list= | |
351 | for file in ${orig_index_files}; do | |
352 | file_list="${file_list} ${file}${backup_extension}" | |
353 | done | |
354 | if test -n "${file_list}"; then | |
355 | $verbose "Removing $file_list $tmp_dir $tmp_dir2 ..." | |
356 | rm -f ${file_list} | |
357 | rm -rf $tmp_dir $tmp_dir2 | |
358 | fi | |
d60d9f65 SS |
359 | done |
360 | ||
c862e87b JM |
361 | $verbose "$0 done." |
362 | true # exit successfully. |