1 package C4::Heading::MARC21;
3 # Copyright (C) 2008 LibLime
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
32 use C4::Heading::MARC21;
36 This is an internal helper class used by
37 C<C4::Heading> to parse headings data from
38 MARC21 records. Object of this type
39 do not carry data, instead, they only
42 =head1 DATA STRUCTURES
44 FIXME - this should be moved to a configuration file.
46 =head2 bib_heading_fields
50 my $bib_heading_fields = {
52 auth_type => 'PERSO_NAME',
53 subfields => 'abcdfghjklmnopqrst',
57 auth_type => 'CORPO_NAME',
58 subfields => 'abcdfghklmnoprst',
62 auth_type => 'MEETI_NAME',
63 subfields => 'acdfghjklnpqst',
67 auth_type => 'UNIF_TITLE',
68 subfields => 'adfghklmnoprst',
72 auth_type => 'NAME_EVENT',
73 subfields => 'acdgvxyz68',
77 auth_type => 'CHRON_TERM',
78 subfields => 'abvxyz68',
82 auth_type => 'TOPIC_TERM',
83 subfields => 'abvxyz68',
87 auth_type => 'GEOGR_NAME',
88 subfields => 'avxyz68',
92 auth_type => 'GENRE/FORM',
93 subfields => 'abvxyz68',
97 auth_type => 'MED_PERFRM',
102 auth_type => 'TOPIC_TERM',
103 subfields => 'vxyz68'
106 auth_type => 'GEOGR_NAME',
107 subfields => 'vxyz68'
110 auth_type => 'CHRON_TERM',
111 subfields => 'vxyz68'
114 auth_type => 'GENRE/FORM',
115 subfields => 'vxyz68'
117 '440' => { auth_type => 'UNIF_TITLE', subfields => 'anp', series => 1 },
119 auth_type => 'PERSO_NAME',
120 subfields => 'abcdfghjklmnopqrstvxyz',
124 auth_type => 'CORPO_NAME',
125 subfields => 'abcdfghklmnoprstvxyz',
129 auth_type => 'MEETI_NAME',
130 subfields => 'acdfghjklnpqstvxyz',
134 auth_type => 'UNIF_TITLE',
135 subfields => 'adfghklmnoprstvxyz',
138 '648' => { auth_type => 'CHRON_TERM', subfields => 'avxyz', subject => 1 },
139 '650' => { auth_type => 'TOPIC_TERM', subfields => 'abvxyz', subject => 1 },
140 '651' => { auth_type => 'GEOGR_NAME', subfields => 'avxyz', subject => 1 },
141 '655' => { auth_type => 'GENRE/FORM', subfields => 'avxyz', subject => 1 },
142 '690' => { auth_type => 'TOPIC_TERM', subfields => 'abvxyz', subject => 1 },
143 '691' => { auth_type => 'GEOGR_NAME', subfields => 'avxyz', subject => 1 },
144 '696' => { auth_type => 'PERSO_NAME', subfields => 'abcdfghjklmnopqrst' },
145 '697' => { auth_type => 'CORPO_NAME', subfields => 'abcdfghklmnoprst' },
146 '698' => { auth_type => 'MEETI_NAME', subfields => 'acdfghjklnpqst' },
147 '699' => { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst' },
148 '700' => { auth_type => 'PERSO_NAME', subfields => 'abcdfghjklmnopqrst' },
149 '710' => { auth_type => 'CORPO_NAME', subfields => 'abcdfghklmnoprst' },
150 '711' => { auth_type => 'MEETI_NAME', subfields => 'acdfghjklnpqst' },
151 '730' => { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst' },
153 auth_type => 'PERSO_NAME',
154 subfields => 'abcdfghjklmnopqrst',
158 auth_type => 'CORPO_NAME',
159 subfields => 'abcdfghklmnoprst',
163 { auth_type => 'MEETI_NAME', subfields => 'acdfghjklnpqst', series => 1 },
165 { auth_type => 'UNIF_TITLE', subfields => 'adfghklmnoprst', series => 1 },
168 my $auth_heading_fields = {
170 auth_type => 'PERSO_NAME',
171 subfields => 'abcdefghjklmnopqrstvxyz68',
175 auth_type => 'CORPO_NAME',
176 subfields => 'abcdefghklmnoprstvxyz68',
180 auth_type => 'MEETI_NAME',
181 subfields => 'acdefghklnpqstvxyz68',
185 auth_type => 'UNIF_TITLE',
186 subfields => 'adfghklmnoprstvxyz68',
190 auth_type => 'NAME_EVENT',
191 subfields => 'acdgvxyz68',
195 auth_type => 'CHRON_TERM',
196 subfields => 'abvxyz68',
200 auth_type => 'TOPIC_TERM',
201 subfields => 'abvxyz68',
205 auth_type => 'GEOG_NAME',
206 subfields => 'avxyz68',
210 auth_type => 'GENRE/FORM',
211 subfields => 'abvxyz68',
215 auth_type => 'MED_PERFRM',
220 auth_type => 'TOPIC_TERM',
221 subfields => 'vxyz68',
224 auth_type => 'GEOGR_NAME',
225 subfields => 'vxyz68',
228 auth_type => 'CHRON_TERM',
229 subfields => 'vxyz68',
232 auth_type => 'GENRE/FORM',
233 subfields => 'vxyz68',
243 'x' => 'generalsubdiv',
244 'y' => 'chronologicalsubdiv',
245 'z' => 'geographicsubdiv',
252 my $marc_handler = C4::Heading::MARC21->new();
258 return bless {}, $class;
261 =head2 valid_heading_tag
265 sub valid_heading_tag {
268 my $frameworkcode = shift;
270 my $heading_fields = $auth ? { %$auth_heading_fields } : { %$bib_heading_fields };
272 if ( exists $heading_fields->{$tag} ) {
281 =head2 valid_heading_subfield
285 sub valid_heading_subfield {
288 my $subfield = shift;
291 my $heading_fields = $auth ? { %$auth_heading_fields } : { %$bib_heading_fields };
293 if ( exists $heading_fields->{$tag} ) {
294 return 1 if ($heading_fields->{$tag}->{subfields} =~ /$subfield/);
299 =head2 get_valid_bib_heading_subfields
303 sub get_valid_bib_heading_subfields {
307 return $bib_heading_fields->{$tag}->{subfields} // undef;
310 =head2 get_auth_heading_subfields_to_report
314 sub get_auth_heading_subfields_to_report {
318 my $subfields = $auth_heading_fields->{$tag}->{subfields} // '';
319 $subfields =~ s/[68]//;
325 Given a field and an indicator to specify if it is an authority field or biblio field we return
326 the correct type, thesauarus, search form, and display form of the heading.
335 my $tag = $field->tag;
336 my $heading_fields = $auth ? { %$auth_heading_fields } : { %$bib_heading_fields };
338 my $field_info = $heading_fields->{$tag};
339 my $auth_type = $field_info->{'auth_type'};
342 ? _get_subject_thesaurus($field)
343 : "lcsh"; # use 'lcsh' for names, UT, etc.
345 _get_search_heading( $field, $field_info->{'subfields'} );
346 my $display_heading =
347 _get_display_heading( $field, $field_info->{'subfields'} );
349 return ( $auth_type, $thesaurus, $search_heading, $display_heading,
353 =head1 INTERNAL FUNCTIONS
355 =head2 _get_subject_thesaurus
359 sub _get_subject_thesaurus {
361 my $ind2 = $field->indicator(2);
363 my $thesaurus = "notdefined";
364 if ( $ind2 eq '0' ) {
367 elsif ( $ind2 eq '1' ) {
370 elsif ( $ind2 eq '2' ) {
373 elsif ( $ind2 eq '3' ) {
376 elsif ( $ind2 eq '4' ) {
377 $thesaurus = "notspecified";
379 elsif ( $ind2 eq '5' ) {
382 elsif ( $ind2 eq '6' ) {
385 elsif ( $ind2 eq '7' ) {
386 my $sf2 = $field->subfield('2');
387 $thesaurus = $sf2 if defined($sf2);
393 =head2 _get_search_heading
397 sub _get_search_heading {
399 my $subfields = shift;
402 my @subfields = $field->subfields();
404 for ( my $i = 0 ; $i <= $#subfields ; $i++ ) {
405 my $code = $subfields[$i]->[0];
406 my $code_re = quotemeta $code;
407 my $value = $subfields[$i]->[1];
408 $value =~ s/[\s]*[-,.:=;!%\/][\s]*$//;
409 next unless $subfields =~ qr/$code_re/;
415 if ( exists $subdivisions{$code} ) {
416 $heading .= " $subdivisions{$code} $value";
419 $heading .= " $value";
424 # remove characters that are part of CCL syntax
425 $heading =~ s/[)(=]//g;
430 =head2 _get_display_heading
434 sub _get_display_heading {
436 my $subfields = shift;
439 my @subfields = $field->subfields();
441 for ( my $i = 0 ; $i <= $#subfields ; $i++ ) {
442 my $code = $subfields[$i]->[0];
443 my $code_re = quotemeta $code;
444 my $value = $subfields[$i]->[1];
445 next unless $subfields =~ qr/$code_re/;
451 if ( exists $subdivisions{$code} ) {
452 $heading .= "--$value";
455 $heading .= " $value";
462 # Additional limiters that we aren't using:
463 # if ($self->{'subject_added_entry'}) {
464 # $limiters .= " AND Heading-use-subject-added-entry=a";
466 # if ($self->{'series_added_entry'}) {
467 # $limiters .= " AND Heading-use-series-added-entry=a";
469 # if (not $self->{'subject_added_entry'} and not $self->{'series_added_entry'}) {
470 # $limiters .= " AND Heading-use-main-or-added-entry=a"
475 Koha Development Team <http://koha-community.org/>
477 Galen Charlton <galen.charlton@liblime.com>