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   20408 use strict;
  2         5  
  2         80  
4 2     2   11 use warnings;
  2         6  
  2         53  
5            
6 2     2   10 use Moo::Role;
  2         5  
  2         12  
7 2     2   751 use Carp qw/croak/;
  2         5  
  2         169  
8            
9 2     2   15 use HTML::TableContent::Table;
  2         5  
  2         4878  
10            
11             our $VERSION = '1.00';
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 32227 return $_[0]->table->render;
28             }
29            
30             sub _build_data {
31 42 50   42   824 return $_[0]->can('_data') ? $_[0]->_coerce_data($_[0]->_data) : [ ];
32             }
33            
34             sub _trigger_data {
35 4 100   4   12338 if ( ref $_[1]->[0] eq 'ARRAY' ) {
36 1         7 return $_[0]->data($_[0]->_coerce_data($_[1]));
37             }
38 3         63 return;
39             }
40            
41             sub _coerce_data {
42 43 100   43   700 if ( ref $_[1]->[0] eq "ARRAY" ) {
43 2         4 my $headers = shift @{ $_[1] };
  2         6  
44 2         5 my $new = [ ];
45 2         5 foreach my $row ( @{ $_[1] } ) {
  2         7  
46 6         9 my %hash = ( );
47 6         10 for (0 .. scalar @{ $row } - 1) {
  6         15  
48 18         37 $hash{$headers->[$_]} = $row->[$_];
49             }
50 6         13 push @{ $new }, \%hash;
  6         13  
51             }
52 2         30 return $new;
53             }
54 41         163 return $_[1];
55             }
56            
57             sub _build_table {
58 45     45   171377 my $self = shift;
59            
60 45         893 my $data = $self->data;
61            
62 45 50       115 return unless scalar @{ $data };
  45         190  
63            
64 45         106 my $table_spec = { };
65 45 100       319 if ($self->can('table_spec')) {
66 3         14 $table_spec = $self->table_spec;
67             }
68            
69 45         951 my $table = HTML::TableContent::Table->new($table_spec);
70 45         556 $table = $self->_set_inner_html('render_table', $table);
71            
72 45         1005 my $caption_spec = $self->_caption_spec;
73            
74 45 50       1084 if (defined $caption_spec) {
75 45         107 my $cap = (keys %{ $caption_spec->[0] })[0];
  45         216  
76 45         934 my $caption = $table->caption($self->$cap);
77 45         667 $caption = $self->_set_inner_html('render_caption', $caption);
78             }
79            
80 45         994 my $header_spec = $self->_header_spec;
81 45         1623 my %row_spec = $self->_row_spec;
82 45         1453 my %cell_spec = $self->_cell_spec;
83            
84 45         517 for (0 .. scalar @{$header_spec} - 1){
  45         196  
85 135         510 my $attr = (keys %{ $header_spec->[$_] })[0];
  135         515  
86 135         2654 my $header = $self->$attr;
87            
88 135 100       1436 if (my $cells = delete $header->attributes->{cells}) {
89 10         33 $cell_spec{$_ + 1} = $cells;
90             }
91            
92 135         390 $header = $self->_set_inner_html('render_header', $header);
93            
94 135         231 push @{ $table->headers }, $header;
  135         2415  
95             }
96            
97 45         360 my $row_index = 1;
98 45         104 foreach my $hash ( @{ $data } ) {
  45         112  
99 1133         4221 my $row_base = $self->_element_spec($row_index, %row_spec);
100            
101 1133         3550 %cell_spec = $self->_refresh_cell_spec($row_base, $row_index, %cell_spec);
102 1133         3554 my $row = $table->add_row($row_base);
103 1133         3062 $row = $self->_set_inner_html('render_row', $row);
104            
105 1133         1902 my $cell_index = 1;
106 1133         3636 foreach ( $table->all_headers ) {
107 3399         17474 my $cell_base = $self->_element_spec($cell_index++, %cell_spec);
108 3399         12583 $cell_base->{text} = $hash->{$_->template_attr};
109 3399         9147 my $cell = $row->add_cell($cell_base);
110 3399         9245 $cell = $self->_set_inner_html('render_cell', $cell);
111 3399         10317 $table->parse_to_column($cell);
112             }
113            
114 1133         2567 $row_index++;
115             }
116            
117 45 50       415 if ( $self->can('last_chance') ) {
118 0         0 $table = $self->last_chance($table);
119             }
120            
121 45         901 return $table;
122             }
123            
124             sub _element_spec {
125 4532     4532   11911 my ( $self, $index, %spec) = @_;
126            
127 4532         8172 my $base = { };
128 4532         8763 my $row_index = delete $spec{row_index};
129            
130 4532 100       13639 return $base unless keys %spec;
131            
132 1166         2803 my $num = $self->_num_to_en($index);
133            
134 1166 100       2918 if (defined $row_index) {
135 126         270 $num = sprintf('%s__%s', $self->_num_to_en($row_index), $num);
136             }
137            
138 1166         3441 my @pot = ($index, qw/current all odd even/, $num);
139            
140 1166         2274 for (@pot) {
141 6996 100       14247 if ( my $sp = delete $spec{$_} ) {
142 137 100       513 if ( $_ =~ m{odd|even} ) {
143 36         104 my $action = sprintf('_add_%s', $_);
144 36         100 $base = $self->$action($base, $index, $sp);
145             } else {
146 101 100       293 my $req_index = $_ =~ m{^\d$}xms ? $row_index : $index;
147 101         259 $base = $self->_add_base($base, $req_index, $sp);
148             }
149             }
150             }
151            
152 1166 100       2752 return $base unless keys %spec;
153            
154 1092         3225 for (keys %spec) {
155 4137 100       9460 next unless defined $spec{$_}->{index};
156 27 100       73 my $safe = defined $row_index ? sprintf('%s__%d', $row_index, $index) : $index;
157            
158 27 100       226 if ( $spec{$_}->{index} =~ m{$safe}ixms ) {
159 5         18 $base = $self->_add_to_base($base, $index, $spec{$_});
160             }
161             }
162            
163 1092         3478 return $base;
164             }
165            
166             sub _add_base {
167 101     101   303 return $_[0]->_add_to_base($_[1], $_[2], $_[3]);
168             }
169            
170             sub _add_odd {
171 24 100   24   70 return $_[1] unless $_[2] % 2 == 1;
172 16         44 return $_[0]->_add_to_base($_[1], $_[2], $_[3]);
173             }
174            
175             sub _add_even {
176 12 100   12   37 return $_[1] unless $_[2] % 2 == 0;
177 4         13 return $_[0]->_add_to_base($_[1], $_[2], $_[3]);
178             }
179            
180             sub _add_to_base {
181 126     126   319 my ( $self, $base, $index, $hash ) = @_;
182            
183 126         284 my @pot = (qw/increment_id cells alternate_classes/);
184 126         235 for (@pot) {
185 378 100       886 if ( my $p = $hash->{$_} ) {
186 75         211 my $action = sprintf('_base_%s', $_);
187 75         207 $self->$action($p, $base, $index, $hash);
188             }
189             }
190            
191 126         210 for ( keys %{ $hash } ) {
  126         412  
192 535 100       1051 next if $_ =~ m{increment_id}ixms;
193            
194 520 100       960 if ( $_ eq 'class' ) {
195 53         205 $base->{$_} = $self->_join_class($hash->{$_}, $base->{$_});
196             }
197            
198 520         1062 $base->{$_} = $hash->{$_};
199             }
200            
201 126         411 return $base;
202             }
203            
204             sub _base_increment_id {
205 15     15   56 return $_[4]->{id} = sprintf('%s%s', $_[1], $_[3]);
206             }
207            
208             sub _base_cells {
209 4     4   16 return $_[2]->{cells} = $_[1];
210             }
211            
212             sub _base_alternate_classes {
213 56     56   98 my $class = shift @{ $_[1] };
  56         130  
214 56         184 $_[2]->{class} = $_[0]->_join_class($class, $_[2]->{class});
215 56         114 push @{ $_[1] }, $class;
  56         175  
216             }
217            
218             sub _refresh_cell_spec {
219 1133     1133   3017 my ($self, $row_base, $row_index, %cell_spec) = @_;
220            
221 1133 100       2629 defined $row_base->{cells} ? $cell_spec{current} = delete $row_base->{cells} : delete $cell_spec{current};
222            
223 1133         2051 $cell_spec{row_index} = $row_index;
224            
225 1133         2488 for (keys %cell_spec) {
226 1203 100 100     3637 next unless ref $cell_spec{$_} eq 'HASH' && defined $cell_spec{$_}->{oac};
227 9         16 my @classes = @{ $cell_spec{$_}->{oac} };
  9         29  
228 9         28 $cell_spec{$_}->{alternate_classes} = \@classes;
229             }
230            
231 1133         3361 return %cell_spec;
232             }
233            
234             sub _join_class {
235 109     109   344 my ( $self, $class, $current ) = @_;
236            
237 109 100       437 return defined $current ? sprintf('%s %s', $current, $class) : sprintf('%s', $class);
238             }
239            
240             sub _set_inner_html {
241 4757     4757   10066 my ($self, $action, $element, $attr) = @_;
242            
243 4757   33     22356 $attr ||= $element->attributes;
244            
245 4757 100       21203 if ( my $inner_html = delete $attr->{inner_html}) {
    100          
246 20 100       92 if ( ref $inner_html eq 'ARRAY' ) {
    50          
247 11         34 $element->inner_html($inner_html);
248             } elsif ( $self->can($inner_html) ) {
249 9         35 $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         199 $element->inner_html($self->$action);
255             }
256            
257 4757         10668 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   5344 return unless $_[1] =~ m/^\d+$/xms;
287            
288 1292         21650 my $small = $_[0]->_small_num_en;
289 1292         8990 my $num = '';
290 1292 100       3542 if ($num = $small->{$_[1]} ){
291 318         973 return $num;
292             }
293            
294 974         3577 my @numbers = split '', $_[1];
295            
296 974 100       2491 if ( scalar @numbers == 2 ) {
297 72         471 return sprintf('%s_%s', $small->{$numbers[0] . 0}, $small->{$numbers[1]});
298             } else {
299 902         1426 my $count = 0;
300 902         1409 @numbers = reverse(@numbers);
301 902         1421 my $string;
302 902         1737 for (@numbers) {
303 2708         3970 my $new = $_;
304            
305 2708 100       5266 if ( $new == 0 ) { $count++; next; }
  185         287  
  185         380  
306            
307 2523 100       4476 unless ( $count == 0 ) {
308 1712         3871 $new .= sprintf '%s' x $count, map { '0' } 1 .. $count;
  2616         6717  
309             }
310            
311 2523 100       6278 unless ($num = $small->{$new}) {
312 902         16591 $num = sprintf('%s_%s', $small->{$_}, $_[0]->_large_num_en->{$count + 1});
313             }
314            
315 2523 100       15071 $string = defined $string ? sprintf('%s_%s', $num, $string) : sprintf('%s', $num);
316 2523         4773 $count++;
317             }
318 902         2544 return $string;
319             }
320             }
321            
322             1;
323            
324             __END__