From ed7f2d1421180980661c8fe72300dcabec99fd75 Mon Sep 17 00:00:00 2001 From: djfiander Date: Thu, 27 Nov 2008 01:58:40 +0000 Subject: [PATCH] Refactor formatting code to properly handle chronology information stored in the enumeration fields (well, I think it's handling it properly; it hasn't been tested yet for that case). Also refactored basic next/prediction code to handle the same situation. Basically this is all minor stuff that needs to be done, but allows me to avoid working on actually taking a stab at predicting the date of the next issue, but that's pretty much all that's left to do for this iteration of the code. git-svn-id: svn://svn.open-ils.org/ILS/trunk@11359 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../src/perlmods/OpenILS/Utils/MFHD/Holding.pm | 255 ++++++++++++--------- 1 file changed, 149 insertions(+), 106 deletions(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm index e0927eeb5e..f0bc0a98f1 100755 --- a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm @@ -61,10 +61,11 @@ sub new { return $self; } -sub format { +sub format_chron { my $self = shift; my $caption = $self->{CAPTION}; - my $str = ""; + my @keys; + my $str = ''; my %month = ( '01' => 'Jan.', '02' => 'Feb.', '03' => 'Mar.', '04' => 'Apr.', '05' => 'May ', '06' => 'Jun.', '07' => 'Jul.', '08' => 'Aug.', '09' => 'Sep.', @@ -72,66 +73,90 @@ sub format { '21' => 'Spring', '22' => 'Summer', '23' => 'Autumn', '24' => 'Winter' ); - # Enumerations - foreach my $key ('a'..'f') { + @keys = @_; + foreach my $i (0 .. @keys) { + my $key = $keys[$i]; my $capstr; + my $chron; + my $sep; last if !defined $caption->caption($key); -# printf("fmt %s: '%s'\n", $key, $caption->caption($key)); - $capstr = $caption->caption($key); - if (substr($capstr, 0, 1) eq '(') { + if (substr($capstr,0,1) eq '(') { # a caption enclosed in parentheses is not displayed $capstr = ''; } - $str .= ($key eq 'a' ? "" : ':') . $capstr . $self->{ENUMS}->{$key}->{HOLDINGS}; + + # If this is the second level of chronology, then it's + # likely to be a month or season, so we should use the + # string name rather than the number given. + if (($i == 1) && exists $month{$self->{CHRON}->{$key}}) { + $chron = $month{$self->{CHRON}->{$key}}; + } else { + $chron = $self->{CHRON}->{$key}; + } + + + $str .= (($i == 0 || $str =~ /[. ]$/) ? '' : ':') . $capstr . $chron; } - # Chronology - if (defined $caption->caption('i')) { - $str .= '('; - foreach my $key ('i'..'l') { + return $str; +} + +sub format { + my $self = shift; + my $caption = $self->{CAPTION}; + my $str = ""; + + if ($caption->enumeration_is_chronology) { + # if issues are identified by chronology only, then the + # chronology data is stored in the enumeration subfields, + # so format those fields as if they were chronological. + $str = $self->format_chron('a'..'f'); + } else { + # OK, there is enumeration data and maybe chronology + # data as well, format both parts appropriately + + # Enumerations + foreach my $key ('a'..'f') { my $capstr; - my $chron; - my $sep; last if !defined $caption->caption($key); + # printf("fmt %s: '%s'\n", $key, $caption->caption($key)); + $capstr = $caption->caption($key); - if (substr($capstr,0,1) eq '(') { + if (substr($capstr, 0, 1) eq '(') { # a caption enclosed in parentheses is not displayed $capstr = ''; } - - # If this is the second level of chronology, then it's - # likely to be a month or season, so we should use the - # string name rather than the number given. - if ($key eq 'j' && exists $month{$self->{CHRON}->{$key}}) { - $chron = $month{$self->{CHRON}->{$key}}; - } else { - $chron = $self->{CHRON}->{$key}; - } - - - $str .= (($key eq 'i' || $str =~ /[. ]$/) ? '' : ':') . $capstr . $chron; - } - $str .= ')'; - } - - 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->caption($key) . $self->{ENUMS}->{$key}->{HOLDINGS}; + $str .= ($key eq 'a' ? "" : ':') . $capstr . $self->{ENUMS}->{$key}->{HOLDINGS}; } - if (exists $caption->{CHRONS}->{m}) { - # Alternative Chronology + # Chronology + if (defined $caption->caption('i')) { $str .= '('; - $str .= $caption->caption('m') . $self->{ENUMS}->{m}->{HOLDINGS}; + $str .= $self->format_chron('i'..'l'); $str .= ')'; } + + 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->caption($key) . $self->{ENUMS}->{$key}->{HOLDINGS}; + } + + # This assumes that alternative chronology is only ever + # provided if there is an alternative enumeration. + if (exists $caption->{CHRONS}->{m}) { + # Alternative Chronology + $str .= '('; + $str .= $caption->caption('m') . $self->{ENUMS}->{m}->{HOLDINGS}; + $str .= ')'; + } + } } # Public Note @@ -149,6 +174,15 @@ sub format { return $str; } +sub next_date { + my $self = shift; + my $next = shift; + my @keys = @_; + + my $caption = $self->{CAPTION}; +} + + # next: Given a holding statement, return a hash containing the # enumeration values for the next issues, whether we hold it or not # @@ -158,85 +192,94 @@ sub next { my $next = {}; my $carry; + # Initialize $next with current enumeration & chronology, then + # we can just operate on $next, based on the contents of the caption foreach my $key ('a' .. 'h') { - next if !exists $self->{ENUMS}->{$key}; - $next->{$key} = $self->{ENUMS}->{$key}->{HOLDINGS}; + $next->{$key} = $self->{ENUMS}->{$key}->{HOLDINGS} + if exists $self->{ENUMS}->{$key}; } - # First handle any "alternative enumeration", since they're - # a lot simpler, and don't depend on the the calendar - foreach my $key ('h', 'g') { - next if !exists $next->{$key}; - if (!exists $caption->{ENUMS}->{$key}) { - warn "Holding data exists for $key, but no caption specified"; - $next->{$key} += 1; - last; - } - - my $cap = $caption->{ENUMS}->{$key}; - if ($cap->{RESTART} && $cap->{COUNT} - && ($next->{$key} == $cap->{COUNT})) { - $next->{$key} = 1; - } else { - $next->{$key} += 1; - last; - } + foreach my $key ('i'..'m') { + $next->{$key} = $self->{CHRON}->{$key} + if exists $self->{CHRON}->{$key}; } if ($caption->enumeration_is_chronology) { - # do something - } + $self->next_date($caption, $next, ('a'..'h')); + } else { + # First handle any "alternative enumeration", since they're + # a lot simpler, and don't depend on the the calendar + foreach my $key ('h', 'g') { + next if !exists $next->{$key}; + if (!exists $caption->{ENUMS}->{$key}) { + warn "Holding data exists for $key, but no caption specified"; + $next->{$key} += 1; + last; + } - # $carry keeps track of whether we need to carry into the next - # higher level of enumeration. It's not actually necessary except - # for when the loop ends: if we need to carry from $b into $a - # then $carry will be set when the loop ends. - # - # We need to keep track of this because there are two different - # reasons why we might increment the highest level of enumeration ($a) - # 1) we hit the correct number of items in $b (ie, 5th iss of quarterly) - # 2) it's the right time of the year. - # - $carry = 0; - foreach my $key (reverse('b'.. 'f')) { - next if !exists $next->{$key}; - if (!exists $caption->{ENUMS}->{$key}) { - # Just assume that it increments continuously and give up - warn "Holding data exists for $key, but no caption specified"; - $next->{$key} += 1; - $carry = 0; - last; + my $cap = $caption->{ENUMS}->{$key}; + if ($cap->{RESTART} && $cap->{COUNT} + && ($next->{$key} == $cap->{COUNT})) { + $next->{$key} = 1; + } else { + $next->{$key} += 1; + last; + } } - my $cap = $caption->{ENUMS}->{$key}; - if ($cap->{RESTART} && $cap->{COUNT} - && ($next->{$key} eq $cap->{COUNT})) { - $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 - # "next" hash has been initialized with the current values - - # NOTE: This DOES NOT take into account the incrementing - # of enumerations based on the calendar. (eg: The Economist) - $next->{$key} += 1; - $carry = 0; - last; + # $carry keeps track of whether we need to carry into the next + # higher level of enumeration. It's not actually necessary except + # for when the loop ends: if we need to carry from $b into $a + # then $carry will be set when the loop ends. + # + # We need to keep track of this because there are two different + # reasons why we might increment the highest level of enumeration ($a) + # 1) we hit the correct number of items in $b (ie, 5th iss of quarterly) + # 2) it's the right time of the year. + # + $carry = 0; + foreach my $key (reverse('b'.. 'f')) { + next if !exists $next->{$key}; + if (!exists $caption->{ENUMS}->{$key}) { + # Just assume that it increments continuously and give up + warn "Holding data exists for $key, but no caption specified"; + $next->{$key} += 1; + $carry = 0; + last; + } + + my $cap = $caption->{ENUMS}->{$key}; + if ($cap->{RESTART} && $cap->{COUNT} + && ($next->{$key} eq $cap->{COUNT})) { + $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 + # "next" hash has been initialized with the current values + + # NOTE: This DOES NOT take into account the incrementing + # of enumerations based on the calendar. (eg: The Economist) + $next->{$key} += 1; + $carry = 0; + last; + } } - } - # The easy part is done. There are two things left to do: - # 1) Calculate the date of the next issue, if necessary - # 2) Increment the highest level of enumeration (either by date - # or because $carry is set because of the above loop + # The easy part is done. There are two things left to do: + # 1) Calculate the date of the next issue, if necessary + # 2) Increment the highest level of enumeration (either by date + # or because $carry is set because of the above loop - if (!%{$caption->{CHRONS}}) { - # The simple case: if there is no chronology specified - # then just check $carry and return - $next->{'a'} += $carry; - } else { - # Complicated: figure out date of next issue + if (!%{$caption->{CHRONS}}) { + # The simple case: if there is no chronology specified + # then just check $carry and return + $next->{'a'} += $carry; + } else { + # Figure out date of next issue, then decide if we need + # to adjust top level enumeration based on that + $self->next_date($caption, $next, ('i'..'m')); + } } return($next); -- 2.11.0