#!/usr/bin/perl -w
#
# footnotes in perl
# using two pass approach
#
# copyright 2008 by Andreas Romeyke (
[email protected])
#
# Competition of Linux Magazine 2008-10 to write a footnote sorter
# in different languages.
#
# call "perl footnotes2.pl infile outfile outfile2"
#
# the first outfile contains the text with footnotes in ordered, the second in used order
#
# the script detects errors in indexing, print and ignores them ("[43242]" will be replaced by "").
#
use strict;
my $INPUT; my $infile;
my $fh; my $filenames;
my %hash;
my $regex=qr/\[\d+\]/;
if (@ARGV != 3) {die "\nwrong count of arguments,\ncall 'perl footnotes2.pl infile outfile outfile2'\n";}
($infile,$filenames->{'ordered'},$filenames->{'used'})=@ARGV;
select STDOUT; $| = 1; # make unbuffered
select STDERR; $| = 1; # make unbuffered
sub sopen ($) {
my $part=$_[0];
open ($fh->{$part}, '>', $filenames->{$part}) || die "can't open $filenames->{'$part'}:$!";
}
sub sclose ($) {
my $part=$_[0];
close($fh->{$part}) || die "can't close $filenames->{'$part'}:$!";
}
sub subst ($$) { # lookup function, needed to add warnings if something wrong
my ($part, $key)=@_;
my $value = $hash{$part}{$key};
if (!defined $value) {print STDERR "Index $key not found in $part part\n"; return ""; }
return $value;
}
sub process_line ($$) { # processes line and print result to special output
my ($part, $line) = @_;
my $FH=$fh->{$part};
$line=~s/($regex)/subst($part,$1)/ge;
print $FH $line;
}
# pass 1, read file in, create index hash
print "Pass 1...";
open ($INPUT, $infile) || die "can’t open $infile: $!";
{
my $part = 'used';
while (<$INPUT>) {
if ($part eq 'used' && (/^\@footnotes:$/)) { $part='ordered'};
map {
$hash{$part}{$_} = "[".((keys %{$hash{$part}})+1)."]"
} grep {
$_=~/^$regex/
} split (/($regex)/);
}
}
close($INPUT) || die "can’t close $infile: $!";
# pass 2, read file in, replace index and write out
print "\nPass 2...";
open ($INPUT, '<', $infile) || die "can’t open $infile: $!";
sopen('ordered'); sopen('used');
while (<$INPUT>) {
process_line('ordered', $_);
process_line('used', $_);
}
sclose('ordered'); sclose('used');
close($INPUT) || die "can’t close $infile: $!";
print "\ndone.\n";