#!/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