my $pat = $self->{_mfhdc_PATTERN};
- # Sanity check publication frequency vs publication pattern:
- # if the frequency is a number, then the pattern better
- # have that number of values associated with it.
- if ( exists($pat->{w})
- && ($pat->{w} =~ /^\d+$/)
- && ($pat->{w} != scalar(@{$pat->{y}->{p}}))) {
- carp(
-"Caption::new: publication frequency '$pat->{w}' != publication pattern @{$pat->{y}->{p}}"
- );
- }
-
# If there's a $x subfield and a $j, then it's compressible
if (exists $pat->{x} && exists $self->{_mfhdc_CHRONS}->{'j'}) {
$self->{_mfhdc_COMPRESSIBLE} = 1;
my $freq = $pattern->{w};
foreach my $i (0..$#keys) {
- $cur[$i] = $next->{$keys[$i]} if exists $next->{$keys[$i]};
+ if (exists $next->{$keys[$i]}) {
+ $cur[$i] = $next->{$keys[$i]};
+ # If the current issue has a combined date (eg, May/June)
+ # get rid of the first date and base the calculation
+ # on the final date in the combined issue.
+ $cur[$i] =~ s|^[^/]+/||;
+ }
}
- # If the current issue has a combined date (eg, May/June)
- # get rid of the first date and base the calculation
- # on the final date in the combined issue.
- $cur[-1] =~ s|^[^/]+/||;
-
if (defined $pattern->{y}->{p}) {
# There is a $y publication pattern defined in the record:
# use it to calculate the next issue date.
($start, $end) = (undef, undef);
}
- @candidate = $genfunc->($start || $pat, @cur);
+ @candidate = $genfunc->($start || $pat, \@cur, $self);
while ($self->is_omitted(@candidate)) {
# printf("# pubpat omitting date '%s'\n",
# join('/', @candidate));
- @candidate = $genfunc->($start || $pat, @candidate);
+ @candidate = $genfunc->($start || $pat, \@candidate, $self);
}
# printf("# testing new candidate '%s' against '%s'\n",
# @candidate is the next issue.
@new = @candidate;
if (defined $end) {
- @newend = $genfunc->($end, @cur);
+ @newend = $genfunc->($end, \@cur, $self);
} else {
$newend[0] = undef;
}
}
}
+ $new[1] = 24 if ($new[1] == 20); # restore fake early winter
+
if (defined($newend[0])) {
# The best match was a combined issue
foreach my $i (0..$#new) {
if ($self->is_combined(@new)) {
my @second_date = MFHD::Date::incr_date($freq, @new);
-
- # I am cheating: This code assumes that only the smallest
- # time increment is combined. So, no "Apr 15/May 1" allowed.
- $new[-1] = $new[-1] . '/' . $second_date[-1];
+ foreach my $i (0..$#new) {
+ # don't combine identical fields
+ next if $new[$i] eq $second_date[$i];
+ $new[$i] .= '/' . $second_date[$i];
+ }
}
}
}
for my $i (0..$#new) {
$next->{$keys[$i]} = $new[$i];
}
+
# Figure out if we need to adjust volume number
- # right now just use the $carry that was passed in.
- # in long run, need to base this on ($carry or date_change)
- if ($carry) {
- # if $carry is set, the date doesn't matter: we're not
- # going to increment the v. number twice at year-change.
+ #
+ # If we are incrementing based on date, $carry doesn't
+ # matter: we're not going to increment the v. number twice
+ #
+ # It is conceivable that a serial could increment based on date for some
+ # volumes and issue numbering for other volumes, but until a real case
+ # comes up, let's assume that defined calendar changes always trump $u
+ if (defined $pattern->{x}) {
+ my $increment = $self->calendar_increment(\@cur, \@new);
+ # if we hit a calendar change, restart dependant restarters
+ # regardless of whether they thought they should
+ if ($increment) {
+ $next->{a} += $increment;
+ foreach my $key ('b'..'f') {
+ next if !exists $next->{$key};
+ my $cap = $self->capfield($key);
+ if ($cap->{RESTART}) {
+ $next->{$key} = 1;
+ if ($self->enum_is_combined($key, $next->{$key})) {
+ $next->{$key} .= '/' . ($next->{$key} + 1);
+ }
+ } else {
+ last; # if we find a non-restarting level, stop
+ }
+ }
+ }
+ } elsif ($carry) {
$next->{a} += $carry;
- } elsif (defined $pattern->{x}) {
- $next->{a} += $self->calendar_increment(\@cur, \@new);
}
}
+sub winter_starts_year {
+ my $self = shift;
+
+ my $pubpats = $self->{_mfhdc_PATTERN}->{y}->{p};
+ my $freq = $self->{_mfhdc_PATTERN}->{w};
+
+ if ($freq =~ /^\d$/) {
+ foreach my $pubpat (@$pubpats) {
+ my $chroncode = substr($pubpat, 0, 1);
+ if ($chroncode eq 's' and substr($pubpat, 1, 2) == 24) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
sub next_alt_enum {
my $self = shift;
my $next = shift;
&& ($next->{$key} eq $cap->{COUNT})) {
$next->{$key} = 1;
$carry = 1;
+ } elsif ($cap->{COUNT} > 0 and !($next->{$key} % $cap->{COUNT})) {
+ # If we have a non-restarting enum, but we define a count,
+ # we need to carry to the next level when the current value
+ # divides evenly by the count
+ # XXX: this code naively assumes that there has never been an
+ # issue number anomaly of any kind (like an extra issue), but this
+ # limit is inherent in the standard
+ $next->{$key} += 1;
+ $carry = 1;
} else {
# If I don't need to "carry" beyond here, then I just increment
# this level of the enumeration and stop looping, since the
}
# Breaks in the sequence
- if (defined($self->{_mfhdh_BREAK})) {
- if ($self->{_mfhdh_BREAK} eq 'n') {
- $str .= ' non-gap break';
- } elsif ($self->{_mfhdh_BREAK} eq 'g') {
- $str .= ' gap';
- } else {
- warn "unrecognized break indicator '$self->{_mfhdh_BREAK}'";
- }
- }
-
+# XXX: this is non-standard and also not the right place for this, since gaps
+# only make sense in the context of multiple holding segments, not a single
+# holding
+# if (defined($self->{_mfhdh_BREAK})) {
+# if ($self->{_mfhdh_BREAK} eq 'n') {
+# $str .= ' non-gap break';
+# } elsif ($self->{_mfhdh_BREAK} eq 'g') {
+# $str .= ' gap';
+# } else {
+# warn "unrecognized break indicator '$self->{_mfhdh_BREAK}'";
+# }
+# }
+#
return $str;
}
$chrons[$i]->[1] = 9;
$chrons[$i]->[2] = 22;
} elsif ($seasons[$i] == 24) {
- $chrons[$i]->[1] = 12;
- $chrons[$i]->[2] = 21;
+ # "winter" can come at the beginning or end of a year,
+ if ($self->caption->winter_starts_year()) {
+ $chrons[$i]->[1] = 1;
+ $chrons[$i]->[2] = 1;
+ } else { # default to astronomical
+ $chrons[$i]->[1] = 12;
+ $chrons[$i]->[2] = 21;
+ }
}
}
}
}
+ # if we have an an annual, set the month to ypm## if available
+ if (exists($self->caption->{_mfhdc_PATTERN}->{y}->{p}) and $self->caption->{_mfhdc_PATTERN}->{w} eq 'a') {
+ my $reg = $self->caption->{_mfhdc_PATTERN}->{y}->{p}->[0];
+ if ($reg =~ /^m(\d+)/) {
+ $chrons[0]->[1] = $1;
+ $chrons[1]->[1] = $1;
+ }
+ }
+
my @dates;
foreach my $chron (@chrons) {
my $date = undef;
863 41 $820.3$a1$b5$i1990$j12$x|a2|b1|i1991|j02$zWrap at end of year/vol.
245 00 $aEconomist: pub. w on Sa, except combined iss on last two weeks of year
-853 20 $821$av.$bno.$u12$vc$i(year)$j(month)$k(day)$ww$x01,04,07,10$ypdsa$yow1299
+853 20 $821$av.$bno.$vc$i(year)$j(month)$k(day)$ww$x01,04,07,10$ypdsa$yow1299
863 41 $821.1$a100$b1200$i2008$j12$k06$x|a100|b1201|i2008|j12|k13$zwithin vol.
863 41 $821.2$a100$b1201$i2008$j12$k13$x|a100|b1202|i2008|j12|k20$zwithin vol. combined iss.
863 41 $821.3$a100$b1202$i2008$j12$k20$x|a101|b1203|i2009|j01|k03$zvolume change over omitted iss.
863 41 $822.4$a2$b4$i2013$j04$k11$x|a2|b5|i2013|j05|k01$zpublished on Wed May 1st
245 00 $aMFHD example: pub. every Mon, Thu, except on New Years, July 4, Labor Day, Thanksgiving, Christmas
-853 20 $823$av.$bno.$uvar$vr$i(year)$j(month)$k(day)$wc$x07$ypw00mo,00th$yod0101,0704,1225$yow0901mo,1104th
+853 20 $823$av.$bno.$uvar$i(year)$j(month)$k(day)$wc$x07$ypw00mo,00th$yod0101,0704,1225$yow0901mo,1104th
863 41 $823.1$a1$b100$i2009$j02$k02$x|a1|b101|i2009|j02|k05$znormal: Mon to Thu
863 41 $823.2$a1$b101$i2009$j02$k05$x|a1|b102|i2009|j02|k09$znormal: Thu to Mon
863 41 $823.3$a1$b150$i2009$j06$k29$x|a2|b151|i2009|j07|k02$znormal: calendar change
863 41 $826.1$a1$b1$i1990$j01$x|a1|b2|i1990|j02$znormal issue
864 41 $827.1$a1$i1990$j09$x|a2|i1991|j09$zAnnual supplement
865 41 $828.1$a1$i1990$j02$x|a2|i1991|j02$zAnnual Index
+
+# Issue numbering restarts at the calendar change
+245 00 $aIssue No. restarts at calendar change
+853 20 $829$av.$bno.$uvar$vr$i(year)$j(month)$k(day)$wd$x0101,0701
+863 41 $829.1$a1$b181$i2011$j06$k30$x|a2|b1|i2011|j07|k01$zJune 30 to July 1
+
+# Winter starts the calendar year
+# Requires a hacky use of MARC due to limitations in MARC standard
+245 00 $aWinter starts the calendar year
+853 20 $830$av.$bno.$u4$vr$i(year)$j(season)$w4$yps24,21,22,23
+863 41 $830.1$a1$b4$i2010$j23$x|a2|b1|i2011|j24$zAutumn 2010 to Winter 2011
+863 41 $830.2$a2$b1$i2011$j24$x|a2|b2|i2011|j21$y2011-01-01$zWinter 2011 to Spring 2011
+
+# Combined seasons
+245 00 $aCombined seasons, and Winter starts the calendar year
+853 20 $831$av.$bno.$u4$vr$i(year)$j(season)$w4$yps24/21,22,23
+863 41 $831.1$a1$b4$i2010$j23$x|a2|b1|i2011|j24/21$zAutumn 2010 to combined Winter/Spring 2011
+
+# Combined seasons, variation
+245 00 $aCombined seasons variation, and Winter starts the calendar year
+853 20 $832$av.$bno.$u4$vr$i(year)$j(season)$w4$yps24,21/22,23
+863 41 $832.1$a1$b4$i2011$j24$x|a2|b1|i2011|j21/22$zWinter 2011 to combined Spring/Summer 2011
+863 41 $832.2$a1$b4$i2011$j21/22$x|a2|b1|i2011|j23$zSpring/Summer 2011 to Autumn 2011
+
+# Defined unit count, non-restarting
+245 00 $aDefined unit count, non-restarting
+853 20 $833$av.$bno.$u4$vc$i(year)$j(month)$wf
+863 41 $833.1$a24$b95$i2011$j01$x|a24|b96|i2011|j07$z3rd Issue to 4th Issue in Volume
+863 41 $833.2$a24$b96$i2011$j07$x|a25|b97|i2012|j01$z4th Issue to 1st Issue in next Volume
+
+# Combined months to end the year
+245 00 $aCombined months to end the year
+853 20 $834$av.$bno.$u12$vr$i(year)$j(month)$wm$ycm12/01$yce22/3
+863 41 $834.1$a24$b1$i2011$j11$x|a24|b2/3|i2011/2012|j12/01$zNov. to Combined Dec./Jan.
+863 41 $834.2$a24$b2/3$i2011/2012$j12/1$x|a24|b4|i2012|j02$zCombined Dec./Jan. to Feb.