File Coverage

blib/lib/JCAMP/DX/LabelDataRecord.pm
Criterion Covered Total %
statement 89 91 97.8
branch 16 22 72.7
condition n/a
subroutine 11 11 100.0
pod 0 8 0.0
total 116 132 87.8


line stmt bran cond sub pod time code
1             #------------------------------------------------------------------------------
2             #$Author: andrius $
3             #$Date: 2018-12-20 10:45:10 +0200 (Kt, 20 gruod. 2018) $
4             #$Revision: 77 $
5             #$URL: svn+ssh://www.crystallography.net/home/coder/svn-repositories/jcamp-dx/tags/v0.02/lib/JCAMP/DX/LabelDataRecord.pm $
6             #------------------------------------------------------------------------------
7             #*
8             # Label Data Record object
9             #**
10              
11             package JCAMP::DX::LabelDataRecord;
12              
13 4     4   27 use strict;
  4         8  
  4         110  
14 4     4   19 use warnings;
  4         5  
  4         107  
15 4     4   1535 use JCAMP::DX::ASDF qw(decode);
  4         11  
  4         4909  
16              
17             our $max_line_length = 80;
18             our @records_with_variable_lists = qw(
19             PEAKTABLE
20             XYDATA
21             XYPOINTS
22             );
23              
24             sub new
25             {
26 132     132 0 963 my( $class, $label, $value ) = @_;
27              
28 132 50       248 if( defined $value ) {
29 132         347 $value =~ s/^\s+//;
30 132         450 $value =~ s/\s+$//;
31             }
32              
33 132         365 my $self = {
34             label => $label,
35             value => $value,
36             };
37              
38 132         229 $self = bless $self, $class;
39 132 50       247 return $self if !defined $value;
40              
41             # Converting records with variable lists
42 132 100       220 if( grep { $_ eq $self->canonical_label }
  396         649  
43             @records_with_variable_lists ) {
44 7         17 parse_AFFN_or_ASDF( $self );
45             }
46              
47 132         330 return $self;
48             }
49              
50             sub canonicalise_label
51             {
52 660     660 0 990 my( $label ) = @_;
53 660         920 $label = uc $label;
54 660         1328 $label =~ s/[\s\-\/\\_]//g;
55 660         1817 return $label;
56             }
57              
58             sub label
59             {
60 677     677 0 1552 return $_[0]->{label};
61             }
62              
63             sub canonical_label
64             {
65 660     660 0 994 return canonicalise_label( $_[0]->label );
66             }
67              
68             sub value
69             {
70 7     7 0 64 return $_[0]->{value};
71             }
72              
73             sub length
74             {
75 4     4 0 6 my( $self ) = @_;
76 4 50       9 if( $self->{variables} ) {
77 4         6 return scalar @{$self->{$self->{variables}[0]}};
  4         16  
78             } else {
79 0         0 return 1;
80             }
81             }
82              
83             sub parse_AFFN_or_ASDF
84             {
85 7     7 0 14 my( $ldr ) = @_;
86              
87             # Process the variable list:
88 7         46 $ldr->{value} =~ s/^\s*(\S+)\s*\n//s;
89 7         22 my $variable_list = $1;
90              
91 7 50       20 return if !$variable_list; # Not an ASDF LDR actually
92              
93 7         18 my @lines = split /\n/, $ldr->value;
94 7 100       41 if( $variable_list =~ /^\((.)\+\+\((.)\.\.\2\)\)$/ ) {
    50          
95             # (X++(Y..Y)) form
96 5         13 delete $ldr->{value};
97 5         19 my @variables = ( $1, $2 );
98 5         12 $ldr->{variables} = \@variables;
99              
100             my @checkpoints =
101 5         12 map { s/^\s*([+-]?\d*\.?\d+([+-]?E\d*)?)//; $1 } @lines;
  116         364  
  116         264  
102             my @lines =
103 5         22 map { s/^\s+//; s/\s+$//; [ decode( $_ ) ] } @lines;
  116         253  
  116         239  
  116         233  
104 5         28 my $diff;
105 5         29 for my $i (0..$#checkpoints) {
106 116 100       227 if( $i < $#checkpoints ) {
107 111         195 $diff = ($checkpoints[$i+1] - $checkpoints[$i]) / @{$lines[$i]};
  111         179  
108             }
109 116         178 push @{$ldr->{$variables[0]}},
110 116         146 map { $checkpoints[$i] + $_ * $diff } 0..$#{$lines[$i]};
  3716         5934  
  116         230  
111 116         341 push @{$ldr->{$variables[1]}}, @{$lines[$i]};
  116         197  
  116         527  
112             }
113             } elsif( $variable_list =~ /^\(([a-z0-9]+)\.\.\1\)$/i ) {
114             # (XY..XY) and (XYZ..XYZ) form
115 2         5 delete $ldr->{value};
116 2         6 my @variables = split '', $1;
117 2         6 $ldr->{variables} = \@variables;
118              
119 2         5 my @pairs = map { split /[;\s]+/, $_ } @lines;
  4         21  
120 2         5 for my $pair (@pairs) {
121 20         36 my @var = split /,/, $pair;
122 20         33 for my $i (0..$#var) {
123 43         57 push @{$ldr->{$variables[$i]}}, $var[$i];
  43         93  
124             }
125             }
126             } else {
127 0         0 die "cannot process variable list of form '$variable_list'";
128             }
129             }
130              
131             sub to_string
132             {
133 12     12 0 32 my( $ldr ) = @_;
134 12         23 my $output = '##' . $ldr->label . '=';
135 12         19 my $value;
136 12 100       28 if( $ldr->{variables} ) {
137 4         10 $value = '(' . join( '', @{$ldr->{variables}} ) . '..' .
138 4         6 join( '', @{$ldr->{variables}} ) . ")\n";
  4         9  
139 4         9 my $line = '';
140 4         8 for my $i (0..($ldr->length-1)) {
141 67         166 my $point = join( ',', map { $ldr->{$_}[$i] }
142 32         63 @{$ldr->{variables}} ) . ' ';
  32         53  
143 32 100       73 if( CORE::length( $line . $point ) < $max_line_length ) {
144 31         44 $line .= $point;
145             } else {
146 1         4 $value .= "$line\n";
147 1         2 $line = $point;
148             }
149             }
150 4 50       20 $value .= $line . "\n" if $line;
151             } else {
152 8         16 $value = $ldr->{value} . "\n";
153             }
154 12         23 $output .= $value;
155 12         41 return $output;
156             }
157              
158             1;