#!/usr/bin/perl use Text::Tabs; use Getopt::Std; use strict; my $default_ov_env='visibleenv'; my %options; getopts('c:k:s:S',\%options); my $strip_spaces=$options{s} || 0; my $commentstr=$options{c}; if (!defined($commentstr)){ print STDERR "usage: $0 -c commentstr [options]\n"; exit 1; } my $keep_all = 1; my %keep=(); my %current=(); $keep{comment}=0; $keep{omit}=0; my $keep_list=$options{k}; if (defined($keep_list)){ my @sections=split(",", $keep_list); map { $keep{$_} =1; $current{$_}=0; } @sections; $keep_all=0; } sub maybe_print{ my $string=shift; my $skip=0; my $match=$keep_all; if (!$match){ map { $match += ( $current{$_} && $keep{$_} ); } keys %keep; } map { $skip += ( $current{$_} && !$keep{$_} ); } keys %keep; if (!$skip && $match){ $string = expand $string; $string =~ s/^[ ]{$strip_spaces}//; print $string; } } my %overlayenv = ( 'u' => 'uncoverenv', 'v' => 'visibleenv', 's' => 'version' ); my $regex=qr{ ^ \s* \Q$commentstr\E \s* \@ ([<>()\:]) \s* ([a-zA-Z_]*)(.*)$ }x; my @ov_stack=(); my @sec_stack=(); LINE: while(<>){ if (m/$regex/){ if (!defined($options{S})){ my $op = $1; my @args = ($2,$3); my ($env,$envarg); if ($op eq ':') { maybe_print($commentstr.'@highlight \hspace*{2em}$\vdots$\\\\'."\n"); } elsif ($op eq '<') { $env = $args[0] ? $overlayenv{$args[0]} : $default_ov_env; $envarg = $args[1] ? '<'.$args[1].'>' : '<+->'; maybe_print(sprintf $commentstr.'@highlight\\\\begin{%s}%s'."\n",$env,$envarg); push (@ov_stack,$env); } elsif ($op eq '('){ $env = $2; $current{$env}=1; push(@sec_stack,$env) } elsif ($op eq '>') { maybe_print(sprintf $commentstr.'@highlight\\\\end{%s}'."\n",pop(@ov_stack)); } elsif ($op eq ')') { $current{pop(@sec_stack)}=0; } } } else { maybe_print($_); } }; =head1 NAME hl-beamer - Preprocessor for hightlight to generate beamer overlays. =head1 SYNOPSIS =over =item B<hl-beamer> -c // InstructiveExample.java | highlight -S java -O latex > figure1.tex =back =head1 DESCRIPTION B<hl-beamer> looks for single line comments (with syntax specified by B<-c>) These comments can start with B<@> followed by some codes to specify beamer overlays or sections (just chunks of text which can be selectively included). =head1 OPTIONS =over =item B<-c> F<commentstring> Start of single line comments =item B<-k> F<section1,section2> List of sections to keep (see B<@(> below). =item B<-s> F<number> strip F<number> spaces from the front of every line (tabs are first converted to spaces using Text::Tabs::expand) =item B<-S> strip all directive comments. =back =head1 CODES =over =item B<@(> F<section> named section. Can be nested. Pass -k F<section> to include in output. The same name can (usefully) be re-used. Sections B<omit> and B<comment> are omitted by default. =item B<@)> close most recent section. =item B<@<> [F<overlaytype>] [F<overlayspec>] define a beamer overlay. F<overlaytype> defaults to visibleenv if not specified. F<overlayspec> defaults to B<+-> if not specified. =item B<@>> close most recent overlay =back =head1 EXAMPLE Example input follows. I would probably process this with =over =item hl-beamer -s 4 -k encodeInner =back =head2 Sample Input // @( omit import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.Serializable; import java.util.Scanner; // @) // @( encoderInner private int findRun(int inRow, int startCol){ // @< int value=bits[inRow][startCol]; int cursor=startCol; // @> // @< while(cursor<columns && bits[inRow][cursor] == value) //@< cursor++; //@> // @> // @< return cursor-1; // @> } // @) =head1 BUGS AND LIMITATIONS Currently F<overlaytype> and F<section> must consist of upper and lower case letters and or underscores. This is basically pure sloth on the part of the author. =head1 SEE ALSO B<highlight>, B<pdflatex> =head1 LICENSE Copyright (C) 2011 by David Bremner This script is free software; you can redistribute it and/or modify it under the terms of either: =over =item a) the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version, or =item b) the "Artistic License", version 2 or later. =back