toys & code: bibliography generator
back before easybib supported automation and I was an art history student with around 30 books to cite in an essay, I made a bet with myself that I could create an MLA-adherent bibliography generator based on ISBN numbers faster than I could type it up manually.
being a nerd, I decided to learn about the z39.50 specification for libraries and lost my bet. what eventually resulted was a bibliography generator coded in perl. it takes numbers as an input. the regular expressions aren’t as tidy as they could be, but I was addressing bugs as they came up. it no longer exists in any functional capacity — easybib is superior (if a bit late to the game ;-)
#!/usr/bin/perl
use ZOOM;
use MARC::Record;
use CGI;
print "Content-type: text/html\n\n";
my $q = new CGI;
$numbers = $q->param('numbers');
if($numbers) {
$numbers =~ s/\r//g;
@numbers = split(/\n/, $numbers);
@numbers = grep /./, @numbers; #get rid of empty elements
my @books = get_oclc_data(@numbers);
foreach $book (@books) {
if($book =~ /<u>(.*<u>.*)/) {
$book = $1;
}
print "$book<br/>\n";
}
} else {
#throw an error
}
sub get_oclc_data {
@temp_books = ();
my @isbns = @_;
$host = "fsz3950.oclc.org:210/WorldCat";
$options = new ZOOM::Options();
$options->option(user => "thiswasmyschoollogin");
$options->option(password => "thiswasmyschoolpassword");
$options->option(persistent => 1);
$options->option(piggyback => 1);
$conn = create ZOOM::Connection($options);
$conn->connect($host, 0) || rerr("Error: $!");
foreach $isbn (@isbns) {
$isbn =~ s/[^0-9X]+//ig;
if(length($isbn) < 10) { $isbn = '0' . $isbn; }
$query = "\@attr 1=7 $isbn";
$rs = $conn->search_pqf($query) || rerr("ehh: $!");
$n = $rs->size() || rerr("ohh: $!");
if($n >= 1) {
$rec = $rs->record(0);
$raw = $rec->raw();
$marc = new_from_usmarc MARC::Record($raw);
($author, $title, $subtitle, $pub_place, $pub_name, $pub_date) = get_bib_data($marc);
$author =~ s/(.*)(?:\,|\.)\z/$1/; # kill ending commas or periods for author names
$title =~ s/(.*)\s\/\z/$1/; # kill ending slashes in titles
$title =~ s/(.*)\,\z/$1/; # kill ending commas in titles
if(length($subtitle)>1) {
$title =~ s/(.*?)\s*\:\s*/$1/; # kill the colon in a title if there is a subtitle
$title .= ": "; #append a properly formatted colon
$subtitle =~ s/(.*)\s*\/\z/$1/; # kill ending slashes in subtitles
$subtitle =~ s/(.*)\,\z/$1/; # kill ending commas in subtitles
$title .= $subtitle; # append the subtitle
}
$pub_place =~ s/(.*)(?:\,|\.)/$1/; # kill ending commas or periods for publisher places
$pub_place =~ s/(.*?)\s*\:\s*/$1/; # kill the colon in the place of publication
$pub_place .= ": "; #append a properly formatted colon
$pub_name =~ s/(.*)(?:\,|\.)\z/$1/; # kill ending commas or periods for publisher names
$pub_date =~ s/\D+//g; #kill non-digits in the publication date
$author = trim($author);
$title = trim($title);
$pub_name = trim($pub_name);
$pub_place = trim($pub_place);
$pub_date = trim($pub_date);
my $mla;
if($author) { $mla .= "<u>$author. "; } #u added for sorting
$mla .= "<u>$title</u>. $pub_place $pub_name, $pub_date.";
push(@temp_books, $mla);
} #end if for $n
} # end foreach $isbn
$conn->destroy();
return sort { substr($a,3,length($a)) cmp substr($b,3,length($b)) } @temp_books;
}
sub get_bib_data($marc) {
$marc = shift;
$author = $marc->subfield('100','a');
$title = $marc->subfield('245','a');
$subtitle = $marc->subfield('245','b');
$pub_place = $marc->subfield('260','a');
$pub_name = $marc->subfield('260','b');
$pub_date = $marc->subfield('260','c');
return ($author, $title, $subtitle, $pub_place, $pub_name, $pub_date);
}
sub trim() {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
sub rerr {
my $error = shift;
print $error;
}
