From 96dac90b7278a44b52226bcca5ed25e30e9a91ba Mon Sep 17 00:00:00 2001 From: Alexander Wagner Date: Mon, 11 Nov 2024 13:43:04 +0100 Subject: [PATCH] Bug 37325: Add punctuation for 260 and 264 Add punctuation automatically for tag 260 (Imprint), if the record leader defines that punctuation is _omitted_ from the fields. The filter does not act on records that hold punctuation and say so in leader 18. - Hook up `Puncutation.pm` with `XSLT.pm` - Add rules for automatic punctuation of Marc21 field 260 according to https://www.loc.gov/aba/pcc/documents/isbdmarc2016.pdf - Subfields handled: a, b, c, f, g, r, t, q Note: there may be complex cases where it is not possible to properly add punctuation automatically from the subfield semantics alone. In these cases it is still possible to add punctuation to the record and specify this in leader 18. Then the filter will not change the record at all. Test plan: 1. Select a record (A) with a properly filled and punctuated 260 field 2. Check that the punctuation display correctly in intranet and OPAC interface 3. Select a record (B) without punctuation OR remove the punctuation from the subfields of field 260. Check that leader 18 is set to `c` or `n`, IOW that this is a semantically correct record. 4. Check that _no_ punctuation chars get displayed in OPAC or intranet 5. Apply the patch 6. Edit the record (A) 7. Check that the Marc leader position 18 is _not_ set to `c` or `n` 8. Set Marc leader 18 to `c` or `n` (`c`: ISBD punctuation omitted / `n` Non-ISBD punctuation omitted) 9. Save the record 10. Check that all punctuation chars appear twice in intranet as well as OPAC interface 11. Check record (B) in intranet and OPAC interface. It should now show automatically added, proper punctuation. For field 264: follow the procedure just outlined but use field 264 instead. If 264 is present, Koha will prefer it over 260. Sponsored-by: Deutsches Elektronen-Synchrotron DESY, Library --- C4/XSLT.pm | 2 +- Koha/Filter/MARC/Punctuation.pm | 193 ++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 Koha/Filter/MARC/Punctuation.pm diff --git a/C4/XSLT.pm b/C4/XSLT.pm index a2134225d8..27eb849bfd 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -191,7 +191,7 @@ sub XSLTParse4Display { my $frameworkcode = GetFrameworkCode($biblionumber) || ''; my $record_processor = Koha::RecordProcessor->new( { - filters => [ 'ExpandCodedFields' ], + filters => [ 'ExpandCodedFields', 'Punctuation' ], options => { interface => $interface, frameworkcode => $frameworkcode diff --git a/Koha/Filter/MARC/Punctuation.pm b/Koha/Filter/MARC/Punctuation.pm new file mode 100644 index 0000000000..a138eaf5a1 --- /dev/null +++ b/Koha/Filter/MARC/Punctuation.pm @@ -0,0 +1,193 @@ +package Koha::Filter::MARC::Punctuation; + +# Copyright 2024 join2 +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +=head1 NAME + +Koha::Filter::MARC::Punctuation - Automatically add punctuation to +Marc records if the leader specifies they were catalogued without it. + +Documentation for proper punctuation: +https://www.loc.gov/aba/pcc/documents/isbdmarc2016.pdf + +=head1 DESCRIPTION + +If the Marc leader 18 specifies, that the record was catalogued +without punctuation add the proper punctuation chars to the individual +fields before passing the record on to fruther processing. Once this +filter is applied it should be safe for further steps to assume that +the record holds Marc punctuation. (The records in the database are +_not_ changed.) + +Trigger to add punctuation: leader 18 is either `n` or `c`. + +Currently handled fields: + +- 260 + +=cut + +use strict; +use warnings; + +use base qw(Koha::RecordProcessor::Base); +our $NAME = 'Punctuation'; + +=head2 _decorate_260 + +Add punctuation to MARC field 260. The function assumes that it is only +called if no punctuation is part of the record. + +=cut + +sub _decorate_260 { + + my ($field) = @_; + + # simple chars _preceeding_ a subfield + my %pchrs = ( + + # 'a' => ' ; ', # only for multiple $a + 'b' => ' : ', + 'c' => ', ', + + # 'f' => ' : ', + # 'g' => ', ', + 'r' => ' = ', + 't' => ' = ', + ); + + # simple chars _appended_ to a subfield + my %achars = ( + '3' => ': ', + ); + + my $lastsf = ''; + my @new_subfields = (); + + foreach my $subfield ( $field->subfields() ) { + my ( $sf, $value ) = @$subfield; + + if ( ( $sf eq 'a' ) and ( $lastsf eq 'a' ) ) { + $value = "; $value"; + } + if ( ( $sf eq 'a' ) and ( $lastsf eq 'b' ) ) { + $value = " ; $value"; + } + + # for $e: assume that we always have either $f or $g + if ( $sf eq 'e' ) { + $value = " ($value "; + } + + if ( $sf eq 'f' ) { + if ( $lastsf eq 'e' ) { + $value = " : $value"; + } else { + $value = " ($value"; + } + } + + if ( $sf eq 'g' ) { + if ( $lastsf ne 'f' ) { + $value = ", ($value)"; + } else { + $value = ", $value)"; + } + } + + $lastsf = $sf; + + if ( $sf eq 'q' ) { + $value = "($value)"; + } + + if ( exists $pchrs{$sf} ) { + $value = $pchrs{$sf} . $value; + } + + # FIXME something seems wrong here, however $3 is + # not used by Koha + # if ( exists $achrs{$sf} ) { + # $value = $value . $achrs{$sf}; + # } + + push( @new_subfields, $sf, $value ); + } + return @new_subfields; +} + +=head2 filter + + my $newrecord = $filter->filter($record); + +Return title fields with proper punctuation either as the record held +them already or as they were added. + +Note: subfields in 260 are used to construct search links in OPAC. The +following will include the description chars in the search links as +does direct cataloguing of the punctuation. Kohas search engine seems +to handle this gracefully and still returns proper results. + +=cut + +sub filter { + my ( $self, $record ) = @_; + + return + unless $record and ref($record) eq 'MARC::Record'; + + my $leader = $record->leader(); + my $punctuation_omitted = + ( ( substr( $leader, 18, 1 ) eq 'c' ) or ( substr( $leader, 18, 1 ) eq 'n' ) ); + + my @new_subfields = (); + if ($punctuation_omitted) { + foreach my $field ( $record->fields() ) { + @new_subfields = (); + + # Process the implemented filters + + # 260 – Publication, Distribution, etc. (Imprint) + if ( $field->tag() eq '260' ) { + @new_subfields = _decorate_260($field); + } + + # 264 – Production, Publication, Distribution, Manufacture, and Copyright Notice + # 264 is similar to 260, but does not hold some subfields + if ( $field->tag() eq '264' ) { + @new_subfields = _decorate_260($field); + } + + # If filtered, replace the field content + if (@new_subfields) { + $field->replace_with( + MARC::Field->new( + $field->tag(), + $field->indicator(1), + $field->indicator(2), + @new_subfields + ) + ); + } + } + } + return $record; +} + +1; -- 2.39.5