File Coverage

blib/lib/Plosurin/To/Perl5.pm
Criterion Covered Total %
statement 126 172 73.2
branch 5 20 25.0
condition 4 15 26.6
subroutine 22 27 81.4
pod 6 18 33.3
total 163 252 64.6


line stmt bran cond sub pod time code
1             #===============================================================================
2             #
3             # DESCRIPTION: Export to Perl 5
4             #
5             # AUTHOR: Aliaksandr P. Zahatski, <zahatski@gmail.com>
6             #===============================================================================
7             =head1 NAME
8              
9             Plosurin::To::Perl5 - export to Perl 5
10              
11             =head1 SYNOPSIS
12              
13             my $p5 = new Plosurin::To::Perl5(
14             'context' => $ctx,
15             'writer' => new Plosurin::Writer::Perl5,
16             'package' => $package,
17             );
18              
19            
20             =head1 DESCRIPTION
21              
22             Plosurin::To::Perl5 - export to Perl 5
23              
24             =cut
25             package Plosurin::To::Perl5;
26 2     2   547 use strict;
  2         6  
  2         61  
27 2     2   11 use warnings;
  2         5  
  2         58  
28 2     2   20 use v5.10;
  2         7  
29 2     2   11 use Data::Dumper;
  2         4  
  2         86  
30 2     2   15 use Plosurin::AbstractVisiter;
  2         4  
  2         50  
31 2     2   10 use base 'Plosurin::AbstractVisiter';
  2         5  
  2         3491  
32             our $VERSION = '0.01';
33              
34             =head2 new context=>$ctx, writer=>$writer, package=>"Tmpl"
35              
36              
37             =cut
38              
39             sub new {
40 3     3 1 8 my $class = shift;
41 3 50 33     28 my $self = bless( $#_ == 0 ? shift : {@_}, ref($class) || $class );
42 3         25 $self->{nodeid} = 1;
43 3   50     14 $self->{package} //= "Tmpl";
44 3         8 $self;
45             }
46              
47             =head2 writer or wr
48             Return current writer object.
49             $self->wr
50             $self->writer
51             =cut
52              
53 0     0 1 0 sub writer { $_[0]->{writer} }
54 14     14 1 65 sub wr { $_[0]->{writer} }
55              
56             =head2 context or ctx
57             retrun current context
58             =cut
59              
60 0     0 1 0 sub context { $_[0]->{context} }
61 3     3 1 7 sub ctx { $_[0]->{context} }
62              
63              
64              
65             sub start_write {
66 1     1 0 3 my $self = shift;
67 1         4 my $w = $self->wr;
68 1 50       8 return if $w->{start_write_done}++;
69 1         12 $w->print(<<"TXT");
70             # Please don't edit this file by hand.
71             package $self->{package};
72             use strict;
73             use utf8;
74             =head1 NAME
75              
76             $self->{package} - set of generated teplates
77              
78             =head1 SYNOPSIS
79              
80             use $self->{package};
81             print &$self->{package}::some_template(key1=>val1);
82              
83             =head1 DESCRIPTION
84              
85             $self->{package} - set of generated teplates by plosurin
86              
87             =cut
88              
89             TXT
90              
91             }
92              
93             sub end_write {
94 1     1 0 3 my $self = shift;
95 1         3 $self->wr->print(<<TMPL);
96             1;
97             __END__
98              
99             =head1 SEE ALSO
100              
101             Closure Templates Documentation L<http://code.google.com/closure/templates/docs/overview.html>
102              
103             Perl 6 implementation L<https://github.com/zag/plosurin>
104              
105             =cut
106             TMPL
107             }
108              
109             sub write {
110 3     3 0 16 my $self = shift;
111 3         7 my $writer = $self->{writer};
112 3         9 foreach my $n (@_) {
113 3         17 $self->visit($n);
114             }
115             }
116              
117             #Node container of command. <content>
118             sub Node {
119 8     8 0 12 my $self = shift;
120 8         13 my $node = shift;
121 8         35 $self->visit_childs($node);
122             }
123              
124             sub command_call_self {
125 1     1 0 4 my ( $self, $n ) = @_;
126 1         4 return $self->command_call($n);
127             }
128              
129             sub command_call {
130 1     1 0 3 my ( $self, $n ) = @_;
131 1         3 my $w = $self->wr;
132 1         3 my $ctx = $self->ctx;
133 1         3 my $template = $n->{tmpl_name};
134 1         6 my $tmpl = $ctx->get_template_by_name($template);
135 1   50     4 my $sub = $ctx->get_perl5_name($tmpl) || die "Not found template $template";
136              
137             #if data='all' or empty params
138             # &sub(@_)
139 1         7 my $attr = $n->attrs;
140 1 50 0     2 if ( scalar( @{ $n->childs } ) == 0
  1   33     6  
141             || exists $attr->{data} && $attr->{data} eq 'all' )
142             {
143              
144 1         5 $w->appendOutputVar( '&' . $sub . '(@_)' );
145             }
146             else {
147              
148             #if need external var ?
149             #$self-> !!!!! #TODO
150             #if not
151 0         0 my @params = ();
152 0         0 foreach my $ch (
153 0 0       0 map { UNIVERSAL::isa( $_, 'Soy::Node' ) ? @{ $_->childs } : $_ }
  0         0  
154 0         0 @{ $n->childs } )
155             {
156              
157             # skip not param nodes
158 0 0       0 next unless UNIVERSAL::isa( $ch, 'Soy::command_param' );
159 0         0 my $vname = 'param' . ++${ $w->{nodeid} };
  0         0  
160 0         0 $w->pushOtputVar($vname);
161 0         0 $self->visit($ch);
162 0         0 push @params, { name => $ch->{name}, vname => $vname };
163 0         0 $w->popOtputVar;
164             }
165 0         0 $w->say(qq!# calling template: $template;!);
166             $w->appendOutputVar(
167             '&'
168             . $sub . '('
169             . join( ',',
170 0         0 map { "'" . $$_{name} . q!' => $! . $$_{vname} } @params )
  0         0  
171             . ')'
172             );
173             }
174             }
175              
176             sub command_param {
177 0     0 0 0 my ( $self, $node ) = @_;
178 0         0 $self->visit_childs($node);
179             }
180              
181             sub command_param_self {
182 0     0 0 0 my ( $self, $node ) = @_;
183 0         0 my $w = $self->wr;
184 0         0 $w->appendOutputVar( $node->{value} );
185             }
186              
187             sub raw_text {
188 4     4 0 11 my ( $self, $node ) = @_;
189 4         10 my $w = $self->wr;
190 4         8 my $txt = $node->{''};
191             #escape '
192 4         10 $txt =~ s/'/\\'/g;
193 4         20 $w->appendOutputVar("'$txt'");
194             }
195              
196             =head2 File
197             Export File
198             =cut
199              
200             sub File {
201 1     1 1 4 my ( $self, $node ) = @_;
202 1         3 my $w = $self->wr;
203              
204             #get tempales
205             # $self->visit_childs($node);
206             #walk
207 1         2 foreach my $t ( @{ $node->childs } ) {
  1         5  
208             #setup current template
209             #setup current params
210             #make params map
211 2         6 my %params = ();
212 2         7 foreach my $p ($t->params()) {
213 4         12 $params{$p->name} = 0;
214             }
215             #setup current template PARAMS
216 2         9 $self->{PARAMS} = \%params;
217            
218 2         7 my $tmpl_name = $t->name;
219 2         7 my $namespace = $node->namespace;
220 2         8 ( my $converted_name = $namespace . $tmpl_name ) =~ tr/\./_/;
221 2         6 $w->print(<<TMPL);
222             =head1 $converted_name
223              
224 2         7 @{[ $t->comment ]}
225              
226 2         14 ( I<src>: C<@{[ $node->{file} ]}>, I<template name>: C<$tmpl_name> )
227              
228             =cut
229              
230             sub $converted_name \{
231             my %args = \@_;
232             TMPL
233 2         8 $w->inc_ident;
234 2         3 my $vname = 'param' . ++${ $w->{nodeid} };
  2         8  
235 2         9 $w->pushOtputVar($vname);
236              
237             #set current namespace (used for {call})
238 2         6 $self->ctx->{namespace} = $namespace;
239              
240             #parse template
241 2         12 $self->visit_childs($t);
242 2         8 $w->initOutputVar();
243 2         8 $w->say("return \$$vname;");
244 2         8 $w->dec_ident;
245 2         6 $w->say('}');
246 2         9 $w->say(''); # empty line
247              
248             #collect statistic
249 2         16 push @{ $self->{tmpls} },
250             {
251             tmpl => $t,
252             namespace => $namespace,
253             name => $tmpl_name,
254             perl5_name => $converted_name,
255 2         3 package_name => $self->{package} . "::" . $converted_name,
256             };
257             # clear current template PARAMS
258 2         9 delete $self->{PARAMS};
259              
260             }
261             }
262             sub command_foreach {
263 1     1 0 4 my ($self, $n) = @_;
264 1         5 my $w = $self->wr;
265             # die Dumper $self->ctx;
266 1         7 my $vname = $n->get_var_name();
267 1         3 my $id = ++${ $w->{nodeid} };
  1         5  
268 1         4 my $list_var = "list_". $vname. $id;
269 1         3 my $list_len_var = "len_". $vname. $id;
270 1         7 my $exp = $n->{expression}->parse($w->var_map, $self->{PARAMS})->as_perl5();
271 1         8 $w->say("my \$$list_var = ". $exp .";");
272 1         6 $w->say("my \$$list_len_var = scalar(\@\$$list_var);");
273 1         8 $w->initOutputVar();
274             #check ifempty
275 1 50       5 if ($n->get_ifempty) {
276 1         6 $w->say("if ( \$$list_len_var > 0 ) {");
277 1         6 $w->inc_ident();
278             }
279             #export foreach
280 1         4 my $index_var_name = "idx_$vname".$id;
281 1         7 $w->say("for (my \$$index_var_name = 0; \$$index_var_name < \$$list_len_var; \$$index_var_name++) {");
282 1         3 $w->inc_ident();
283 1         3 my $data_var_name = "data_$vname".$id;
284             #map tempalte variable to actual name
285 1         5 $w->set_var_map($vname,$data_var_name);
286             #data variable
287 1         5 $w->say("my \$$data_var_name = \$$list_var\->[\$$index_var_name];");
288 1         5 $self->visit_childs($n);
289 1         21 $w->dec_ident();
290 1         4 $w->say('}');
291 1 50       3 if (my $ifempty_node = $n->get_ifempty) {
292 1         4 $w->dec_ident();
293 1         4 $w->say('} else {');
294 1         4 $w->inc_ident();
295 1         2 $w->say('#ifempty content');
296 1         4 $self->visit_childs($ifempty_node);
297 1         5 $w->dec_ident();
298 1         3 $w->say('} # ifempty');
299             }
300              
301             }
302              
303             sub command_print {
304 2     2 0 7 my ( $self, $n ) = @_;
305 2         8 my $w = $self->wr;
306 2         10 my $p5_code = $n->{expression}->parse($w->var_map, , $self->{PARAMS})->as_perl5();
307 2         12 $w->appendOutputVar($p5_code)
308             }
309              
310 2     2   1085 use Perl6::Pod::To::XHTML;
  2         334342  
  2         72  
311 2     2   17 use Perl6::Pod::To;
  2         5  
  2         48  
312 2     2   920 use Perl6::Pod::Lib;
  2         8917  
  2         635  
313             #pod6xhtml -nb -t div -M Perl6::Pod::Lib -c \'=Include $file($rule)'
314             sub command_import {
315 0     0 0   my ( $self, $n ) = @_;
316 0           my $w = $self->wr;
317 0           my $file = $n->attrs->{file};
318 0   0       my $rule = $n->attrs->{rule} || '';
319 0 0         unless (-e $file ) {
320 0           die "File for import : $file not found!"
321             }
322 0           my %args = (doctype =>'div', body=>0);
323 0 0         my $in_fd = "=Include $file" .( $rule ? "($rule)" : '');
324 0           $in_fd = \"=begin pod \n$in_fd\n=end pod";
325 0           my $str ='';
326 0           open FH,'>',\$str;
327 0           my $p = Perl6::Pod::To::to_abstract( 'Perl6::Pod::To::XHTML', \*FH, %args );
328 0           $p->begin_input;
329             #include libs ( see $Perl6::Pod::Lib::PERL6POD )
330 0           my @libs = (qw/Perl6::Pod::Lib/);
331 0 0         if (@libs) {
332 0           my $use = join "\n" => map { "=begin pod\n=use $_\n=end pod" } @libs;
  0            
333 0           $use .= "\n";
334 0           $p->_parse_chunk(\$use);
335             }
336 0           $p->_parse_chunk($in_fd);
337 0           $p->end_input;
338 0           close FH;
339             #replace ' -> \'
340 0           $str =~ s/\'/\\'/g;
341 0           $w->appendOutputVar( qq!'$str'! );
342             }
343              
344              
345             1;
346             __END__
347              
348             =head1 SEE ALSO
349              
350             Closure Templates Documentation L<http://code.google.com/closure/templates/docs/overview.html>
351              
352             Perl 6 implementation L<https://github.com/zag/plosurin>
353              
354              
355             =head1 AUTHOR
356              
357             Zahatski Aliaksandr, <zag@cpan.org>
358              
359             =head1 COPYRIGHT AND LICENSE
360              
361             Copyright (C) 2011 by Zahatski Aliaksandr
362              
363             This library is free software; you can redistribute it and/or modify
364             it under the same terms as Perl itself.
365              
366             =cut
367