From 3827208cfb07443b7d3ec41268200e9ed5ef5214 Mon Sep 17 00:00:00 2001 From: djfiander Date: Fri, 17 Oct 2008 01:33:49 +0000 Subject: [PATCH] Bare minimum of MFHD parsing code git-svn-id: svn://svn.open-ils.org/ILS/branches/acq-experiment@10857 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm | 58 ++++++++++++++ .../src/perlmods/OpenILS/Utils/MFHD/Caption.pm | 78 +++++++++++++++++++ .../src/perlmods/OpenILS/Utils/MFHD/Holding.pm | 90 ++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100755 Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm create mode 100755 Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm create mode 100755 Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm new file mode 100755 index 0000000000..98a1d1e485 --- /dev/null +++ b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm @@ -0,0 +1,58 @@ +package MFHD; +use strict; +use integer; +use Carp; + +use MARC::Record; +use MFHD::Caption; +use MFHD::Holding; + +sub new { + my $proto = shift; + my $class = ref($proto) || $proto; + my $self = {}; + my $rec = shift; + + $self->{CAPTIONS} = {}; + foreach my $caption ($rec->field('853')) { + my $cap_id; + $cap_id = $caption->subfield('8') || '0'; + if (exists $self->{CAPTIONS}->{$cap_id}) { + carp "Multiple unlabelled MFHD captions"; + } + $self->{CAPTIONS}->{$cap_id} = new MFHD::Caption($caption); + } + + $self->{HOLDINGS} = {}; + foreach my $holding ($rec->field('863')) { + my $linkage; + my ($link_id, $seqno); + + $linkage = $holding->subfield('8'); + ($link_id, $seqno) = split(/\./, $linkage); + + if (!exists $self->{HOLDINGS}->{$link_id}) { + $self->{HOLDINGS}->{$link_id} = {}; + } + $self->{HOLDINGS}->{$link_id}->{$seqno} = + new MFHD::Holding($seqno, $holding, $self->{CAPTIONS}->{$link_id}); + } + + bless ($self, $class); + return $self; +} + +sub captions { + my $self = shift; + + return sort keys %{$self->{CAPTIONS}} +} + +sub holdings { + my $self = shift; + my $capid = shift; + + return sort {$a->{SEQNO} cmp $b->{SEQNO}} values %{$self->{HOLDINGS}->{$capid}}; +} + +1; diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm new file mode 100755 index 0000000000..b1abc20f54 --- /dev/null +++ b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm @@ -0,0 +1,78 @@ +package MFHD::Caption; +use strict; +use integer; +use Carp; + +use MARC::Record; + +sub new +{ + my $proto = shift; + my $class = ref($proto) || $proto; + my $caption = shift; + my $self = {}; + my $last_enum = undef; + + $self->{CAPTION} = $caption; + $self->{ENUMS} = {}; + $self->{CHRONS} = {}; + $self->{PATTERN} = {}; + $self->{COPY} = undef; + $self->{UNIT} = undef; + + foreach my $subfield ($caption->subfields) { + my ($key, $val) = @$subfield; + if ($key eq '8') { + $self->{LINK} = $val; + } elsif ($key =~ /[a-h]/) { + # Enumeration Captions + $self->{ENUMS}->{$key} = {CAPTION => $val, + COUNT => undef, + RESTART => undef}; + if ($key =~ /[ag]/) { + $last_enum = undef; + } else { + $last_enum = $key; + } + } elsif ($key =~ /[i-m]/) { + # Chronology captions + $self->{CHRONS}->{$key} = $val; + } elsif ($key eq 'u') { + # Bib units per next higher enumeration level + carp('$u specified for top-level enumeration') + unless defined($last_enum); + $self->{ENUMS}->{$last_enum}->{COUNT} = $val; + } elsif ($key eq 'v') { + carp '$v specified for top-level enumeration' + unless defined($last_enum); + $self->{ENUMS}->{$last_enum}->{RESTART} = ($val eq 'r'); + } elsif ($key =~ /[npw-z]/) { + # Publication Pattern ('o' == type of unit, 'q'..'t' undefined) + $self->{PATTERN}->{$key} = $val; + } elsif ($key eq 'o') { + # Type of unit + $self->{UNIT} = $val; + } elsif ($key eq 't') { + $self->{COPY} = $val; + } else { + carp "Unknown caption subfield '$key'"; + } + } + + bless ($self, $class); + return $self; +} + +sub caption { + my $self = shift; + my $key; + + if (@_) { + $key = shift; + return $self->{ENUMS}->{$key}->{CAPTION}; + } else { + return $self->{CAPTION}; + } +} + +1; diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm new file mode 100755 index 0000000000..0ce0fe008d --- /dev/null +++ b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm @@ -0,0 +1,90 @@ +package MFHD::Holding; +use strict; +use integer; +use Carp; + +use MARC::Record; + +sub new { + my $proto = shift; + my $class = ref($proto) || $proto; + my $seqno = shift; + my $holding = shift; + my $caption = shift; + my $self = {}; + my $last_enum = undef; + + $self->{SEQNO} = $seqno; + $self->{HOLDING} = $holding; + $self->{CAPTION} = $caption; + $self->{ENUMS} = {}; + $self->{CHRON} = {}; + $self->{DESCR} = {}; + $self->{COPY} = undef; + $self->{BREAK} = undef; + $self->{NOTES} = {}; + $self->{COPYRIGHT} = []; + + foreach my $subfield ($holding->subfields) { + my ($key, $val) = @$subfield; + if ($key =~ /[a-h]/) { + # Enumeration details of holdings + $self->{ENUMS}->{$key} = {HOLDINGS => $val, + UNIT => undef,}; + $last_enum = $key; + } elsif ($key =~ /[i-m]/) { + $self->{CHRON}->{$key} = $val; + if (!exists $caption->{CHRONS}->{$key}) { + carp "Holding specified enumeration level '$key' not included in caption $caption->{LINK}"; + } + } elsif ($key eq 'o') { + carp '$o specified prior to first enumeration' + unless defined($last_enum); + $self->{ENUMS}->{$last_enum}->{UNIT} = $val; + $last_enum = undef; + } elsif ($key =~ /[npq]/) { + $self->{DESCR}->{$key} = $val; + } elsif ($key eq 's') { + push @{$self->{COPYRIGHT}}, $val; + } elsif ($key eq 't') { + $self->{COPY} = $val; + } elsif ($key eq 'w') { + carp "Unrecognized break indicator '$val'" + unless $val =~ /^[gn]$/; + $self->{BREAK} = $val; + } + } + + bless ($self, $class); + return $self; +} + +sub format { + my $self = shift; + my $caption = $self->{CAPTION}; + my $str = ""; + + foreach my $key ('a'..'f') { + last if !exists $caption->{ENUMS}->{$key}; +# printf("fmt %s: '%s'\n", $key, $caption->caption($key)); + + $str .= ($key eq 'a' ? "" : ':') . $caption->caption($key) . $self->{ENUMS}->{$key}->{HOLDINGS}; + } + + if (exists $caption->{ENUMS}->{'g'}) { + # There's at least one level of alternative enumeration + $str .= ' '; + foreach my $key ('g', 'h') { + $str .= ($key eq 'g' ? '' : ':') . $caption->enum($key) . $self->{ENUMS}->{$key}->{HOLDINGS}; + } + } + + return $str; +} + +sub next { + my $self = shift; + my $caption = $self->{CAPTION}; +} + +1; -- 2.11.0