Bugzilla – Attachment 35485 Details for
Bug 12357
Enhancements to RIS and BibTeX exporting
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 12357 - Enhancements to RIS and BibTeX exporting
Bug-12357---Enhancements-to-RIS-and-BibTeX-exporti.patch (text/plain), 17.24 KB, created by
Kyle M Hall (khall)
on 2015-01-23 12:19:19 UTC
(
hide
)
Description:
Bug 12357 - Enhancements to RIS and BibTeX exporting
Filename:
MIME Type:
Creator:
Kyle M Hall (khall)
Created:
2015-01-23 12:19:19 UTC
Size:
17.24 KB
patch
obsolete
>From a151d11e516629f11c6741c4a13f6a7b7ee953ee Mon Sep 17 00:00:00 2001 >From: Kyle M Hall <kyle@bywatersolutions.com> >Date: Fri, 23 Jan 2015 07:11:36 -0500 >Subject: [PATCH] Bug 12357 - Enhancements to RIS and BibTeX exporting > >Some libraries would like to be able to add arbitrary fields to both the >RIS and BibTeX citation formats that a record can be saved as from the >staff intranet and public catalog. In addition, they would like to be >able to override the default record type and use Koha's itemtype as the >record type for those formats as well. > >Test Plan: > 1) Apply this patch > 2) Run updatedatabase.pl > 3) Add the following to the new syspref RisExportAdditionalFields: >TY: 942$c >LC: 010$a >NT: [501$a, 505$g] > 4) Find or create a record with an 010$a (lccn) field, a 501$a field, > a 942$c field, and multiple 505$g fields. > 5) Locate the record in the catalog, choose "Save" and select RIS > 6) Inspect the downloaded file, note the replaced TY field, the LC > field, and multiple NT fields > 7) Add the following to the new syspref BibtexExportAdditionalFields: >'@': 942$c >lccn: 010$a >notes: [501$a, 505$g] > 9) Using the previously selected record, choose "Save" and select BIBTEX >10) Inspect the downloaded file, note the lccn, the multiple note > fields, and the new record type value > >Signed-off-by: Frederic Demians <f.demians@tamil.fr> >--- > C4/Record.pm | 71 ++++++++++++--- > C4/Ris.pm | 97 +++++++++++++++----- > installer/data/mysql/sysprefs.sql | 2 + > installer/data/mysql/updatedatabase.pl | 16 +++ > .../en/modules/admin/preferences/cataloguing.pref | 23 +++++ > 5 files changed, 173 insertions(+), 36 deletions(-) > >diff --git a/C4/Record.pm b/C4/Record.pm >index 16d3f54..8f2ad9c 100644 >--- a/C4/Record.pm >+++ b/C4/Record.pm >@@ -34,6 +34,7 @@ use C4::Koha; #marc2csv > use C4::XSLT (); > use YAML; #marcrecords2csv > use Text::CSV::Encoded; #marc2csv >+use Koha::SimpleMARC qw(read_field); > > use vars qw($VERSION @ISA @EXPORT); > >@@ -326,8 +327,8 @@ sub marc2endnote { > } > my $fields = { > DB => C4::Context->preference("LibraryName"), >- Title => $marc_rec_obj->title(), >- Author => $marc_rec_obj->author(), >+ Title => $marc_rec_obj->title(), >+ Author => $marc_rec_obj->author(), > Publisher => $f710a, > City => $f260a, > Year => $marc_rec_obj->publication_date, >@@ -345,7 +346,7 @@ sub marc2endnote { > $template.="AB - Abstract\n" if $abstract; > my ($text, $errmsg) = $style->format($template, $fields); > return ($text); >- >+ > } > > =head2 marc2csv - Convert several records from UNIMARC to CSV >@@ -464,7 +465,7 @@ sub marcrecord2csv { > foreach (@marcfieldsarray) { > my @result = split('=', $_); > if (scalar(@result) == 2) { >- push @marcfields, { header => $result[0], field => $result[1] }; >+ push @marcfields, { header => $result[0], field => $result[1] }; > } else { > push @marcfields, { field => $result[0] } > } >@@ -480,7 +481,7 @@ sub marcrecord2csv { > > my $field = $_->{field}; > # Remove any blank char that might have unintentionally insered into the tag name >- $field =~ s/\s+//g; >+ $field =~ s/\s+//g; > > # If we have a user-supplied header, we use it > if (exists $_->{header}) { >@@ -504,7 +505,7 @@ sub marcrecord2csv { > } > } > $csv->combine(@marcfieldsheaders); >- $output = $csv->string() . "\n"; >+ $output = $csv->string() . "\n"; > } > > # For each marcfield to export >@@ -529,7 +530,7 @@ sub marcrecord2csv { > push @tmpfields, (defined $authvalues->{$subfield}) ? $authvalues->{$subfield} : $subfield; > } > } >- push (@fieldstab, join($subfieldseparator, @tmpfields)); >+ push (@fieldstab, join($subfieldseparator, @tmpfields)); > # Or a field > } else { > my @fields = ($record->field($marcfield)); >@@ -557,7 +558,7 @@ sub marcrecord2csv { > > push @valuesarray, $value; > } >- push (@fieldstab, join($fieldseparator, @valuesarray)); >+ push (@fieldstab, join($fieldseparator, @valuesarray)); > } > }; > >@@ -599,7 +600,7 @@ sub changeEncoding { > my $error; > unless($flavour) {$flavour = C4::Context->preference("marcflavour")}; > unless($to_encoding) {$to_encoding = "UTF-8"}; >- >+ > # ISO-2709 Record (MARC21 or UNIMARC) > if (lc($format) =~ /^marc$/o) { > # if we're converting encoding of an ISO2709 file, we need to roundtrip through XML >@@ -610,7 +611,7 @@ sub changeEncoding { > unless ($error) { > ($error,$newrecord) = marcxml2marc($marcxml,$to_encoding,$flavour); > } >- >+ > # MARCXML Record > } elsif (lc($format) =~ /^marcxml$/o) { # MARCXML Record > my $marc; >@@ -708,14 +709,60 @@ sub marc2bibtex { > ); > } > >- $tex .= "\@book{"; >+ my $BibtexExportAdditionalFields = C4::Context->preference('BibtexExportAdditionalFields'); >+ my $additional_fields; >+ if ($BibtexExportAdditionalFields) { >+ $BibtexExportAdditionalFields = "$BibtexExportAdditionalFields\n\n"; >+ $additional_fields = eval { YAML::Load($BibtexExportAdditionalFields); }; >+ if ($@) { >+ warn "Unable to parse BibtexExportAdditionalFields : $@"; >+ $additional_fields = undef; >+ } >+ } >+ >+ if ( $additional_fields && $additional_fields->{'@'} ) { >+ my ( $f, $sf ) = split( /\$/, $additional_fields->{'@'} ); >+ my ( $type ) = read_field( { record => $record, field => $f, subfield => $sf, field_numbers => [1] } ); >+ >+ if ($type) { >+ $tex .= '@' . $type . '{'; >+ } >+ else { >+ $tex .= "\@book{"; >+ } >+ } >+ else { >+ $tex .= "\@book{"; >+ } >+ > my @elt; > for ( my $i = 0 ; $i < scalar( @bh ) ; $i = $i + 2 ) { > next unless $bh[$i+1]; > push @elt, qq|\t$bh[$i] = {$bh[$i+1]}|; > } > $tex .= join(",\n", $id, @elt); >- $tex .= "\n}\n"; >+ $tex .= "\n"; >+ >+ if ($additional_fields) { >+ foreach my $bibtex_tag ( keys %$additional_fields ) { >+ next if $bibtex_tag eq '@'; >+ >+ my @fields = >+ ref( $additional_fields->{$bibtex_tag} ) eq 'ARRAY' >+ ? @{ $additional_fields->{$bibtex_tag} } >+ : $additional_fields->{$bibtex_tag}; >+ >+ for my $tag (@fields) { >+ my ( $f, $sf ) = split( /\$/, $tag ); >+ my @values = read_field( { record => $record, field => $f, subfield => $sf } ); >+ foreach my $v (@values) { >+ $tex .= qq(\t$bibtex_tag = {$v}\n); >+ } >+ } >+ } >+ } >+ >+ $tex .= "}\n"; > > return $tex; > } >diff --git a/C4/Ris.pm b/C4/Ris.pm >index 137b99d..f212ca2 100644 >--- a/C4/Ris.pm >+++ b/C4/Ris.pm >@@ -59,12 +59,14 @@ package C4::Ris; > # > # > >-#use strict; >-#use warnings; >+use Modern::Perl; > > use List::MoreUtils qw/uniq/; > use vars qw($VERSION @ISA @EXPORT); > >+use C4::Biblio qw(GetMarcSubfieldStructureFromKohaField); >+use Koha::SimpleMARC qw(read_field); >+ > # set the version for version checking > $VERSION = 3.07.00.049; > >@@ -76,6 +78,11 @@ $VERSION = 3.07.00.049; > &marc2ris > ); > >+our $utf; >+our $intype; >+our $marcprint; >+our $protoyear; >+ > > =head1 marc2bibtex - Convert from UNIMARC to RIS > >@@ -101,25 +108,47 @@ sub marc2ris { > close STDOUT; > open STDOUT,'>', \$outvar; > >+ ## First we should check the character encoding. This may be >+ ## MARC-8 or UTF-8. The former is indicated by a blank, the latter >+ ## by 'a' at position 09 (zero-based) of the leader >+ my $leader = $record->leader(); >+ if ( $intype eq "marc21" ) { >+ if ( $leader =~ /^.{9}a/ ) { >+ print "<marc>---\r\n<marc>UTF-8 data\r\n" if $marcprint; >+ $utf = 1; >+ } >+ else { >+ print "<marc>---\r\n<marc>MARC-8 data\r\n" if $marcprint; >+ } >+ } >+ ## else: other MARC formats do not specify the character encoding >+ ## we assume it's *not* UTF-8 >+ >+ my $RisExportAdditionalFields = C4::Context->preference('RisExportAdditionalFields'); >+ my $ris_additional_fields; >+ if ($RisExportAdditionalFields) { >+ $RisExportAdditionalFields = "$RisExportAdditionalFields\n\n"; >+ $ris_additional_fields = eval { YAML::Load($RisExportAdditionalFields); }; >+ if ($@) { >+ warn "Unable to parse RisExportAdditionalFields : $@"; >+ $ris_additional_fields = undef; >+ } >+ } > >- ## First we should check the character encoding. This may be >- ## MARC-8 or UTF-8. The former is indicated by a blank, the latter >- ## by 'a' at position 09 (zero-based) of the leader >- my $leader = $record->leader(); >- if ($intype eq "marc21") { >- if ($leader =~ /^.{9}a/) { >- print "<marc>---\r\n<marc>UTF-8 data\r\n" if $marcprint; >- $utf = 1; >- } >- else { >- print "<marc>---\r\n<marc>MARC-8 data\r\n" if $marcprint; >- } >- } >- ## else: other MARC formats do not specify the character encoding >- ## we assume it's *not* UTF-8 >- >- ## start RIS dataset >- &print_typetag($leader); >+ ## start RIS dataset >+ if ( $ris_additional_fields && $ris_additional_fields->{TY} ) { >+ my ( $f, $sf ) = split( /\$/, $ris_additional_fields->{TY} ); >+ my ( $type ) = read_field( { record => $record, field => $f, subfield => $sf, field_numbers => [1] } ); >+ if ($type) { >+ print "TY - $type\r\n"; >+ } >+ else { >+ &print_typetag($leader); >+ } >+ } >+ else { >+ &print_typetag($leader); >+ } > > ## retrieve all author fields and collect them in a list > my @author_fields; >@@ -285,6 +314,25 @@ sub marc2ris { > print_uri($record->field('856')); > } > >+ if ($ris_additional_fields) { >+ foreach my $ris_tag ( keys %$ris_additional_fields ) { >+ next if $ris_tag eq 'TY'; >+ >+ my @fields = >+ ref( $ris_additional_fields->{$ris_tag} ) eq 'ARRAY' >+ ? @{ $ris_additional_fields->{$ris_tag} } >+ : $ris_additional_fields->{$ris_tag}; >+ >+ for my $tag (@fields) { >+ my ( $f, $sf ) = split( /\$/, $tag ); >+ my @values = read_field( { record => $record, field => $f, subfield => $sf } ); >+ foreach my $v (@values) { >+ print "$ris_tag - $v\r\n"; >+ } >+ } >+ } >+ } >+ > ## end RIS dataset > print "ER - \r\n"; > >@@ -497,6 +545,7 @@ sub print_title { > my $clean_title = $titlefield->subfield('a'); > > my $clean_subtitle = $titlefield->subfield('b'); >+$clean_subtitle ||= q{}; > $clean_title =~ s% *[/:;.]$%%; > $clean_subtitle =~ s%^ *(.*) *[/:;.]$%$1%; > >@@ -777,7 +826,7 @@ sub get_keywords { > } > else { > ## retrieve all available subfields >- @kwsubfields = $kwfield->subfields(); >+ my @kwsubfields = $kwfield->subfields(); > > ## loop over all available subfield tuples > foreach my $kwtuple (@kwsubfields) { >@@ -891,9 +940,9 @@ sub pool_subx { > > ## loop over all notefields > foreach my $notefield (@notefields) { >- if ($notefield != undef) { >+ if (defined $notefield) { > ## retrieve all available subfield tuples >- @notesubfields = $notefield->subfields(); >+ my @notesubfields = $notefield->subfields(); > > ## loop over all subfield tuples > foreach my $notetuple (@notesubfields) { >@@ -967,7 +1016,7 @@ sub charconv { > ## return unaltered if already utf-8 > return @_; > } >- elsif ($uniout eq "t") { >+ elsif (my $uniout eq "t") { > ## convert to utf-8 > return marc8_to_utf8("@_"); > } >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index 89707ef..92fdbab 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -66,6 +66,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('BasketConfirmations','1','always ask for confirmation.|do not ask for confirmation.','When closing or reopening a basket,','Choice'), > ('BiblioAddsAuthorities','0',NULL,'If ON, adding a new biblio will check for an existing authority record and create one on the fly if one doesn\'t exist','YesNo'), > ('BiblioDefaultView','normal','normal|marc|isbd','Choose the default detail view in the catalog; choose between normal, marc or isbd','Choice'), >+('BibtexExportAdditionalFields', '', NULL , 'Define additional BibTex tags to export from MARC records in YAML format as an associative array with either a marc tag/subfield combination as the value, or a list of tag/subfield combinations.', 'textarea'), > ('BlockExpiredPatronOpacActions','1',NULL,'Set whether an expired patron can perform opac actions such as placing holds or renew books, can be overridden on a per patron-type basis','YesNo'), > ('BlockReturnOfWithdrawnItems','1','0','If enabled, items that are marked as withdrawn cannot be returned.','YesNo'), > ('BorrowerMandatoryField','surname|cardnumber',NULL,'Choose the mandatory fields for a patron\'s account','free'), >@@ -361,6 +362,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('ReturnLog','1',NULL,'If ON, enables the circulation (returns) log','YesNo'), > ('ReturnToShelvingCart','0','','If set, when any item is \'checked in\', it\'s location code will be changed to CART.','YesNo'), > ('reviewson','1','','If ON, enables patron reviews of bibliographic records in the OPAC','YesNo'), >+('RisExportAdditionalFields', '', NULL , 'Define additional RIS tags to export from MARC records in YAML format as an associative array with either a marc tag/subfield combination as the value, or a list of tag/subfield combinations.', 'textarea'), > ('RoutingListAddReserves','1','','If ON the patrons on routing lists are automatically added to holds on the issue.','YesNo'), > ('RoutingListNote','To change this note edit <a href=\"/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=RoutingListNote#jumped\">RoutingListNote</a> system preference.','70|10','Define a note to be shown on all routing lists','Textarea'), > ('RoutingSerials','1',NULL,'If ON, serials routing is enabled','YesNo'), >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index 4653c02..3bc14fa 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -9669,6 +9669,22 @@ if ( CheckVersion($DBversion) ) { > SetVersion ($DBversion); > } > >+$DBversion = "3.17.00.XXX"; >+if ( CheckVersion($DBversion) ) { >+ $dbh->do(q{ >+ INSERT INTO systempreferences (variable,value,options,explanation,type) >+ VALUES ('RisExportAdditionalFields', '', NULL , 'Define additional RIS tags to export from MARC records in YAML format as an associative array with either a marc tag/subfield combination as the value, or a list of tag/subfield combinations.', 'textarea') >+ }); >+ >+ $dbh->do(q{ >+ INSERT INTO systempreferences (variable,value,options,explanation,type) >+ VALUES ('BibtexExportAdditionalFields', '', NULL , 'Define additional BibTex tags to export from MARC records in YAML format as an associative array with either a marc tag/subfield combination as the value, or a list of tag/subfield combinations.', 'textarea') >+ }); >+ >+ print "Upgrade to $DBversion done (Bug XXX - Add ability to export arbitrary MARC fields for RIS and BibTex)\n"; >+ SetVersion($DBversion); >+} >+ > =head1 FUNCTIONS > > =head2 TableExists($table) >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref >index 157bfc8..8e7278b 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref >@@ -215,3 +215,26 @@ Cataloging: > yes: "do" > no: "don't" > - attempt to match aggressively by trying all variations of the ISBNs in the imported record as a phrase in the ISBN fields of already cataloged records. Note that this preference has no effect if UseQueryParser is on. >+ Exporting: >+ - >+ - Include following fields when exporting BibTeX, >+ - pref: BibtexExportAdditionalFields >+ type: textarea >+ - "Use one line per tag in the format BT_TAG: TAG$SUBFIELD ( e.g. lccn: 010$a )" >+ - "<br/>" >+ - "To specificy multiple marc tags/subfields as targets for a repeating BibTex tag, use the following format: BT_TAG: [TAG2$SUBFIELD1, TAG2$SUBFIELD2] ( e.g. notes: [501$a, 505$g] )" >+ - "<br/>" >+ - "All values of repeating tags and subfields will be printed with the given BibTeX tag." >+ - "<br/>" >+ - "Use '@' ( with quotes ) as the BT_TAG to replace the bibtex record type with a field value of your choosing." >+ - >+ - Include following fields when exporting RIS, >+ - pref: RisExportAdditionalFields >+ type: textarea >+ - "Use one line per tag in the format RIS_TAG: TAG$SUBFIELD ( e.g. LC: 010$a )" >+ - "<br/>" >+ - "To specificy multiple marc tags/subfields as targets for a repeating RIS tag, use the following format: RIS_TAG: [TAG2$SUBFIELD1, TAG2$SUBFIELD2] ( e.g. NT: [501$a, 505$g] )" >+ - "<br/>" >+ - "All values of repeating tags and subfields will be printed with the given RIS tag." >+ - "<br/>" >+ - "Use of TY ( record type ) as a key will <i>replace</i> the default TY with the field value of your choosing." >-- >1.7.2.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 12357
:
28646
|
28647
|
28648
|
28649
|
28650
|
29291
|
29292
|
29293
|
29294
|
29295
|
29296
|
29297
|
31677
|
31678
|
31679
|
31680
|
33123
|
33124
|
33125
|
33126
|
35485
|
35487
|
35489
|
35826
|
35827
|
35828
|
38602
|
38604
|
39469
|
39471
|
39773
|
39774
|
39775
|
39776
|
39803
|
39804
|
39805
|
39806