summaryrefslogtreecommitdiff
path: root/web/glasgow/lit2x-0.16/grasp-utils/scripts/ltx.prl
blob: 1bce758270df0a569edeac1fb147258381964740 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
$Pgm = $0; $Pgm =~ s/.*\/([^\/]+)$/\1/;
#
# set up signal handler
sub quit_upon_signal { &rm_temp_files_and_exit(); }
$SIG{'INT'}  = 'quit_upon_signal';
$SIG{'QUIT'} = 'quit_upon_signal';
#
$Verbose = 0;
if ($ARGV[0] eq '-v') {
    $Verbose = 1;
    shift(@ARGV);
}
#
die "$Pgm: must have exactly one argument\n" if $#ARGV != 0;
# figure out input file and its filename root
if (-f $ARGV[0]) {
    $TeX_input = $ARGV[0];
    if ($TeX_input =~ /(.+)\.[^\.\/\n]+$/) {
	$TeX_root  = $1;
    } else {
	$TeX_root  = $TeX_input;
    }
} elsif (-f $ARGV[0].'.tex') {
    $TeX_input = $ARGV[0].'.tex';
    $TeX_root  = $ARGV[0];
} else {
    die "$Pgm: input file $ARGV[0] doesn't exist\n";
}

sub rm_temp_files {
    system("rm -f $(TMPDIR)/ltx-*.$$");
}
sub rm_temp_files_and_exit {
    system("rm -f $(TMPDIR)/ltx-*.$$");
    exit(1);
}
$SIG{'INT'}  = 'rm_temp_files_and_exit';
$SIG{'QUIT'} = 'rm_temp_files_and_exit';

sub die_gracefully {
    local($msg) = @_;
    
    print STDERR $msg;
    &rm_temp_files_and_exit();
}

# must read through root file to see if a \bibliography
# is there...
$Bibliography_requested = 0;
open(TEXIF, "<$TeX_input") 
    || &die_gracefully("$Pgm: Can't read $TeX_input\n");
while (<TEXIF>) {
    $Bibliography_requested = 1 if /^\\bibliography/;
}
close(TEXIF);
&die_gracefully("$Pgm: reading $TeX_input had errors\n") if $? >> 8;

# run latex first time (?)
&run_latex(); # sets $Says_labels_changed
$Times_run = 1;

while (&something_more_needed()) {

    print STDERR "labels_changed=$Says_label_changed;bibtex_needed=$BibTeX_run_needed;makeindex_needed=$MakeIndex_run_needed\n" if $Verbose;

    if ($BibTeX_run_needed) {
	&run_bibtex();
    }
    if ($MakeIndex_run_needed) {
	unlink "$TeX_root.ind";
	(system("makeindex $TeX_root.idx") >> 8) 
	    && &die_gracefully("$Pgm: makeindex $TeX_root.idx had errors\n");
    }

    # save (copy) .aux file as .aux-prev file for future ref
    # ditto for .idx file
    unlink "$TeX_root.aux-prev";
    (system("cp $TeX_root.aux $TeX_root.aux-prev") >> 8)
	&& &die_gracefully("$Pgm: cp $TeX_root.aux $TeX_root.aux-prev failed\n");
    if (-f "$TeX_root.idx") {
	unlink "$TeX_root.idx-prev";
	(system("cp $TeX_root.idx $TeX_root.idx-prev") >> 8)
	    && &die_gracefully("$Pgm: cp $TeX_root.idx $TeX_root.idx-prev failed\n");
    }

    # run latex again
    &run_latex(); # sets $Says_labels_changed
    $Times_run++;

    if ($Times_run >= 4) {
	print STDERR "*** I don't run LaTeX more than four times;\n";
	print STDERR "*** Something is probably wrong...\n";
	&rm_temp_files_and_exit();
    }
}
&rm_temp_files();
exit(0);

sub run_latex {
    $Says_labels_changed = 0;
    $Multiply_defined_labels = 0;

    select(STDERR); $| = 1; select(STDOUT); # no buffering on STDERR
    print STDERR "$Pgm: *** running LaTeX...\n" if $Verbose;
    unlink "$TeX_root.dvi";

    open(LTXPIPE, "latex $TeX_input 2>&1 |") 
    	|| &die_gracefully("$Pgm: Can't run latex pipe\n");
    while (<LTXPIPE>) {
	$Multiply_defined_labels = 1 if /^LaTeX Warning: Label .* multiply defined/;
	$Says_labels_changed = 1 if /^LaTeX Warning: Label\(s\) may have changed/
					&& ! $Multiply_defined_labels;
	print STDERR $_;
    }
    close(LTXPIPE);
    &die_gracefully("$Pgm: LaTeX run had errors\n") if $? >> 8;

    # sort .idx file, because this helps makeindex
    # (can you say `bug'?)
    if (-f "$TeX_root.idx") {
	print STDERR "$Pgm: *** sorting $TeX_root.idx...\n" if $Verbose;
	(system("sort $TeX_root.idx -o $TeX_root.idx") >> 8)
	&& &die_gracefully("$Pgm: sorting $TeX_root.idx failed\n");
    }

}

sub run_bibtex { # ugly because bibtex doesn't return a correct error status
    local($bibtex_had_errors) = 0;

    print STDERR "$Pgm: *** running BibTeX...\n" if $Verbose;
    unlink "$TeX_root.bbl";

    $| = 1; # no buffering
    open(BIBTXPIPE, "bibtex $TeX_root 2>&1 |") 
    	|| &die_gracefully("$Pgm: Can't run bibtex pipe\n");
    while (<BIBTXPIPE>) {
	$bibtex_had_errors = 1 if /^\(There.*error message(s)?\)$/;
	print STDERR $_;
    }
    close(BIBTXPIPE);
    &die_gracefully("$Pgm: BibTeX run had errors\n")
    	if $? >> 8 || $bibtex_had_errors;
}

sub something_more_needed {
    # returns 1 or 0 if we need to run LaTeX
    # possibly preceded by bibtex and/or makeindex run

    # $Says_labels_changed was set by previous &run_latex...
    $BibTeX_run_needed    = 0;
    $MakeIndex_run_needed = 0;

    if ( ! -f ($TeX_root . '.aux-prev')) { # this was the first run

	print STDERR "$Pgm: *** 'twas first run of LaTeX on $TeX_input\n" if $Verbose;

	# we need makeindex to run if a non-zero-sized .idx file exists
	#
	$MakeIndex_run_needed = 1
	    if -f "$TeX_root.idx" && -s "$TeX_root.idx";

	# we need bibtex to run if there are \citations in the .aux file
	#
        &slurp_aux_file('aux');
	$BibTeX_run_needed = 1
	    if $Bibliography_requested &&
	      -f "$(TMPDIR)/ltx-aux-cite.$$" &&
	      -s "$(TMPDIR)/ltx-aux-cite.$$";


    } else { # ltx had been run before (.aux-prev/.idx-prev files exist)

	# slurp both .aux and .aux-prev files
        &slurp_aux_file('aux');
        &slurp_aux_file('aux-prev');

	local($tmp_pre) = "$(TMPDIR)/ltx";

	if ((-s "$tmp_pre-.aux-cite.$$") # there are still \cite's in there
	 && (system("cmp -s $tmp_pre-.aux-cite.$$ $tmp_pre-.aux-prev-cite.$$") >> 8)) {
	    $BibTeX_run_needed = 1 if $Bibliography_requested;
	    if ($Verbose) {
		system("diff -c1 $tmp_pre-.aux-prev-cite.$$ $tmp_pre-.aux-cite.$$");
	    }
	}

	if (-f "$TeX_root.idx") {
	    $MakeIndex_run_needed =
		(system("cmp -s $TeX_root.idx $TeX_root.idx-prev") >> 8) ? 1 : 0;
	    if ($MakeIndex_run_needed && $Verbose) {
		system("diff -c1 $TeX_root.idx-prev $TeX_root.idx");
	    }
	}
    }

    $Says_labels_changed || $BibTeX_run_needed || $MakeIndex_run_needed;
}

sub slurp_aux_file {
    local($ext) = @_;

    # copy all citations from slurpfile into $(TMPDIR)/ltx-$ext-cite.$$

    open(SLURPF,"< $TeX_root.$ext")
	|| &die_gracefully("$Pgm: Can't open $TeX_root.$ext for reading\n");
    open(CITEF,"> $(TMPDIR)/ltx-$ext-cite.$$")
	|| &die_gracefully("$Pgm: Can't open $(TMPDIR)/ltx-$ext-cite.$$ for writing\n");

    while (<SLURPF>) {
	print CITEF $_  if /\\citation/;
    }
    close(CITEF);
    close(SLURPF);
}