File Coverage

blib/lib/Data/Report/Plugin/Text.pm
Criterion Covered Total %
statement 138 162 85.1
branch 51 70 72.8
condition 12 20 60.0
subroutine 15 18 83.3
pod 0 3 0.0
total 216 273 79.1


line stmt bran cond sub pod time code
1             # Data::Report::Plugin::Text.pm -- Text plugin for Data::Report
2             # RCS Info : $Id: Text.pm,v 1.10 2008/08/18 09:51:23 jv Exp $
3             # Author : Johan Vromans
4             # Created On : Wed Dec 28 13:21:11 2005
5             # Last Modified By: Johan Vromans
6             # Last Modified On: Mon Aug 18 11:46:04 2008
7             # Update Count : 149
8             # Status : Unknown, Use with caution!
9              
10             package Data::Report::Plugin::Text;
11              
12 10     10   2318 use strict;
  10         19  
  10         372  
13 10     10   55 use warnings;
  10         16  
  10         337  
14 10     10   57 use base qw(Data::Report::Base);
  10         18  
  10         6132  
15 10     10   77 use Carp;
  10         21  
  10         25077  
16              
17             ################ User API ################
18              
19             sub start {
20 11     11 0 67 my $self = shift;
21 11         54 $self->_argcheck(0);
22 11         72 $self->SUPER::start;
23 11         38 $self->_make_format;
24 11         19 $self->{lines} = 0;
25 11         53 $self->{page} = $=;
26             }
27              
28             sub add {
29 25     25 0 105 my ($self, $data) = @_;
30              
31 25         52 my $style = delete($data->{_style});
32 25 50 66     100 if ( $style && !$self->_checkname($style) ) {
33 0         0 croak("Invalid style name: \"$style\"");
34             }
35 25         124 $self->SUPER::add($data);
36              
37 25         109 $self->_checkhdr;
38              
39 25         36 my $skip_after = 0;
40 25         30 my $line_after = 0;
41 25         32 my $cancel_skip = 0;
42 25 100 100     104 if ( $style and my $t = $self->_getstyle($style) ) {
43 3 50       66 return if $t->{ignore};
44 3 50       22 $self->_skip if $t->{skip_before};
45 3         6 $skip_after = $t->{skip_after};
46 3 50       13 $self->_line if $t->{line_before};
47 3         5 $line_after = $t->{line_after};
48 3         14 $cancel_skip = $t->{cancel_skip};
49             }
50 25 100       141 $style = "*" unless defined($style);
51 25         78 $self->_checkskip($cancel_skip);
52              
53 25         33 my @values;
54             my @widths;
55 0         0 my @indents;
56 0         0 my $linebefore;
57 0         0 my $lineafter;
58              
59 25         28 foreach my $col ( @{$self->_get_fields} ) {
  25         67  
60 103         163 my $fname = $col->{name};
61 103 100       323 my $t = $style ? $self->_getstyle($style, $fname) : {};
62 103 100       248 next if $t->{ignore};
63              
64 102 100       263 push(@values, defined($data->{$fname}) ? $data->{$fname} : "");
65 102         169 push(@widths, $col->{width});
66 102 100       208 if ($col->{truncate} ) {
67 8         18 $values[-1] = substr($values[-1], 0, $widths[-1]);
68             }
69              
70             # Examine style mods.
71 102         118 my $indent = 0;
72 102         103 my $wrapindent = 0;
73 102         111 my $excess = 0;
74 102 50       210 if ( $t ) {
75 102   100     368 $indent = $t->{indent} || 0;
76 102 100       196 $wrapindent = defined($t->{wrap_indent}) ? $t->{wrap_indent} : $indent;
77 102 50 33     424 croak("Row $style, column $fname, ".
78             "illegal value for indent property: $indent")
79             if $indent < 0 || $indent >= $self->_get_fdata->{$fname}->{width};
80 102 50 33     440 croak("Row $style, column $fname, ".
81             "illegal value for wrap_indent property: $wrapindent")
82             if $wrapindent < 0 || $wrapindent >= $self->_get_fdata->{$fname}->{width};
83 102 50       231 if ( $t->{line_before} ) {
84 0 0       0 $linebefore->{$fname} =
85             ($t->{line_before} eq "1" ? "-" : $t->{line_before}) x $col->{width};
86             }
87 102 100       209 if ( $t->{line_after} ) {
88 8 100       44 $lineafter->{$fname} =
89             ($t->{line_after} eq "1" ? "-" : $t->{line_after}) x $col->{width};
90             }
91 102 50       231 if ( $t->{excess} ) {
92 0         0 $widths[-1] += 2;
93             }
94 102 100 66     453 if ( $t->{truncate} || $col->{truncate} ) {
95 8         16 $values[-1] = substr($values[-1], 0, $widths[-1] - $indent);
96             }
97             }
98 102         333 push(@indents, [$indent, $wrapindent]);
99              
100             }
101              
102 25 50       70 if ( $linebefore ) {
103 0         0 $linebefore->{_style} = "";
104 0         0 $self->add($linebefore);
105             }
106              
107 25         32 my @lines;
108 25         33 while ( 1 ) {
109 67         79 my $more = 0;
110 67         72 my @v;
111 67         141 foreach my $i ( 0..$#widths ) {
112 298         315 my ($ind, $wind) = @{$indents[$i]};
  298         470  
113 298 100       618 $ind = $wind if @lines;
114 298         426 my $maxw = $widths[$i] - $ind;
115 298         410 $ind = " " x $ind;
116 298 100       515 if ( length($values[$i]) <= $maxw ) {
117 117         205 push(@v, $ind.$values[$i]);
118 117         216 $values[$i] = "";
119             }
120             else {
121 181         278 my $t = substr($values[$i], 0, $maxw);
122 181 100       654 if ( substr($values[$i], $maxw, 1) eq " " ) {
    50          
123 25         40 push(@v, $ind.$t);
124 25         41 substr($values[$i], 0, length($t) + 1, "");
125             }
126             elsif ( $t =~ /^(.*)([ ]+)/ ) {
127 156         269 my $pre = $1;
128 156         269 push(@v, $ind.$pre);
129 156         302 substr($values[$i], 0, length($pre) + length($2), "");
130             }
131             else {
132 0         0 push(@v, $ind.$t);
133 0         0 substr($values[$i], 0, $maxw, "");
134             }
135 181         305 $more++;
136             }
137             }
138 67         269 my $t = sprintf($self->{format}, @v);
139 67         319 $t =~ s/ +$//;
140 67 50       284 push(@lines, $t) if $t =~ /\S/;
141 67 100       241 last unless $more;
142             }
143              
144 25 50       80 if ( $self->{lines} < @lines ) {
145 0         0 $self->_needhdr(1);
146 0         0 $self->_checkhdr;
147             }
148 25         79 $self->_print(@lines);
149              
150             # Post: Lines for cells.
151 25 100       61 if ( $lineafter ) {
152 6         17 $lineafter->{_style} = "";
153 6         66 $self->add($lineafter);
154             }
155             # Post: Line for row.
156 25 100       161 if ( $line_after ) {
    50          
157 3         25 $self->_line;
158             }
159             # Post: Skip after this row.
160             elsif ( $skip_after ) {
161 0         0 $self->_skip;
162             }
163             }
164              
165             sub finish {
166 11     11 0 51 my $self = shift;
167 11         38 $self->_argcheck(0);
168 11         30 $self->_checkskip(1); # cancel skips.
169 11         84 $self->SUPER::finish();
170             }
171              
172             ################ Pseudo-Internal (used by Base class) ################
173              
174             sub _std_heading {
175 10     10   23 my ($self) = @_;
176              
177             # Print column names.
178 42         126 my $t = sprintf($self->{format},
179 43         170 map { $_->{title} }
180             grep {
181 10         30 my $t = $self->_getstyle("_head", $_->{name});
182 43         157 ! $t->{ignore};
183             }
184 10         21 @{$self->_get_fields});
185              
186             # Add separator line.
187 10         44 $t .= "-" x ($self->{width});
188 10         17 $t .= "\n";
189              
190             # Remove trailing blanks.
191 10         166 $t =~ s/ +$//gm;
192              
193             # Print it.
194 10         32 $self->_print($t);
195              
196 10         37 $self->_needskip(0);
197              
198             }
199              
200             ################ Internal methods ################
201              
202             sub _print {
203 44     44   150 my ($self, @values) = @_;
204 44         98 my $value = join("", @values);
205 44         168 $self->SUPER::_print($value);
206 44         147 $self->{lines} -= ($value =~ tr/\n//);
207             }
208              
209             sub _pageskip {
210 10     10   17 my ($self) = @_;
211 10         32 $self->{lines} = $self->{page};
212             }
213              
214             sub _make_format {
215 11     11   19 my ($self) = @_;
216              
217 11         18 my $width = 0; # new width
218 11         23 my $format = ""; # new format
219              
220 11         28 foreach my $a ( @{$self->_get_fields} ) {
  11         78  
221              
222 47         238 my $t = $self->_getstyle("_head", $a->{name});
223 47 100       129 next if $t->{ignore};
224              
225             # Never mind the trailing blanks -- we'll trim anyway.
226 46         81 $width += $a->{width} + 2;
227 46 100       99 if ( $a->{align} eq "<" ) {
228 30         135 $format .= "%-".
229             join(".", ($a->{width}+2) x 2) .
230             "s";
231             }
232             else {
233 16         71 $format .= "%".
234             join(".", ($a->{width}) x 2) .
235             "s ";
236             }
237             }
238              
239             # Store format and width in object.
240 11         35 $self->{format} = $format . "\n";
241 11         42 $self->{width} = $width - 2;
242              
243             # PBP: Return nothing sensible.
244 11         22 return;
245             }
246              
247             sub _checkskip {
248 39     39   61 my ($self, $cancel) = @_;
249 39 50 33     79 return if !$self->_does_needskip || $self->{lines} <= 0;
250 0 0       0 $self->_print("\n") unless $cancel;
251 0         0 $self->_needskip(0);
252             }
253              
254             sub _needskip {
255 10     10   17 my $self = shift;
256 10         29 $self->{needskip } = shift;
257             }
258             sub _does_needskip {
259 39     39   51 my $self = shift;
260 39         145 $self->{needskip};
261             }
262              
263             sub _line {
264 3     3   7 my ($self) = @_;
265              
266 3         10 $self->_checkhdr;
267 3         16 $self->_checkskip(1); # cancel skips.
268              
269 3         15 $self->_print("-" x ($self->{width}), "\n");
270             }
271              
272             sub _skip {
273 0     0     my ($self) = @_;
274              
275 0           $self->_checkhdr;
276 0           $self->_needskip(1);
277             }
278              
279             sub _center {
280 0     0     my ($self, $text, $width) = @_;
281 0           (" " x (($width - length($text))/2)) . $text;
282             }
283              
284             sub _expand {
285 0     0     my ($self, $text) = @_;
286 0           $text =~ s/(.)/$1 /g;
287 0           $text =~ s/ +$//;
288 0           $text;
289             }
290              
291             1;