jeremy tribby | bibliography generator

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;
}