From 67bd2db8d3357f2f3854ae8299bcbc4087badb2a Mon Sep 17 00:00:00 2001 From: Alexander Wagner Date: Thu, 18 Jul 2024 16:03:20 +0200 Subject: [PATCH] Bug 37196: Add automatic punctuation for Marc title fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new MARC filter to automatically inject punctuation for MARC fields 245, 246 and 246 if the MARC Leader 18 is set to `c` or `n`. Otherwise assume the punctuation exists and use the subfield data _as is_. Hook in this filter before any XSL tranformations happen, so all subsequent processing can assume that punctuation _exists_. The following subfields are handled: - 245: bcdefghknps - 246/247: bfghinqrt Note: some special cases (like title translations that should get an `=` instead of a `:`) can not be handled fully automatically. Testplan: 1. Start `ktd` 2. Check a record with additional title fields. Examples: - biblionumber 55: DÃ in do Eimhir = Poems to Eimhir / Somhairle MacGill-Eain = Sorley MacLean ; edited by Christopher Whyte. - biblionumber 58 'More fruitful than the soil' : army, empire and the Scottish Highlands, 1715-1815 / Andrew Mackillop. Those should display correctly, as they hold all punctuations _in_ the record. (Marc Leader 18 set to `a`). 3. Apply the patch 4. Call up the records again They should display unchanged as the Leader 18 is still set to `a` => no automatic punctuation is applied 5. Edit both records and only set the Leader 18 to either `c` or `n`. (Note: this is _incorrect_ wrt the record semantic.) All punctuation chars appear _twice_ as Koha adds them automatically as instructed even though they are there. The title display like - DÃ in do Eimhir = : Poems to Eimhir / / Somhairle MacGill-Eain = Sorley MacLean ; edited by Christopher Whyte. - 'More fruitful than the soil' : : army, empire and the Scottish Highlands, 1715-1815 / / Andrew Mackillop. Note that for biblionumber 55 Koha displays `= :` as it is not possible to know automatically that there should be an `=` instad of the `:`. Sponsored-by: Deutsches Elektronen-Synchrotron DESY, Library --- C4/XSLT.pm | 2 +- Koha/Filter/MARC/Punctuation.pm | 158 ++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 Koha/Filter/MARC/Punctuation.pm diff --git a/C4/XSLT.pm b/C4/XSLT.pm index 458d732d23..64db41bc82 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..94d338c10a --- /dev/null +++ b/Koha/Filter/MARC/Punctuation.pm @@ -0,0 +1,158 @@ +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 SYNOPSIS + + +=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: + +- 245 +- 246 +- 247 + +=cut + +use strict; +use warnings; + +use base qw(Koha::RecordProcessor::Base); +our $NAME = 'Punctuation'; + +=head2 filter + + my $newrecord = $filter->filter($record); + +Return title fiels with proper punctuation either as the record held +them already or as they were added. + +=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'); + + if ($punctuation_omitted) { + foreach my $field ( $record->fields ) { + if ($field->tag() eq "245") { + + # simple chars _preceeding_ a subfield + my %pchrs = ( + 'b' => ' : ', + 'c' => ' / ', + 'd' => ' ; ', + 'e' => '. ', + 'f' => ', ', + 'g' => ', ', + 'k' => ' : ', + 'n' => '. ', + 'p' => ', ', + 's' => '. ', + ); + + my $i = 0; + foreach my $subfield ( $field->subfields ) { + my $key = $subfield->[0]; + my $value = $subfield->[1]; + + if ( exists $pchrs{$key} ) { + $value = $pchrs{$key} . $value; + } + + # media type needs to be enclosed + if ($key eq 'h') { + $value = '[' . $value . ']'; + } + + $field->add_subfields( $key => $value ); # add subfield to the end of the subfield list + $field->delete_subfield( pos => 0 ); # delete the subfield at the top of the subfield list + $i++; + + # TBD does titles always end with a `.`? + } + } + if (($field->tag() eq "246") or + ($field->tag() eq "247")) { + my %pchrs = ( + 'b' => ' : ', + 'f' => ', ', + 'n' => '. ', + 'q' => ', ', + 'r' => ' = ', + 't' => ' = ', + ); + + my $i = 0; + foreach my $subfield ( $field->subfields ) { + my $key = $subfield->[0]; + my $value = $subfield->[1]; + + if ( exists $pchrs{$key} ) { + $value = $pchrs{$key} . $value; + } + + if ($key eq 'i') { + # _append_ a char to i + $value .= ': '; + } + if ($key eq 'g') { + $value = '(' . $value . ')'; + } + # media type needs to be enclosed + if ($key eq 'h') { + $value = '[' . $value . ']'; + } + + $field->add_subfields( $key => $value ); # add subfield to the end of the subfield list + $field->delete_subfield( pos => 0 ); # delete the subfield at the top of the subfield list + $i++; + + # TBD does titles always end with a `.`? + } + } + } + } + + return $record; +} + +1; -- 2.39.2