return @return_holdings;
}
+#
+# create an array of compressed holdings from all holdings for a given caption,
+# combining as needed
+#
+# NOTE: this sub is similar to, but much less aggressive/strict than
+# get_compressed_holdings(). Ultimately, get_compressed_holdings() might be
+# deprecated in favor of this
+#
+# TODO: gap marking, gap preservation
+#
+# TODO: some of this could be moved to the Caption (and/or Holding) object to
+# allow for combining in the absense of an overarching MFHD object
+#
+sub get_combined_holdings {
+ my $self = shift;
+ my $caption = shift;
+
+ my @holdings = $self->holdings_by_caption($caption);
+ return () if !@holdings;
+
+ # basic check for necessary pattern information
+ if (!scalar keys %{$caption->pattern}) {
+ carp "Cannot combine without pattern data, returning original holdings";
+ return @holdings;
+ }
+
+ my @sorted_holdings = sort {$a cmp $b} @holdings;
+
+ my @combined_holdings = (shift(@sorted_holdings));
+ my $seqno = 1;
+ $combined_holdings[0]->seqno($seqno);
+ foreach my $holding (@sorted_holdings) {
+ # short-circuit: if we hit an open-ended holding,
+ # it 'includes' all the rest, so just exit the loop
+ if ($combined_holdings[-1]->is_open_ended) {
+ last;
+ } elsif ($holding eq $combined_holdings[-1]) {
+ # duplicate, skip
+ next;
+ } else {
+ # at this point, we know that $holding is gt $combined_holdings[-1]
+ # we just need to figure out if they overlap or not
+
+ # first, get the end (or only) holding of [-1]
+ my $last_holding_end = $combined_holdings[-1]->is_compressed ?
+ $combined_holdings[-1]->clone->compressed_to_last
+ : $combined_holdings[-1]->clone;
+
+ # next, make sure $holding isn't fully contained
+ my $holding_end = $holding->is_compressed ?
+ $holding->clone->compressed_to_last
+ : $holding;
+ # if $holding is fully contained, skip it
+ if ($holding_end le $last_holding_end) {
+ next;
+ }
+
+ # now, get the beginning (or only) holding of $holding
+ my $holding_start = $holding->is_compressed ?
+ $holding->clone->compressed_to_first
+ : $holding;
+
+ if ($last_holding_end->increment ge $holding_start) {
+ # they overlap, combine them
+ my $holding_end;
+ if ($holding->is_compressed) {
+ $holding_end = $holding->is_open_ended ?
+ undef
+ : $holding->compressed_to_last;
+ } else {
+ $holding_end = $holding;
+ }
+ $combined_holdings[-1]->compressed_end($holding_end);
+ } else {
+ # no overlap, start a new group
+ $holding->seqno(++$seqno);
+ push(@combined_holdings, $holding);
+ }
+ }
+ }
+
+ return @combined_holdings;
+}
+
##
## close any open-ended holdings which are followed by another holding by
## combining them