#!/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]); }