#!/usr/bin/perl -w
#
# footnotes in perl
# using two pass approach
#
# copyright 2008 by Andreas Romeyke (fa.romeyke@web.de)
#
# 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";
