File Coverage

blib/lib/HTML/TableContent/Template/Base.pm
Criterion Covered Total %
statement 169 171 98.8
branch 66 72 91.6
condition 4 6 66.6
subroutine 22 22 100.0
pod 0 1 0.0
total 261 272 95.9


line stmt bran cond sub pod time code
1             package HTML::TableContent::Template::Base;
2            
3 2     2   14233 use strict;
  2         4  
  2         73  
4 2     2   11 use warnings;
  2         4  
  2         50  
5            
6 2     2   12 use Moo::Role;
  2         6  
  2         12  
7 2     2   758 use Carp qw/croak/;
  2         6  
  2         96  
8            
9 2     2   10 use HTML::TableContent::Table;
  2         4  
  2         3722  
10            
11             our $VERSION = '0.18';
12            
13             has table => (
14             is => 'rw',
15             builder => '_build_table',
16             clearer => 1,
17             );
18            
19             has data => (
20             is => 'rw',
21             builder => '_build_data',
22             lazy => 1,
23             trigger => 1,
24             );
25            
26             sub render {
27 46     46 0 25744 return $_[0]->table->render;
28             }
29            
30             sub _build_data {
31 42 50   42   773 return $_[0]->can('_data') ? $_[0]->_coerce_data($_[0]->_data) : [ ];
32             }
33            
34             sub _trigger_data {
35 4 100   4   8148 if ( ref $_[1]->[0] eq 'ARRAY' ) {
36 1         7 return $_[0]->data($_[0]->_coerce_data($_[1]));
37             }
38 3         48 return;
39             }
40            
41             sub _coerce_data {
42 43 100   43   648 if ( ref $_[1]->[0] eq "ARRAY" ) {
43 2         5 my $headers = shift @{ $_[1] };
  2         6  
44 2         6 my $new = [ ];
45 2         5 foreach my $row ( @{ $_[1] } ) {
  2         42  
46 6         15 my %hash = ( );
47 6         9 for (0 .. scalar @{ $row } - 1) {
  6         16  
48 18         37 $hash{$headers->[$_]} = $row->[$_];
49             }
50 6         9 push @{ $new }, \%hash;
  6         14  
51             }
52 2         26 return $new;
53             }
54 41         167 return $_[1];
55             }
56            
57             sub _build_table {
58 45     45   124333 my $self = shift;
59            
60 45         802 my $data = $self->data;
61            
62 45 50       128 return unless scalar @{ $data };
  45         163  
63            
64 45         104 my $table_spec = { };
65 45 100       319 if ($self->can('table_spec')) {
66 3         14 $table_spec = $self->table_spec;
67             }
68            
69 45         882 my $table = HTML::TableContent::Table->new($table_spec);
70 45         528 $table = $self->_set_inner_html('render_table', $table);
71            
72 45         868 my $caption_spec = $self->_caption_spec;
73            
74 45 50       963 if (defined $caption_spec) {
75 45         99 my $cap = (keys %{ $caption_spec->[0] })[0];
  45         204  
76 45         803 my $caption = $table->caption($self->$cap);
77 45         592 $caption = $self->_set_inner_html('render_caption', $caption);
78             }
79            
80 45         856 my $header_spec = $self->_header_spec;
81 45         1527 my %row_spec = $self->_row_spec;
82 45         1325 my %cell_spec = $self->_cell_spec;
83            
84 45         487 for (0 .. scalar @{$header_spec} - 1){
  45         168  
85 135         496 my $attr = (keys %{ $header_spec->[$_] })[0];
  135         456  
86 135         2230 my $header = $self->$attr;
87            
88 135 100       1428 if (my $cells = delete $header->attributes->{cells}) {
89 10         30 $cell_spec{$_ + 1} = $cells;
90             }
91            
92 135         381 $header = $self->_set_inner_html('render_header', $header);
93            
94 135         236 push @{ $table->headers }, $header;
  135         2032  
95             }
96            
97 45         362 my $row_index = 1;
98 45         95 foreach my $hash ( @{ $data } ) {
  45         128  
99 1133         3752 my $row_base = $self->_element_spec($row_index, %row_spec);
100            
101 1133         3742 %cell_spec = $self->_refresh_cell_spec($row_base, $row_index, %cell_spec);
102 1133         3689 my $row = $table->add_row($row_base);
103 1133         2891 $row = $self->_set_inner_html('render_row', $row);
104            
105 1133         1994 my $cell_index = 1;
106 1133         3017 foreach ( $table->all_headers ) {
107 3399         15907 my $cell_base = $self->_element_spec($cell_index++, %cell_spec);
108 3399         11292 $cell_base->{text} = $hash->{$_->template_attr};
109 3399         9726 my $cell = $row->add_cell($cell_base);
110 3399         8509 $cell = $self->_set_inner_html('render_cell', $cell);
111 3399         10291 $table->parse_to_column($cell);
112             }
113            
114 1133         2391 $row_index++;
115             }
116            
117 45 50       441 if ( $self->can('last_chance') ) {
118 0         0 $table = $self->last_chance($table);
119             }
120            
121 45         750 return $table;
122             }
123            
124             sub _element_spec {
125 4532     4532   12081 my ( $self, $index, %spec) = @_;
126            
127 4532         9107 my $base = { };
128 4532         8723 my $row_index = delete $spec{row_index};
129            
130 4532 100       12826 return $base unless keys %spec;
131            
132 1166         2834 my $num = $self->_num_to_en($index);
133            
134 1166 100       2775 if (defined $row_index) {
135 126         271 $num = sprintf('%s__%s', $self->_num_to_en($row_index), $num);
136             }
137            
138 1166         3213 my @pot = ($index, qw/current all odd even/, $num);
139            
140 1166         2261 for (@pot) {
141 6996 100       15897 if ( my $sp = delete $spec{$_} ) {
142 137 100       481 if ( $_ =~ m{odd|even} ) {
143 36         100 my $action = sprintf('_add_%s', $_);
144 36         102 $base = $self->$action($base, $index, $sp);
145             } else {
146 101 100       273 my $req_index = $_ =~ m{^\d$}xms ? $row_index : $index;
147 101         233 $base = $self->_add_base($base, $req_index, $sp);
148             }
149             }
150             }
151            
152 1166 100       2906 return $base unless keys %spec;
153            
154 1092         2766 for (keys %spec) {
155 4137 100       9477 next unless defined $spec{$_}->{index};
156 27 100       65 my $safe = defined $row_index ? sprintf('%s__%d', $row_index, $index) : $index;
157            
158 27 100       184 if ( $spec{$_}->{index} =~ m{$safe}ixms ) {
159 5         19 $base = $self->_add_to_base($base, $index, $spec{$_});
160             }
161             }
162            
163 1092         3226 return $base;
164             }
165            
166             sub _add_base {
167 101     101   277 return $_[0]->_add_to_base($_[1], $_[2], $_[3]);
168             }
169            
170             sub _add_odd {
171 24 100   24   75 return $_[1] unless $_[2] % 2 == 1;
172 16         47 return $_[0]->_add_to_base($_[1], $_[2], $_[3]);
173             }
174            
175             sub _add_even {
176 12 100   12   39 return $_[1] unless $_[2] % 2 == 0;
177 4         12 return $_[0]->_add_to_base($_[1], $_[2], $_[3]);
178             }
179            
180             sub _add_to_base {
181 126     126   298 my ( $self, $base, $index, $hash ) = @_;
182            
183 126         331 my @pot = (qw/increment_id cells alternate_classes/);
184 126         242 for (@pot) {
185 378 100       896 if ( my $p = $hash->{$_} ) {
186 75         197 my $action = sprintf('_base_%s', $_);
187 75         209 $self->$action($p, $base, $index, $hash);
188             }
189             }
190            
191 126         202 for ( keys %{ $hash } ) {
  126         378  
192 535 100       1183 next if $_ =~ m{increment_id}ixms;
193            
194 520 100       1104 if ( $_ eq 'class' ) {
195 53         182 $base->{$_} = $self->_join_class($hash->{$_}, $base->{$_});
196             }
197            
198 520         1092 $base->{$_} = $hash->{$_};
199             }
200            
201 126         1069 return $base;
202             }
203            
204             sub _base_increment_id {
205 15     15   51 return $_[4]->{id} = sprintf('%s%s', $_[1], $_[3]);
206             }
207            
208             sub _base_cells {
209 4     4   15 return $_[2]->{cells} = $_[1];
210             }
211            
212             sub _base_alternate_classes {
213 56     56   94 my $class = shift @{ $_[1] };
  56         128  
214 56         179 $_[2]->{class} = $_[0]->_join_class($class, $_[2]->{class});
215 56         112 push @{ $_[1] }, $class;
  56         152  
216             }
217            
218             sub _refresh_cell_spec {
219 1133     1133   2886 my ($self, $row_base, $row_index, %cell_spec) = @_;
220            
221 1133 100       2806 defined $row_base->{cells} ? $cell_spec{current} = delete $row_base->{cells} : delete $cell_spec{current};
222            
223 1133         2007 $cell_spec{row_index} = $row_index;
224            
225 1133         2261 for (keys %cell_spec) {
226 1203 100 100     3934 next unless ref $cell_spec{$_} eq 'HASH' && defined $cell_spec{$_}->{oac};
227 9         18 my @classes = @{ $cell_spec{$_}->{oac} };
  9         26  
228 9         26 $cell_spec{$_}->{alternate_classes} = \@classes;
229             }
230            
231 1133         3356 return %cell_spec;
232             }
233            
234             sub _join_class {
235 109     109   297 my ( $self, $class, $current ) = @_;
236            
237 109 100       450 return defined $current ? sprintf('%s %s', $current, $class) : sprintf('%s', $class);
238             }
239            
240             sub _set_inner_html {
241 4757     4757   9792 my ($self, $action, $element, $attr) = @_;
242            
243 4757   33     23124 $attr ||= $element->attributes;
244            
245 4757 100       21569 if ( my $inner_html = delete $attr->{inner_html}) {
    100          
246 20 100       84 if ( ref $inner_html eq 'ARRAY' ) {
    50          
247 11         35 $element->inner_html($inner_html);
248             } elsif ( $self->can($inner_html) ) {
249 9         37 $element->inner_html($self->$inner_html);
250             } else {
251 0         0 croak "inner_html on $element->template_attr needs to be either an ArrayRef or A reference to a Sub";
252             }
253             } elsif ( $self->can($action) ) {
254 58         183 $element->inner_html($self->$action);
255             }
256            
257 4757         9802 return $element;
258             }
259            
260             has '_small_num_en' => (
261             is => 'ro',
262             lazy => 1,
263             default => sub {
264             my %NUM = ( );
265             @NUM{1 .. 20,30,40,50,60,70,80,90} = qw/
266             one two three four five six seven eight nine ten
267             eleven twelve thirteen fourteen fifteen
268             sixteen seventeen eighteen nineteen
269             twenty thirty forty fifty sixty seventy eighty ninety
270             /;
271             return \%NUM;
272             }
273             );
274            
275             has '_large_num_en' => (
276             is => 'ro',
277             lazy => 1,
278             default => sub {
279             my %NUM = ( );
280             @NUM{3 .. 6} = qw/hundred thousand billion trillion/;
281             return \%NUM;
282             }
283             );
284            
285             sub _num_to_en {
286 1292 50   1292   4777 return unless $_[1] =~ m/^\d+$/xms;
287            
288 1292         18227 my $small = $_[0]->_small_num_en;
289 1292         9018 my $num = '';
290 1292 100       3411 if ($num = $small->{$_[1]} ){
291 318         892 return $num;
292             }
293            
294 974         2969 my @numbers = split '', $_[1];
295            
296 974 100       2265 if ( scalar @numbers == 2 ) {
297 72         410 return sprintf('%s_%s', $small->{$numbers[0] . 0}, $small->{$numbers[1]});
298             } else {
299 902         1408 my $count = 0;
300 902         1370 @numbers = reverse(@numbers);
301 902         1292 my $string;
302 902         1576 for (@numbers) {
303 2708         4029 my $new = $_;
304            
305 2708 100       6424 if ( $new == 0 ) { $count++; next; }
  185         286  
  185         381  
306            
307 2523 100       5244 unless ( $count == 0 ) {
308 1712         3740 $new .= sprintf '%s' x $count, map { '0' } 1 .. $count;
  2616         6004  
309             }
310            
311 2523 100       6634 unless ($num = $small->{$new}) {
312 902         13957 $num = sprintf('%s_%s', $small->{$_}, $_[0]->_large_num_en->{$count + 1});
313             }
314            
315 2523 100       14141 $string = defined $string ? sprintf('%s_%s', $num, $string) : sprintf('%s', $num);
316 2523         4504 $count++;
317             }
318 902         2491 return $string;
319             }
320             }
321            
322             1;
323            
324             __END__