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 )