#!/usr/bin/perl # # Program to process specially coded LaTex files # to generate multiple versions of the document. # For example, lecture notes, slides, and partial # lecture notes from the same source file. # # Special commands of the form can be inserted # in the first column of lines in the LaTex document # to control which lines go to which streams. # Streams are named by a single letter. # # Defined in terms of Perl regexps, the commands are: # ^ # define a new stream # ^<\*([a-zA-Z]+)> # set default output # ^<\*> # set default output to all streams # ^<([a-zA-Z]+)> # send this line to specific streams # ^<\!([a-zA-Z]+)> # block this line from specific streams # # Command line options: # # --out [hsn] ! select one output stream (single character) # --quiet ! discard other streams (default is comment) # --tex ! automate the latex command # --clean ! clean up the latex mess and the .[nhs].tex file # # $st selects the default output stream to be generated when # this program is run on a file # # Blake Hannaford # University of Washington # June 2001 # use Getopt::Long; $ifhandle = 1239817239187; $ofhandle = 89120398230487; %optctl = ("out=s" => \$st, "quiet"=> \$q); #$st = "h"; # "handouts" $st = "s"; # "slides" #$st = "n"; # "notes" #&GetOptions(\%optctl); if(&GetOptions("out=s" => \$st, "quiet"=> \$q, "clean"=> \$cl, "tex"=> \$te) == 0 ) { print STDERR <" . $fname1); # create output file } else{print STDERR "Sorry, can't find or open $fname \n"; die;} } else{$ifhandle = STDIN; $ofhandle = STDOUT; } $line = 0; $valid_streams = "nhs"; # the (pre)defined streams $active_streams = $valid_streams; # default streams while (<$ifhandle>) { chomp; $line++; $sok = 1; # syntax OK for generic lines $cmd = 0; # storage for possible stream command $this_line = $active_streams; # streams for current line if(m/(^<.*>)/) { # Analyze stream control commands $cmd = $1 ; # store the command $sok = 0; # assume syntax error unless match below if(m/^/) { # define a new stream if(index($valid_streams, $1) < 0) { $valid_streams .= $1; } #print STDERR " valid streams:", $valid_streams, "\n"; $sok++; } # if(m/^/) { # accept a processing command for a stream # @commands($1) = $2; # #print STDERR " Command: $1,$2", "\n"; # $sok++; } if(m/^<\*([a-zA-Z]+)>/){ # set default output $active_streams = $this_line = $1; $sok++;} if(m/^<\*>/){ # set all streams to default output $active_streams = $this_line = $valid_streams; $sok++;} if(m/^<([a-zA-Z]+)>/){ # send this line to specific streams $this_line= $1 ; #print STDERR " current line to: ", $this_line, "\n"; $sok++;} if(m/^<\!([a-zA-Z]+)>/){ # block this line from specific streams $this_line =~ s/$1// ; #print STDERR " current line to: ", $this_line, "\n"; $sok++;} if($sok == 1){ s/(^<.*>)// ; } # clear the command } if($sok == 0) {print STDERR "Coursetex syntax error: [line ", $line, "] ", $_, "\n"; $this_line = 0; } # print STDERR "[", "$this_line", "] ", $_ , "\n" ; if(index($this_line, $st) < 0) # if not in stream { if($q ==0){ #and not quiet mode print $ofhandle "%" ; # comment out lines NOT in this stream if($sok == 1 && $cmd != 0){print $ofhandle $cmd ;} # restore the command if cleared print $ofhandle $_; print $ofhandle "\n"; } } else { # this line is IN the current stream print $ofhandle $_ ; # print the line if($cmd ne 0 ) {print $ofhandle "\t%",$cmd} # tack command onto end as a comment print $ofhandle "\n"; } } close($ofhandle); close($ifhandle); if($te == 1) { system ("latex $fname1\n"); $fnameroot = $fname1; $fnameroot =~ s/\.tex//; # truncate file name if($cl != 0) {system("mv $fnameroot.log junk"); system("mv $fnameroot.aux junk"); #system("mv $fnameroot."); # clean up junk files } } exit 1;