@@ -, +, @@ call number in labels if cn_source is "lcc' or 'nlm' we split using Library::CallNumber::LC if cn_source is 'ddc' we split using a in-house method * a filing rule used to sort items by callnumbers * a splitting rule used to print labels s/\s/\n/g # Break on spaces s/(\s?=)/\n=/g # Break on = (unless it's done already) s/^(J|K)\n/$1 / # Remove the first break if callnumber starts with J or K - Assume that this DB data is safe (We can add a new permission?) - Assume that the data is not safe and deal with possible attack - Use Template Toolkit syntax instead (Really safer?) [% callnumber.replace('\s', '\n').replace ... %] - Cut the regex parts: find, replace, modifiers --- C4/ClassSplitRoutine.pm | 63 +++++++++++++ C4/ClassSplitRoutine/Dewey.pm | 79 ++++++++++++++++ C4/ClassSplitRoutine/Generic.pm | 72 +++++++++++++++ C4/ClassSplitRoutine/LCC.pm | 63 +++++++++++++ C4/ClassSplitRoutine/RegEx.pm | 59 ++++++++++++ C4/Labels/Label.pm | 100 ++++++--------------- Koha/ClassSplitRule.pm | 78 ++++++++++++++++ Koha/ClassSplitRules.pm | 56 ++++++++++++ admin/classsources.pl | 23 +++-- .../prog/en/modules/admin/admin-home.tt | 2 +- .../prog/en/modules/admin/classsources.tt | 90 +++++++++++++++++-- t/Labels.t | 3 +- t/Labels_split_Regex.t | 38 ++++++++ t/Labels_split_ddcn.t | 5 +- t/Labels_split_lccn.t | 3 +- 15 files changed, 638 insertions(+), 96 deletions(-) create mode 100644 C4/ClassSplitRoutine.pm create mode 100644 C4/ClassSplitRoutine/Dewey.pm create mode 100644 C4/ClassSplitRoutine/Generic.pm create mode 100644 C4/ClassSplitRoutine/LCC.pm create mode 100644 C4/ClassSplitRoutine/RegEx.pm create mode 100644 Koha/ClassSplitRule.pm create mode 100644 Koha/ClassSplitRules.pm create mode 100755 t/Labels_split_Regex.t --- a/C4/ClassSplitRoutine.pm +++ a/C4/ClassSplitRoutine.pm @@ -0,0 +1,63 @@ +package C4::ClassSplitRoutine; + +# Copyright 2018 Koha Development Team +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +require Exporter; +use Class::Factory::Util; + +use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); + + +=head1 NAME + +C4::ClassSplitRoutine - base object for creation of classification splitting routines + +=head1 SYNOPSIS + +use C4::ClassSplitRoutine; + +=head1 FUNCTIONS + +=cut + +@ISA = qw(Exporter); +@EXPORT = qw( + &GetSplitRoutineNames +); + +=head2 GetSplitRoutineNames + + my @routines = GetSplitRoutineNames(); + +Get names of all modules under C4::ClassSplitRoutine::*. + +=cut + +sub GetSplitRoutineNames { + return C4::ClassSplitRoutine->subclasses(); +} + +1; + +=head1 AUTHOR + +Koha Development Team + +=cut --- a/C4/ClassSplitRoutine/Dewey.pm +++ a/C4/ClassSplitRoutine/Dewey.pm @@ -0,0 +1,79 @@ +package C4::ClassSplitRoutine::Dewey; + +# Copyright 2018 Koha Development Team +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use C4::Debug; + +=head1 NAME + +C4::ClassSplitRoutine::Dewey - Dewey call number split method + +=head1 SYNOPSIS + +use C4::ClassSplitRoutine; + +my $cn_split = C4::ClassSplitRoutine::Dewey::split_callnumber($cn_item); + +=head1 FUNCTIONS + +=head2 split_callnumber + + my $cn_split = C4::ClassSplitRoutine::Dewey::split_callnumber($cn_item); + +=cut + +sub split_callnumber { + my ($cn_item) = @_; + + my $possible_decimal = + qr/\d{3,}(?:\.\d+)?/; # at least three digits for a DDCN + + $cn_item =~ s/\///g + ; # in theory we should be able to simply remove all segmentation markers and arrive at the correct call number... + my (@lines) = $cn_item =~ m/ + ^([-a-zA-Z]*\s?(?:$possible_decimal)?) # R220.3 CD-ROM 787.87 # will require extra splitting + \s+ + (.+) # H2793Z H32 c.2 EAS # everything else (except bracketing spaces) + \s* + /x; + unless (@lines) { + warn sprintf( 'regexp failed to match string: %s', $cn_item ); + push @lines, $cn_item; # if no match, just push the whole string. + } + + if ( $lines[0] =~ /^([-a-zA-Z]+)\s?($possible_decimal)$/ ) { + shift @lines; # pull off the mathching first element, like example 1 + unshift @lines, $1, $2; # replace it with the two pieces + } + + push @lines, split /\s+/, + pop @lines + ; # split the last piece into an arbitrary number of pieces at spaces + $debug and print STDERR "split_ddcn array: ", join( " | ", @lines ), "\n"; + return @lines; +} + +1; + +=head1 AUTHOR + +Koha Development Team + +=cut --- a/C4/ClassSplitRoutine/Generic.pm +++ a/C4/ClassSplitRoutine/Generic.pm @@ -0,0 +1,72 @@ +package C4::ClassSplitRoutine::Generic; + +# Copyright 2018 Koha Development Team +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use C4::Debug; + +=head1 NAME + +C4::ClassSplitRoutine::Generic - generic call number sorting key routine + +=head1 SYNOPSIS + +use C4::ClassSplitRoutine; + +=head1 FUNCTIONS + + +=head2 split_callnumber + + my $cn_split = C4::ClassSplitRoutine::Generic::split_callnumber($cn_item); + + NOTE: Custom call number types go here. It may be necessary to create additional + splitting algorithms if some custom call numbers cannot be made to work here. + Presently this splits standard non-ddcn, non-lccn fiction and biography call numbers. + +=cut + +sub split_callnumber { + my ($cn_item) = @_; + + my @lines; + + # Split call numbers based on spaces + push @lines, split /\s+/, $cn_item + ; # split the call number into an arbitrary number of pieces at spaces + if ( $lines[-1] !~ /^.*\d-\d.*$/ && $lines[-1] =~ /^(.*\d+)(\D.*)$/ ) { + pop @lines; # pull off the matching last element + push @lines, $1, $2; # replace it with the two pieces + } + unless ( scalar @lines ) { + warn sprintf( 'regexp failed to match string: %s', $cn_item ); + push( @lines, $cn_item ); + } + $debug and print STDERR "split_ccn array: ", join( " | ", @lines ), "\n"; + + return @lines; +} + +1; + +=head1 AUTHOR + +Koha Development Team + +=cut --- a/C4/ClassSplitRoutine/LCC.pm +++ a/C4/ClassSplitRoutine/LCC.pm @@ -0,0 +1,63 @@ +package C4::ClassSplitRoutine::LCC; + +# Copyright 2018 Koha Development Team +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; +use Library::CallNumber::LC; + +use C4::Debug; + +=head1 NAME + +C4::ClassSplitRoutine::LCC - LCC call number split method + +=head1 SYNOPSIS + +use C4::ClassSplitRoutine; + +my $cn_split = C4::ClassSplitRoutine::LCC::split_callnumber($cn_item); + +=head1 FUNCTIONS + +=head2 split_callnumber + + my $cn_split = C4::ClassSplitRoutine::LCC::split_callnumber($cn_item); + +=cut + +sub split_callnumber { + my ($cn_item) = @_; + # lccn examples: 'HE8700.7 .P6T44 1983', 'BS2545.E8 H39 1996'; + my @lines = Library::CallNumber::LC->new($cn_item)->components(); + unless (scalar @lines && defined $lines[0]) { + $debug and warn sprintf('regexp failed to match string: %s', $cn_item); + @lines = $cn_item; # if no match, just use the whole string. + } + my $LastPiece = pop @lines; + push @lines, split /\s+/, $LastPiece if $LastPiece; # split the last piece into an arbitrary number of pieces at spaces + $debug and warn "split LCC array: ", join(" | ", @lines), "\n"; + return @lines; +} + +1; + +=head1 AUTHOR + +Koha Development Team + +=cut --- a/C4/ClassSplitRoutine/RegEx.pm +++ a/C4/ClassSplitRoutine/RegEx.pm @@ -0,0 +1,59 @@ +package C4::ClassSplitRoutine::RegEx; + +# Copyright 2018 Koha Development Team +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use C4::Debug; + +=head1 NAME + +C4::ClassSplitRoutine::RegEx - regex call number sorting key routine + +=head1 SYNOPSIS + +use C4::ClassSplitRoutine; + +my $cn_sort = C4::ClassSplitRoutine::RegEx::split_callnumber($cn_item, $regexs); + +=head1 FUNCTIONS + +=head2 split_callnumber + + my $cn_split = C4::ClassSplitRoutine::RegEx::split_callnumber($cn_item, $regexs); + +=cut + +sub split_callnumber { + my ($cn_item, $regexs) = @_; + + for my $regex ( @$regexs ) { + eval "\$cn_item =~ $regex"; + } + my @lines = split "\n", $cn_item; + + return @lines; +} + +1; + +=head1 AUTHOR + +Koha Development Team + +=cut --- a/C4/Labels/Label.pm +++ a/C4/Labels/Label.pm @@ -7,15 +7,18 @@ use Text::Wrap; use Algorithm::CheckDigits; use Text::CSV_XS; use Data::Dumper; -use Library::CallNumber::LC; use Text::Bidi qw( log2vis ); use C4::Context; use C4::Debug; use C4::Biblio; - - -my $possible_decimal = qr/\d{3,}(?:\.\d+)?/; # at least three digits for a DDCN +use Koha::ClassSources; +use Koha::ClassSortRules; +use Koha::ClassSplitRules; +use C4::ClassSplitRoutine::Dewey; +use C4::ClassSplitRoutine::LCC; +use C4::ClassSplitRoutine::Generic; +use C4::ClassSplitRoutine::RegEx; sub _check_params { my $given_params = {}; @@ -121,67 +124,6 @@ sub _get_text_fields { return \@sorted_fields; } - -sub _split_lccn { - my ($lccn) = @_; - $_ = $lccn; - # lccn examples: 'HE8700.7 .P6T44 1983', 'BS2545.E8 H39 1996'; - my @parts = Library::CallNumber::LC->new($lccn)->components(); - unless (scalar @parts && defined $parts[0]) { - $debug and warn sprintf('regexp failed to match string: %s', $_); - @parts = $_; # if no match, just use the whole string. - } - my $LastPiece = pop @parts; - push @parts, split /\s+/, $LastPiece if $LastPiece; # split the last piece into an arbitrary number of pieces at spaces - $debug and warn "split_lccn array: ", join(" | ", @parts), "\n"; - return @parts; -} - -sub _split_ddcn { - my ($ddcn) = @_; - $_ = $ddcn; - s/\///g; # in theory we should be able to simply remove all segmentation markers and arrive at the correct call number... - my (@parts) = m/ - ^([-a-zA-Z]*\s?(?:$possible_decimal)?) # R220.3 CD-ROM 787.87 # will require extra splitting - \s+ - (.+) # H2793Z H32 c.2 EAS # everything else (except bracketing spaces) - \s* - /x; - unless (scalar @parts) { - warn sprintf('regexp failed to match string: %s', $_); - push @parts, $_; # if no match, just push the whole string. - } - - if ($parts[0] =~ /^([-a-zA-Z]+)\s?($possible_decimal)$/) { - shift @parts; # pull off the mathching first element, like example 1 - unshift @parts, $1, $2; # replace it with the two pieces - } - - push @parts, split /\s+/, pop @parts; # split the last piece into an arbitrary number of pieces at spaces - $debug and print STDERR "split_ddcn array: ", join(" | ", @parts), "\n"; - return @parts; -} - -## NOTE: Custom call number types go here. It may be necessary to create additional splitting algorithms if some custom call numbers -## cannot be made to work here. Presently this splits standard non-ddcn, non-lccn fiction and biography call numbers. - -sub _split_ccn { - my ($fcn) = @_; - my @parts = (); - # Split call numbers based on spaces - push @parts, split /\s+/, $fcn; # split the call number into an arbitrary number of pieces at spaces - if ($parts[-1] !~ /^.*\d-\d.*$/ && $parts[-1] =~ /^(.*\d+)(\D.*)$/) { - pop @parts; # pull off the matching last element - push @parts, $1, $2; # replace it with the two pieces - } - unless (scalar @parts) { - warn sprintf('regexp failed to match string: %s', $_); - push (@parts, $_); - } - $debug and print STDERR "split_ccn array: ", join(" | ", @parts), "\n"; - return @parts; -} - sub _get_barcode_data { my ( $f, $item, $record ) = @_; my $kohatables = _desc_koha_tables(); @@ -400,6 +342,14 @@ sub draw_label_text { # FIXME - returns all items, so you can't get data from an embedded holdings field. # TODO - add a GetMarcBiblio1item(bibnum,itemnum) or a GetMarcItem(itemnum). my $cn_source = ($item->{'cn_source'} ? $item->{'cn_source'} : C4::Context->preference('DefaultClassificationSource')); + my $class_source = Koha::ClassSources->find( $cn_source ); + my ( $split_routine, $regexs ); + if ($class_source) { + my $class_split_rule = Koha::ClassSplitRules->find( $class_source->class_split_rule ); + $split_routine = $class_split_rule->split_routine; + $regexs = $class_split_rule->regexs; + } + else { $split_routine = $cn_source } LABEL_FIELDS: # process data for requested fields on current label for my $field (@$label_fields) { if ($field->{'code'} eq 'itemtype') { @@ -429,14 +379,18 @@ sub draw_label_text { # Fields which hold call number data FIXME: ( 060? 090? 092? 099? ) my @callnumber_list = qw(itemcallnumber 050a 050b 082a 952o 995k); if ((grep {$field->{'code'} =~ m/$_/} @callnumber_list) and ($self->{'printing_type'} eq 'BIB') and ($self->{'callnum_split'})) { # If the field contains the call number, we do some sp - if ($cn_source eq 'lcc' || $cn_source eq 'nlm') { # NLM and LCC should be split the same way - @label_lines = _split_lccn($field_data); - @label_lines = _split_ccn($field_data) if !@label_lines; # If it was not a true lccn, try it as a custom call number - push (@label_lines, $field_data) if !@label_lines; # If it was not that, send it on unsplit - } elsif ($cn_source eq 'ddc') { - @label_lines = _split_ddcn($field_data); - @label_lines = _split_ccn($field_data) if !@label_lines; - push (@label_lines, $field_data) if !@label_lines; + if ($split_routine eq 'LCC' || $split_routine eq 'nlm') { # NLM and LCC should be split the same way + @label_lines = C4::ClassSplitRoutine::LCC::split_callnumber($field_data); + @label_lines = C4::ClassSplitRoutine::Generic::split_callnumber($field_data) unless @label_lines; # If it was not a true lccn, try it as a custom call number + push (@label_lines, $field_data) unless @label_lines; # If it was not that, send it on unsplit + } elsif ($split_routine eq 'Dewey') { + @label_lines = C4::ClassSplitRoutine::Dewey::split_callnumber($field_data); + @label_lines = C4::ClassSplitRoutine::Generic::split_callnumber($field_data) unless @label_lines; + push (@label_lines, $field_data) unless @label_lines; + } elsif ($split_routine eq 'RegEx' ) { + @label_lines = C4::ClassSplitRoutine::RegEx::split_callnumber($field_data, $regexs); + @label_lines = C4::ClassSplitRoutine::Generic::split_callnumber($field_data) unless @label_lines; + push (@label_lines, $field_data) unless @label_lines; } else { warn sprintf('Call number splitting failed for: %s. Please add this call number to bug #2500 at bugs.koha-community.org', $field_data); push @label_lines, $field_data; --- a/Koha/ClassSplitRule.pm +++ a/Koha/ClassSplitRule.pm @@ -0,0 +1,78 @@ +package Koha::ClassSplitRule; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use JSON qw(to_json from_json); + +use Koha::Database; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::ClassSplitRule Koha Classfication Spliting Rule Object class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 new + +Accept 'regexs' as a valid attribute. +It should be an arrayref that will be serialized in JSON before stored in DB. + +=cut + +sub new { + my ($class, $attributes) = @_; + + if ( exists $attributes->{regexs} ) { + $attributes->{split_regex} = to_json($attributes->{regexs}); + delete $attributes->{regexs}; + } + return $class->SUPER::new($attributes); +} + +=head3 regexs + +my $regexs = $rule->regexs + +$rule->regex(\@regexs); + +Getter or setter for split_regex + +=cut + +sub regexs { + my ( $self, $regexs ) = @_; + return $regexs + ? $self->split_regex( to_json($regexs) ) + : from_json( $self->split_regex ); +} + +=head3 type + +=cut + +sub _type { + return 'ClassSplitRule'; +} + +1; --- a/Koha/ClassSplitRules.pm +++ a/Koha/ClassSplitRules.pm @@ -0,0 +1,56 @@ +package Koha::ClassSplitRules; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Koha::Database; + +use Koha::ClassSplitRule; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::ClassSplitRules - Koha Classification Split Rules Object set class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 _type + +Returns name of corresponding DBIC resultset + +=cut + +sub _type { + return 'ClassSplitRule'; +} + +=head3 object_class + +Returns name of corresponding Koha object class + +=cut + +sub object_class { + return 'Koha::ClassSplitRule'; +} + +1; --- a/admin/classsources.pl +++ a/admin/classsources.pl @@ -27,6 +27,7 @@ use C4::Output; use C4::Koha; use C4::ClassSource; use C4::ClassSortRoutine; +use C4::ClassSplitRoutine; use Koha::ClassSources; use Koha::ClassSortRules; use Koha::ClassSplitRules; @@ -40,7 +41,7 @@ my $class_sort_rule = $input->param('class_sort_rule'); my $class_split_rule = $input->param('class_split_rule'); my $sort_routine = $input->param('sort_routine'); my $split_routine = $input->param('split_routine'); -my $split_regex = $input->param('split_regex'); +my @split_regex = $input->multi_param('split_regex'); my $description = $input->param('description'); my $used = $input->param('used'); @@ -194,16 +195,20 @@ elsif ( $op eq "add_split_rule" ) { } elsif ( $op eq "add_split_rule_validate" ) { my $split_rule = Koha::ClassSplitRules->find($class_split_rule); + + @split_regex = grep {!/^$/} @split_regex; # Remove empty if ($split_rule) { $split_rule->set( { description => $description, split_routine => $split_routine, - split_regex => - ( $split_routine eq 'RegEx' ? $split_regex : '' ), } ); - eval { $split_rule->store; }; + eval { + $split_rule->regexs(\@split_regex) + if $split_routine eq 'RegEx'; + $split_rule->store; + }; if ($@) { push @messages, { type => 'error', code => 'error_on_update_split_rule' }; @@ -220,8 +225,7 @@ elsif ( $op eq "add_split_rule_validate" ) { class_split_rule => $class_split_rule, description => $description, split_routine => $split_routine, - split_regex => - ( $split_routine eq 'RegEx' ? $split_regex : '' ), + regexs => \@split_regex, } ); eval { $split_rule->store; }; @@ -273,11 +277,6 @@ sub get_class_sort_routines { } sub get_class_split_routines { - my @split_routines = qw( - Dewey - Generic - LCC - RegEx - ); + my @split_routines = GetSplitRoutineNames(); return \@split_routines; } --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt @@ -113,7 +113,7 @@ [% END %] [% IF ( CAN_user_parameters_manage_classifications ) %]
Classification sources
-
Define classification sources (i.e., call number schemes) used by your collection. Also define filing rules used for sorting call numbers.
+
Define classification sources (i.e., call number schemes) used by your collection. Also define filing rules used for sorting call numbers and splitting rules for splitting them.
[% END %] [% IF ( CAN_user_parameters_manage_matching_rules ) %]
Record matching rules
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/classsources.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/classsources.tt @@ -16,6 +16,14 @@ [% INCLUDE 'doc-head-close.inc' %] + @@ -233,12 +241,33 @@ Required -
  • - - - Required -
  • - +
  • + +
    + [% IF split_rule %] + [% FOR re IN split_rule.regexs %] +
    + + Delete +
    + [% END %] + [% ELSE %] +
    + +
    + [% END %] +
    +
    + New + Required +
    + +
    + + +
    +
    +
  • @@ -349,6 +378,26 @@ $("#split_regex").removeAttr('required'); } }; + function update_delete_links_visibility() { + if( $("div.split_regex").length > 1 ) { + $("div.split_regex").find('a.del_regex').show(); + } else { + $("div.split_regex").find('a.del_regex').hide(); + } + } + + function add_regex() { + var div_node = $("div.split_regex:last"); + var div_clone = $(div_node).clone(true); + $(div_clone).find("input").val(""); + $(div_node).after(div_clone); + update_delete_links_visibility(); + } + function del_regex(a_node) { + $(a_node).parent('div').remove(); + update_delete_links_visibility(); + } + $(document).ready(function(){ update_regex_block(); $("#split_routine").on("change", function(){ @@ -364,6 +413,35 @@ $(".delete_split_rule").on("click", function(e){ return confirm(_("Are you sure you want to delete this splitting rule?")); }); + + $(".add_regex").on("click", function(e){ + e.preventDefault(); + add_regex(); + }); + $(".del_regex").on("click", function(e){ + e.preventDefault(); + del_regex(this); + }); + + $("button[name='test_split_cns']").on("click", function(e){ + e.preventDefault(); + var regexs = []; + $("input[name='split_regex']").each(function(){ + regexs.push($(this).val()); + }); + var callnumbers = $("textarea[name='callnumbers']").val(); + $.getJSON('/cgi-bin/koha/svc/split_callnumbers', {regexs: JSON.stringify(regexs), callnumbers: callnumbers}, function(answer){ + var callnumbers = answer['split_callnumbers']; + $("#result_split_callnumbers").html(''); + var list_node = $('
      '); + $(callnumbers).each(function(){ + var split_cn = this['split'].join('
      '); + var li_node = $('
    1. '+split_cn+'
    2. '); + $(list_node).append(li_node); + }); + $("#result_split_callnumbers").append(list_node); + }).fail(function(){alert("Something went wrong.")}); + }); }); --- a/t/Labels.t +++ a/t/Labels.t @@ -20,6 +20,7 @@ use strict; use warnings; +use C4::ClassSplitRoutine::LCC; use Test::More tests => 11; BEGIN { @@ -62,4 +63,4 @@ Q ok(C4::Labels::Label::_get_text_fields(), 'test getting textx fields'); -is(C4::Labels::Label::_split_lccn(),"0", 'test when _split_lccn is null'); +is(C4::ClassSplitRoutine::LCC::split_callnumber(),"0", 'test when split LCC is null'); --- a/t/Labels_split_Regex.t +++ a/t/Labels_split_Regex.t @@ -0,0 +1,38 @@ +#!/usr/bin/perl +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 5; +use C4::ClassSplitRoutine::RegEx; + +my $callnumbers = { + '830 Han' => [qw{830 Han}], + '159.9 (091) Gesh' => [qw{159.9 (091) Gesh}], + 'J 3 Kin =774' => ['J 3', 'Kin', '=774'], + '830 Hil =774 4' => [qw{830 Hil =774 4}], + '830 Las=20 4' => [qw{830 Las =20 4}], +}; + +# Split on spaces and before = +# If starts with J or K then do not split the first 2 groups +my @regexs = ('s/\s/\n/g', 's/(\s?=)/\n=/g', 's/^(J|K)\n/$1 /'); +foreach my $cn (sort keys %$callnumbers) { + my @parts = C4::ClassSplitRoutine::RegEx::split_callnumber($cn, \@regexs); + my @expected = @{$callnumbers->{$cn}}; + is_deeply(\@parts, \@expected); +} --- a/t/Labels_split_ddcn.t +++ a/t/Labels_split_ddcn.t @@ -42,7 +42,7 @@ BEGIN { $test_num += 4; } plan tests => $test_num; - use_ok('C4::Labels::Label'); + use_ok('C4::ClassSplitRoutine::Dewey'); use vars qw($ddcns); } @@ -50,7 +50,8 @@ foreach my $ddcn (sort keys %$ddcns) { my (@parts, @expected); ok($ddcn, "ddcn: $ddcn"); ok(@expected = @{$ddcns->{$ddcn}}, "split expected to produce " . scalar(@expected) . " pieces"); - ok(@parts = C4::Labels::Label::_split_ddcn($ddcn), "C4::Labels::Label::_split_ddcn($ddcn)"); + ok(@parts = C4::ClassSplitRoutine::Dewey::split_callnumber($ddcn), "Dewey::split_callnumber($ddcn)"); + ok(scalar(@expected) == scalar(@parts), sprintf("%d of %d pieces produced", scalar(@parts), scalar(@expected))); my $i = 0; foreach my $unit (@expected) { --- a/t/Labels_split_lccn.t +++ a/t/Labels_split_lccn.t @@ -20,6 +20,7 @@ use strict; use warnings; +use C4::ClassSplitRoutine::LCC; use Test::More; BEGIN { @@ -52,7 +53,7 @@ foreach my $lccn (sort keys %$lccns) { my (@parts, @expected); ok($lccn, "lccn: $lccn"); ok(@expected = @{$lccns->{$lccn}}, "split expected to produce " . scalar(@expected) . " pieces"); - ok(@parts = C4::Labels::Label::_split_lccn($lccn), "C4::Labels::Label::_split_lccn($lccn)"); + ok(@parts = C4::ClassSplitRoutine::LCC::split_callnumber($lccn), "split LCC ($lccn)"); ok(scalar(@expected) == scalar(@parts), sprintf("%d of %d pieces produced", scalar(@parts), scalar(@expected))); my $i = 0; foreach my $unit (@expected) { --