File Coverage

blib/lib/Catmandu/Fix/mab_map.pm
Criterion Covered Total %
statement 12 65 18.4
branch 0 20 0.0
condition 0 4 0.0
subroutine 4 6 66.6
pod 0 1 0.0
total 16 96 16.6


line stmt bran cond sub pod time code
1             package Catmandu::Fix::mab_map;
2              
3              
4             our $VERSION = '0.21';
5              
6 1     1   921 use Catmandu::Sane;
  1         2  
  1         7  
7 1     1   171 use Carp qw(confess);
  1         2  
  1         46  
8 1     1   5 use Moo;
  1         2  
  1         4  
9 1     1   529 use Catmandu::Fix::Has;
  1         699  
  1         6  
10              
11             has mab_path => ( fix_arg => 1 );
12             has path => ( fix_arg => 1 );
13             has record => ( fix_opt => 1 );
14             has split => ( fix_opt => 1 );
15             has join => ( fix_opt => 1 );
16             has value => ( fix_opt => 1 );
17             has pluck => ( fix_opt => 1 );
18              
19             sub emit {
20 0     0 0   my ( $self, $fixer ) = @_;
21 0           my $path = $fixer->split_path( $self->path );
22 0   0       my $record_key = $fixer->emit_string( $self->record // 'record' );
23 0   0       my $join_char = $fixer->emit_string( $self->join // '' );
24 0           my $mab_path = $self->mab_path;
25              
26 0           my $field_regex;
27 0           my ( $field, $ind, $subfield_regex, $from, $to );
28              
29 0 0         if ( $mab_path
30             =~ /(\S{3})(\[(.+)\])?([_a-z0-9]+)?(\/(\d+)(-(\d+))?)?/ )
31             {
32 0           $field = $1;
33 0           $ind = $3;
34 0 0         $subfield_regex = defined $4 ? "[$4]" : "[_A-Za-z0-9]";
35 0           $from = $6;
36 0           $to = $8;
37             }
38             else {
39 0           Catmandu::Error->throw('invalid mab path');
40             }
41              
42 0           $field_regex = $field;
43 0           $field_regex =~ s/\*/./g;
44              
45 0           my $var = $fixer->var;
46 0           my $vals = $fixer->generate_var;
47 0           my $perl = $fixer->emit_declare_vars( $vals, '[]' );
48              
49             $perl .= $fixer->emit_foreach(
50             "${var}->{${record_key}}",
51             sub {
52 0     0     my $var = shift;
53 0           my $v = $fixer->generate_var;
54 0           my $perl = "";
55              
56 0           $perl .= "next if ${var}->[0] !~ /${field_regex}/;";
57              
58 0 0         if (defined $ind) {
59 0           $perl .= "next if (!defined ${var}->[1] || ${var}->[1] ne '${ind}');";
60             }
61              
62 0 0         if ( $self->value ) {
63 0           $perl .= $fixer->emit_declare_vars( $v,
64             $fixer->emit_string( $self->value ) );
65             }
66             else {
67 0           my $i = $fixer->generate_var;
68             my $add_subfields = sub {
69 0           my $start = shift;
70 0 0         if ($self->pluck) {
71             # Treat the subfield_regex as a hash index
72 0           my $pluck = $fixer->generate_var;
73             return
74 0           "my ${pluck} = {};" .
75             "for (my ${i} = ${start}; ${i} < \@{${var}}; ${i} += 2) {".
76             "push(\@{ ${pluck}->{ ${var}->[${i}] } }, ${var}->[${i} + 1]);" .
77             "}" .
78             "for my ${i} (split('','${subfield_regex}')) { " .
79             "push(\@{${v}}, \@{ ${pluck}->{${i}} }) if exists ${pluck}->{${i}};" .
80             "}";
81             }
82             else {
83             # Treat the subfield_regex as regex that needs to match the subfields
84             return
85 0           "for (my ${i} = ${start}; ${i} < \@{${var}}; ${i} += 2) {".
86             "if (${var}->[${i}] =~ /${subfield_regex}/) {".
87             "push(\@{${v}}, ${var}->[${i} + 1]);".
88             "}".
89             "}";
90             }
91 0           };
92 0           $perl .= $fixer->emit_declare_vars( $v, "[]" );
93 0           $perl .= $add_subfields->(2);
94 0           $perl .= "if (\@{${v}}) {";
95 0 0         if ( !$self->split ) {
96 0           $perl .= "${v} = join(${join_char}, \@{${v}});";
97 0 0         if ( defined( my $off = $from ) ) {
98 0 0         my $len = defined $to ? $to - $off + 1 : 1;
99 0           $perl .= "if (eval { ${v} = substr(${v}, ${off}, ${len}); 1 }) {";
100             }
101             }
102             $perl .= $fixer->emit_create_path(
103             $fixer->var,
104             $path,
105             sub {
106 0           my $var = shift;
107 0 0         if ( $self->split ) {
108 0           "if (is_array_ref(${var})) {"
109             . "push \@{${var}}, ${v};"
110             . "} else {"
111             . "${var} = [${v}];" . "}";
112             }
113             else {
114 0           "if (is_string(${var})) {"
115             . "${var} = join(${join_char}, ${var}, ${v});"
116             . "} else {"
117             . "${var} = ${v};" . "}";
118             }
119             }
120 0           );
121 0 0         if ( defined($from) ) {
122 0           $perl .= "}";
123             }
124 0           $perl .= "}";
125             }
126 0           $perl;
127             }
128 0           );
129              
130 0           $perl;
131             }
132              
133             1;
134              
135             __END__
136              
137             =pod
138              
139             =encoding UTF-8
140              
141             =head1 NAME
142              
143             Catmandu::Fix::mab_map - copy mab values of one field to a new field
144              
145             =head1 SYNOPSIS
146              
147             # Copy all 245 subfields into the my.title hash
148             mab_map('245','my.title');
149              
150             # Copy the 245-$a$b$c subfields into the my.title hash
151             mab_map('245abc','my.title');
152              
153             # Copy the 100 subfields into the my.authors array
154             mab_map('100','my.authors.$append');
155            
156             # Add the 710 subfields into the my.authors array
157             mab_map('710','my.authors.$append');
158              
159             # Copy the 600-$x subfields into the my.subjects array while packing each into a genre.text hash
160             mab_map('600x','my.subjects.$append', -in => 'genre.text');
161              
162             # Copy the 008 characters 35-35 into the my.language hash
163             mab_map('008_/35-35','my.language');
164              
165             # Copy all the 600 fields into a my.stringy hash joining them by '; '
166             mab_map('600','my.stringy', -join => '; ');
167              
168             # When 024 field exists create the my.has024 hash with value 'found'
169             mab_map('024','my.has024', -value => 'found');
170              
171             # Do the same examples now with the fields in 'record2'
172             mab_map('245','my.title', -record => 'record2');
173              
174             =head1 AUTHOR
175              
176             Johann Rolschewski <jorol@cpan.org>
177              
178             =head1 COPYRIGHT AND LICENSE
179              
180             This software is copyright (c) 2013 by Johann Rolschewski.
181              
182             This is free software; you can redistribute it and/or modify it under
183             the same terms as the Perl 5 programming language system itself.
184              
185             =cut