File Coverage

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


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