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
44 # This file is part of Koha.
46 # Koha is free software; you can redistribute it and/or modify it under the
47 # terms of the GNU General Public License as published by the Free Software
48 # Foundation; either version 2 of the License, or (at your option) any later
51 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
52 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
53 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
55 # You should have received a copy of the GNU General Public License along with
56 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
57 # Suite 330, Boston, MA 02111-1307 USA
62 #use warnings; FIXME - Bug 2505
64 use vars qw($VERSION @ISA @EXPORT);
66 # set the version for version checking
71 # only export API methods
78 =head1 marc2bibtex - Convert from UNIMARC to RIS
80 my ($ris) = marc2ris($record);
84 C<$record> - a MARC::Record object
92 my $marcflavour = C4::Context->preference("marcflavour");
93 my $intype = lc($marcflavour);
94 my $marcprint = 0; # Debug flag;
96 # Let's redirect stdout
97 open my $oldout, ">&STDOUT";
100 open STDOUT,'>', \$outvar;
103 ## First we should check the character encoding. This may be
104 ## MARC-8 or UTF-8. The former is indicated by a blank, the latter
105 ## by 'a' at position 09 (zero-based) of the leader
106 my $leader = $record->leader();
107 if ($intype eq "marc21") {
108 if ($leader =~ /^.{9}a/) {
109 print "<marc>---\r\n<marc>UTF-8 data\r\n" if $marcprint;
113 print "<marc>---\r\n<marc>MARC-8 data\r\n" if $marcprint;
116 ## else: other MARC formats do not specify the character encoding
117 ## we assume it's *not* UTF-8
120 &print_typetag($leader);
122 ## retrieve all author fields and collect them in a list
125 if ($intype eq "unimarc") {
126 ## Fields 700, 701, and 702 can contain author names
127 @author_fields = ($record->field('700'), $record->field('701'), $record->field('702'));
129 else { ## marc21, ukmarc
130 ## Field 100 sometimes carries main author
131 ## Field(s) 700 carry added entries - personal names
132 @author_fields = ($record->field('100'), $record->field('700'));
135 ## loop over all author fields
136 foreach my $field (@author_fields) {
137 if (length($field)) {
138 my $author = &get_author($field);
139 print "AU - ",&charconv($author),"\r\n";
143 # ToDo: should we specify anonymous as author if we didn't find
144 # one? or use one of the corporate/meeting names below?
146 ## add corporate names or meeting names as editors ??
149 if ($intype eq "unimarc") {
150 ## Fields 710, 711, and 712 can carry corporate names
151 ## Field(s) 720, 721, 722, 730 have additional candidates
152 @editor_fields = ($record->field('710'), $record->field('711'), $record->field('712'), $record->field('720'), $record->field('721'), $record->field('722'), $record->field('730'));
154 else { ## marc21, ukmarc
155 ## Fields 110 and 111 carry the main entries - corporate name and
156 ## meeting name, respectively
157 ## Field(s) 710, 711 carry added entries - personal names
158 @editor_fields = ($record->field('110'), $record->field('111'), $record->field('710'), $record->field('711'));
161 ## loop over all editor fields
162 foreach my $field (@editor_fields) {
163 if (length($field)) {
164 my $editor = &get_editor($field);
165 print "ED - ",&charconv($editor),"\r\n";
169 ## get info from the title field
170 if ($intype eq "unimarc") {
171 &print_title($record->field('200'));
173 else { ## marc21, ukmarc
174 &print_title($record->field('245'));
178 if ($intype eq "unimarc") {
179 &print_stitle($record->field('225'));
181 else { ## marc21, ukmarc
182 &print_stitle($record->field('490'));
186 if ($intype eq "unimarc") {
187 &print_isbn($record->field('010'));
188 &print_issn($record->field('011'));
190 elsif ($intype eq "ukmarc") {
191 &print_isbn($record->field('021'));
192 ## this is just an assumption
193 &print_issn($record->field('022'));
195 else { ## assume marc21
196 &print_isbn($record->field('020'));
197 &print_issn($record->field('022'));
200 if ($intype eq "marc21") {
201 &print_loc_callno($record->field('050'));
202 &print_dewey($record->field('082'));
204 ## else: unimarc, ukmarc do not seem to store call numbers?
207 if ($intype eq "unimarc") {
208 &print_pubinfo($record->field('210'));
210 else { ## marc21, ukmarc
211 &print_pubinfo($record->field('260'));
214 ## 6XX fields contain KW candidates. We add all of them to a
215 ## hash to eliminate duplicates
218 if ($intype eq "unimarc") {
219 foreach ('600', '601', '602', '604', '605', '606','607', '608', '610', '615', '620', '660'. '661', '670', '675', '676', '680', '686') {
220 &get_keywords(\%kwpool, "$_",$record->field($_));
223 elsif ($intype eq "ukmarc") {
224 foreach ('600', '610', '611', '630', '650', '651','653', '655', '660', '661', '668', '690', '691', '692', '695') {
225 &get_keywords(\%kwpool, "$_",$record->field($_));
228 else { ## assume marc21
229 foreach ('600', '610', '611', '630', '650', '651','653', '654', '655', '656', '657', '658') {
230 &get_keywords(\%kwpool, "$_",$record->field($_));
234 ## print all keywords found in the hash. The value of each hash
235 ## entry is the number of occurrences, but we're not really interested
236 ## in that and rather print the key
237 while (my ($key, $value) = each %kwpool) {
238 print "KW - ", &charconv($key), "\r\n";
241 ## 5XX have various candidates for notes and abstracts. We pool
242 ## all notes-like stuff in one list.
245 ## these fields have notes candidates
246 if ($intype eq "unimarc") {
247 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') {
248 &pool_subx(\@notepool, $_, $record->field($_));
251 elsif ($intype eq "ukmarc") {
252 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') {
253 &pool_subx(\@notepool, $_, $record->field($_));
256 else { ## assume marc21
257 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') {
258 &pool_subx(\@notepool, $_, $record->field($_));
262 my $allnotes = join "; ", @notepool;
264 if (length($allnotes) > 0) {
265 print "N1 - ", &charconv($allnotes), "\r\n";
268 ## 320/520 have the abstract
269 if ($intype eq "unimarc") {
270 &print_abstract($record->field('320'));
272 elsif ($intype eq "ukmarc") {
273 &print_abstract($record->field('512'), $record->field('513'));
275 else { ## assume marc21
276 &print_abstract($record->field('520'));
280 if ($record->field('856')){
281 print_uri($record->field('856'));
287 # Let's re-redirect stdout
289 open STDOUT, ">&", $oldout;
296 ##********************************************************************
297 ## print_typetag(): prints the first line of a RIS dataset including
298 ## the preceeding newline
299 ## Argument: the leader of a MARC dataset
300 ## Returns: the value at leader position 06
301 ##********************************************************************
304 ## the keys of typehash are the allowed values at position 06
305 ## of the leader of a MARC record, the values are the RIS types
306 ## that might appropriately represent these types.
340 ## The type of a MARC record is found at position 06 of the leader
341 my $typeofrecord = substr($leader, 6, 1);
343 ## ToDo: for books, field 008 positions 24-27 might have a few more
348 ## the ukmarc here is just a guess
349 if ($intype eq "marc21" || $intype eq "ukmarc") {
350 %typehash = %ustypehash;
352 elsif ($intype eq "unimarc") {
353 %typehash = %unitypehash;
356 ## assume MARC21 as default
357 %typehash = %ustypehash;
360 if (!exists $typehash{$typeofrecord}) {
361 print "TY - BOOK\r\n"; ## most reasonable default
362 warn ("no type found - assume BOOK") if $marcprint;
365 print "TY - $typehash{$typeofrecord}\r\n";
368 ## use $typeofrecord as the return value, just in case
372 ##********************************************************************
373 ## normalize_author(): normalizes an authorname
374 ## Arguments: authorname subfield a
375 ## authorname subfield b
376 ## authorname subfield c
377 ## name type if known: 0=direct order
378 ## 1=only surname or full name in
380 ## 3=family, clan, dynasty name
381 ## Returns: the normalized authorname
382 ##********************************************************************
383 sub normalize_author {
384 my($rawauthora, $rawauthorb, $rawauthorc, $nametype) = @_;
386 if ($nametype == 0) {
387 # ToDo: convert every input to Last[,(F.|First)[ (M.|Middle)[,Suffix]]]
388 warn("name >>$rawauthora<< in direct order - leave as is") if $marcprint;
391 elsif ($nametype == 1) {
392 ## start munging subfield a (the real name part)
393 ## remove spaces after separators
394 $rawauthora =~ s%([,.]+) *%$1%g;
396 ## remove trailing separators after spaces
397 $rawauthora =~ s% *[,;:/]*$%%;
399 ## remove periods after a non-abbreviated name
400 $rawauthora =~ s%(\w{2,})\.%$1%g;
402 ## start munging subfield b (something like the suffix)
403 ## remove trailing separators after spaces
404 $rawauthorb =~ s% *[,;:/]*$%%;
406 ## we currently ignore subfield c until someone complains
407 if (length($rawauthorb) > 0) {
408 return join ",", ($rawauthora, $rawauthorb);
414 elsif ($nametype == 3) {
419 ##********************************************************************
420 ## get_author(): gets authorname info from MARC fields 100, 700
421 ## Argument: field (100 or 700)
422 ## Returns: an author string in the format found in the record
423 ##********************************************************************
425 my ($authorfield) = @_;
428 ## the sequence of the name parts is encoded either in indicator
429 ## 1 (marc21) or 2 (unimarc)
430 if ($intype eq "unimarc") {
433 else { ## assume marc21
437 print "<marc>:Author(Ind$indicator): ", $authorfield->indicator("$indicator"),"\r\n" if $marcprint;
438 print "<marc>:Author(\$a): ", $authorfield->subfield('a'),"\r\n" if $marcprint;
439 print "<marc>:Author(\$b): ", $authorfield->subfield('b'),"\r\n" if $marcprint;
440 print "<marc>:Author(\$c): ", $authorfield->subfield('c'),"\r\n" if $marcprint;
441 print "<marc>:Author(\$h): ", $authorfield->subfield('h'),"\r\n" if $marcprint;
442 if ($intype eq "ukmarc") {
443 my $authorname = $authorfield->subfield('a') . "," . $authorfield->subfield('h');
444 normalize_author($authorname, $authorfield->subfield('b'), $authorfield->subfield('c'), $authorfield->indicator("$indicator"));
447 normalize_author($authorfield->subfield('a'), $authorfield->subfield('b'), $authorfield->subfield('c'), $authorfield->indicator("$indicator"));
451 ##********************************************************************
452 ## get_editor(): gets editor info from MARC fields 110, 111, 710, 711
453 ## Argument: field (110, 111, 710, or 711)
454 ## Returns: an author string in the format found in the record
455 ##********************************************************************
457 my ($editorfield) = @_;
463 print "<marc>Editor(\$a): ", $editorfield->subfield('a'),"\r\n" if $marcprint;
464 print "<marc>Editor(\$b): ", $editorfield->subfield('b'),"\r\n" if $marcprint;
465 print "<marc>editor(\$c): ", $editorfield->subfield('c'),"\r\n" if $marcprint;
466 return $editorfield->subfield('a');
470 ##********************************************************************
471 ## print_title(): gets info from MARC field 245
472 ## Arguments: field (245)
474 ##********************************************************************
476 my ($titlefield) = @_;
478 print "<marc>empty title field (245)\r\n" if $marcprint;
479 warn("empty title field (245)") if $marcprint;
482 print "<marc>Title(\$a): ",$titlefield->subfield('a'),"\r\n" if $marcprint;
483 print "<marc>Title(\$b): ",$titlefield->subfield('b'),"\r\n" if $marcprint;
484 print "<marc>Title(\$c): ",$titlefield->subfield('c'),"\r\n" if $marcprint;
486 ## The title is usually written in a very odd notation. The title
487 ## proper ($a) often ends with a space followed by a separator like
488 ## a slash or a colon. The subtitle ($b) doesn't start with a space
489 ## so simple concatenation looks odd. We have to conditionally remove
490 ## the separator and make sure there's a space between title and
493 my $clean_title = $titlefield->subfield('a');
495 my $clean_subtitle = $titlefield->subfield('b');
496 $clean_title =~ s% *[/:;.]$%%;
497 $clean_subtitle =~ s%^ *(.*) *[/:;.]$%$1%;
499 if (length($clean_title) > 0
500 || (length($clean_subtitle) > 0 && $intype ne "unimarc")) {
501 print "TI - ", &charconv($clean_title);
503 ## subfield $b is relevant only for marc21/ukmarc
504 if (length($clean_subtitle) > 0 && $intype ne "unimarc") {
505 print ": ",&charconv($clean_subtitle);
510 ## The statement of responsibility is just this: horrors. There is
511 ## no formal definition how authors, editors and the like should
512 ## be written and designated. The field is free-form and resistant
513 ## to all parsing efforts, so this information is lost on me
517 ##********************************************************************
518 ## print_stitle(): prints info from series title field
521 ##********************************************************************
523 my ($titlefield) = @_;
526 print "<marc>empty series title field\r\n" if $marcprint;
529 print "<marc>Series title(\$a): ",$titlefield->subfield('a'),"\r\n" if $marcprint;
530 my $clean_title = $titlefield->subfield('a');
532 $clean_title =~ s% *[/:;.]$%%;
534 if (length($clean_title) > 0) {
535 print "T2 - ", &charconv($clean_title),"\r\n";
538 if ($intype eq "unimarc") {
539 print "<marc>Series vol(\$v): ",$titlefield->subfield('v'),"\r\n" if $marcprint;
540 if (length($titlefield->subfield('v')) > 0) {
541 print "VL - ", &charconv($titlefield->subfield('v')),"\r\n";
547 ##********************************************************************
548 ## print_isbn(): gets info from MARC field 020
549 ## Arguments: field (020)
550 ##********************************************************************
554 if (!$isbnfield || length ($isbnfield->subfield('a')) == 0) {
555 print "<marc>no isbn found (020\$a)\r\n" if $marcprint;
556 warn("no isbn found") if $marcprint;
559 if (length ($isbnfield->subfield('a')) < 10) {
560 print "<marc>truncated isbn (020\$a)\r\n" if $marcprint;
561 warn("truncated isbn") if $marcprint;
564 my $isbn = substr($isbnfield->subfield('a'), 0, 10);
565 print "SN - ", &charconv($isbn), "\r\n";
569 ##********************************************************************
570 ## print_issn(): gets info from MARC field 022
571 ## Arguments: field (022)
572 ##********************************************************************
576 if (!$issnfield || length ($issnfield->subfield('a')) == 0) {
577 print "<marc>no issn found (022\$a)\r\n" if $marcprint;
578 warn("no issn found") if $marcprint;
581 if (length ($issnfield->subfield('a')) < 9) {
582 print "<marc>truncated issn (022\$a)\r\n" if $marcprint;
583 warn("truncated issn") if $marcprint;
586 my $issn = substr($issnfield->subfield('a'), 0, 9);
587 print "SN - ", &charconv($issn), "\r\n";
592 # print_uri() prints info from 856 u
597 if (my $uri = $f856->subfield('u')){
598 print "UR - ", charconv($uri), "\n";
602 ##********************************************************************
603 ## print_loc_callno(): gets info from MARC field 050
604 ## Arguments: field (050)
605 ##********************************************************************
606 sub print_loc_callno {
607 my($callnofield) = @_;
609 if (!$callnofield || length ($callnofield->subfield('a')) == 0) {
610 print "<marc>no LOC call number found (050\$a)\r\n" if $marcprint;
611 warn("no LOC call number found") if $marcprint;
614 print "AV - ", &charconv($callnofield->subfield('a')), " ", &charconv($callnofield->subfield('b')), "\r\n";
618 ##********************************************************************
619 ## print_dewey(): gets info from MARC field 082
620 ## Arguments: field (082)
621 ##********************************************************************
623 my($deweyfield) = @_;
625 if (!$deweyfield || length ($deweyfield->subfield('a')) == 0) {
626 print "<marc>no Dewey number found (082\$a)\r\n" if $marcprint;
627 warn("no Dewey number found") if $marcprint;
630 print "U1 - ", &charconv($deweyfield->subfield('a')), " ", &charconv($deweyfield->subfield('2')), "\r\n";
634 ##********************************************************************
635 ## print_pubinfo(): gets info from MARC field 260
636 ## Arguments: field (260)
637 ##********************************************************************
639 my($pubinfofield) = @_;
641 if (!$pubinfofield) {
642 print "<marc>no publication information found (260)\r\n" if $marcprint;
643 warn("no publication information found") if $marcprint;
646 ## the following information is available in MARC21:
648 ## $b publisher -> PB
650 ## the corresponding subfields for UNIMARC:
652 ## $c publisher -> PB
655 ## all of them are repeatable. We pool all places into a
656 ## comma-separated list in CY. We also pool all publishers
657 ## into a comma-separated list in PB. We break the rule with
658 ## the date field because this wouldn't make much sense. In
659 ## this case, we use the first occurrence for PY, the second
660 ## for Y2, and ignore the rest
662 my @pubsubfields = $pubinfofield->subfields();
668 my $pubsub_publisher;
671 if ($intype eq "unimarc") {
673 $pubsub_publisher = "c";
676 else { ## assume marc21
678 $pubsub_publisher = "b";
682 ## loop over all subfield list entries
683 for my $tuple (@pubsubfields) {
684 ## each tuple consists of the subfield code and the value
685 if (@$tuple[0] eq $pubsub_place) {
686 ## strip any trailing crap
689 ## pool all occurrences in a list
692 elsif (@$tuple[0] eq $pubsub_publisher) {
693 ## strip any trailing crap
696 ## pool all occurrences in a list
697 push (@publishers, $_);
699 elsif (@$tuple[0] eq $pubsub_date) {
700 ## the dates are free-form, so we want to extract
701 ## a four-digit year and leave the rest as
703 $protoyear = @$tuple[1];
704 print "<marc>Year (260\$c): $protoyear\r\n" if $marcprint;
706 ## strip any separator chars at the end
707 $protoyear =~ s% *[\.;:/]*$%%;
709 ## isolate a four-digit year. We discard anything
710 ## preceeding the year, but keep everything after
711 ## the year as other info.
712 $protoyear =~ s%\D*([0-9\-]{4})(.*)%$1///$2%;
714 ## check what we've got. If there is no four-digit
715 ## year, make it up. If digits are replaced by '-',
716 ## replace those with 0s
718 if (index($protoyear, "/") == 4) {
720 ## replace all '-' in the four-digit year
722 substr($protoyear,0,4) =~ s!-!0!g;
726 print "<marc>no four-digit year found, use 0000\r\n" if $marcprint;
727 $protoyear = "0000///$protoyear";
728 warn("no four-digit year found, use 0000") if $marcprint;
731 if ($pycounter == 0 && length($protoyear)) {
732 print "PY - $protoyear\r\n";
734 elsif ($pycounter == 1 && length($_)) {
735 print "Y2 - $protoyear\r\n";
742 ## now dump the collected CY and PB lists
744 print "CY - ", &charconv(join(", ", @cities)), "\r\n";
746 if (@publishers > 0) {
747 print "PB - ", &charconv(join(", ", @publishers)), "\r\n";
752 ##********************************************************************
753 ## get_keywords(): prints info from MARC fields 6XX
754 ## Arguments: list of fields (6XX)
755 ##********************************************************************
757 my($href, $fieldname, @keywords) = @_;
759 ## a list of all possible subfields
760 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');
762 ## loop over all 6XX fields
763 foreach $kwfield (@keywords) {
764 if ($kwfield != undef) {
765 ## authornames get special treatment
766 if ($fieldname eq "600") {
767 my $val = normalize_author($kwfield->subfield('a'), $kwfield->subfield('b'), $kwfield->subfield('c'), $kwfield->indicator('1'));
769 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;
772 ## retrieve all available subfields
773 @kwsubfields = $kwfield->subfields();
775 ## loop over all available subfield tuples
776 foreach $kwtuple (@kwsubfields) {
777 ## loop over all subfields to check
778 foreach $subfield (@subfields) {
779 ## [0] contains subfield code
780 if (@$kwtuple[0] eq $subfield) {
781 ## [1] contains value, remove trailing separators
782 @$kwtuple[1] =~ s% *[,;.:/]*$%%;
783 if (length(@$kwtuple[1]) > 0) {
785 ${$href}{@$kwtuple[1]} += 1;
786 print "<marc>Field $fieldname subfield $subfield:", @$kwtuple[1], "\r\n" if $marcprint;
788 ## we can leave the subfields loop here
798 ##********************************************************************
799 ## pool_subx(): adds contents of several subfields to a list
800 ## Arguments: reference to a list
802 ## list of fields (5XX)
803 ##********************************************************************
805 my($aref, $fieldname, @notefields) = @_;
807 ## we use a list that contains the interesting subfields
809 # ToDo: this is apparently correct only for marc21
812 if ($fieldname eq "500") {
815 elsif ($fieldname eq "501") {
818 elsif ($fieldname eq "502") {
821 elsif ($fieldname eq "504") {
822 @subfields = ('a', 'b');
824 elsif ($fieldname eq "505") {
825 @subfields = ('a', 'g', 'r', 't', 'u');
827 elsif ($fieldname eq "506") {
828 @subfields = ('a', 'b', 'c', 'd', 'e');
830 elsif ($fieldname eq "507") {
831 @subfields = ('a', 'b');
833 elsif ($fieldname eq "508") {
836 elsif ($fieldname eq "510") {
837 @subfields = ('a', 'b', 'c', 'x', '3');
839 elsif ($fieldname eq "511") {
842 elsif ($fieldname eq "513") {
843 @subfields = ('a', 'b');
845 elsif ($fieldname eq "514") {
846 @subfields = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'u', 'z');
848 elsif ($fieldname eq "515") {
851 elsif ($fieldname eq "516") {
854 elsif ($fieldname eq "518") {
855 @subfields = ('a', '3');
857 elsif ($fieldname eq "521") {
858 @subfields = ('a', 'b', '3');
860 elsif ($fieldname eq "522") {
863 elsif ($fieldname eq "524") {
864 @subfields = ('a', '2', '3');
866 elsif ($fieldname eq "525") {
869 elsif ($fieldname eq "526") {
870 @subfields = ('a', 'b', 'c', 'd', 'i', 'x', 'z', '5');
872 elsif ($fieldname eq "530") {
873 @subfields = ('a', 'b', 'c', 'd', 'u', '3');
875 elsif ($fieldname eq "533") {
876 @subfields = ('a', 'b', 'c', 'd', 'e', 'f', 'm', 'n', '3');
878 elsif ($fieldname eq "534") {
879 @subfields = ('a', 'b', 'c', 'e', 'f', 'k', 'l', 'm', 'n', 'p', 't', 'x', 'z');
881 elsif ($fieldname eq "535") {
882 @subfields = ('a', 'b', 'c', 'd', 'g', '3');
885 ## loop over all notefields
886 foreach $notefield (@notefields) {
887 if ($notefield != undef) {
888 ## retrieve all available subfield tuples
889 @notesubfields = $notefield->subfields();
891 ## loop over all subfield tuples
892 foreach $notetuple (@notesubfields) {
893 ## loop over all subfields to check
894 foreach $subfield (@subfields) {
895 ## [0] contains subfield code
896 if (@$notetuple[0] eq $subfield) {
897 ## [1] contains value, remove trailing separators
898 print "<marc>field $fieldname subfield $subfield: ", @$notetuple[1], "\r\n" if $marcprint;
899 @$notetuple[1] =~ s% *[,;.:/]*$%%;
900 if (length(@$notetuple[1]) > 0) {
902 push @{$aref}, @$notetuple[1];
912 ##********************************************************************
913 ## print_abstract(): prints abstract fields
914 ## Arguments: list of fields (520)
915 ##********************************************************************
917 # ToDo: take care of repeatable subfields
920 ## we check the following subfields
921 my @subfields = ('a', 'b');
923 ## we generate a list for all useful strings
926 ## loop over all abfields
927 foreach $abfield (@abfields) {
928 foreach $field (@subfields) {
929 if (length ($abfield->subfield($field)) > 0) {
930 my $ab = $abfield->subfield($field);
932 print "<marc>field 520 subfield $field: $ab\r\n" if $marcprint;
934 ## strip trailing separators
935 $ab =~ s% *[;,:./]*$%%;
937 ## add string to the list
938 push (@abstrings, $ab);
943 my $allabs = join "; ", @abstrings;
945 if (length($allabs) > 0) {
946 print "N2 - ", &charconv($allabs), "\r\n";
953 ##********************************************************************
954 ## charconv(): converts to a different charset based on a global var
957 ##********************************************************************
960 ## return unaltered if already utf-8
963 elsif ($uniout eq "t") {
965 return marc8_to_utf8("@_");
968 ## return unaltered if no utf-8 requested