Catmandu-RIS

 view release on metacpan or  search on metacpan

lib/Catmandu/Importer/RIS.pm  view on Meta::CPAN

package Catmandu::Importer::RIS;

our $VERSION = '0.13';

use namespace::clean;
use Catmandu::Sane;
use Catmandu::Util qw(:is :array);
use Moo;

with 'Catmandu::Importer';

has sep_char => (is => 'ro', default => sub {'\s+-?\s*'});
has human    => (is => 'ro');
has ris      => (is => 'lazy');

sub _build_ris {
    my $self = shift;
    my $hash = {};

    if ($self->human && -r $self->human) {
      my $importer = Catmandu->importer('CSV', 
        file => $self->human, 
        header => 0 , 
        fields => 'name,value' ,
        sep_char => ',',
      );
      $importer->each(sub {
          my $item = shift;
          $hash->{$item->{name}} = $item->{value};
      });
    }
    else {
      while(<DATA>) {
          chomp;
          my ($n,$v) = split('\s*,\s*',$_,2);
          $hash->{$n} = $v;
      }
    }
    $hash;
}

sub generator {
    my ($self) = @_;
    sub {
        state $fh = $self->fh;
        state $sep_char = $self->sep_char;
        state $pattern  = qr/$sep_char/;
        state $line;
        state $data;
        my $previous_key= '';
        while($line = <$fh>) {

            chomp($line);
            next if $line eq '';
            # Remove BOM
            $line =~ s/^\x{feff}//;
            $line =~ s/^\s\s/$previous_key/;

            my ($key,$val) = split($pattern,$line,2);

            if ($key eq 'ER') {
                my $tmp = $data;
                $data = {};
                return $tmp;
            }
            else {
                $key = $self->ris->{$key} if $self->human && exists $self->ris->{$key};

                $previous_key = $key;
                $val =~ s/\r// if defined $val;
                # handle repeated fields
                if ($data->{$key}) {
                  $data->{$key} = [ grep { is_string $_ } @{$data->{$key}} ] if is_array_ref $data->{$key};
                	$data->{$key} = [ $data->{$key} ] if is_string $data->{$key};
                  push @{$data->{$key}}, $val;
                } else {
                  $data->{$key} = $val;
                }
            } 
        }
        return undef;
    };
}

1;

=head1 NAME

Catmandu::Importer::RIS - a RIS importer

=head1 SYNOPSIS

Command line interface:

  catmandu convert RIS < input.txt

  # Use the --human option to translate RIS tags into human readable strings
  catmandu convert RIS --human 1 < input.txt

  # Provide a comma separated mapping file to translate RIS tags
  catmandu convert RIS --human mappings/my_tags.txt < input.txt

In Perl code:

  use Catmandu::Importer::RIS;

  my $importer = Catmandu::Importer::RIS->new(file => "/foo/bar.txt");

  my $n = $importer->each(sub {
    my $hashref = $_[0];
    # ...
  });

=head1 CONFIGURATION



( run in 0.581 second using v1.01-cache-2.11-cpan-df04353d9ac )