4 ## marc2ris: converts MARC21 and UNIMARC datasets to RIS format
5 ## See comments below for compliance with other MARC dialects
7 ## usage: perl marc2ris < infile.marc > outfile.ris
9 ## Dependencies: perl 5.6.0 or later
13 ## markus@mhoenicka.de 2002-11-16
15 ## This program is free software; you can redistribute it and/or modify
16 ## it under the terms of the GNU General Public License as published by
17 ## the Free Software Foundation; either version 2 of the License, or
18 ## (at your option) any later version.
20 ## This program is distributed in the hope that it will be useful,
21 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 ## GNU General Public License for more details.
25 ## You should have received a copy of the GNU General Public License
26 ## along with this program; if not, write to the Free Software
27 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 ## Some background about MARC as understood by this script
30 ## The default input format used in this script is MARC21, which
31 ## superseded USMARC and CANMARC. The specification can be found at:
32 ## http://lcweb.loc.gov/marc/
33 ## UNIMARC follows the specification at:
34 ## http://www.ifla.org/VI/3/p1996-1/sec-uni.htm
35 ## UKMARC support is a bit shaky because there is no specification available
36 ## for free. The wisdom used in this script was taken from a PDF document
37 ## comparing UKMARC to MARC21 found at:
38 ## www.bl.uk/services/bibliographic/marcchange.pdf
41 # Modified 2008 by BibLibre for Koha
42 # Modified 2011 by Catalyst
43 # Modified 2011 by Equinox Software, Inc.
45 # This file is part of Koha.
47 # Koha is free software; you can redistribute it and/or modify it
48 # under the terms of the GNU General Public License as published by
49 # the Free Software Foundation; either version 3 of the License, or
50 # (at your option) any later version.
52 # Koha is distributed in the hope that it will be useful, but
53 # WITHOUT ANY WARRANTY; without even the implied warranty of
54 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55 # GNU General Public License for more details.
57 # You should have received a copy of the GNU General Public License
58 # along with Koha; if not, see <http://www.gnu.org/licenses>.
64 use List
::MoreUtils qw
/uniq/;
65 use vars
qw($VERSION @ISA @EXPORT);
67 use C4::Biblio qw(GetMarcSubfieldStructureFromKohaField);
68 use Koha
::SimpleMARC
qw(read_field);
70 # set the version for version checking
71 $VERSION = 3.07.00.049;
75 # only export API methods
87 =head1 marc2bibtex - Convert from UNIMARC to RIS
89 my ($ris) = marc2ris($record);
93 C<$record> - a MARC::Record object
101 my $marcflavour = C4
::Context
->preference("marcflavour");
102 $intype = lc($marcflavour);
103 my $marcprint = 0; # Debug flag;
105 # Let's redirect stdout
106 open my $oldout, ">&STDOUT";
109 open STDOUT
,'>:encoding(utf8)', \
$outvar;
111 ## First we should check the character encoding. This may be
112 ## MARC-8 or UTF-8. The former is indicated by a blank, the latter
113 ## by 'a' at position 09 (zero-based) of the leader
114 my $leader = $record->leader();
115 if ( $intype eq "marc21" ) {
116 if ( $leader =~ /^.{9}a/ ) {
117 print "<marc>---\r\n<marc>UTF-8 data\r\n" if $marcprint;
121 print "<marc>---\r\n<marc>MARC-8 data\r\n" if $marcprint;
124 ## else: other MARC formats do not specify the character encoding
125 ## we assume it's *not* UTF-8
127 my $RisExportAdditionalFields = C4
::Context
->preference('RisExportAdditionalFields');
128 my $ris_additional_fields;
129 if ($RisExportAdditionalFields) {
130 $RisExportAdditionalFields = "$RisExportAdditionalFields\n\n";
131 $ris_additional_fields = eval { YAML
::Load
($RisExportAdditionalFields); };
133 warn "Unable to parse RisExportAdditionalFields : $@";
134 $ris_additional_fields = undef;
139 if ( $ris_additional_fields && $ris_additional_fields->{TY
} ) {
140 my ( $f, $sf ) = split( /\$/, $ris_additional_fields->{TY
} );
141 my ( $type ) = read_field
( { record
=> $record, field
=> $f, subfield
=> $sf, field_numbers
=> [1] } );
143 print "TY - $type\r\n";
146 &print_typetag
($leader);
150 &print_typetag
($leader);
153 ## retrieve all author fields and collect them in a list
156 if ($intype eq "unimarc") {
157 ## Fields 700, 701, and 702 can contain author names
158 @author_fields = ($record->field('700'), $record->field('701'), $record->field('702'));
160 else { ## marc21, ukmarc
161 ## Field 100 sometimes carries main author
162 ## Field(s) 700 carry added entries - personal names
163 @author_fields = ($record->field('100'), $record->field('700'));
166 ## loop over all author fields
167 foreach my $field (@author_fields) {
168 if (length($field)) {
169 my $author = &get_author
($field);
170 print "AU - ",&charconv
($author),"\r\n";
174 # ToDo: should we specify anonymous as author if we didn't find
175 # one? or use one of the corporate/meeting names below?
177 ## add corporate names or meeting names as editors ??
180 if ($intype eq "unimarc") {
181 ## Fields 710, 711, and 712 can carry corporate names
182 ## Field(s) 720, 721, 722, 730 have additional candidates
183 @editor_fields = ($record->field('710'), $record->field('711'), $record->field('712'), $record->field('720'), $record->field('721'), $record->field('722'), $record->field('730'));
185 else { ## marc21, ukmarc
186 ## Fields 110 and 111 carry the main entries - corporate name and
187 ## meeting name, respectively
188 ## Field(s) 710, 711 carry added entries - personal names
189 @editor_fields = ($record->field('110'), $record->field('111'), $record->field('710'), $record->field('711'));
192 ## loop over all editor fields
193 foreach my $field (@editor_fields) {
194 if (length($field)) {
195 my $editor = &get_editor
($field);
196 print "ED - ",&charconv
($editor),"\r\n";
200 ## get info from the title field
201 if ($intype eq "unimarc") {
202 &print_title
($record->field('200'));
204 else { ## marc21, ukmarc
205 &print_title
($record->field('245'));
209 if ($intype eq "unimarc") {
210 &print_stitle
($record->field('225'));
212 else { ## marc21, ukmarc
213 &print_stitle
($record->field('490'));
217 if ($intype eq "unimarc") {
218 &print_isbn
($record->field('010'));
219 &print_issn
($record->field('011'));
221 elsif ($intype eq "ukmarc") {
222 &print_isbn
($record->field('021'));
223 ## this is just an assumption
224 &print_issn
($record->field('022'));
226 else { ## assume marc21
227 &print_isbn
($record->field('020'));
228 &print_issn
($record->field('022'));
231 if ($intype eq "marc21") {
232 &print_loc_callno
($record->field('050'));
233 &print_dewey
($record->field('082'));
235 ## else: unimarc, ukmarc do not seem to store call numbers?
238 if ($intype eq "unimarc") {
239 &print_pubinfo
($record->field('210'));
241 else { ## marc21, ukmarc
242 if ($record->field('264')) {
243 &print_pubinfo
($record->field('264'));
246 &print_pubinfo
($record->field('260'));
250 ## 6XX fields contain KW candidates. We add all of them to a
253 if ($intype eq "unimarc") {
254 @field_list = ('600', '601', '602', '604', '605', '606','607', '608', '610', '615', '620', '660', '661', '670', '675', '676', '680', '686');
255 } elsif ($intype eq "ukmarc") {
256 @field_list = ('600', '610', '611', '630', '650', '651','653', '655', '660', '661', '668', '690', '691', '692', '695');
257 } else { ## assume marc21
258 @field_list = ('600', '610', '611', '630', '650', '651','653', '654', '655', '656', '657', '658');
262 for my $f ( @field_list ) {
263 my @fields = $record->field($f);
264 push @kwpool, ( get_keywords
("$f",$record->field($f)) );
268 @kwpool = uniq
@kwpool;
270 for my $kw ( @kwpool ) {
271 print "KW - ", &charconv
($kw), "\r\n";
274 ## 5XX have various candidates for notes and abstracts. We pool
275 ## all notes-like stuff in one list.
278 ## these fields have notes candidates
279 if ($intype eq "unimarc") {
280 foreach ('300', '301', '302', '303', '304', '305', '306', '307', '308', '310', '311', '312', '313', '314', '315', '316', '317', '318', '320', '321', '322', '323', '324', '325', '326', '327', '328', '332', '333', '336', '337', '345') {
281 &pool_subx
(\
@notepool, $_, $record->field($_));
284 elsif ($intype eq "ukmarc") {
285 foreach ('500', '501', '502', '503', '504', '505', '506', '508', '514', '515', '516', '521', '524', '525', '528', '530', '531', '532', '533', '534', '535', '537', '538', '540', '541', '542', '544', '554', '555', '556', '557', '561', '563', '580', '583', '584', '586') {
286 &pool_subx
(\
@notepool, $_, $record->field($_));
289 else { ## assume marc21
290 foreach ('500', '501', '502', '504', '505', '506', '507', '508', '510', '511', '513', '514', '515', '516', '518', '521', '522', '524', '525', '526', '530', '533', '534', '535') {
291 &pool_subx
(\
@notepool, $_, $record->field($_));
295 my $allnotes = join "; ", @notepool;
297 if (length($allnotes) > 0) {
298 print "N1 - ", &charconv
($allnotes), "\r\n";
301 ## 320/520 have the abstract
302 if ($intype eq "unimarc") {
303 &print_abstract
($record->field('320'));
305 elsif ($intype eq "ukmarc") {
306 &print_abstract
($record->field('512'), $record->field('513'));
308 else { ## assume marc21
309 &print_abstract
($record->field('520'));
313 if ($record->field('856')) {
314 print_uri
($record->field('856'));
317 if ($ris_additional_fields) {
318 foreach my $ris_tag ( keys %$ris_additional_fields ) {
319 next if $ris_tag eq 'TY';
322 ref( $ris_additional_fields->{$ris_tag} ) eq 'ARRAY'
323 ? @
{ $ris_additional_fields->{$ris_tag} }
324 : $ris_additional_fields->{$ris_tag};
326 for my $tag (@fields) {
327 my ( $f, $sf ) = split( /\$/, $tag );
328 my @values = read_field
( { record
=> $record, field
=> $f, subfield
=> $sf } );
329 foreach my $v (@values) {
330 print "$ris_tag - $v\r\n";
339 # Let's re-redirect stdout
341 open STDOUT
, ">&", $oldout;
348 ##********************************************************************
349 ## print_typetag(): prints the first line of a RIS dataset including
350 ## the preceding newline
351 ## Argument: the leader of a MARC dataset
352 ## Returns: the value at leader position 06
353 ##********************************************************************
356 ## the keys of typehash are the allowed values at position 06
357 ## of the leader of a MARC record, the values are the RIS types
358 ## that might appropriately represent these types.
392 ## The type of a MARC record is found at position 06 of the leader
393 my $typeofrecord = substr($leader, 6, 1);
395 ## ToDo: for books, field 008 positions 24-27 might have a few more
400 ## the ukmarc here is just a guess
401 if ($intype eq "marc21" || $intype eq "ukmarc") {
402 %typehash = %ustypehash;
404 elsif ($intype eq "unimarc") {
405 %typehash = %unitypehash;
408 ## assume MARC21 as default
409 %typehash = %ustypehash;
412 if (!exists $typehash{$typeofrecord}) {
413 print "TY - BOOK\r\n"; ## most reasonable default
414 warn ("no type found - assume BOOK") if $marcprint;
417 print "TY - $typehash{$typeofrecord}\r\n";
420 ## use $typeofrecord as the return value, just in case
424 ##********************************************************************
425 ## normalize_author(): normalizes an authorname
426 ## Arguments: authorname subfield a
427 ## authorname subfield b
428 ## authorname subfield c
429 ## name type if known: 0=direct order
430 ## 1=only surname or full name in
432 ## 3=family, clan, dynasty name
433 ## Returns: the normalized authorname
434 ##********************************************************************
435 sub normalize_author
{
436 my($rawauthora, $rawauthorb, $rawauthorc, $nametype) = @_;
438 if ($nametype == 0) {
439 # ToDo: convert every input to Last[,(F.|First)[ (M.|Middle)[,Suffix]]]
440 warn("name >>$rawauthora<< in direct order - leave as is") if $marcprint;
443 elsif ($nametype == 1) {
444 ## start munging subfield a (the real name part)
445 ## remove spaces after separators
446 $rawauthora =~ s
%([,.]+) *%$1%g;
448 ## remove trailing separators after spaces
449 $rawauthora =~ s
% *[,;:/]*$%%;
451 ## remove periods after a non-abbreviated name
452 $rawauthora =~ s
%(\w
{2,})\
.%$1%g;
454 ## start munging subfield b (something like the suffix)
455 ## remove trailing separators after spaces
456 $rawauthorb =~ s
% *[,;:/]*$%%;
458 ## we currently ignore subfield c until someone complains
459 if (length($rawauthorb) > 0) {
460 return join ", ", ($rawauthora, $rawauthorb);
466 elsif ($nametype == 3) {
471 ##********************************************************************
472 ## get_author(): gets authorname info from MARC fields 100, 700
473 ## Argument: field (100 or 700)
474 ## Returns: an author string in the format found in the record
475 ##********************************************************************
477 my ($authorfield) = @_;
480 ## the sequence of the name parts is encoded either in indicator
481 ## 1 (marc21) or 2 (unimarc)
482 if ($intype eq "unimarc") {
485 else { ## assume marc21
489 print "<marc>:Author(Ind$indicator): ", $authorfield->indicator("$indicator"),"\r\n" if $marcprint;
490 print "<marc>:Author(\$a): ", $authorfield->subfield('a'),"\r\n" if $marcprint;
491 print "<marc>:Author(\$b): ", $authorfield->subfield('b'),"\r\n" if $marcprint;
492 print "<marc>:Author(\$c): ", $authorfield->subfield('c'),"\r\n" if $marcprint;
493 print "<marc>:Author(\$h): ", $authorfield->subfield('h'),"\r\n" if $marcprint;
494 if ($intype eq "ukmarc") {
495 my $authorname = $authorfield->subfield('a') . "," . $authorfield->subfield('h');
496 normalize_author
($authorname, $authorfield->subfield('b'), $authorfield->subfield('c'), $authorfield->indicator("$indicator"));
499 normalize_author
($authorfield->subfield('a') // '', $authorfield->subfield('b') // '', $authorfield->subfield('c') // '', $authorfield->indicator("$indicator"));
503 ##********************************************************************
504 ## get_editor(): gets editor info from MARC fields 110, 111, 710, 711
505 ## Argument: field (110, 111, 710, or 711)
506 ## Returns: an author string in the format found in the record
507 ##********************************************************************
509 my ($editorfield) = @_;
515 print "<marc>Editor(\$a): ", $editorfield->subfield('a'),"\r\n" if $marcprint;
516 print "<marc>Editor(\$b): ", $editorfield->subfield('b'),"\r\n" if $marcprint;
517 print "<marc>editor(\$c): ", $editorfield->subfield('c'),"\r\n" if $marcprint;
518 return $editorfield->subfield('a');
522 ##********************************************************************
523 ## print_title(): gets info from MARC field 245
524 ## Arguments: field (245)
526 ##********************************************************************
528 my ($titlefield) = @_;
530 print "<marc>empty title field (245)\r\n" if $marcprint;
531 warn("empty title field (245)") if $marcprint;
534 print "<marc>Title(\$a): ",$titlefield->subfield('a'),"\r\n" if $marcprint;
535 print "<marc>Title(\$b): ",$titlefield->subfield('b'),"\r\n" if $marcprint;
536 print "<marc>Title(\$c): ",$titlefield->subfield('c'),"\r\n" if $marcprint;
538 ## The title is usually written in a very odd notation. The title
539 ## proper ($a) often ends with a space followed by a separator like
540 ## a slash or a colon. The subtitle ($b) doesn't start with a space
541 ## so simple concatenation looks odd. We have to conditionally remove
542 ## the separator and make sure there's a space between title and
545 my $clean_title = $titlefield->subfield('a');
547 my $clean_subtitle = $titlefield->subfield('b');
548 $clean_subtitle ||= q{};
549 $clean_title =~ s
% *[/:;.]$%%;
550 $clean_subtitle =~ s
%^ *(.*) *[/:;.]$%$1%;
552 if (length($clean_title) > 0
553 || (length($clean_subtitle) > 0 && $intype ne "unimarc")) {
554 print "TI - ", &charconv
($clean_title);
556 ## subfield $b is relevant only for marc21/ukmarc
557 if (length($clean_subtitle) > 0 && $intype ne "unimarc") {
558 print ": ",&charconv
($clean_subtitle);
563 ## The statement of responsibility is just this: horrors. There is
564 ## no formal definition how authors, editors and the like should
565 ## be written and designated. The field is free-form and resistant
566 ## to all parsing efforts, so this information is lost on me
570 ##********************************************************************
571 ## print_stitle(): prints info from series title field
574 ##********************************************************************
576 my ($titlefield) = @_;
579 print "<marc>empty series title field\r\n" if $marcprint;
582 print "<marc>Series title(\$a): ",$titlefield->subfield('a'),"\r\n" if $marcprint;
583 my $clean_title = $titlefield->subfield('a');
585 $clean_title =~ s
% *[/:;.]$%%;
587 if (length($clean_title) > 0) {
588 print "T2 - ", &charconv
($clean_title),"\r\n";
591 if ($intype eq "unimarc") {
592 print "<marc>Series vol(\$v): ",$titlefield->subfield('v'),"\r\n" if $marcprint;
593 if (length($titlefield->subfield('v')) > 0) {
594 print "VL - ", &charconv
($titlefield->subfield('v')),"\r\n";
600 ##********************************************************************
601 ## print_isbn(): gets info from MARC field 020
602 ## Arguments: field (020)
603 ##********************************************************************
607 if (!$isbnfield || length ($isbnfield->subfield('a')) == 0) {
608 print "<marc>no isbn found (020\$a)\r\n" if $marcprint;
609 warn("no isbn found") if $marcprint;
612 if (length ($isbnfield->subfield('a')) < 10) {
613 print "<marc>truncated isbn (020\$a)\r\n" if $marcprint;
614 warn("truncated isbn") if $marcprint;
617 my $isbn = substr($isbnfield->subfield('a'), 0, 10);
618 print "SN - ", &charconv
($isbn), "\r\n";
622 ##********************************************************************
623 ## print_issn(): gets info from MARC field 022
624 ## Arguments: field (022)
625 ##********************************************************************
629 if (!$issnfield || length ($issnfield->subfield('a')) == 0) {
630 print "<marc>no issn found (022\$a)\r\n" if $marcprint;
631 warn("no issn found") if $marcprint;
634 if (length ($issnfield->subfield('a')) < 9) {
635 print "<marc>truncated issn (022\$a)\r\n" if $marcprint;
636 warn("truncated issn") if $marcprint;
639 my $issn = substr($issnfield->subfield('a'), 0, 9);
640 print "SN - ", &charconv
($issn), "\r\n";
645 # print_uri() prints info from 856 u
650 foreach my $f856 (@f856s) {
651 if (my $uri = $f856->subfield('u')) {
652 print "UR - ", charconv
($uri), "\r\n";
657 ##********************************************************************
658 ## print_loc_callno(): gets info from MARC field 050
659 ## Arguments: field (050)
660 ##********************************************************************
661 sub print_loc_callno
{
662 my($callnofield) = @_;
664 if (!$callnofield || length ($callnofield->subfield('a')) == 0) {
665 print "<marc>no LOC call number found (050\$a)\r\n" if $marcprint;
666 warn("no LOC call number found") if $marcprint;
669 print "AV - ", &charconv
($callnofield->subfield('a')), " ", &charconv
($callnofield->subfield('b')), "\r\n";
673 ##********************************************************************
674 ## print_dewey(): gets info from MARC field 082
675 ## Arguments: field (082)
676 ##********************************************************************
678 my($deweyfield) = @_;
680 if (!$deweyfield || length ($deweyfield->subfield('a')) == 0) {
681 print "<marc>no Dewey number found (082\$a)\r\n" if $marcprint;
682 warn("no Dewey number found") if $marcprint;
685 print "U1 - ", &charconv
($deweyfield->subfield('a')), " ", &charconv
($deweyfield->subfield('2')), "\r\n";
689 ##********************************************************************
690 ## print_pubinfo(): gets info from MARC field 260
691 ## Arguments: field (260)
692 ##********************************************************************
694 my($pubinfofield) = @_;
696 if (!$pubinfofield) {
697 print "<marc>no publication information found (260/264)\r\n" if $marcprint;
698 warn("no publication information found") if $marcprint;
701 ## the following information is available in MARC21:
703 ## $b publisher -> PB
705 ## the corresponding subfields for UNIMARC:
707 ## $c publisher -> PB
710 ## all of them are repeatable. We pool all places into a
711 ## comma-separated list in CY. We also pool all publishers
712 ## into a comma-separated list in PB. We break the rule with
713 ## the date field because this wouldn't make much sense. In
714 ## this case, we use the first occurrence for PY, the second
715 ## for Y2, and ignore the rest
717 my @pubsubfields = $pubinfofield->subfields();
723 my $pubsub_publisher;
726 if ($intype eq "unimarc") {
728 $pubsub_publisher = "c";
731 else { ## assume marc21
733 $pubsub_publisher = "b";
737 ## loop over all subfield list entries
738 for my $tuple (@pubsubfields) {
739 ## each tuple consists of the subfield code and the value
740 if (@
$tuple[0] eq $pubsub_place) {
741 ## strip any trailing crap
744 ## pool all occurrences in a list
747 elsif (@
$tuple[0] eq $pubsub_publisher) {
748 ## strip any trailing crap
751 ## pool all occurrences in a list
752 push (@publishers, $_);
754 elsif (@
$tuple[0] eq $pubsub_date) {
755 ## the dates are free-form, so we want to extract
756 ## a four-digit year and leave the rest as
758 $protoyear = @
$tuple[1];
759 print "<marc>Year (260\$c): $protoyear\r\n" if $marcprint;
761 ## strip any separator chars at the end
762 $protoyear =~ s
% *[\
.;:/]*$%%;
764 ## isolate a four-digit year. We discard anything
765 ## preceding the year, but keep everything after
766 ## the year as other info.
767 $protoyear =~ s
%\D
*([0-9\
-]{4})(.*)%$1///$2%;
769 ## check what we've got. If there is no four-digit
770 ## year, make it up. If digits are replaced by '-',
771 ## replace those with 0s
773 if (index($protoyear, "/") == 4) {
775 ## replace all '-' in the four-digit year
777 substr($protoyear,0,4) =~ s!-!0!g;
781 print "<marc>no four-digit year found, use 0000\r\n" if $marcprint;
782 $protoyear = "0000///$protoyear";
783 warn("no four-digit year found, use 0000") if $marcprint;
786 if ($pycounter == 0 && length($protoyear)) {
787 print "PY - $protoyear\r\n";
789 elsif ($pycounter == 1 && length($_)) {
790 print "Y2 - $protoyear\r\n";
797 ## now dump the collected CY and PB lists
799 print "CY - ", &charconv
(join(", ", @cities)), "\r\n";
801 if (@publishers > 0) {
802 print "PB - ", &charconv
(join(", ", @publishers)), "\r\n";
807 ##********************************************************************
808 ## get_keywords(): prints info from MARC fields 6XX
809 ## Arguments: list of fields (6XX)
810 ##********************************************************************
812 my($fieldname, @keywords) = @_;
815 ## a list of all possible subfields
816 my @subfields = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'y', 'z', '2', '3', '4');
818 ## loop over all 6XX fields
819 foreach my $kwfield (@keywords) {
820 if ($kwfield != undef) {
821 ## authornames get special treatment
822 if ($fieldname eq "600") {
823 my $val = normalize_author
($kwfield->subfield('a'), $kwfield->subfield('b'), $kwfield->subfield('c'), $kwfield->indicator('1'));
825 print "<marc>Field $kwfield subfield a:", $kwfield->subfield('a'), "\r\n<marc>Field $kwfield subfield b:", $kwfield->subfield('b'), "\r\n<marc>Field $kwfield subfield c:", $kwfield->subfield('c'), "\r\n" if $marcprint;
828 ## retrieve all available subfields
829 my @kwsubfields = $kwfield->subfields();
831 ## loop over all available subfield tuples
832 foreach my $kwtuple (@kwsubfields) {
833 ## loop over all subfields to check
834 foreach my $subfield (@subfields) {
835 ## [0] contains subfield code
836 if (@
$kwtuple[0] eq $subfield) {
837 ## [1] contains value, remove trailing separators
838 @
$kwtuple[1] =~ s
% *[,;.:/]*$%%;
839 if (length(@
$kwtuple[1]) > 0) {
840 push @kw, @
$kwtuple[1];
841 print "<marc>Field $fieldname subfield $subfield:", @
$kwtuple[1], "\r\n" if $marcprint;
843 ## we can leave the subfields loop here
854 ##********************************************************************
855 ## pool_subx(): adds contents of several subfields to a list
856 ## Arguments: reference to a list
858 ## list of fields (5XX)
859 ##********************************************************************
861 my($aref, $fieldname, @notefields) = @_;
863 ## we use a list that contains the interesting subfields
865 # ToDo: this is apparently correct only for marc21
868 if ($fieldname eq "500") {
871 elsif ($fieldname eq "501") {
874 elsif ($fieldname eq "502") {
877 elsif ($fieldname eq "504") {
878 @subfields = ('a', 'b');
880 elsif ($fieldname eq "505") {
881 @subfields = ('a', 'g', 'r', 't', 'u');
883 elsif ($fieldname eq "506") {
884 @subfields = ('a', 'b', 'c', 'd', 'e');
886 elsif ($fieldname eq "507") {
887 @subfields = ('a', 'b');
889 elsif ($fieldname eq "508") {
892 elsif ($fieldname eq "510") {
893 @subfields = ('a', 'b', 'c', 'x', '3');
895 elsif ($fieldname eq "511") {
898 elsif ($fieldname eq "513") {
899 @subfields = ('a', 'b');
901 elsif ($fieldname eq "514") {
902 @subfields = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'u', 'z');
904 elsif ($fieldname eq "515") {
907 elsif ($fieldname eq "516") {
910 elsif ($fieldname eq "518") {
911 @subfields = ('a', '3');
913 elsif ($fieldname eq "521") {
914 @subfields = ('a', 'b', '3');
916 elsif ($fieldname eq "522") {
919 elsif ($fieldname eq "524") {
920 @subfields = ('a', '2', '3');
922 elsif ($fieldname eq "525") {
925 elsif ($fieldname eq "526") {
926 @subfields = ('a', 'b', 'c', 'd', 'i', 'x', 'z', '5');
928 elsif ($fieldname eq "530") {
929 @subfields = ('a', 'b', 'c', 'd', 'u', '3');
931 elsif ($fieldname eq "533") {
932 @subfields = ('a', 'b', 'c', 'd', 'e', 'f', 'm', 'n', '3');
934 elsif ($fieldname eq "534") {
935 @subfields = ('a', 'b', 'c', 'e', 'f', 'k', 'l', 'm', 'n', 'p', 't', 'x', 'z');
937 elsif ($fieldname eq "535") {
938 @subfields = ('a', 'b', 'c', 'd', 'g', '3');
941 ## loop over all notefields
942 foreach my $notefield (@notefields) {
943 if (defined $notefield) {
944 ## retrieve all available subfield tuples
945 my @notesubfields = $notefield->subfields();
947 ## loop over all subfield tuples
948 foreach my $notetuple (@notesubfields) {
949 ## loop over all subfields to check
950 foreach my $subfield (@subfields) {
951 ## [0] contains subfield code
952 if (@
$notetuple[0] eq $subfield) {
953 ## [1] contains value, remove trailing separators
954 print "<marc>field $fieldname subfield $subfield: ", @
$notetuple[1], "\r\n" if $marcprint;
955 @
$notetuple[1] =~ s
% *[,;.:/]*$%%;
956 if (length(@
$notetuple[1]) > 0) {
958 push @
{$aref}, @
$notetuple[1];
968 ##********************************************************************
969 ## print_abstract(): prints abstract fields
970 ## Arguments: list of fields (520)
971 ##********************************************************************
973 # ToDo: take care of repeatable subfields
976 ## we check the following subfields
977 my @subfields = ('a', 'b');
979 ## we generate a list for all useful strings
982 ## loop over all abfields
983 foreach my $abfield (@abfields) {
984 foreach my $field (@subfields) {
985 if ( length( $abfield->subfield($field) ) > 0 ) {
986 my $ab = $abfield->subfield($field);
988 print "<marc>field 520 subfield $field: $ab\r\n" if $marcprint;
990 ## strip trailing separators
991 $ab =~ s
% *[;,:./]*$%%;
993 ## add string to the list
994 push( @abstrings, $ab );
999 my $allabs = join "; ", @abstrings;
1001 if (length($allabs) > 0) {
1002 print "N2 - ", &charconv
($allabs), "\r\n";
1009 ##********************************************************************
1010 ## charconv(): converts to a different charset based on a global var
1011 ## Arguments: string
1013 ##********************************************************************
1016 ## return unaltered if already utf-8
1019 elsif (my $uniout eq "t") {
1021 return marc8_to_utf8
("@_");
1024 ## return unaltered if no utf-8 requested