Chris@10
|
1 #!/usr/bin/perl --
|
Chris@10
|
2 # Copyright (C) 1993-1995 Ian Jackson.
|
Chris@10
|
3
|
Chris@10
|
4 # This file is free software; you can redistribute it and/or modify
|
Chris@10
|
5 # it under the terms of the GNU General Public License as published by
|
Chris@10
|
6 # the Free Software Foundation; either version 2, or (at your option)
|
Chris@10
|
7 # any later version.
|
Chris@10
|
8
|
Chris@10
|
9 # It is distributed in the hope that it will be useful,
|
Chris@10
|
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Chris@10
|
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
Chris@10
|
12 # GNU General Public License for more details.
|
Chris@10
|
13
|
Chris@10
|
14 # You should have received a copy of the GNU General Public License
|
Chris@10
|
15 # along with GNU Emacs; see the file COPYING. If not, write to
|
Chris@10
|
16 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
Chris@10
|
17 # Boston, MA 02111-1307, USA.
|
Chris@10
|
18
|
Chris@10
|
19 # (Note: I do not consider works produced using these BFNN processing
|
Chris@10
|
20 # tools to be derivative works of the tools, so they are NOT covered
|
Chris@10
|
21 # by the GPL. However, I would appreciate it if you credited me if
|
Chris@10
|
22 # appropriate in any documents you format using BFNN.)
|
Chris@10
|
23
|
Chris@10
|
24 @outputs=('ascii','info','html');
|
Chris@10
|
25
|
Chris@10
|
26 while ($ARGV[0] =~ m/^\-/) {
|
Chris@10
|
27 $_= shift(@ARGV);
|
Chris@10
|
28 if (m/^-only/) {
|
Chris@10
|
29 @outputs= (shift(@ARGV));
|
Chris@10
|
30 } else {
|
Chris@10
|
31 warn "unknown option `$_' ignored";
|
Chris@10
|
32 }
|
Chris@10
|
33 }
|
Chris@10
|
34
|
Chris@10
|
35 $prefix= $ARGV[0];
|
Chris@10
|
36 $prefix= 'stdin' unless length($prefix);
|
Chris@10
|
37 $prefix =~ s/\.bfnn$//;
|
Chris@10
|
38
|
Chris@10
|
39 if (open(O,"$prefix.xrefdb")) {
|
Chris@10
|
40 @xrefdb= <O>;
|
Chris@10
|
41 close(O);
|
Chris@10
|
42 } else {
|
Chris@10
|
43 warn "no $prefix.xrefdb ($!)";
|
Chris@10
|
44 }
|
Chris@10
|
45
|
Chris@10
|
46 $section= -1;
|
Chris@10
|
47 for $thisxr (@xrefdb) {
|
Chris@10
|
48 $_= $thisxr;
|
Chris@10
|
49 chop;
|
Chris@10
|
50 if (m/^Q (\w+) ((\d+)\.(\d+)) (.*)$/) {
|
Chris@10
|
51 $qrefn{$1}= $2;
|
Chris@10
|
52 $qreft{$1}= $5;
|
Chris@10
|
53 $qn2ref{$3,$4}= $1;
|
Chris@10
|
54 $maxsection= $3;
|
Chris@10
|
55 $maxquestion[$3]= $4;
|
Chris@10
|
56 } elsif (m/^S (\d+) /) {
|
Chris@10
|
57 $maxsection= $1;
|
Chris@10
|
58 $sn2title{$1}=$';
|
Chris@10
|
59 }
|
Chris@10
|
60 }
|
Chris@10
|
61
|
Chris@10
|
62 open(U,">$prefix.xrefdb-new");
|
Chris@10
|
63
|
Chris@10
|
64 for $x (@outputs) { require("m-$x.pl"); }
|
Chris@10
|
65
|
Chris@10
|
66 &call('init');
|
Chris@10
|
67
|
Chris@10
|
68 while (<>) {
|
Chris@10
|
69 chop;
|
Chris@10
|
70 next if m/^\\comment\b/;
|
Chris@10
|
71 if (!m/\S/) {
|
Chris@10
|
72 &call('endpara');
|
Chris@10
|
73 next;
|
Chris@10
|
74 }
|
Chris@10
|
75 if (s/^\\section +//) {
|
Chris@10
|
76 $line= $_;
|
Chris@10
|
77 $section++; $question=0;
|
Chris@10
|
78 print U "S $section $line\n";
|
Chris@10
|
79 $|=1; print "S$section",' 'x10,"\r"; $|=0;
|
Chris@10
|
80 &call('endpara');
|
Chris@10
|
81 &call('startmajorheading',"$section",
|
Chris@10
|
82 "Section $section",
|
Chris@10
|
83 $section<$maxsection ? "Section ".($section+1) : '',
|
Chris@10
|
84 $section>1 ? 'Section '.($section-1) : 'Top');
|
Chris@10
|
85 &text($line);
|
Chris@10
|
86 &call('endmajorheading');
|
Chris@10
|
87 if ($section) {
|
Chris@10
|
88 &call('endpara');
|
Chris@10
|
89 &call('startindex');
|
Chris@10
|
90 for $thisxr (@xrefdb) {
|
Chris@10
|
91 $_= $thisxr;
|
Chris@10
|
92 chop;
|
Chris@10
|
93 if (m/^Q (\w+) (\d+)\.(\d+) (.*)$/) {
|
Chris@10
|
94 $ref= $1; $num1= $2; $num2= $3; $text= $4;
|
Chris@10
|
95 next unless $num1 == $section;
|
Chris@10
|
96 &call('startindexitem',$ref,"Q$num1.$num2","Question $num1.$num2");
|
Chris@10
|
97 &text($text);
|
Chris@10
|
98 &call('endindexitem');
|
Chris@10
|
99 }
|
Chris@10
|
100 }
|
Chris@10
|
101 &call('endindex');
|
Chris@10
|
102 }
|
Chris@10
|
103 } elsif (s/^\\question \d{2}[a-z]{3}((:\w+)?) +//) {
|
Chris@10
|
104 $line= $_;
|
Chris@10
|
105 $question++;
|
Chris@10
|
106 $qrefstring= $1;
|
Chris@10
|
107 $qrefstring= "q_${section}_$question" unless $qrefstring =~ s/^://;
|
Chris@10
|
108 print U "Q $qrefstring $section.$question $line\n";
|
Chris@10
|
109 $|=1; print "Q$section.$question",' 'x10,"\r"; $|=0;
|
Chris@10
|
110 &call('endpara');
|
Chris@10
|
111 &call('startminorheading',$qrefstring,
|
Chris@10
|
112 "Question $section.$question",
|
Chris@10
|
113 $question < $maxquestion[$section] ? "Question $section.".($question+1) :
|
Chris@10
|
114 $section < $maxsection ? "Question ".($section+1).".1" : '',
|
Chris@10
|
115 $question > 1 ? "Question $section.".($question-1) :
|
Chris@10
|
116 $section > 1 ? "Question ".($section-1).'.'.($maxquestion[$section-1]) :
|
Chris@10
|
117 'Top',
|
Chris@10
|
118 "Section $section");
|
Chris@10
|
119 &text("Question $section.$question. $line");
|
Chris@10
|
120 &call('endminorheading');
|
Chris@10
|
121 } elsif (s/^\\only +//) {
|
Chris@10
|
122 @saveoutputs= @outputs;
|
Chris@10
|
123 @outputs=();
|
Chris@10
|
124 for $x (split(/\s+/,$_)) {
|
Chris@10
|
125 push(@outputs,$x) if grep($x eq $_, @saveoutputs);
|
Chris@10
|
126 }
|
Chris@10
|
127 } elsif (s/^\\endonly$//) {
|
Chris@10
|
128 @outputs= @saveoutputs;
|
Chris@10
|
129 } elsif (s/^\\copyto +//) {
|
Chris@10
|
130 $fh= $';
|
Chris@10
|
131 while(<>) {
|
Chris@10
|
132 last if m/^\\endcopy$/;
|
Chris@10
|
133 while (s/^([^\`]*)\`//) {
|
Chris@10
|
134 print $fh $1;
|
Chris@10
|
135 m/([^\\])\`/ || warn "`$_'";
|
Chris@10
|
136 $_= $';
|
Chris@10
|
137 $cmd= $`.$1;
|
Chris@10
|
138 $it= `$cmd`; chop $it;
|
Chris@10
|
139 print $fh $it;
|
Chris@10
|
140 }
|
Chris@10
|
141 print $fh $_;
|
Chris@10
|
142 }
|
Chris@10
|
143 } elsif (m/\\index$/) {
|
Chris@10
|
144 &call('startindex');
|
Chris@10
|
145 for $thisxr (@xrefdb) {
|
Chris@10
|
146 $_= $thisxr;
|
Chris@10
|
147 chop;
|
Chris@10
|
148 if (m/^Q (\w+) (\d+\.\d+) (.*)$/) {
|
Chris@10
|
149 $ref= $1; $num= $2; $text= $3;
|
Chris@10
|
150 &call('startindexitem',$ref,"Q$num","Question $num");
|
Chris@10
|
151 &text($text);
|
Chris@10
|
152 &call('endindexitem');
|
Chris@10
|
153 } elsif (m/^S (\d+) (.*)$/) {
|
Chris@10
|
154 $num= $1; $text= $2;
|
Chris@10
|
155 next unless $num;
|
Chris@10
|
156 &call('startindexmainitem',"s_$num",
|
Chris@10
|
157 "Section $num.","Section $num");
|
Chris@10
|
158 &text($text);
|
Chris@10
|
159 &call('endindexitem');
|
Chris@10
|
160 } else {
|
Chris@10
|
161 warn $_;
|
Chris@10
|
162 }
|
Chris@10
|
163 }
|
Chris@10
|
164 &call('endindex');
|
Chris@10
|
165 } elsif (m/^\\call-(\w+) +(\w+)\s*(.*)$/) {
|
Chris@10
|
166 $fn= $1.'_'.$2;
|
Chris@10
|
167 eval { &$fn($3); };
|
Chris@10
|
168 warn $@ if length($@);
|
Chris@10
|
169 } elsif (m/^\\call +(\w+)\s*(.*)$/) {
|
Chris@10
|
170 eval { &call($1,$2); };
|
Chris@10
|
171 warn $@ if length($@);
|
Chris@10
|
172 } elsif (s/^\\set +(\w+)\s*//) {
|
Chris@10
|
173 $svalue= $'; $svari= $1;
|
Chris@10
|
174 eval("\$user_$svari=\$svalue"); $@ && warn "setting $svalue failed: $@\n";
|
Chris@10
|
175 } elsif (m/^\\verbatim$/) {
|
Chris@10
|
176 &call('startverbatim');
|
Chris@10
|
177 while (<>) {
|
Chris@10
|
178 chop;
|
Chris@10
|
179 last if m/^\\endverbatim$/;
|
Chris@10
|
180 &call('verbatim',$_);
|
Chris@10
|
181 }
|
Chris@10
|
182 &call('endverbatim');
|
Chris@10
|
183 } else {
|
Chris@10
|
184 s/\.$/\. /;
|
Chris@10
|
185 &text($_." ");
|
Chris@10
|
186 }
|
Chris@10
|
187 }
|
Chris@10
|
188
|
Chris@10
|
189 print ' 'x25,"\r";
|
Chris@10
|
190 &call('finish');
|
Chris@10
|
191 rename("$prefix.xrefdb-new","$prefix.xrefdb") || warn "rename xrefdb: $!";
|
Chris@10
|
192 exit 0;
|
Chris@10
|
193
|
Chris@10
|
194
|
Chris@10
|
195 sub text {
|
Chris@10
|
196 local($in,$rhs,$word,$refn,$reft,$fn,$style);
|
Chris@10
|
197 $in= "$holdover$_[0]";
|
Chris@10
|
198 $holdover= '';
|
Chris@10
|
199 while ($in =~ m/\\/) {
|
Chris@10
|
200 #print STDERR ">$`##$'\n";
|
Chris@10
|
201 $rhs=$';
|
Chris@10
|
202 &call('text',$`);
|
Chris@10
|
203 $_= $rhs;
|
Chris@10
|
204 if (m/^\w+ $/) {
|
Chris@10
|
205 $holdover= "\\$&";
|
Chris@10
|
206 $in= '';
|
Chris@10
|
207 } elsif (s/^fn\s+([^\s\\]*\w)//) {
|
Chris@10
|
208 $in= $_;
|
Chris@10
|
209 $word= $1;
|
Chris@10
|
210 &call('courier');
|
Chris@10
|
211 &call('text',$word);
|
Chris@10
|
212 &call('endcourier');
|
Chris@10
|
213 } elsif (s/^tab\s+(\d+)\s+//) {
|
Chris@10
|
214 $in= $_; &call('tab',$1);
|
Chris@10
|
215 } elsif (s/^nl\s+//) {
|
Chris@10
|
216 $in= $_; &call('newline');
|
Chris@10
|
217 } elsif (s/^qref\s+(\w+)//) {
|
Chris@10
|
218 $refn= $qrefn{$1};
|
Chris@10
|
219 $reft= $qreft{$1};
|
Chris@10
|
220 if (!length($refn)) {
|
Chris@10
|
221 warn "unknown question `$1'";
|
Chris@10
|
222 }
|
Chris@10
|
223 $in= "$`\\pageref:$1:$refn:$reft\\endpageref.$_";
|
Chris@10
|
224 } elsif (s/^pageref:(\w+):([^:\n]+)://) {
|
Chris@10
|
225 $in= $_;
|
Chris@10
|
226 &call('pageref',$1,$2);
|
Chris@10
|
227 } elsif (s/^endpageref\.//) {
|
Chris@10
|
228 $in= $_; &call('endpageref');
|
Chris@10
|
229 } elsif (s/^(\w+)\{//) {
|
Chris@10
|
230 $in= $_; $fn= $1;
|
Chris@10
|
231 eval { &call("$fn"); };
|
Chris@10
|
232 if (length($@)) { warn $@; $fn= 'x'; }
|
Chris@10
|
233 push(@styles,$fn);
|
Chris@10
|
234 } elsif (s/^\}//) {
|
Chris@10
|
235 $in= $_;
|
Chris@10
|
236 $fn= pop(@styles);
|
Chris@10
|
237 if ($fn ne 'x') { &call("end$fn"); }
|
Chris@10
|
238 } elsif (s/^\\//) {
|
Chris@10
|
239 $in= $_;
|
Chris@10
|
240 &call('text',"\\");
|
Chris@10
|
241 } elsif (s,^(\w+)\s+([-A-Za-z0-9.\@:/]*\w),,) {
|
Chris@10
|
242 #print STDERR "**$&**$_\n";
|
Chris@10
|
243 $in= $_;
|
Chris@10
|
244 $style=$1; $word= $2;
|
Chris@10
|
245 &call($style);
|
Chris@10
|
246 &call('text',$word);
|
Chris@10
|
247 &call("end$style");
|
Chris@10
|
248 } else {
|
Chris@10
|
249 warn "unknown control `\\$_'";
|
Chris@10
|
250 $in= $_;
|
Chris@10
|
251 }
|
Chris@10
|
252 }
|
Chris@10
|
253 &call('text',$in);
|
Chris@10
|
254 }
|
Chris@10
|
255
|
Chris@10
|
256
|
Chris@10
|
257 sub call {
|
Chris@10
|
258 local ($fnbase, @callargs) = @_;
|
Chris@10
|
259 local ($coutput);
|
Chris@10
|
260 for $coutput (@outputs) {
|
Chris@10
|
261 if ($fnbase eq 'text' && eval("\@${coutput}_cmds")) {
|
Chris@10
|
262 #print STDERR "special handling text (@callargs) for $coutput\n";
|
Chris@10
|
263 $evstrg= "\$${coutput}_args[\$#${coutput}_args].=\"\@callargs\"";
|
Chris@10
|
264 eval($evstrg);
|
Chris@10
|
265 length($@) && warn "call adding for $coutput (($evstrg)): $@";
|
Chris@10
|
266 } else {
|
Chris@10
|
267 $fntc= $coutput.'_'.$fnbase;
|
Chris@10
|
268 &$fntc(@callargs);
|
Chris@10
|
269 }
|
Chris@10
|
270 }
|
Chris@10
|
271 }
|
Chris@10
|
272
|
Chris@10
|
273
|
Chris@10
|
274 sub recurse {
|
Chris@10
|
275 local (@outputs) = $coutput;
|
Chris@10
|
276 local ($holdover);
|
Chris@10
|
277 &text($_[0]);
|
Chris@10
|
278 }
|
Chris@10
|
279
|
Chris@10
|
280
|
Chris@10
|
281 sub arg {
|
Chris@10
|
282 #print STDERR "arg($_[0]) from $coutput\n";
|
Chris@10
|
283 $cmd= $_[0];
|
Chris@10
|
284 eval("push(\@${coutput}_cmds,\$cmd); push(\@${coutput}_args,'')");
|
Chris@10
|
285 length($@) && warn "arg setting up for $coutput: $@";
|
Chris@10
|
286 }
|
Chris@10
|
287
|
Chris@10
|
288 sub endarg {
|
Chris@10
|
289 #print STDERR "endarg($_[0]) from $coutput\n";
|
Chris@10
|
290 $evstrg= "\$${coutput}_cmd= \$cmd= pop(\@${coutput}_cmds); ".
|
Chris@10
|
291 "\$${coutput}_arg= \$arg= pop(\@${coutput}_args); ";
|
Chris@10
|
292 eval($evstrg);
|
Chris@10
|
293 length($@) && warn "endarg extracting for $coutput (($evstrg)): $@";
|
Chris@10
|
294 #print STDERR ">call $coutput $cmd $arg< (($evstrg))\n";
|
Chris@10
|
295 $evstrg= "&${coutput}_do_${cmd}(\$arg)";
|
Chris@10
|
296 eval($evstrg);
|
Chris@10
|
297 length($@) && warn "endarg running ${coutput}_do_${cmd} (($evstrg)): $@";
|
Chris@10
|
298 }
|