bf5c767d0858f6dbf1034293065435cdecb4e71f
[ghc-hetmet.git] / glafp-utils / ltx / ltx.prl
1 $Pgm = $0; $Pgm =~ s/.*\/([^\/]+)$/\1/;
2 #
3 # set up signal handler
4 sub quit_upon_signal { &rm_temp_files_and_exit(); }
5 $SIG{'INT'}  = 'quit_upon_signal';
6 $SIG{'QUIT'} = 'quit_upon_signal';
7 #
8 $Verbose = 0;
9 if ($ARGV[0] eq '-v') {
10     $Verbose = 1;
11     shift(@ARGV);
12 }
13 #
14 die "$Pgm: must have exactly one argument\n" if $#ARGV != 0;
15 # figure out input file and its filename root
16 if (-f $ARGV[0]) {
17     $TeX_input = $ARGV[0];
18     if ($TeX_input =~ /(.+)\.[^\.\/\n]+$/) {
19         $TeX_root  = $1;
20     } else {
21         $TeX_root  = $TeX_input;
22     }
23 } elsif (-f $ARGV[0].'.tex') {
24     $TeX_input = $ARGV[0].'.tex';
25     $TeX_root  = $ARGV[0];
26 } else {
27     die "$Pgm: input file $ARGV[0] doesn't exist\n";
28 }
29
30 if ( $ENV{'TMPDIR'} ) { # where to make tmp file names
31     $Tmp_prefix = $ENV{'TMPDIR'} ;
32 } else {
33     $Tmp_prefix ='$(TMPDIR)';
34     $ENV{'TMPDIR'} = '$(TMPDIR)'; # set the env var as well
35 }
36
37 sub rm_temp_files {
38     system("rm -f $Tmp_prefix/ltx-*.$$");
39 }
40 sub rm_temp_files_and_exit {
41     system("rm -f $Tmp_prefix/ltx-*.$$");
42     exit(1);
43 }
44 $SIG{'INT'}  = 'rm_temp_files_and_exit';
45 $SIG{'QUIT'} = 'rm_temp_files_and_exit';
46
47 sub die_gracefully {
48     local($msg) = @_;
49     
50     print STDERR $msg;
51     &rm_temp_files_and_exit();
52 }
53
54 # must read through root file to see if a \bibliography
55 # is there...
56 $Bibliography_requested = 0;
57 open(TEXIF, "<$TeX_input") 
58     || &die_gracefully("$Pgm: Can't read $TeX_input\n");
59 while (<TEXIF>) {
60     $Bibliography_requested = 1 if /^\\bibliography/;
61 }
62 close(TEXIF);
63 &die_gracefully("$Pgm: reading $TeX_input had errors\n") if $? >> 8;
64
65 # run latex first time (?)
66 &run_latex(); # sets $Says_labels_changed
67 $Times_run = 1;
68
69 while (&something_more_needed()) {
70
71     print STDERR "labels_changed=$Says_label_changed;bibtex_needed=$BibTeX_run_needed;makeindex_needed=$MakeIndex_run_needed\n" if $Verbose;
72
73     if ($BibTeX_run_needed) {
74         &run_bibtex();
75     }
76     if ($MakeIndex_run_needed) {
77         unlink "$TeX_root.ind";
78         (system("makeindex $TeX_root.idx") >> 8) 
79             && &die_gracefully("$Pgm: makeindex $TeX_root.idx had errors\n");
80     }
81
82     # save (copy) .aux file as .aux-prev file for future ref
83     # ditto for .idx file
84     unlink "$TeX_root.aux-prev";
85     (system("cp $TeX_root.aux $TeX_root.aux-prev") >> 8)
86         && &die_gracefully("$Pgm: cp $TeX_root.aux $TeX_root.aux-prev failed\n");
87     if (-f "$TeX_root.idx") {
88         unlink "$TeX_root.idx-prev";
89         (system("cp $TeX_root.idx $TeX_root.idx-prev") >> 8)
90             && &die_gracefully("$Pgm: cp $TeX_root.idx $TeX_root.idx-prev failed\n");
91     }
92
93     # run latex again
94     &run_latex(); # sets $Says_labels_changed
95     $Times_run++;
96
97     if ($Times_run >= 4) {
98         print STDERR "*** I don't run LaTeX more than four times;\n";
99         print STDERR "*** Something is probably wrong...\n";
100         &rm_temp_files_and_exit();
101     }
102 }
103 &rm_temp_files();
104 exit(0);
105
106 sub run_latex {
107     $Says_labels_changed = 0;
108     $Multiply_defined_labels = 0;
109
110     select(STDERR); $| = 1; select(STDOUT); # no buffering on STDERR
111     print STDERR "$Pgm: *** running LaTeX...\n" if $Verbose;
112     unlink "$TeX_root.dvi";
113
114     open(LTXPIPE, "latex $TeX_input 2>&1 |") 
115         || &die_gracefully("$Pgm: Can't run latex pipe\n");
116     while (<LTXPIPE>) {
117         $Multiply_defined_labels = 1 if /^LaTeX Warning: Label .* multiply defined/;
118         $Says_labels_changed = 1 if /^LaTeX Warning: Label\(s\) may have changed/
119                                         && ! $Multiply_defined_labels;
120         print STDERR $_;
121     }
122     close(LTXPIPE);
123     &die_gracefully("$Pgm: LaTeX run had errors\n") if $? >> 8;
124
125     # sort .idx file, because this helps makeindex
126     # (can you say `bug'?)
127     if (-f "$TeX_root.idx") {
128         print STDERR "$Pgm: *** sorting $TeX_root.idx...\n" if $Verbose;
129         (system("sort $TeX_root.idx -o $TeX_root.idx") >> 8)
130         && &die_gracefully("$Pgm: sorting $TeX_root.idx failed\n");
131     }
132
133 }
134
135 sub run_bibtex { # ugly because bibtex doesn't return a correct error status
136     local($bibtex_had_errors) = 0;
137
138     print STDERR "$Pgm: *** running BibTeX...\n" if $Verbose;
139     unlink "$TeX_root.bbl";
140
141     $| = 1; # no buffering
142     open(BIBTXPIPE, "bibtex $TeX_root 2>&1 |") 
143         || &die_gracefully("$Pgm: Can't run bibtex pipe\n");
144     while (<BIBTXPIPE>) {
145         $bibtex_had_errors = 1 if /^\(There.*error message(s)?\)$/;
146         print STDERR $_;
147     }
148     close(BIBTXPIPE);
149     &die_gracefully("$Pgm: BibTeX run had errors\n")
150         if $? >> 8 || $bibtex_had_errors;
151 }
152
153 sub something_more_needed {
154     # returns 1 or 0 if we need to run LaTeX
155     # possibly preceded by bibtex and/or makeindex run
156
157     # $Says_labels_changed was set by previous &run_latex...
158     $BibTeX_run_needed    = 0;
159     $MakeIndex_run_needed = 0;
160
161     if ( ! -f ($TeX_root . '.aux-prev')) { # this was the first run
162
163         print STDERR "$Pgm: *** 'twas first run of LaTeX on $TeX_input\n" if $Verbose;
164
165         # we need makeindex to run if a non-zero-sized .idx file exists
166         #
167         $MakeIndex_run_needed = 1
168             if -f "$TeX_root.idx" && -s "$TeX_root.idx";
169
170         # we need bibtex to run if there are \citations in the .aux file
171         #
172         &slurp_aux_file('aux');
173         $BibTeX_run_needed = 1
174             if $Bibliography_requested &&
175               -f "$Tmp_prefix/ltx-aux-cite.$$" &&
176               -s "$Tmp_prefix/ltx-aux-cite.$$";
177
178
179     } else { # ltx had been run before (.aux-prev/.idx-prev files exist)
180
181         # slurp both .aux and .aux-prev files
182         &slurp_aux_file('aux');
183         &slurp_aux_file('aux-prev');
184
185         local($tmp_pre) = "$Tmp_prefix/ltx";
186
187         if ((-s "$tmp_pre-.aux-cite.$$") # there are still \cite's in there
188          && (system("cmp -s $tmp_pre-.aux-cite.$$ $tmp_pre-.aux-prev-cite.$$") >> 8)) {
189             $BibTeX_run_needed = 1 if $Bibliography_requested;
190             if ($Verbose) {
191                 system("$(CONTEXT_DIFF) $tmp_pre-.aux-prev-cite.$$ $tmp_pre-.aux-cite.$$");
192             }
193         }
194
195         if (-f "$TeX_root.idx") {
196             $MakeIndex_run_needed =
197                 (system("cmp -s $TeX_root.idx $TeX_root.idx-prev") >> 8) ? 1 : 0;
198             if ($MakeIndex_run_needed && $Verbose) {
199                 system("$(CONTEXT_DIFF) $TeX_root.idx-prev $TeX_root.idx");
200             }
201         }
202     }
203
204     $Says_labels_changed || $BibTeX_run_needed || $MakeIndex_run_needed;
205 }
206
207 sub slurp_aux_file {
208     local($ext) = @_;
209
210     # copy all citations from slurpfile into $Tmp_prefix/ltx-$ext-cite.$$
211
212     open(SLURPF,"< $TeX_root.$ext")
213         || &die_gracefully("$Pgm: Can't open $TeX_root.$ext for reading\n");
214     open(CITEF,"> $Tmp_prefix/ltx-$ext-cite.$$")
215         || &die_gracefully("$Pgm: Can't open $Tmp_prefix/ltx-$ext-cite.$$ for writing\n");
216
217     while (<SLURPF>) {
218         print CITEF $_  if /\\citation/;
219     }
220     close(CITEF);
221     close(SLURPF);
222 }