File Coverage

blib/lib/Dotiac/DTL/Tag/for.pm
Criterion Covered Total %
statement 246 274 89.7
branch 50 74 67.5
condition 20 30 66.6
subroutine 12 14 85.7
pod 11 11 100.0
total 339 403 84.1


line stmt bran cond sub pod time code
1             #for.pm
2             #Last Change: 2009-01-19
3             #Copyright (c) 2009 Marc-Seabstian "Maluku" Lucksch
4             #Version 0.8
5             ####################
6             #This file is part of the Dotiac::DTL project.
7             #http://search.cpan.org/perldoc?Dotiac::DTL
8             #
9             #for.pm is published under the terms of the MIT license, which basically
10             #means "Do with it whatever you want". For more information, see the
11             #license.txt file that should be enclosed with libsofu distributions. A copy of
12             #the license is (at the time of writing) also available at
13             #http://www.opensource.org/licenses/mit-license.php .
14             ###############################################################################
15            
16             package Dotiac::DTL::Tag::for;
17 11     11   59 use base qw/Dotiac::DTL::Tag/;
  11         22  
  11         852  
18 11     11   63 use strict;
  11         20  
  11         388  
19 11     11   61 use warnings;
  11         30  
  11         37384  
20             require Scalar::Util;
21            
22             our $VERSION = 0.8;
23            
24             sub new {
25 34     34 1 70 my $class=shift;
26 34         146 my $self={p=>shift()};
27 34         68 my $name=shift;
28 34         137 my %name = Dotiac::DTL::get_variables($name,"in","reversed");
29 34         93 $self->{var}=[split /\s*,\s*/,join(" ",@{$name{""}})];
  34         218  
30 34 100       113 if ($name{reversed}) {
31 4         12 $self->{rev}=1;
32             }
33 34         101 $self->{source}=$name{in}->[0];
34 34 50       108 die "Can't use \"for\" without \"in\"" unless $self->{source};
35 34 50       46 die "Can't use \"for\" without a variablename" unless @{$self->{var}};
  34         101  
36 34         57 my $obj=shift;
37 34         55 my $data=shift;
38 34         46 my $pos=shift;
39 34         60 my $found="";
40 34         159 $self->{content}=$obj->parse($data,$pos,\$found,"endfor","empty");
41 34 50       115 if ($found eq "empty") {
42 0         0 $self->{empty}=$obj->parse($data,$pos,\$found,"endfor");
43             }
44 34         101 bless $self,$class;
45 34         152 return $self;
46             }
47             sub print {
48 41     41 1 89 my $self=shift;
49 41         241 print $self->{p};
50 41         162 my $var=Dotiac::DTL::devar_content($self->{source},@_);
51 41         113 my $varname=$self->{var}->[0];
52 41         71 my $vars=shift;
53 41         96 my $parent = $vars->{forloop};
54 41         51 my @vars=@{$self->{var}};
  41         131  
55 41         120 my $ref=Scalar::Util::reftype($var);
56 41 100 66     219 if ($ref and $ref eq "HASH") {
57 9 50       12 if (%{$var}) {
  9         25  
58 9         13 my @loop = sort keys %{$var};
  9         39  
59 9 100       34 @loop=reverse @loop if $self->{rev};
60 9         14 my $varname2="";
61 9 100       25 $varname2=$vars[1] if $#vars;
62 9         26 foreach my $v (0 .. $#loop) {
63 27         233 my $fl = {counter=>$v+1,counter0=>$v,revcounter=>@loop-$v,revcounter0=>$#loop-$v,first=>($v==0),last=>($v==$#loop),parentloop=>$parent,key=>$loop[$v]};
64 27         60 my $x= $var->{$loop[$v]};
65 27         42 my %d;
66 27 100       48 if ($#vars) {
67 6         12 $d{$varname2}=$x;
68 6         14 $d{$varname}=$loop[$v];
69             }
70             else {
71 21         47 $d{$varname}=$x;
72             }
73 27         296 $self->{content}->print({%{$vars},forloop=>$fl,%d},@_);
  27         168  
74             }
75             }
76             else {
77 0 0       0 $self->{empty}->print($vars,@_) if $self->{empty};
78             }
79             }
80             else {
81 32         66 my @loop=();
82             #@loop = ($var) unless $self->{empty};
83 32 50 33     236 if ($ref and $ref eq "ARRAY" and @{$var}) {
  32   33     110  
84 32         103 @loop=@{$var};
  32         105  
85             }
86             else {
87 0 0       0 $self->{empty}->print($vars,@_) if $self->{empty};
88             }
89 32 100       90 @loop=reverse @loop if $self->{rev};
90 32         94 foreach my $v (0 .. $#loop) {
91 151         1634 my $fl = {counter=>($v+1),counter0=>$v,revcounter=>@loop-$v,revcounter0=>$#loop-$v,first=>($v==0),last=>($v==$#loop),parentloop=>$parent};
92 151         306 my $x= $loop[$v];
93 151         382 my %d;
94 151 100 100     614 if (ref $x and ref $x eq "ARRAY" and $#vars) {
      100        
95 4         6 my @d=@{$x};
  4         15  
96 4         13 $#d=$#vars;
97 4         21 @d{@vars}=@d;
98             }
99             else {
100 147         321 $d{$varname}=$x;
101             }
102 151         230 $self->{content}->print({%{$vars},forloop=>$fl,%d},@_);
  151         907  
103             }
104            
105             }
106            
107 41         1676 $self->{n}->print($vars,@_);
108             }
109             sub string {
110 41     41 1 82 my $self=shift;
111 41         64 my $r="";
112 41         265 my $var=Dotiac::DTL::devar_content($self->{source},@_);
113 41         121 my $varname=$self->{var}->[0];
114 41         64 my $vars=shift;
115 41         58 my @vars=@{$self->{var}};
  41         129  
116 41         86 my $parent = $vars->{forloop};
117 41         101 my $ref=Scalar::Util::reftype($var);
118 41 100 66     209 if ($ref and $ref eq "HASH") {
119 9 50       17 if (%{$var}) {
  9         27  
120 9         14 my @loop = sort keys %{$var};
  9         44  
121 9 100       29 @loop=reverse @loop if $self->{rev};
122 9         20 my $varname2="";
123 9 100       25 $varname2=$vars[1] if $#vars;
124 9         26 foreach my $v (0 .. $#loop) {
125 27         208 my $fl = {counter=>$v+1,counter0=>$v,revcounter=>@loop-$v,revcounter0=>$#loop-$v,first=>($v==0),last=>($v==$#loop),parentloop=>$parent,key=>$loop[$v]};
126 27         56 my $x= $var->{$loop[$v]};
127 27         31 my %d;
128 27 100       47 if ($#vars) {
129 6         15 $d{$varname2}=$x;
130 6         13 $d{$varname}=$loop[$v];
131             }
132             else {
133 21         39 $d{$varname}=$x;
134             }
135 27         43 $r.=$self->{content}->string({%{$vars},forloop=>$fl,%d},@_);
  27         171  
136             }
137             }
138             else {
139 0 0       0 $r=$self->{empty}->string($vars,@_) if $self->{empty};
140             }
141             }
142             else {
143 32         58 my @loop=();
144             #@loop = ($var) unless $self->{empty};
145 32 50 33     210 if ($ref and $ref eq "ARRAY" and @{$var}) {
  32   33     113  
146 32         47 @loop=@{$var};
  32         96  
147             }
148             else {
149 0 0       0 $r=$self->{empty}->string($vars,@_) if $self->{empty};
150             }
151 32 100       105 @loop=reverse @loop if $self->{rev};
152 32         97 foreach my $v (0 .. $#loop) {
153 151         1136 my $fl = {counter=>$v+1,counter0=>$v,revcounter=>@loop-$v,revcounter0=>$#loop-$v,first=>($v==0),last=>($v==$#loop),parentloop=>$parent};
154 151         413 my $x=$loop[$v];
155 151         245 my %d;
156 151 100 100     647 if (ref $x and ref $x eq "ARRAY" and $#vars) {
      100        
157 4         7 my @d=@{$x};
  4         12  
158 4         13 $#d=$#vars;
159 4         21 @d{@vars}=@d;
160             }
161             else {
162 147         395 $d{$varname}=$x;
163             }
164 151         256 $r.=$self->{content}->string({%{$vars},forloop=>$fl,%d},@_);
  151         1115  
165             }
166            
167             }
168 41         234 return $self->{p}.$r.$self->{n}->string($vars,@_);
169            
170             }
171             sub perl {
172 35     35 1 74 my $self=shift;
173 35         65 my $fh=shift;
174 35         64 my $id=shift;
175 35         196 $self->SUPER::perl($fh,$id,@_);
176 35         79 print $fh "my ";
177 35         235 print $fh (Data::Dumper->Dump([$self->{var}->[0]],["\$var$id"]));
178 35         1297 print $fh "my ";
179 35         219 print $fh (Data::Dumper->Dump([$self->{source}],["\$source$id"]));
180 35 100       1288 if (@{$self->{var}} > 1) {
  35         161  
181 4         9 print $fh "my ";
182 4         27 print $fh (Data::Dumper->Dump([$self->{var}],["\$vars$id"]));
183             }
184             #if ($self->{empty}) {
185             # print $fh "my ";
186             # print $fh (Data::Dumper->Dump([$self->{empty}],["\$empty$id"]));
187             #}
188 35         395 $id=$self->{content}->perl($fh,$id+1,@_);
189 35 50       133 $id=$self->{empty}->perl($fh,$id+1,@_) if $self->{empty};
190 35         142 return $self->{n}->perl($fh,$id+1,@_);
191            
192            
193            
194             }
195             sub perlprint {
196 35     35 1 59 my $self=shift;
197 35         48 my $fh=shift;
198 35         53 my $id=shift;
199 35         42 my $level=shift;
200 35         139 $self->SUPER::perlprint($fh,$id,$level,@_);
201 35         61 my $in="\t" x $level;
202 35         120 print $fh $in,"my \$forvar$id = Dotiac::DTL::devar_content(\$source$id,\$vars,\$escape,\@_);\n";
203 35         77 print $fh $in,"my \$fortype$id = 0;\n";
204             #print $fh $in,"my \@forloop$id = (".($self->{empty}?"":"\$forvar$id").");\n";
205 35         73 print $fh $in,"my \@forloop$id = ();\n";
206 35         75 print $fh $in,"my \$parentloop$id = \$vars->{forloop};\n";
207 35         75 print $fh $in,"my \$forvars$id = \$vars;\n";
208 35         82 print $fh $in,"my \$ref$id = Scalar::Util::reftype(\$forvar$id);\n";
209 35         74 print $fh $in,"if (\$ref$id and \$ref$id eq \"HASH\" ) {\n";
210 35         91 print $fh $in,"\t\$fortype$id = 1;\n";
211 35         96 print $fh $in,"\t\@forloop$id = sort keys \%{\$forvar$id};\n";
212 35         81 print $fh $in,"} elsif (\$ref$id and \$ref$id eq \"ARRAY\" ) {\n";
213 35         73 print $fh $in,"\t\@forloop$id = \@{\$forvar$id};\n";
214 35         52 print $fh $in,"}\n";
215 35 100       99 print $fh $in,"\@forloop$id = reverse \@forloop$id;\n" if $self->{rev};
216 35 50       87 if ($self->{empty}) {
217 0         0 print $fh $in,"if (\@forloop$id) {\n";
218 0         0 print $fh $in,"\tforeach my \$loop (0 .. \$#forloop$id) {\n";
219 0         0 $level++;
220             }
221             else {
222 35         122 print $fh $in,"foreach my \$loop (0 .. \$#forloop$id) {\n";
223             }
224 35         107 my $in2="\t" x ($level+1);
225 35         75 print $fh $in2,"my \$vars={\%{\$forvars$id}};\n";
226 35         105 print $fh $in2,"\$vars->{forloop} = {counter=>\$loop+1,counter0=>\$loop,revcounter=>\@forloop$id-\$loop,revcounter0=>\$#forloop$id-\$loop,first=>(\$loop==0),last=>(\$loop==\$#forloop$id),parentloop=>\$parentloop$id};\n";
227 35 100       44 if (@{$self->{var}} > 1) {
  35         97  
228 4         10 print $fh $in2,"if (\$fortype$id) {\n";
229 4         14 print $fh $in2,"\t\$vars->{forloop}->{key}=\$forloop$id"."[\$loop];\n";
230 4         12 print $fh $in2,"\t\$vars->{\$var$id"."}=\$forloop$id"."[\$loop];\n";
231 4         16 print $fh $in2,"\t\$vars->{\$vars$id"."->[1]}=\$forvar$id"."->{\$forloop$id"."[\$loop]};\n";
232 4         10 print $fh $in2,"} else {\n";
233 4         11 print $fh $in2,"\tmy \$x = \$forloop$id"."[\$loop];\n";
234 4         6 print $fh $in2,"\tif (ref \$x and ref \$x eq \"ARRAY\") {\n";
235 4         13 print $fh $in2,"\t\tmy \@d=\@{\$x};\n";
236 4         9 print $fh $in2,"\t\t\$#d=\$#\$vars$id;\n";
237 4         13 print $fh $in2,"\t\t\@\$vars{\@\$vars$id}=\@d;\n";
238 4         10 print $fh $in2,"\t}\n";
239 4         6 print $fh $in2,"}\n";
240             }
241             else {
242 31         143 print $fh $in2,"if (\$fortype$id) {\n";
243 31         78 print $fh $in2,"\t\$vars->{forloop}->{key}=\$forloop$id"."[\$loop];\n";
244 31         137 print $fh $in2,"\t\$vars->{\$var$id}=\$forvar$id"."->{\$forloop$id"."[\$loop]};\n";
245 31         52 print $fh $in2,"} else {\n";
246 31         70 print $fh $in2,"\t\$vars->{\$var$id}=\$forloop$id"."[\$loop];\n";
247 31         50 print $fh $in2,"}\n";
248             }
249 35         198 $id = $self->{content}->perlprint($fh,$id+1,$level+1,@_);
250 35 50       109 if ($self->{empty}) {
251 0         0 print $fh $in,"\t}\n";
252 0         0 print $fh $in,"} else {\n";
253 0         0 $id = $self->{empty}->perlprint($fh,$id+1,$level+1,@_);
254 0         0 print $fh $in,"}\n";
255 0         0 $level--;
256             }
257             else {
258 35         78 print $fh $in,"}\n";
259             }
260 35         176 return $self->{n}->perlprint($fh,$id+1,$level,@_);
261             }
262             sub perlstring {
263 35     35 1 53 my $self=shift;
264 35         50 my $fh=shift;
265 35         44 my $id=shift;
266 35         51 my $level=shift;
267 35         174 $self->SUPER::perlstring($fh,$id,$level,@_);
268 35         80 my $in="\t" x $level;
269 35         130 print $fh $in,"my \$forvar$id = Dotiac::DTL::devar_content(\$source$id,\$vars,\$escape,\@_);\n";
270 35         84 print $fh $in,"my \$fortype$id = 0;\n";
271             #print $fh $in,"my \@forloop$id = (".($self->{empty}?"":"\$forvar$id").");\n";
272 35         75 print $fh $in,"my \@forloop$id = ();\n";
273 35         79 print $fh $in,"my \$parentloop$id = \$vars->{forloop};\n";
274 35         74 print $fh $in,"my \$forvars$id = \$vars;\n";
275 35         89 print $fh $in,"my \$ref$id = Scalar::Util::reftype(\$forvar$id);\n";
276 35         84 print $fh $in,"if (\$ref$id and \$ref$id eq \"HASH\" ) {\n";
277 35         72 print $fh $in,"\t\$fortype$id = 1;\n";
278 35         81 print $fh $in,"\t\@forloop$id = sort keys \%{\$forvar$id};\n";
279 35         93 print $fh $in,"} elsif (\$ref$id and \$ref$id eq \"ARRAY\" ) {\n";
280 35         77 print $fh $in,"\t\@forloop$id = \@{\$forvar$id};\n";
281 35         50 print $fh $in,"}\n";
282 35 100       113 print $fh $in,"\@forloop$id = reverse \@forloop$id;\n" if $self->{rev};
283 35 50       98 if ($self->{empty}) {
284 0         0 print $fh $in,"if (\@forloop$id) {\n";
285 0         0 print $fh $in,"\tforeach my \$loop (0 .. \$#forloop$id) {\n";
286 0         0 $level++;
287             }
288             else {
289 35         109 print $fh $in,"foreach my \$loop (0 .. \$#forloop$id) {\n";
290             }
291 35         77 my $in2="\t" x ($level+1);
292 35         78 print $fh $in2,"my \$vars={\%{\$forvars$id}};\n";
293 35         125 print $fh $in2,"\$vars->{forloop} = {counter=>\$loop+1,counter0=>\$loop,revcounter=>\@forloop$id-\$loop,revcounter0=>\$#forloop$id-\$loop,first=>(\$loop==0),last=>(\$loop==\$#forloop$id),parentloop=>\$parentloop$id};\n";
294 35 100       45 if (@{$self->{var}} > 1) {
  35         115  
295 4         14 print $fh $in2,"if (\$fortype$id) {\n";
296 4         13 print $fh $in2,"\t\$vars->{forloop}->{key}=\$forloop$id"."[\$loop];\n";
297 4         10 print $fh $in2,"\t\$vars->{\$var$id"."}=\$forloop$id"."[\$loop];\n";
298 4         16 print $fh $in2,"\t\$vars->{\$vars$id"."->[1]}=\$forvar$id"."->{\$forloop$id"."[\$loop]};\n";
299 4         7 print $fh $in2,"} else {\n";
300 4         10 print $fh $in2,"\tmy \$x = \$forloop$id"."[\$loop];\n";
301 4         9 print $fh $in2,"\tif (ref \$x and ref \$x eq \"ARRAY\") {\n";
302 4         7 print $fh $in2,"\t\tmy \@d=\@{\$x};\n";
303 4         10 print $fh $in2,"\t\t\$#d=\$#\$vars$id;\n";
304 4         9 print $fh $in2,"\t\t\@\$vars{\@\$vars$id}=\@d;\n";
305 4         5 print $fh $in2,"\t}\n";
306 4         8 print $fh $in2,"}\n";
307             }
308             else {
309 31         89 print $fh $in2,"if (\$fortype$id) {\n";
310 31         93 print $fh $in2,"\t\$vars->{forloop}->{key}=\$forloop$id"."[\$loop];\n";
311 31         109 print $fh $in2,"\t\$vars->{\$var$id}=\$forvar$id"."->{\$forloop$id"."[\$loop]};\n";
312 31         58 print $fh $in2,"} else {\n";
313 31         80 print $fh $in2,"\t\$vars->{\$var$id}=\$forloop$id"."[\$loop];\n";
314 31         50 print $fh $in2,"}\n";
315             }
316 35         207 $id = $self->{content}->perlstring($fh,$id+1,$level+1,@_);
317 35 50       106 if ($self->{empty}) {
318 0         0 print $fh $in,"\t}\n";
319 0         0 print $fh $in,"} else {\n";
320 0         0 $id = $self->{empty}->perlstring($fh,$id+1,$level+1,@_);
321 0         0 print $fh $in,"}\n";
322 0         0 $level--;
323             }
324             else {
325 35         68 print $fh $in,"}\n";
326             }
327 35         182 return $self->{n}->perlstring($fh,$id+1,$level,@_);
328             }
329            
330             sub perleval {
331 35     35 1 60 my $self=shift;
332 35         59 my $fh=shift;
333 35         45 my $id=shift;
334 35         167 $id=$self->{content}->perleval($fh,$id+1,@_);
335 35 50       122 $id=$self->{empty}->perleval($fh,$id+1,@_) if $self->{empty};
336 35         133 $self->{n}->perleval($fh,$id+1,@_);
337             }
338             sub perlcount {
339 0     0 1 0 my $self=shift;
340 0         0 my $id=shift;
341 0         0 $id=$self->{content}->perlcount($id+1,@_);
342 0 0       0 $id=$self->{empty}->perlcount($id+1,@_) if $self->{empty};
343 0         0 return $self->{n}->perlcount($id+1);
344             }
345             sub perlinit {
346 35     35 1 65 my $self=shift;
347 35         47 my $fh=shift;
348 35         56 my $id=shift;
349 35         165 $id=$self->{content}->perlinit($fh,$id+1,@_);
350 35 50       110 $id=$self->{empty}->perlinit($fh,$id+1,@_) if $self->{empty};
351 35         121 return $self->{n}->perlinit($fh,$id+1);
352             }
353             sub next {
354 34     34 1 67 my $self=shift;
355 34         148 $self->{n}=shift;
356             }
357             sub eval {
358 0     0 1   my $self=shift;
359 0           $self->{n}->eval(@_);
360             }
361             1;
362            
363             __END__