MARC-File-MARCMaker
view release on metacpan or search on metacpan
lib/MARC/File/MARCMaker.pm view on Meta::CPAN
} #if $tagno < 10
else {
#translate characters for subfield data
#get indicators
my $ind1 = substr( $line, 5, 1 );
my $ind2 = substr( $line, 6, 1 );
my $tagdata = substr( $line, 7 );
#report error if first character of tagdata is not a subfield indicator ($)
$marc->_warn( "First character of subfield data must be a subfield indicator (dollar sign), $tagdata, $location for tag $tagno" ) unless ($tagdata =~ /^\$/ );
if ( $filter_func ) {
next LINE unless $filter_func->( $tagno, $tagdata );
}
#why doesn't SUBFIELD_INDICATOR work in the split?
my @subfields_mnemonic = split( /\x24/, $tagdata );
#convert characters from mnemonics to characters
my @subfields = map {_maker2char($_, $charset)} @subfields_mnemonic;
#is there a better way to deal with the empty first item?
my $empty = shift @subfields;
$marc->_warn( "Subfield data appears before first subfield? $location in $tagno" ) if $empty;
# Split the subfield data into subfield name and data pairs
my @subfield_data;
for ( @subfields ) {
if ( length > 0 ) {
push( @subfield_data, substr($_,0,1),substr($_,1) );
} else {
$marc->_warn( "Entirely empty subfield found in tag $tagno" );
}
} #for @subfields
if ( !@subfield_data ) {
$marc->_warn( "no subfield data found $location for tag $tagno" );
next;
}
my $field = MARC::Field->new($tagno, $ind1, $ind2, @subfield_data );
if ( $field->warnings() ) {
$marc->_warn( $field->warnings() );
}
$marc->append_fields( $field );
}
} # looping through all the fields
return $marc;
} #decode MARCMaker
=head2 update_leader() #from USMARC
This may be unnecessary code. Delete this section if that is the case.
If any changes get made to the MARC record, the first 5 bytes of the
leader (the length) will be invalid. This function updates the
leader with the correct length of the record as it would be if
written out to a file.
sub update_leader() { #from USMARC
my $self = shift;
my (undef,undef,$reclen,$baseaddress) = $self->_build_tag_directory();
$self->_set_leader_lengths( $reclen, $baseaddress );
} #updated_leader() from USMARC
=head2 encode() #based on MARC::File::USMARC
Returns a string of characters suitable for writing out to a MARCMaker file,
including the leader, directory and all the fields.
Uses as_marcmaker() below to build each field.
=cut
sub encode { #MARCMaker, based on USMARC's encode()
my $marc = shift;
$marc = shift if (ref($marc)||$marc) =~ /^MARC::File/;
my $field_string = '';
#convert each field (after the leader) to MARCMaker format
foreach my $field ($marc->fields()) {
$field_string .= $field->MARC::File::MARCMaker::as_marcmaker();
} #foreach field in record
# Glomp it all together
return join("", "=LDR ", $marc->leader, "\n", $field_string, "\n");
} #encode from USMARC
=head2 as_marcmaker()
Based on MARC::Field::as_usmarc().
Turns a MARC::Field into a MARCMaker formatted field string.
=head2 TODO (as_marcmaker())
-Change field encoding portion of as_marcmaker() to internal _as_marcmaker()
-Implement as_marcmaker() as wrapper for MARC::Record object and MARC::Field object encoding into MARCMaker format.
=cut
sub as_marcmaker() {
my $self = shift;
# $self = shift if (ref($self)||$self) =~ /^MARC::File/;
die "Wanted a MARC::Field but got a ", ref($self) unless ref($self) eq "MARC::Field";
my $charset = ustext_default();
# Tags < 010 are pretty easy
if ( $self->is_control_field ) {
#convert characters to MARCMaker codes
my $field_data = (_char2maker($self->data(), $charset));
#swap blank spaces for backslash ( \ )
$field_data =~ s/ /\\/g;
#return formatted field
return sprintf "=%s %s\n", $self->tag(), $field_data;
( run in 0.637 second using v1.01-cache-2.11-cpan-39bf76dae61 )