next up previous contents
Up: No Title Previous: C Listing zum Wrapper

D Listing zu makebib

#!/usr/local/dist/bin/perl
# 
# Dieses Programm sucht alle Literaturverweise in saemtlichen
# LaTeX Dateien des aktuellen Verzeichnisses. Anhand der
# Environment-Variable $BIBINPUTS findet es die dazugehoerigen
# *.bib Dateien und erzeugt eine neue Bibliotheksdatei mit Namen
# main.bib im aktuellen Verzeichnis. Falls hier eine solche Datei
# schon existiert, so kann man den Namen der neuen Bibliotheksdatei
# dem Programm auch als Switch mitgeben.


## Argumente bearbeiten
## Aktuelle Kommandozeilenparameter in $argv ablegen
$argv = join(' ',@ARGV);

## Versionsnummer, Patchlevel und Erscheinungsdatum
$PATCHLEVEL = "1a";
$VERSION = "97";
$RELDATE = "(Sep 29, 1997)";

$MakebibV_SHORT = $VERSION . '.' . "$PATCHLEVEL";
$MakebibVERSION = $MakebibV_SHORT . ' ' . $RELDATE;

## Hinweise zum Author
$AUTHORADDRESS =
   "http://www.informatik.tu-muenchen.de/~allgeyer/index.html";

## Name der neuen *.bib Datei
$newbibfile = "main.bib";

## Parameter aufloesen
while ($ARGV[0] =~ /^-/)
   {
   $_ = shift;
   ## Debugging gewuenscht
   if (/^-debug$/)
      {
      $DEBUG = 1;
      }
   ## -newbibfile (file) wurde spezifiziert:
   elsif (/^-newbibfile$/)
      {
      $_ = shift;
      ((($newbibfile) = /^(.+)$/) ||
      print "\nUnrecognised value for -newbibfile: $_\n" &&
      &usage && die);
      }
   ## -h(elp) wurde eingegeben:
   elsif (/^-h(elp)?$/)
      {
      &usage;
      exit 0;
      }
   ## Kein bekannter Parameter?
   else
      {
      &usage;
      die "Unrecognised switch: $_\n";
      }
   ## end (if)
   }
## end (while)

## Hole $HOME aus der Environment Variable
## und erweitere @INC damit
push(@INC,$ENV{'HOME'});
$HOME = $ENV{'HOME'};

## Statusausgabe
print "Running \'makebib.pl $argv\': ..";

## Hole $BIBINPUTS aus der Environment Variable
if ( $ENV{'BIBINPUTS'} eq '' )
   {
   $BIBINPUTS = '.';
   }
else
   {
   $BIBINPUTS = $ENV{'BIBINPUTS'};
   }
## end (if)

## Aktuelles Verzeichnis nach LaTeX Dateien durchsuchen
@texfiles = glob ("*.tex");

foreach $texfile (@texfiles)
   {
   ## Debugging:
   print "\nTexfile found: $texfile\n" if $DEBUG;

   &search_cite ($texfile);
   &search_bibliography ($texfile);
   }

## Suchpfad aus $BIBINPUTS setzen
@searchpath = split /:/, $BIBINPUTS;

## In jedem Verzeichnis aus $BIBINPUTS
foreach $dir (@searchpath)
   {
   opendir (THISDIR, $dir);
      
      ## extrahiere alle *.bib Dateien
      @allbibfiles = grep /.*\.bib/, map "$dir/$_", readdir THISDIR;

      ## und suche diejenigen heraus, auf die im
      ## vorliegenden Dokument Bezug genommen wird.
      foreach $file (@bibliographylist)
         {
         @bibfiles = (@bibfiles, grep /${file}\.bib$/, @allbibfiles);
         }  
      ## end (foreach)  
   
   closedir (THISDIR);
   }
## end (foreach)

## Debugging:
print "\nBibfiles: @bibfiles\n" if $DEBUG;

## Neuen Bibfile-Hash erstellen
foreach $bibfile (@bibfiles)
   {
   &make_bibfile_hash ($bibfile);
   }

# Statusausgabe
print "\n\n$index entries of bibliography found in all LaTeX-files.\n";
print "Can assign them $index2 entries ";
print "of bibliography found in all the BibTeX-files.\n";

if ( $index2 > $index )
   {
   print "\nMaybe there are double entries in the BibTeX-files!\n";
   print "So I'll only put $index entries of bibliography into";
   print "$newbibfile!\n";
   }
## end (if)

## Neues Bibfile ausgeben
&make_new_bibfile;

## Statusmeldung
print "\nDone.\n";


##########################################
##   Unterprogramme                     ##
##########################################
sub make_bibfile_hash
   {
   ## Statusausgabe
   print "..";

   local($bibfile) = @_;
   local($cite);

   open (BIBFILE, $bibfile) || die ("Kann $bibfile nicht lesen!\n");
      LINE: while (<BIBFILE>)
         {
         if (/\@\w+\s*\{\s*(\S*)\s*,\s*/)   ## @MasterThesis, @Book ...
            {                               ## gefunden!
            CITE: foreach $cite (@citelist) ## Durchlaufe alle Lit.-
               {                            ## Verweise und schaue, ob
               next CITE if ($cite ne $1);  ## die gesuchte dabei ist. 

               $newcitelist{$cite} = $_;  ## Gesuchter Literaturverweis
               $index2++;                 ## vorhanden! Speichere ihn   
                                          ## erhoehe Index2.
               while (<BIBFILE>)          ## Fuege alle weiteren Zeilen
                  {                       ## bis zur naechsten Typangabe 
                  if (/\@/)               ## (bspw. @Book, ...) hinzu
                     {
                     ## Debugging
                     print "\nCite_elem: $newcitelist{$cite}\n" if $DEBUG;

                     redo LINE;           ## und gehe zurueck.
                     }
                  else
                     {
                     s/%.*//;             ## Sonst entferne Kommentare
                     s/^\s*\n$//;         ## und Leerzeichen und
                                          ## fuege aktuelle Zeile an.      
                     $newcitelist{$cite} .= $_; 
                     }
                  ## end (if)
                  }
               ## end (while)
               }
            ## end (foreach)
            }
         ## end (if)
         }
      ## end (while)

   close (BIBFILE);
   }
## end (sub make_bibfile_hash)


sub search_cite
   {
   ## Statusausgabe
   print "..";
   
   local($texfile) = @_;
   
   open (TEXFILE, $texfile)   || die ("Can't read $texfile!\n");
      LINE: while (<TEXFILE>)
         {
         while (m/\\cite\{(\S*)\}/g)            ## Suche nach \cite{(...)}
            {
            @tempcitelist = (split /,/, $1);    ## Erzeuge Referenzliste
               
            foreach $tempcite (@tempcitelist)   ## Fuer jede Referenz
               {                                ## in der Referenzliste:
               foreach $cite (@citelist)        ## Durchlaufe jedes
                  {                             ## Listenelement,
                  next LINE if ($cite eq $tempcite);  ## ueberpruefe, ob
                  }                             ## Listeneintrag $tempcite
               ## end (foreach)                 ## schon in der Liste
                                                ## @citelist vorhanden ist
               
               @citelist = (@citelist, $tempcite);    ## Wenn nicht, dann
               $index++;                              ## erhoehe Index und
               }                                      ## nehme $tempcite in
            ## end (foreach)                          ## @citelist auf.
            }
         ## end (if)
         }
      ## end (while)
      
   close (TEXFILE);
   
   ## Debugging
   print "Citelist: @citelist\n\n" if $DEBUG;
   }
## end (sub search_cite)



sub make_new_bibfile
   {
   ## Abfrage, wenn main.bib schon vorhanden
   print "\n$newbibfile still exists. Continue (y/n)? " and
   &yes_no if -e "$newbibfile";
   
   ## Leerzeile
   print "\n";

   ## Ueberschreiben? Ja, dann lege ein neues File an.
   open (NEWBIBLIST, ">$newbibfile");
   close (NEWBIBLIST);

   ## Setze $index zurueck
   $index = 0;

   ## Statusausgabe
   print "Following entries will be added:\n";
   print "--------------------------------\n";

   ## Sortierte Ausgabe aller BibTeX-Eintraege
   ## Fuer jeden Wert im Hash %newcitelist
   foreach $newcite (sort keys(%newcitelist))
      {
      ## Erhoehe index
      $index++;

      ## Statusausgabe
      printf "%4d) %s\n", $index, $newcite;

      ## Neue main.bib Datei erstellen
      open (NEWBIBLIST, ">>$newbibfile");
         print NEWBIBLIST ("$newcitelist{$newcite}\n");
      close (NEWBIBLIST);
      }
   }
## end (sub make_new_bibfile)


sub search_bibliography
   {
   ## Statusausgabe
   print "..";

   local($texfile) = @_;
   
   open (TEXFILE, $texfile) ||
   die ("Kann $texfile nicht lesen!\n");

   LINE: while (<TEXFILE>)
      {
      if (/\\bibliography\{([\w\s,]*)\}/g) ## Suche nach
         {                                 ## \bibliography{(...)}
         ## Gefundenen String splitten und
         ## der Bibliographieliste anhaengen.
         @bibliographylist = (@bibliographylist, split /,/, $1);

         ## Debugging
         print "\nBibliographylist: @bibliographylist\n" if $DEBUG;
         }
      ## end (if)
      }
   ## end (while)

   close (TEXFILE);
   }
## end (sub search_bibliography)


## Abfrage nach Ja oder Nein
sub yes_no
   {
   ## Akzepiere eingegebene Zeichenkette nur,
   ## wenn 'Y' oder 'y' eingegeben wurde.
   $ans = <stdin>;
   return if $ans =~ /^[Yy]$/;
   
   ## Falsche Taste erwischt oder Unsinn eingegeben?
   if ($ans !~ /^[Nn]$/)
      {
      print "Please type Y,y or N,n! (y,n)? " and &yes_no; 
      }
   else
      {
      ## Statusausgabe
      print "\nQuit!\n";

      exit 1;
      }
   ## end (if)
   }
## end (sub yes_no)


## Eingabe Fehler
sub usage
   {                     
   print <<EOF;
This is Makebib Version $MakebibVERSION by Peter Allgeyer,
Institut fuer Informatik, Technical University of Munich.

Usage: makebib.pl
   [-newbibfile <file>]
   [-debug]
   [-h(elp)]

EOF
   }
## end (sub usage)



Copyright Munich Network Management Team