cannam@95: #!/usr/bin/perl -- cannam@95: # Copyright (C) 1993-1995 Ian Jackson. cannam@95: cannam@95: # This file is free software; you can redistribute it and/or modify cannam@95: # it under the terms of the GNU General Public License as published by cannam@95: # the Free Software Foundation; either version 2, or (at your option) cannam@95: # any later version. cannam@95: cannam@95: # It is distributed in the hope that it will be useful, cannam@95: # but WITHOUT ANY WARRANTY; without even the implied warranty of cannam@95: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the cannam@95: # GNU General Public License for more details. cannam@95: cannam@95: # You should have received a copy of the GNU General Public License cannam@95: # along with GNU Emacs; see the file COPYING. If not, write to cannam@95: # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, cannam@95: # Boston, MA 02111-1307, USA. cannam@95: cannam@95: # (Note: I do not consider works produced using these BFNN processing cannam@95: # tools to be derivative works of the tools, so they are NOT covered cannam@95: # by the GPL. However, I would appreciate it if you credited me if cannam@95: # appropriate in any documents you format using BFNN.) cannam@95: cannam@95: @outputs=('ascii','info','html'); cannam@95: cannam@95: while ($ARGV[0] =~ m/^\-/) { cannam@95: $_= shift(@ARGV); cannam@95: if (m/^-only/) { cannam@95: @outputs= (shift(@ARGV)); cannam@95: } else { cannam@95: warn "unknown option `$_' ignored"; cannam@95: } cannam@95: } cannam@95: cannam@95: $prefix= $ARGV[0]; cannam@95: $prefix= 'stdin' unless length($prefix); cannam@95: $prefix =~ s/\.bfnn$//; cannam@95: cannam@95: if (open(O,"$prefix.xrefdb")) { cannam@95: @xrefdb= ; cannam@95: close(O); cannam@95: } else { cannam@95: warn "no $prefix.xrefdb ($!)"; cannam@95: } cannam@95: cannam@95: $section= -1; cannam@95: for $thisxr (@xrefdb) { cannam@95: $_= $thisxr; cannam@95: chop; cannam@95: if (m/^Q (\w+) ((\d+)\.(\d+)) (.*)$/) { cannam@95: $qrefn{$1}= $2; cannam@95: $qreft{$1}= $5; cannam@95: $qn2ref{$3,$4}= $1; cannam@95: $maxsection= $3; cannam@95: $maxquestion[$3]= $4; cannam@95: } elsif (m/^S (\d+) /) { cannam@95: $maxsection= $1; cannam@95: $sn2title{$1}=$'; cannam@95: } cannam@95: } cannam@95: cannam@95: open(U,">$prefix.xrefdb-new"); cannam@95: cannam@95: for $x (@outputs) { require("m-$x.pl"); } cannam@95: cannam@95: &call('init'); cannam@95: cannam@95: while (<>) { cannam@95: chop; cannam@95: next if m/^\\comment\b/; cannam@95: if (!m/\S/) { cannam@95: &call('endpara'); cannam@95: next; cannam@95: } cannam@95: if (s/^\\section +//) { cannam@95: $line= $_; cannam@95: $section++; $question=0; cannam@95: print U "S $section $line\n"; cannam@95: $|=1; print "S$section",' 'x10,"\r"; $|=0; cannam@95: &call('endpara'); cannam@95: &call('startmajorheading',"$section", cannam@95: "Section $section", cannam@95: $section<$maxsection ? "Section ".($section+1) : '', cannam@95: $section>1 ? 'Section '.($section-1) : 'Top'); cannam@95: &text($line); cannam@95: &call('endmajorheading'); cannam@95: if ($section) { cannam@95: &call('endpara'); cannam@95: &call('startindex'); cannam@95: for $thisxr (@xrefdb) { cannam@95: $_= $thisxr; cannam@95: chop; cannam@95: if (m/^Q (\w+) (\d+)\.(\d+) (.*)$/) { cannam@95: $ref= $1; $num1= $2; $num2= $3; $text= $4; cannam@95: next unless $num1 == $section; cannam@95: &call('startindexitem',$ref,"Q$num1.$num2","Question $num1.$num2"); cannam@95: &text($text); cannam@95: &call('endindexitem'); cannam@95: } cannam@95: } cannam@95: &call('endindex'); cannam@95: } cannam@95: } elsif (s/^\\question \d{2}[a-z]{3}((:\w+)?) +//) { cannam@95: $line= $_; cannam@95: $question++; cannam@95: $qrefstring= $1; cannam@95: $qrefstring= "q_${section}_$question" unless $qrefstring =~ s/^://; cannam@95: print U "Q $qrefstring $section.$question $line\n"; cannam@95: $|=1; print "Q$section.$question",' 'x10,"\r"; $|=0; cannam@95: &call('endpara'); cannam@95: &call('startminorheading',$qrefstring, cannam@95: "Question $section.$question", cannam@95: $question < $maxquestion[$section] ? "Question $section.".($question+1) : cannam@95: $section < $maxsection ? "Question ".($section+1).".1" : '', cannam@95: $question > 1 ? "Question $section.".($question-1) : cannam@95: $section > 1 ? "Question ".($section-1).'.'.($maxquestion[$section-1]) : cannam@95: 'Top', cannam@95: "Section $section"); cannam@95: &text("Question $section.$question. $line"); cannam@95: &call('endminorheading'); cannam@95: } elsif (s/^\\only +//) { cannam@95: @saveoutputs= @outputs; cannam@95: @outputs=(); cannam@95: for $x (split(/\s+/,$_)) { cannam@95: push(@outputs,$x) if grep($x eq $_, @saveoutputs); cannam@95: } cannam@95: } elsif (s/^\\endonly$//) { cannam@95: @outputs= @saveoutputs; cannam@95: } elsif (s/^\\copyto +//) { cannam@95: $fh= $'; cannam@95: while(<>) { cannam@95: last if m/^\\endcopy$/; cannam@95: while (s/^([^\`]*)\`//) { cannam@95: print $fh $1; cannam@95: m/([^\\])\`/ || warn "`$_'"; cannam@95: $_= $'; cannam@95: $cmd= $`.$1; cannam@95: $it= `$cmd`; chop $it; cannam@95: print $fh $it; cannam@95: } cannam@95: print $fh $_; cannam@95: } cannam@95: } elsif (m/\\index$/) { cannam@95: &call('startindex'); cannam@95: for $thisxr (@xrefdb) { cannam@95: $_= $thisxr; cannam@95: chop; cannam@95: if (m/^Q (\w+) (\d+\.\d+) (.*)$/) { cannam@95: $ref= $1; $num= $2; $text= $3; cannam@95: &call('startindexitem',$ref,"Q$num","Question $num"); cannam@95: &text($text); cannam@95: &call('endindexitem'); cannam@95: } elsif (m/^S (\d+) (.*)$/) { cannam@95: $num= $1; $text= $2; cannam@95: next unless $num; cannam@95: &call('startindexmainitem',"s_$num", cannam@95: "Section $num.","Section $num"); cannam@95: &text($text); cannam@95: &call('endindexitem'); cannam@95: } else { cannam@95: warn $_; cannam@95: } cannam@95: } cannam@95: &call('endindex'); cannam@95: } elsif (m/^\\call-(\w+) +(\w+)\s*(.*)$/) { cannam@95: $fn= $1.'_'.$2; cannam@95: eval { &$fn($3); }; cannam@95: warn $@ if length($@); cannam@95: } elsif (m/^\\call +(\w+)\s*(.*)$/) { cannam@95: eval { &call($1,$2); }; cannam@95: warn $@ if length($@); cannam@95: } elsif (s/^\\set +(\w+)\s*//) { cannam@95: $svalue= $'; $svari= $1; cannam@95: eval("\$user_$svari=\$svalue"); $@ && warn "setting $svalue failed: $@\n"; cannam@95: } elsif (m/^\\verbatim$/) { cannam@95: &call('startverbatim'); cannam@95: while (<>) { cannam@95: chop; cannam@95: last if m/^\\endverbatim$/; cannam@95: &call('verbatim',$_); cannam@95: } cannam@95: &call('endverbatim'); cannam@95: } else { cannam@95: s/\.$/\. /; cannam@95: &text($_." "); cannam@95: } cannam@95: } cannam@95: cannam@95: print ' 'x25,"\r"; cannam@95: &call('finish'); cannam@95: rename("$prefix.xrefdb-new","$prefix.xrefdb") || warn "rename xrefdb: $!"; cannam@95: exit 0; cannam@95: cannam@95: cannam@95: sub text { cannam@95: local($in,$rhs,$word,$refn,$reft,$fn,$style); cannam@95: $in= "$holdover$_[0]"; cannam@95: $holdover= ''; cannam@95: while ($in =~ m/\\/) { cannam@95: #print STDERR ">$`##$'\n"; cannam@95: $rhs=$'; cannam@95: &call('text',$`); cannam@95: $_= $rhs; cannam@95: if (m/^\w+ $/) { cannam@95: $holdover= "\\$&"; cannam@95: $in= ''; cannam@95: } elsif (s/^fn\s+([^\s\\]*\w)//) { cannam@95: $in= $_; cannam@95: $word= $1; cannam@95: &call('courier'); cannam@95: &call('text',$word); cannam@95: &call('endcourier'); cannam@95: } elsif (s/^tab\s+(\d+)\s+//) { cannam@95: $in= $_; &call('tab',$1); cannam@95: } elsif (s/^nl\s+//) { cannam@95: $in= $_; &call('newline'); cannam@95: } elsif (s/^qref\s+(\w+)//) { cannam@95: $refn= $qrefn{$1}; cannam@95: $reft= $qreft{$1}; cannam@95: if (!length($refn)) { cannam@95: warn "unknown question `$1'"; cannam@95: } cannam@95: $in= "$`\\pageref:$1:$refn:$reft\\endpageref.$_"; cannam@95: } elsif (s/^pageref:(\w+):([^:\n]+)://) { cannam@95: $in= $_; cannam@95: &call('pageref',$1,$2); cannam@95: } elsif (s/^endpageref\.//) { cannam@95: $in= $_; &call('endpageref'); cannam@95: } elsif (s/^(\w+)\{//) { cannam@95: $in= $_; $fn= $1; cannam@95: eval { &call("$fn"); }; cannam@95: if (length($@)) { warn $@; $fn= 'x'; } cannam@95: push(@styles,$fn); cannam@95: } elsif (s/^\}//) { cannam@95: $in= $_; cannam@95: $fn= pop(@styles); cannam@95: if ($fn ne 'x') { &call("end$fn"); } cannam@95: } elsif (s/^\\//) { cannam@95: $in= $_; cannam@95: &call('text',"\\"); cannam@95: } elsif (s,^(\w+)\s+([-A-Za-z0-9.\@:/]*\w),,) { cannam@95: #print STDERR "**$&**$_\n"; cannam@95: $in= $_; cannam@95: $style=$1; $word= $2; cannam@95: &call($style); cannam@95: &call('text',$word); cannam@95: &call("end$style"); cannam@95: } else { cannam@95: warn "unknown control `\\$_'"; cannam@95: $in= $_; cannam@95: } cannam@95: } cannam@95: &call('text',$in); cannam@95: } cannam@95: cannam@95: cannam@95: sub call { cannam@95: local ($fnbase, @callargs) = @_; cannam@95: local ($coutput); cannam@95: for $coutput (@outputs) { cannam@95: if ($fnbase eq 'text' && eval("\@${coutput}_cmds")) { cannam@95: #print STDERR "special handling text (@callargs) for $coutput\n"; cannam@95: $evstrg= "\$${coutput}_args[\$#${coutput}_args].=\"\@callargs\""; cannam@95: eval($evstrg); cannam@95: length($@) && warn "call adding for $coutput (($evstrg)): $@"; cannam@95: } else { cannam@95: $fntc= $coutput.'_'.$fnbase; cannam@95: &$fntc(@callargs); cannam@95: } cannam@95: } cannam@95: } cannam@95: cannam@95: cannam@95: sub recurse { cannam@95: local (@outputs) = $coutput; cannam@95: local ($holdover); cannam@95: &text($_[0]); cannam@95: } cannam@95: cannam@95: cannam@95: sub arg { cannam@95: #print STDERR "arg($_[0]) from $coutput\n"; cannam@95: $cmd= $_[0]; cannam@95: eval("push(\@${coutput}_cmds,\$cmd); push(\@${coutput}_args,'')"); cannam@95: length($@) && warn "arg setting up for $coutput: $@"; cannam@95: } cannam@95: cannam@95: sub endarg { cannam@95: #print STDERR "endarg($_[0]) from $coutput\n"; cannam@95: $evstrg= "\$${coutput}_cmd= \$cmd= pop(\@${coutput}_cmds); ". cannam@95: "\$${coutput}_arg= \$arg= pop(\@${coutput}_args); "; cannam@95: eval($evstrg); cannam@95: length($@) && warn "endarg extracting for $coutput (($evstrg)): $@"; cannam@95: #print STDERR ">call $coutput $cmd $arg< (($evstrg))\n"; cannam@95: $evstrg= "&${coutput}_do_${cmd}(\$arg)"; cannam@95: eval($evstrg); cannam@95: length($@) && warn "endarg running ${coutput}_do_${cmd} (($evstrg)): $@"; cannam@95: }