#!/usr/bin/perl -w
#-------------------------------------------------------------------------------
# footnote.pl (C) 2008 T.Birnthaler OSTC GmbH
# $Id: footnote.pl,v 1.6 2008/09/03 14:58:34 tsbirn Exp tsbirn $
#-------------------------------------------------------------------------------
# Numerierte Fussnoten-Verweise der Form "[N]" eines beliebig langen Textes
# in der Reihenfolge des Vorkommens im Text neu von 1..n durchnummerieren.
# Die Zeilen der Form "[N] TEXT" mit neuer Fussnotennummer + Fussnotentext nach
# dem Schlüsselwort "@footnote:" aufsteigend sortiert ausgeben.
#
# Folgende Fehler werden erkannt:
# 1) Zu Verweisnummer im Text gibt es keine Nummer in Fussnotenliste.
# 2) Nummer in Fussnotenliste kommt mehrfach vor.
# 3) Zu Nummer in Fussnotenliste gibt es keine Verweisnummer im Text
# (überflüssiger Fussnoteneintrag).
# 4) Fussnoteneintrag nicht in Form "[N] TEXT" (ungültig)
#-------------------------------------------------------------------------------
# Beispiel:
# Text mit Verweis [123]
# Text [5] mit Verweis [1]
# ...
# Text mit Verweis [123]
# Text [5] mit Verweis [1]
# @footnote:
# [123] Dies ist der Fussnotentext 1
# [1] Dies ist der Fussnotentext 2
# [5] Dies ist der Fussnotentext 3
#-------------------------------------------------------------------------------
use strict;
my $dbg = 0;
my %footnote_map = ();
my $textline_cnt = 0;
my @footnote_text = ();
my $new_nr = 0;
#-------------------------------------------------------------------------------
# Text zeilenweise einlesen, jede Zeile SOFORT mit aufsteigenden numerierten
# Fussnotennummern wieder ausgeben
#-------------------------------------------------------------------------------
print STDERR "READING TEXT..." if ($dbg);
while (<>)
{
last if (/^\@footnote:$/);
++$textline_cnt;
print STDERR "TEXT: $_" if ($dbg);
# Alle neuen Verweise in Zeile mit aufsteig. Nummer neu numeriert merken
while (/\[(\d+)\]/g)
{
$footnote_map{$1} = ++$new_nr if (not defined($footnote_map{$1}));
print STDERR "MAP: $1 => $footnote_map{$1}\n" if ($dbg);
}
# Alle Verweise in Zeile durch passende aufsteig. nummerierte ersetzen
s/\[(\d+)\]/[$footnote_map{$1}]/g;
print $_;
}
# Trennzeile "@footnote:" ausgeben
print $_;
print STDERR "TEXT LINES: $textline_cnt\n" if ($dbg);
print STDERR "SEPLINE: $_\n" if ($dbg);
print STDERR "NEW: $new_nr new footnote numbers\n" if ($dbg);
#-------------------------------------------------------------------------------
# Fussnoten einlesen, alte Nummer in neue konvertieren und merken.
#-------------------------------------------------------------------------------
print STDERR "READING FOOTNOTES..." if ($dbg);
while (<>)
{
print STDERR "FOOT: $_" if ($dbg);
# Zeilen nicht im Format "[N] TEXT" überspringen
# ERROR 4: Fussnoteneintrag nicht in Form "[N] TEXT" (ungültig)
if (not /^\[(\d+)\]\s+\S/)
{
warn("ERR(4): footnote entry wrong format '$_'\n");
next;
}
# Zeile mit Format "[N] TEXT" zerlegen in N + TEXT
my ($nr, $text) = /^\[(\d+)\]\s+(.*)/s;
# ERROR 3: Zu Nummer in Fussnotenliste gibt es keine Verweisnummer im Text
# (überflüssiger Fussnoteneintrag).
if (not defined $footnote_map{$nr}) {
warn("ERR(3): [$nr] not used in text\n");
next;
}
# ERROR 2: Nummer in Fussnotenliste kommt mehrfach vor.
elsif (defined $footnote_text[$footnote_map{$nr}]) {
warn("ERR(2): [$nr] used more than once in footnote list\n");
}
# Text zu neuer Fussnotennummer merken
$footnote_text[$footnote_map{$nr}] = $text;
}
print STDERR "FOOT: ", scalar @footnote_text - 1, " footnotes found\n" if ($dbg);
#-------------------------------------------------------------------------------
# Fussnoten aufsteigend sortiert nach Nummer ausgeben
#-------------------------------------------------------------------------------
foreach my $nr (1 .. scalar @footnote_text)
{
print "[", $nr, "] ", $footnote_text[$nr]
if (defined $footnote_text[$nr]);
}
# ERROR 1: Zu Verweisnummer im Text gibt es keine Nummer in Fussnotenliste.
while (my ($old_nr, $new_nr) = each %footnote_map)
{
warn("ERR(1): missing [$old_nr] in footnote list\n")
if (not defined $footnote_text[$new_nr]);
}