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