Bare minimum of MFHD parsing code
authordjfiander <djfiander@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Fri, 17 Oct 2008 01:33:49 +0000 (01:33 +0000)
committerdjfiander <djfiander@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Fri, 17 Oct 2008 01:33:49 +0000 (01:33 +0000)
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 [new file with mode: 0755]
Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm [new file with mode: 0755]
Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm [new file with mode: 0755]

diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm
new file mode 100755 (executable)
index 0000000..98a1d1e
--- /dev/null
@@ -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 (executable)
index 0000000..b1abc20
--- /dev/null
@@ -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 (executable)
index 0000000..0ce0fe0
--- /dev/null
@@ -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;