File Coverage

blib/lib/JCAMP/DX.pm
Criterion Covered Total %
statement 72 74 97.3
branch 29 32 90.6
condition 7 9 77.7
subroutine 10 11 90.9
pod 0 8 0.0
total 118 134 88.0


line stmt bran cond sub pod time code
1             #------------------------------------------------------------------------------
2             #$Author: andrius $
3             #$Date: 2018-12-20 11:24:42 +0200 (Kt, 20 gruod. 2018) $
4             #$Revision: 78 $
5             #$URL: svn+ssh://www.crystallography.net/home/coder/svn-repositories/jcamp-dx/tags/v0.02/lib/JCAMP/DX.pm $
6             #------------------------------------------------------------------------------
7             #*
8             # Parser for JCAMP-DX format.
9             #**
10              
11             package JCAMP::DX;
12              
13 4     4   16572 use strict;
  4         32  
  4         112  
14 4     4   21 use warnings;
  4         7  
  4         96  
15 4     4   1547 use JCAMP::DX::LabelDataRecord;
  4         8  
  4         3680  
16              
17             our $VERSION = '0.02';
18              
19             sub new
20             {
21 19     19 0 46 my( $class, $title ) = @_;
22 19         74 my $self = bless {
23             labels => [],
24             data => {},
25             blocks => [],
26             }, $class;
27              
28 19 100       48 if( $title ) {
29 2         8 $self->push_LDR( JCAMP::DX::LabelDataRecord->new( 'TITLE', $title ) );
30             }
31              
32 19         38 return $self;
33             }
34              
35             sub new_from_file
36             {
37 10     10 0 4470 my( $class, $filename, $options ) = @_;
38 10         288 open( my $inp, $filename );
39              
40 10 100       53 ${$options->{store_file}} = '' if $options->{store_file};
  5         26  
41              
42 10         237 my $title = <$inp>;
43 10 100       39 ${$options->{store_file}} .= $title if $options->{store_file};
  5         13  
44 10         60 $title =~ s/^\s*##title=//i;
45 10         48 $title =~ s/\r?\n$//;
46              
47 10         44 my $block = $class->new_from_fh( $inp, $title, $options );
48              
49 10         115 close $inp;
50 10         151 return $block;
51             }
52              
53             sub new_from_fh
54             {
55 16     16 0 40 my( $class, $inp, $title, $options ) = @_;
56 16         31 my $block = $class->new();
57 16         35 my( $last_label, $buffer ) = ( 'title', $title );
58 16         48 while( my $line = <$inp> ) {
59 268 100       530 ${$options->{store_file}} .= $line if $options->{store_file};
  134         250  
60 268         473 $line =~ s/\$\$.*$//; # removing comments
61 268         852 $line =~ s/\r?\n$//; # removing newlines
62 268 100       701 next if $line =~ /^\s*$/;
63 260 100       530 last if $line =~ /^\s*##end=/i;
64 244 100       770 if( $line =~ s/^\s*##title=//i ) {
    100          
    50          
65 6 100 66     24 if( defined $last_label && $last_label ne '' ) {
66 2         8 $block->push_LDR(
67             JCAMP::DX::LabelDataRecord->new( $last_label, $buffer )
68             );
69 2         4 undef $last_label;
70 2         5 undef $buffer;
71             }
72 6         18 $block->push_block( $class->new_from_fh( $inp, $line, $options ) );
73             } elsif( $line =~ /^\s*##([^=]*)=(.*)$/ ) {
74 112 100 66     370 if( defined $last_label && $last_label ne '' ) {
75 108         262 $block->push_LDR(
76             JCAMP::DX::LabelDataRecord->new( $last_label, $buffer )
77             );
78             }
79 112         494 ( $last_label, $buffer ) = ( $1, $2 );
80             } elsif( $block->{labels} ) {
81 126         352 $buffer .= "\n$line";
82             }
83             }
84              
85 16 100 100     61 if( defined $last_label && $last_label ne '' ) {
86 12         34 $block->push_LDR(
87             JCAMP::DX::LabelDataRecord->new( $last_label, $buffer )
88             );
89             }
90              
91 16         37 return $block;
92             }
93              
94             sub push_block
95             {
96 6     6 0 14 my( $self, $block ) = @_;
97 6         7 push @{$self->{blocks}}, $block;
  6         26  
98             }
99              
100             sub push_LDR
101             {
102 132     132 0 334 my( $self, $ldr ) = @_;
103              
104 132 100       277 if( exists $self->{data}{$ldr->canonical_label} ) {
105 2         6 warn "duplicate values for label '" . $ldr->canonical_label .
106             "' were found, will not overwrite";
107 2         131 return;
108             }
109              
110 130         202 push @{$self->{labels}}, $ldr;
  130         257  
111 130         268 $self->{data}{$ldr->canonical_label} = $ldr;
112             }
113              
114             sub title
115             {
116 0     0 0 0 return $_[0]->{data}{TITLE}->value;
117             }
118              
119             sub order_labels
120             {
121 1     1 0 3 my( $self ) = @_;
122              
123             $self->{labels} = [
124             (exists $self->{data}{TITLE} ? $self->{data}{TITLE} : () ),
125             (exists $self->{data}{JCAMPDX} ? $self->{data}{JCAMPDX} : () ),
126 3 100       6 grep { $_->label ne 'TITLE' && $_->label ne 'JCAMP-DX' }
127 1 50       6 @{$self->{labels}} ];
  1 50       3  
128             }
129              
130             sub to_string
131             {
132 3     3 0 332 my( $self ) = @_;
133 3         5 my $output = '';
134              
135 3         6 for my $label (@{$self->{labels}}) {
  3         9  
136 8         19 $output .= $label->to_string;
137             }
138              
139 3         4 for my $block (@{$self->{blocks}}) {
  3         17  
140 0         0 $output .= $block->to_string;
141             }
142              
143 3         6 $output .= "##END=\n";
144 3         13 return $output;
145             }
146              
147             1;