File Coverage

blib/lib/Stenciller/Wrap.pm
Criterion Covered Total %
statement 218 231 94.3
branch 64 98 65.3
condition 13 29 44.8
subroutine 29 30 96.6
pod n/a
total 324 388 83.5


line stmt bran cond sub pod time code
1 7     7   3238 use Stenciller::Standard;
  7         19  
  7         49  
2 7     7   103377 use Stenciller::Stencil;
  7         24  
  7         363  
3 7     7   70 use strict;
  7         13  
  7         212  
4 7     7   39 use warnings;
  7         15  
  7         318  
5              
6             # PODNAME: Stenciller::Wrap
7              
8 7     7   6483 use Module::Pluggable search_path => ['Stenciller::Plugin'];
  7         80086  
  7         57  
9              
10 7     7   16351 class Stenciller::Wrap using Moose with Stenciller::Utils {
  7     7   234  
  7     7   47  
  7         15  
  7         384  
  7         41  
  7         14  
  7         79  
  7         2132  
  7         18  
  7         61  
  7         436  
  7         14  
  7         376  
  7         41  
  7         13  
  7         681  
  7         261  
  7         35  
  7         14  
  7         55  
  7         33552  
  7         19  
  7         71  
  7         47166  
  7         17  
  7         73  
  7         31642  
  7         16  
  7         81  
  7         564  
  7         15  
  7         65  
  7         1466  
  7         15  
  7         63  
  7         8977  
  7         16  
  7         85  
  7         45970  
  7         27  
  7         35  
  7         24  
  7         200  
  7         35  
  7         13  
  7         386  
  7         34  
  7         16  
  7         1111  
  7         69  
  7         38919  
  7         148  
  7         1120  
  7         23757  
  0         0  
11              
12 7         94 our $VERSION = '0.1302'; # VERSION
13              
14 7     7   103774 use Module::Load;
  7         10421  
  7         51  
15 7     7   473 use Carp 'croak';
  7         16  
  7         2083  
16              
17 7         39 has filepath => (
18             is => 'ro',
19             isa => File,
20             required => 1,
21             coerce => 1,
22             documentation => 'The textfile to parse.',
23             );
24 7         42305 has is_utf8 => (
25             is => 'ro',
26             isa => Bool,
27             default => 1,
28             documentation => 'Determines how the stencil file is read.'
29             );
30             has stencils => (
31             is => 'ro',
32             isa => ArrayRef[Stencil],
33             traits => ['Array'],
34 7         242 default => sub { [ ] },
35 7         30027 documentation => 'After parsing, this contains all parsed stencils.',
36             init_arg => undef,
37             handles => {
38             add_stencil => 'push',
39             all_stencils => 'elements',
40             get_stencil => 'get',
41             count_stencils => 'count',
42             has_stencils => 'count',
43             },
44             );
45             has header_lines => (
46             is => 'ro',
47             isa => ArrayRef[Str],
48             traits => ['Array'],
49 7         300 default => sub { [] },
50 7         120600 init_arg => undef,
51             documentation => 'After parsing, this contains all lines in the header.',
52             handles => {
53             add_header_line => 'push',
54             all_header_lines => 'elements',
55             },
56             );
57 7         72814 has skip_if_input_empty => (
58             is => 'ro',
59             isa => Bool,
60             default => 1,
61             documentation => 'If a stencil has no input content, skip entire stencil.',
62             );
63 7         30423 has skip_if_output_empty => (
64             is => 'ro',
65             isa => Bool,
66             default => 1,
67             documentation => 'If a stencil has no output content, skip entire stencil.',
68             );
69              
70 7 50   7   20531 around BUILDARGS($next: $class, @args) {
  7 50   7   16  
  7 50       2148  
  7 50       29976  
  7         171  
  7         33  
  7         32  
  7         33  
  7         69  
  7         14  
71 7 50 33     39 if(scalar @args == 1 && ref $args[0] eq 'HASH') {
72 0         0 $class->$next(%{ $args[0] });
  0         0  
73             }
74             else {
75 7         50 $class->$next(@args);
76             }
77             }
78              
79 7 50   7   8453 method BUILD {
  7     7   22  
  7         621  
  7         7498  
  7         32  
  7         12  
80 7         35 $self->parse;
81             }
82 7 0   7   14140 around has_stencils($next: $self) {
  7 0   0   20  
  7 0       1199  
  7         1339  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
83 0         0 my $count = $self->$next;
84 0   0     0 return !!$count || 0;
85             }
86              
87             method transform(Str :$plugin_name! does doc('Plugin to read contents with.'),
88             HashRef :$constructor_args? does doc('Constructor arguments for the plugin.') = {},
89             HashRef :$transform_args? does doc('Settings for the specific transformation.') = {}, ...
90             --> Str but assumed does doc('The transformed content.')
91 7 50 33 7   209302 ) {
  7 50   7   19  
  7 50   7   822  
  7 50   7   39  
  7 50   7   15  
  7 100   7   1605  
  7 50       40  
  7 100       29  
  7 50       999  
  7         38  
  7         16  
  7         861  
  7         40  
  7         15  
  7         2150  
  7         5517  
  7         5986  
  7         22  
  7         16  
  7         186  
  0         0  
  7         42  
  7         30  
  7         14  
  7         36  
  7         61  
  7         17  
  7         31  
  7         48  
  7         13  
  7         29  
  7         14  
92              
93 7         24 my $plugin_class = "Stenciller::Plugin::$plugin_name";
94 7         42 Module::Load::load($plugin_class);
95 7 50       186 die sprintf "Can't load %s: %s", $plugin_class, $@ if $@;
96              
97 7 50       73 if(!$plugin_class->does('Stenciller::Transformer')) {
98 0         0 croak("[$plugin_name] doesn't do the Stenciller::Transformer role. Quitting.");
99             }
100 7         1467 return $plugin_class->new(stenciller => $self, %{ $constructor_args })->transform($transform_args);
  7         68  
101             }
102              
103 7 50   7   8944 method parse {
  7     7   15  
  7         8666  
  7         1746  
  7         28  
  7         13  
104 7 50       247 my @contents = split /\v/ => $self->is_utf8 ? $self->filepath->slurp_utf8 : $self->filepath->slurp;
105              
106 7         11659 my $stencil_start = qr/^== +stencil +(\{.*\} +)?==$/;
107 7         32 my $input_start = qr/^--+input--+$/;
108 7         26 my $input_end = qr/^--+end input--+$/;
109 7         24 my $output_start = qr/^--+output--+$/;
110 7         24 my $output_end = qr/^--+end output--+$/;
111              
112 7         19 my $environment = 'header';
113 7         12 my $line_count = 0;
114              
115 7         16 my $stencil = undef;
116              
117             LINE:
118 7         18 foreach my $line (@contents) {
119 276 100       991 ++$line_count if $environment ne 'next_stencil'; # because then we are redo-ing the line
120              
121 276 100   524   1115 if(any { $environment eq $_ } (qw/header next_stencil/)) {
  524 100       1516  
    100          
    100          
    100          
    50          
122 36 100 50     1171 $self->add_header_line($line) and next LINE if $line !~ $stencil_start;
123              
124 15         42 my $possible_hash = $1;
125 15 100 66     433 my $settings = defined $possible_hash && $possible_hash =~ m{\{.*\}}
126             ? $self->eval_to_hashref($possible_hash, $self->filepath)
127             : {}
128             ;
129              
130 15 100       471 my $stencil_name = exists $settings->{'name'} ? delete $settings->{'name'} : $self->filepath->basename(qr/\..*/) . "-$line_count";
131 15         643 $stencil_name =~ s{[. -]}{_}g;
132 15         39 $stencil_name =~ s{[^a-zA-Z0-9_]}{}g;
133              
134             $stencil = Stenciller::Stencil->new(
135             stencil_name => $stencil_name,
136             loop_values => delete $settings->{'loop'},
137             line_number => $line_count,
138             maybe skip => delete $settings->{'skip'},
139 15         44 provided scalar keys %{ $settings }, extra_settings => $settings,
  15         655  
140             );
141 15         110 $environment = 'before_input';
142             }
143             elsif($environment eq 'before_input') {
144 56 100 50     422 $stencil->add_before_input($line) and next LINE if $line !~ $input_start;
145 15         58 $environment = 'input';
146             }
147             elsif($environment eq 'input') {
148 56 100 50     415 $stencil->add_input($line) and next LINE if $line !~ $input_end;
149 15         55 $environment = 'between';
150             }
151             elsif($environment eq 'between') {
152 53 100 50     392 $stencil->add_between($line) and next LINE if $line !~ $output_start;
153 15         54 $environment = 'output';
154             }
155             elsif($environment eq 'output') {
156 56 100 50     425 $stencil->add_output($line) and next LINE if $line !~ $output_end;
157 15         85 $environment = 'after_output';
158             }
159             elsif($environment eq 'after_output') {
160 19 100 50     156 $stencil->add_after_output($line) and next LINE if $line !~ $stencil_start;
161 8         61 $self->handle_completed_stencil($stencil);
162 8         62 $environment = 'next_stencil';
163 8         26 redo LINE;
164             }
165             }
166 7 50       35 if($environment ne 'after_output') {
167 0         0 croak (sprintf 'File <%s> appears malformed. Ended on <%s>', $self->filepath, $environment);
168             }
169 7         32 $self->handle_completed_stencil($stencil);
170             }
171              
172 7 50   7   23825 method handle_completed_stencil(Maybe[Stencil] $stencil) {
  7 50   7   28  
  7 50   15   1311  
  7 50       35  
  7 50       17  
  7         2136  
  7         1077  
  15         75  
  15         45  
  15         45  
  15         47  
  15         23  
  15         91  
  15         25  
173 15 50       68 return if !Stencil->check($stencil);
174 15 50       1364 return if $stencil->skip;
175 15 100 66     684 return if !$stencil->has_input && $self->skip_if_input_empty;
176 13 50 33     619 return if !$stencil->has_output && $self->skip_if_output_empty;
177              
178 13 100       649 if(!$stencil->has_loop_values) {
179 12         576 $self->add_stencil($stencil);
180 12         380 return;
181             }
182              
183 1         54 foreach my $loop_value ($stencil->all_loop_values) {
184 2         29 my $clone = $stencil->clone_with_loop_value($loop_value);
185 2         80 $self->add_stencil($clone);
186             }
187             }
188              
189 7 50   7   8805 method max_stencil_index {
  7     9   15  
  7         778  
  7         1072  
  9         90  
  9         17  
190 9         364 return $self->count_stencils - 1;
191             }
192             }
193              
194             1;
195              
196             __END__
197              
198             =pod
199              
200             =encoding UTF-8
201              
202             =head1 NAME
203              
204             Stenciller::Wrap
205              
206             =head1 VERSION
207              
208             Version 0.1302, released 2015-11-28.
209              
210             =head1 SOURCE
211              
212             L<https://github.com/Csson/p5-Stenciller>
213              
214             =head1 HOMEPAGE
215              
216             L<https://metacpan.org/release/Stenciller>
217              
218             =head1 AUTHOR
219              
220             Erik Carlsson <info@code301.com>
221              
222             =head1 COPYRIGHT AND LICENSE
223              
224             This software is copyright (c) 2015 by Erik Carlsson.
225              
226             This is free software; you can redistribute it and/or modify it under
227             the same terms as the Perl 5 programming language system itself.
228              
229             =cut