]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm
subfield 'y' (regularity pattern) is repeatable. Need to keep all
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Utils / MFHD / Caption.pm
1 package MFHD::Caption;
2 use strict;
3 use integer;
4 use Carp;
5
6 use MARC::Record;
7
8 sub new
9 {
10     my $proto = shift;
11     my $class = ref($proto) || $proto;
12     my $caption = shift;
13     my $self = {};
14     my $last_enum = undef;
15
16     $self->{CAPTION} = $caption;
17     $self->{ENUMS} = {};
18     $self->{CHRONS} = {};
19     $self->{PATTERN} = {};
20     $self->{COPY} = undef;
21     $self->{UNIT} = undef;
22     $self->{COMPRESSIBLE} = 1;  # until proven otherwise
23
24     foreach my $subfield ($caption->subfields) {
25         my ($key, $val) = @$subfield;
26         if ($key eq '8') {
27             $self->{LINK} = $val;
28         } elsif ($key =~ /[a-h]/) {
29             # Enumeration Captions
30             $self->{ENUMS}->{$key} = {CAPTION => $val,
31                                       COUNT => undef,
32                                       RESTART => undef};
33             if ($key =~ /[ag]/) {
34                 $last_enum = undef;
35             } else {
36                 $last_enum = $key;
37             }
38         } elsif ($key =~ /[i-m]/) {
39             # Chronology captions
40             $self->{CHRONS}->{$key} = $val;
41         } elsif ($key eq 'u') {
42             # Bib units per next higher enumeration level
43             carp('$u specified for top-level enumeration')
44               unless defined($last_enum);
45             $self->{ENUMS}->{$last_enum}->{COUNT} = $val;
46         } elsif ($key eq 'v') {
47             carp '$v specified for top-level enumeration'
48               unless defined($last_enum);
49             $self->{ENUMS}->{$last_enum}->{RESTART} = ($val eq 'r');
50         } elsif ($key =~ /[npwxz]/) {
51             # Publication Pattern ('o' == type of unit, 'q'..'t' undefined)
52             $self->{PATTERN}->{$key} = $val;
53         } elsif ($key eq 'y') {
54             # Publication pattern: 'y' is repeatable
55             $self->{PATTERN}->{y} = [] if (!defined $self->{PATTERN}->{y});
56             push @{$self->{PATTERN}->{y}}, $val;
57         } elsif ($key eq 'o') {
58             # Type of unit
59             $self->{UNIT} = $val;
60         } elsif ($key eq 't') {
61             $self->{COPY} = $val;
62         } else {
63             carp "Unknown caption subfield '$key'";
64         }
65     }
66
67     # subsequent levels of enumeration (primary and alternate)
68     # If an enumeration level doesn't document the number
69     # of "issues" per "volume", or whether numbering of issues
70     # restarts, then we can't compress.
71     foreach my $key ('b', 'c', 'd', 'e', 'f', 'h') {
72         if (exists $self->{ENUMS}->{$key}) {
73             my $pattern = $self->{ENUMS}->{$key};
74             if (!$pattern->{RESTART} || !$pattern->{COUNT}
75                 || ($pattern->{COUNT} eq 'var')
76                 || ($pattern->{COUNT} eq 'und')) {
77                 $self->{COMPRESSIBLE} = 0;
78                 last;
79             }
80         }
81     }
82
83     # If there's a $x subfield and a $j, then it's compressible
84     if (exists $self->{PATTERN}->{x} && exists $self->{CHRONS}->{'j'}) {
85         $self->{COMPRESSIBLE} = 1;
86     }
87
88     bless ($self, $class);
89
90     if (exists $self->{PATTERN}->{y}) {
91         $self->decode_pattern;
92     }
93
94     return $self;
95 }
96
97 sub decode_pattern {
98     my $self = shift;
99     my $pattern = $self->{PATTERN}->{y};
100 }
101
102 sub compressible {
103     my $self = shift;
104
105     return $self->{COMPRESSIBLE};
106 }
107
108 sub caption {
109     my $self = shift;
110     my $key;
111
112     if (@_) {
113         $key = shift;
114         if (exists $self->{ENUMS}->{$key}) {
115             return $self->{ENUMS}->{$key}->{CAPTION};
116         } elsif (exists $self->{CHRONS}->{$key}) {
117             return $self->{CHRONS}->{$key};
118         } else {
119             return undef;
120         }
121     } else {
122         return $self->{CAPTION};
123     }
124 }
125
126 # If items are identified by chronology only, with no separate
127 # enumeration (eg, a newspaper issue), then the chronology is
128 # recorded in the enumeration subfields $a - $f.  We can tell
129 # that this is the case if there are $a - $f subfields and no
130 # chronology subfields ($i-$k), and none of the $a-$f subfields
131 # have associated $u or $v subfields, but there are $w and $y
132 # subfields.
133
134 sub enumeration_is_chronology {
135     my $self = shift;
136
137     # There is always a '$a' subfield in well-formed fields.
138     return 0 if exists $self->{CHRONS}->{i};
139
140     foreach my $key ('a' .. 'f') {
141         my $enum;
142
143         last if !exists $self->{ENUMS}->{$key};
144
145         $enum = $self->{ENUMS}->{$key};
146         return 0 if defined $enum->{COUNT} || defined $enum->{RESTART};
147     }
148
149     return (exists $self->{PATTERN}->{w} && exists $self->{PATTERN}->{y});
150 }
151
152 1;