10 use base 'MARC::Field';
14 my $class = ref($proto) || $proto;
18 my $last_enum = undef;
20 $self->{_mfhdh_SEQNO} = $seqno;
21 $self->{_mfhdh_CAPTION} = $caption;
22 $self->{_mfhdh_DESCR} = {};
23 $self->{_mfhdh_COPY} = undef;
24 $self->{_mfhdh_BREAK} = undef;
25 $self->{_mfhdh_NOTES} = {};
26 $self->{_mfhdh_COPYRIGHT} = [];
28 foreach my $subfield ($self->subfields) {
29 my ($key, $val) = @$subfield;
31 if (($caption && $caption->enumeration_is_chronology && $key =~ /[a-h]/) || $key =~ /[i-m]/) {
33 $self->{_mfhdh_SUBFIELDS}->{$key} = $val;
34 } elsif ($key =~ /[a-h]/) {
35 # Enumeration details of holdings
36 $self->{_mfhdh_SUBFIELDS}->{$key} = {HOLDINGS => $val,
39 } elsif ($key =~ /[i-m]/) {
40 } elsif ($key eq 'o') {
41 warn '$o specified prior to first enumeration'
42 unless defined($last_enum);
43 $self->{_mfhdh_SUBFIELDS}->{$last_enum}->{UNIT} = $val;
45 } elsif ($key =~ /[npq]/) {
46 $self->{_mfhdh_DESCR}->{$key} = $val;
47 } elsif ($key eq 's') {
48 push @{$self->{_mfhdh_COPYRIGHT}}, $val;
49 } elsif ($key eq 't') {
50 $self->{_mfhdh_COPY} = $val;
51 } elsif ($key eq 'w') {
52 carp "Unrecognized break indicator '$val'"
53 unless $val =~ /^[gn]$/;
54 $self->{_mfhdh_BREAK} = $val;
58 bless ($self, $class);
65 return $self->{_mfhdh_SEQNO};
71 return $self->{_mfhdh_CAPTION};
76 my $caption = $self->{_mfhdh_CAPTION};
79 my %month = ( '01' => 'Jan.', '02' => 'Feb.', '03' => 'Mar.',
80 '04' => 'Apr.', '05' => 'May ', '06' => 'Jun.',
81 '07' => 'Jul.', '08' => 'Aug.', '09' => 'Sep.',
82 '10' => 'Oct.', '11' => 'Nov.', '12' => 'Dec.',
83 '21' => 'Spring', '22' => 'Summer',
84 '23' => 'Autumn', '24' => 'Winter' );
87 foreach my $i (0 .. @keys) {
93 last if !defined $caption->capstr($key);
95 $capstr = $caption->capstr($key);
96 if (substr($capstr,0,1) eq '(') {
97 # a caption enclosed in parentheses is not displayed
101 # If this is the second level of chronology, then it's
102 # likely to be a month or season, so we should use the
103 # string name rather than the number given.
104 if (($i == 1) && exists $month{$self->{_mfhdh_SUBFIELDS}->{$key}}) {
105 $chron = $month{$self->{_mfhdh_SUBFIELDS}->{$key}};
107 $chron = $self->{_mfhdh_SUBFIELDS}->{$key};
111 $str .= (($i == 0 || $str =~ /[. ]$/) ? '' : ':') . $capstr . $chron;
119 my $caption = $self->{_mfhdh_CAPTION};
122 if ($caption->enumeration_is_chronology) {
123 # if issues are identified by chronology only, then the
124 # chronology data is stored in the enumeration subfields,
125 # so format those fields as if they were chronological.
126 $str = $self->format_chron('a'..'f');
128 # OK, there is enumeration data and maybe chronology
129 # data as well, format both parts appropriately
132 foreach my $key ('a'..'f') {
137 last if !defined $caption->capstr($key);
139 $capstr = $caption->capstr($key);
140 if (substr($capstr, 0, 1) eq '(') {
141 # a caption enclosed in parentheses is not displayed
144 $str .= ($key eq 'a' ? '' : ':') . $capstr . $self->{_mfhdh_SUBFIELDS}->{$key}->{HOLDINGS};
148 if (defined $caption->capstr('i')) {
150 $str .= $self->format_chron('i'..'l');
154 if ($caption->capstr('g')) {
155 # There's at least one level of alternative enumeration
157 foreach my $key ('g', 'h') {
158 $str .= ($key eq 'g' ? '' : ':') . $caption->capstr($key) . $self->{_mfhdh_SUBFIELDS}->{$key}->{HOLDINGS};
161 # This assumes that alternative chronology is only ever
162 # provided if there is an alternative enumeration.
163 if ($caption->capstr('m')) {
164 # Alternative Chronology
166 $str .= $caption->capstr('m') . $self->{_mfhdh_SUBFIELDS}->{m}->{HOLDINGS};
173 $str .= ' '. $caption->capstr('z') if (defined $caption->capstr('z'));
175 # Breaks in the sequence
176 if (defined($self->{_mfhdh_BREAK})) {
177 if ($self->{_mfhdh_BREAK} eq 'n') {
178 $str .= ' non-gap break';
179 } elsif ($self->{_mfhdh_BREAK} eq 'g') {
182 warn "unrecognized break indicator '$self->{_mfhdh_BREAK}'";
190 # next: Given a holding statement, return a hash containing the
191 # enumeration values for the next issues, whether we hold it or not
192 # Just pass through to Caption::next
196 my $caption = $self->{_mfhdh_CAPTION};
198 return $caption->next($self);
201 # match($pat): check to see if $self matches the enumeration passed
202 # in as $pat. This is expected to be used in conjunction with the next()
203 # function defined above.
210 my $caption = $self->{_mfhdh_CAPTION};
212 foreach my $key ('a'..'f') {
216 # If the next smaller enumeration exists, and is numbered
217 # continuously, then we don't need to check this one, because
218 # gaps in issue numbering matter, not changes in volume numbering
219 next if (exists $self->{_mfhdh_SUBFIELDS}->{$nextkey}
220 && !$caption->capfield($nextkey)->{RESTART});
222 # If a subfield exists in $self but not in $pat, or vice versa
223 # or if the field has different values, then fail
224 if (exists($self->{_mfhdh_SUBFIELDS}->{$key}) != exists($pat->{$key})
225 || (exists $pat->{$key}
226 && ($self->{_mfhdh_SUBFIELDS}->{$key}->{HOLDINGS} ne $pat->{$key}))) {
234 # Check that all the fields in a holdings statement are
235 # included in the corresponding caption.
240 foreach my $key (keys %{$self->{_mfhdh_SUBFIELDS}}) {
241 if (!($self->{_mfhdh_CAPTION}) && $self->{_mfhdh_CAPTION}->capfield($key)) {