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: 2021-02-10 13:44:25 +0200 (Tr, 10 vas. 2021) $
4             #$Revision: 94 $
5             #$URL: svn+ssh://www.crystallography.net/home/coder/svn-repositories/JCAMP-DX/tags/v0.03/lib/JCAMP/DX/LabelDataRecord.pm $
6             #------------------------------------------------------------------------------
7             #*
8             # Label Data Record object
9             #**
10              
11             package JCAMP::DX::LabelDataRecord;
12              
13 4     4   26 use strict;
  4         8  
  4         114  
14 4     4   20 use warnings;
  4         6  
  4         164  
15              
16             # ABSTRACT: Label Data Record object
17             our $VERSION = '0.03'; # VERSION
18              
19 4     4   1739 use JCAMP::DX::ASDF qw(decode);
  4         11  
  4         5093  
20              
21             our $max_line_length = 80;
22             our @records_with_variable_lists = qw(
23             PEAKTABLE
24             XYDATA
25             XYPOINTS
26             );
27              
28             sub new
29             {
30 132     132 0 1044 my( $class, $label, $value ) = @_;
31              
32 132 50       276 if( defined $value ) {
33 132         402 $value =~ s/^\s+//;
34 132         392 $value =~ s/\s+$//;
35             }
36              
37 132         365 my $self = {
38             label => $label,
39             value => $value,
40             };
41              
42 132         244 $self = bless $self, $class;
43 132 50       236 return $self if !defined $value;
44              
45             # Converting records with variable lists
46 132 100       231 if( grep { $_ eq $self->canonical_label }
  396         656  
47             @records_with_variable_lists ) {
48 7         20 parse_AFFN_or_ASDF( $self );
49             }
50              
51 132         375 return $self;
52             }
53              
54             sub canonicalise_label
55             {
56 660     660 0 1009 my( $label ) = @_;
57 660         981 $label = uc $label;
58 660         1311 $label =~ s/[\s\-\/\\_]//g;
59 660         1778 return $label;
60             }
61              
62             sub label
63             {
64 677     677 0 1286 return $_[0]->{label};
65             }
66              
67             sub canonical_label
68             {
69 660     660 0 993 return canonicalise_label( $_[0]->label );
70             }
71              
72             sub value
73             {
74 7     7 0 64 return $_[0]->{value};
75             }
76              
77             sub length
78             {
79 4     4 0 9 my( $self ) = @_;
80 4 50       8 if( $self->{variables} ) {
81 4         6 return scalar @{$self->{$self->{variables}[0]}};
  4         15  
82             } else {
83 0         0 return 1;
84             }
85             }
86              
87             sub parse_AFFN_or_ASDF
88             {
89 7     7 0 15 my( $ldr ) = @_;
90              
91             # Process the variable list:
92 7         41 $ldr->{value} =~ s/^\s*(\S+)\s*\n//s;
93 7         21 my $variable_list = $1;
94              
95 7 50       19 return if !$variable_list; # Not an ASDF LDR actually
96              
97 7         18 my @lines = split /\n/, $ldr->value;
98 7 100       44 if( $variable_list =~ /^\((.)\+\+\((.)\.\.\2\)\)$/ ) {
    50          
99             # (X++(Y..Y)) form
100 5         15 delete $ldr->{value};
101 5         19 my @variables = ( $1, $2 );
102 5         14 $ldr->{variables} = \@variables;
103              
104             my @checkpoints =
105 5         11 map { s/^\s*([+-]?\d*\.?\d+([+-]?E\d*)?)//; $1 } @lines;
  116         394  
  116         272  
106             my @lines =
107 5         14 map { s/^\s+//; s/\s+$//; [ decode( $_ ) ] } @lines;
  116         274  
  116         232  
  116         242  
108 5         19 my $diff;
109 5         27 for my $i (0..$#checkpoints) {
110 116 100       236 if( $i < $#checkpoints ) {
111 111         210 $diff = ($checkpoints[$i+1] - $checkpoints[$i]) / @{$lines[$i]};
  111         185  
112             }
113 116         185 push @{$ldr->{$variables[0]}},
114 116         145 map { $checkpoints[$i] + $_ * $diff } 0..$#{$lines[$i]};
  3716         5990  
  116         243  
115 116         324 push @{$ldr->{$variables[1]}}, @{$lines[$i]};
  116         187  
  116         529  
116             }
117             } elsif( $variable_list =~ /^\(([a-z0-9]+)\.\.\1\)$/i ) {
118             # (XY..XY) and (XYZ..XYZ) form
119 2         6 delete $ldr->{value};
120 2         7 my @variables = split '', $1;
121 2         5 $ldr->{variables} = \@variables;
122              
123 2         4 my @pairs = map { split /[;\s]+/, $_ } @lines;
  4         22  
124 2         5 for my $pair (@pairs) {
125 20         39 my @var = split /,/, $pair;
126 20         31 for my $i (0..$#var) {
127 43         55 push @{$ldr->{$variables[$i]}}, $var[$i];
  43         98  
128             }
129             }
130             } else {
131 0         0 die "cannot process variable list of form '$variable_list'";
132             }
133             }
134              
135             sub to_string
136             {
137 12     12 0 30 my( $ldr ) = @_;
138 12         25 my $output = '##' . $ldr->label . '=';
139 12         19 my $value;
140 12 100       27 if( $ldr->{variables} ) {
141 4         13 $value = '(' . join( '', @{$ldr->{variables}} ) . '..' .
142 4         7 join( '', @{$ldr->{variables}} ) . ")\n";
  4         9  
143 4         7 my $line = '';
144 4         8 for my $i (0..($ldr->length-1)) {
145 67         123 my $point = join( ',', map { $ldr->{$_}[$i] }
146 32         45 @{$ldr->{variables}} ) . ' ';
  32         47  
147 32 100       72 if( CORE::length( $line . $point ) < $max_line_length ) {
148 31         59 $line .= $point;
149             } else {
150 1         2 $value .= "$line\n";
151 1         3 $line = $point;
152             }
153             }
154 4 50       13 $value .= $line . "\n" if $line;
155             } else {
156 8         18 $value = $ldr->{value} . "\n";
157             }
158 12         24 $output .= $value;
159 12         43 return $output;
160             }
161              
162             1;