File: | C4/Heading/MARC21.pm |
Coverage: | 9.5% |
line | stmt | bran | cond | sub | time | code |
---|---|---|---|---|---|---|
1 | package C4::Heading::MARC21; | |||||
2 | ||||||
3 | # Copyright (C) 2008 LibLime | |||||
4 | # | |||||
5 | # This file is part of Koha. | |||||
6 | # | |||||
7 | # Koha is free software; you can redistribute it and/or modify it under the | |||||
8 | # terms of the GNU General Public License as published by the Free Software | |||||
9 | # Foundation; either version 2 of the License, or (at your option) any later | |||||
10 | # version. | |||||
11 | # | |||||
12 | # Koha is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
13 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
14 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
15 | # | |||||
16 | # You should have received a copy of the GNU General Public License along | |||||
17 | # with Koha; if not, write to the Free Software Foundation, Inc., | |||||
18 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |||||
19 | ||||||
20 | 3 3 3 | 42 14 105 | use strict; | |||
21 | #use warnings; FIXME - Bug 2505 | |||||
22 | 3 3 3 | 22 12 142 | use MARC::Record; | |||
23 | 3 3 3 | 21 12 3282 | use MARC::Field; | |||
24 | ||||||
25 | our $VERSION = 3.00; | |||||
26 | ||||||
27 - 49 | =head1 NAME C4::Heading::MARC21 =head1 SYNOPSIS use C4::Heading::MARC21; =head1 DESCRIPTION This is an internal helper class used by C<C4::Heading> to parse headings data from MARC21 records. Object of this type do not carry data, instead, they only dispatch functions. =head1 DATA STRUCTURES FIXME - this should be moved to a configuration file. =head2 bib_heading_fields =cut | |||||
50 | ||||||
51 | my $bib_heading_fields = { | |||||
52 | '100' => { auth_type => 'PERSO_NAME', subfields => 'abcdefghjklmnopqrst', main_entry => 1 }, | |||||
53 | '110' => { auth_type => 'CORPO_NAME', subfields => 'abcdefghklmnoprst', main_entry => 1 }, | |||||
54 | '111' => { auth_type => 'MEETI_NAME', subfields => 'acdefghjklnpqst', main_entry => 1 }, | |||||
55 | '130' => { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst', main_entry => 1 }, | |||||
56 | '440' => { auth_type => 'UNIF_TITLE', subfields => 'anp', series => 1 }, | |||||
57 | '600' => { auth_type => 'PERSO_NAME', subfields => 'abcdefghjklmnopqrstvxyz', subject => 1 }, | |||||
58 | '610' => { auth_type => 'CORPO_NAME', subfields => 'abcdefghklmnoprstvxyz', subject => 1 }, | |||||
59 | '611' => { auth_type => 'MEETI_NAME', subfields => 'acdefghjklnpqstvxyz', subject => 1 }, | |||||
60 | '630' => { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprstvxyz', subject => 1 }, | |||||
61 | '648' => { auth_type => 'CHRON_TERM', subfields => 'avxyz', subject => 1 }, | |||||
62 | '650' => { auth_type => 'TOPIC_TERM', subfields => 'abvxyz', subject => 1 }, | |||||
63 | '651' => { auth_type => 'GEOGR_NAME', subfields => 'avxyz', subject => 1 }, | |||||
64 | '655' => { auth_type => 'GENRE/FORM', subfields => 'avxyz', subject => 1 }, | |||||
65 | '700' => { auth_type => 'PERSO_NAME', subfields => 'abcdefghjklmnopqrst' }, | |||||
66 | '710' => { auth_type => 'CORPO_NAME', subfields => 'abcdefghklmnoprst' }, | |||||
67 | '711' => { auth_type => 'MEETI_NAME', subfields => 'acdefghjklnpqst' }, | |||||
68 | '730' => { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst' }, | |||||
69 | '800' => { auth_type => 'PERSO_NAME', subfields => 'abcdefghjklmnopqrst', series => 1 }, | |||||
70 | '810' => { auth_type => 'CORPO_NAME', subfields => 'abcdefghklmnoprst', series => 1 }, | |||||
71 | '811' => { auth_type => 'MEETI_NAME', subfields => 'acdefghjklnpqst', series => 1 }, | |||||
72 | '830' => { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst', series => 1 }, | |||||
73 | }; | |||||
74 | ||||||
75 - 77 | =head2 subdivisions =cut | |||||
78 | ||||||
79 | my %subdivisions = ( | |||||
80 | 'v' => 'formsubdiv', | |||||
81 | 'x' => 'generalsubdiv', | |||||
82 | 'y' => 'chronologicalsubdiv', | |||||
83 | 'z' => 'geographicsubdiv', | |||||
84 | ); | |||||
85 | ||||||
86 - 92 | =head1 METHODS =head2 new my $marc_handler = C4::Heading::MARC21->new(); =cut | |||||
93 | ||||||
94 | sub new { | |||||
95 | 0 | my $class = shift; | ||||
96 | 0 | return bless {}, $class; | ||||
97 | } | |||||
98 | ||||||
99 - 101 | =head2 valid_bib_heading_tag =cut | |||||
102 | ||||||
103 | sub valid_bib_heading_tag { | |||||
104 | 0 | my $self = shift; | ||||
105 | 0 | my $tag = shift; | ||||
106 | ||||||
107 | 0 | if (exists $bib_heading_fields->{$tag}) { | ||||
108 | 0 | return 1 | ||||
109 | } else { | |||||
110 | 0 | return 0; | ||||
111 | } | |||||
112 | ||||||
113 | } | |||||
114 | ||||||
115 - 117 | =head2 parse_heading =cut | |||||
118 | ||||||
119 | sub parse_heading { | |||||
120 | 0 | my $self = shift; | ||||
121 | 0 | my $field = shift; | ||||
122 | ||||||
123 | 0 | my $tag = $field->tag; | ||||
124 | 0 | my $field_info = $bib_heading_fields->{$tag}; | ||||
125 | ||||||
126 | 0 | my $auth_type = $field_info->{'auth_type'}; | ||||
127 | 0 | my $subject = $field_info->{'subject'} ? 1 : 0; | ||||
128 | 0 | my $series = $field_info->{'series'} ? 1 : 0; | ||||
129 | 0 | my $main_entry = $field_info->{'main_entry'} ? 1 : 0; | ||||
130 | 0 | my $thesaurus = $subject ? _get_subject_thesaurus($field) : "lcsh"; # use 'lcsh' for names, UT, etc. | ||||
131 | 0 | my $search_heading = _get_search_heading($field, $field_info->{'subfields'}); | ||||
132 | 0 | my $display_heading = _get_display_heading($field, $field_info->{'subfields'}); | ||||
133 | ||||||
134 | 0 | return ($auth_type, $subject, $series, $main_entry, $thesaurus, $search_heading, $display_heading); | ||||
135 | } | |||||
136 | ||||||
137 - 141 | =head1 INTERNAL FUNCTIONS =head2 _get_subject_thesaurus =cut | |||||
142 | ||||||
143 | sub _get_subject_thesaurus { | |||||
144 | 0 | my $field = shift; | ||||
145 | 0 | my $ind2 = $field->indicator(2); | ||||
146 | ||||||
147 | 0 | my $thesaurus = "notdefined"; | ||||
148 | 0 | if ($ind2 eq '0') { | ||||
149 | 0 | $thesaurus = "lcsh"; | ||||
150 | } elsif ($ind2 eq '1') { | |||||
151 | 0 | $thesaurus = "lcac"; | ||||
152 | } elsif ($ind2 eq '2') { | |||||
153 | 0 | $thesaurus = "mesh"; | ||||
154 | } elsif ($ind2 eq '3') { | |||||
155 | 0 | $thesaurus = "nal"; | ||||
156 | } elsif ($ind2 eq '4') { | |||||
157 | 0 | $thesaurus = "notspecified"; | ||||
158 | } elsif ($ind2 eq '5') { | |||||
159 | 0 | $thesaurus = "cash"; | ||||
160 | } elsif ($ind2 eq '6') { | |||||
161 | 0 | $thesaurus = "rvm"; | ||||
162 | } elsif ($ind2 eq '7') { | |||||
163 | 0 | my $sf2 = $field->subfield('2'); | ||||
164 | 0 | $thesaurus = $sf2 if defined($sf2); | ||||
165 | } | |||||
166 | ||||||
167 | 0 | return $thesaurus; | ||||
168 | } | |||||
169 | ||||||
170 - 172 | =head2 _get_search_heading =cut | |||||
173 | ||||||
174 | sub _get_search_heading { | |||||
175 | 0 | my $field = shift; | ||||
176 | 0 | my $subfields = shift; | ||||
177 | ||||||
178 | 0 | my $heading = ""; | ||||
179 | 0 | my @subfields = $field->subfields(); | ||||
180 | 0 | my $first = 1; | ||||
181 | for (my $i = 0; $i <= $#subfields; $i++) { | |||||
182 | 0 | my $code = $subfields[$i]->[0]; | ||||
183 | 0 | my $code_re = quotemeta $code; | ||||
184 | 0 | my $value = $subfields[$i]->[1]; | ||||
185 | 0 | next unless $subfields =~ qr/$code_re/; | ||||
186 | 0 | if ($first) { | ||||
187 | 0 | $first = 0; | ||||
188 | 0 | $heading = $value; | ||||
189 | } else { | |||||
190 | 0 | if (exists $subdivisions{$code}) { | ||||
191 | 0 | $heading .= " $subdivisions{$code} $value"; | ||||
192 | } else { | |||||
193 | 0 | $heading .= " $value"; | ||||
194 | } | |||||
195 | } | |||||
196 | 0 | } | ||||
197 | ||||||
198 | # remove characters that are part of CCL syntax | |||||
199 | 0 | $heading =~ s/[)(=]//g; | ||||
200 | ||||||
201 | 0 | return $heading; | ||||
202 | } | |||||
203 | ||||||
204 - 206 | =head2 _get_display_heading =cut | |||||
207 | ||||||
208 | sub _get_display_heading { | |||||
209 | 0 | my $field = shift; | ||||
210 | 0 | my $subfields = shift; | ||||
211 | ||||||
212 | 0 | my $heading = ""; | ||||
213 | 0 | my @subfields = $field->subfields(); | ||||
214 | 0 | my $first = 1; | ||||
215 | for (my $i = 0; $i <= $#subfields; $i++) { | |||||
216 | 0 | my $code = $subfields[$i]->[0]; | ||||
217 | 0 | my $code_re = quotemeta $code; | ||||
218 | 0 | my $value = $subfields[$i]->[1]; | ||||
219 | 0 | next unless $subfields =~ qr/$code_re/; | ||||
220 | 0 | if ($first) { | ||||
221 | 0 | $first = 0; | ||||
222 | 0 | $heading = $value; | ||||
223 | } else { | |||||
224 | 0 | if (exists $subdivisions{$code}) { | ||||
225 | 0 | $heading .= "--$value"; | ||||
226 | } else { | |||||
227 | 0 | $heading .= " $value"; | ||||
228 | } | |||||
229 | } | |||||
230 | 0 | } | ||||
231 | 0 | return $heading; | ||||
232 | } | |||||
233 | ||||||
234 - 240 | =head1 AUTHOR Koha Development Team <http://koha-community.org/> Galen Charlton <galen.charlton@liblime.com> =cut | |||||
241 | ||||||
242 | 1; |