File Coverage

blib/lib/Stenciller/Wrap.pm
Criterion Covered Total %
statement 212 227 93.3
branch 61 98 62.2
condition 13 29 44.8
subroutine 29 30 96.6
pod n/a
total 315 384 82.0


line stmt bran cond sub pod time code
1 5     5   1411 use Stenciller::Standard;
  5         12  
  5         53  
2 5     5   55762 use Stenciller::Stencil;
  5         14  
  5         256  
3 5     5   43 use strict;
  5         8  
  5         208  
4 5     5   29 use warnings;
  5         8  
  5         328  
5             our $VERSION = '0.1212'; # VERSION:
6             # PODNAME: Stenciller::Wrap
7              
8 5     5   3065 use Module::Pluggable search_path => ['Stenciller::Plugin'];
  5         41357  
  5         37  
9              
10 5     5   10063 class Stenciller::Wrap using Moose with Stenciller::Utils {
  5     5   115  
  5     5   33  
  5         6  
  5         259  
  5         23  
  5         7  
  5         47  
  5         1403  
  5         6  
  5         35  
  5         264  
  5         10  
  5         213  
  5         21  
  5         6  
  5         370  
  5         150  
  5         26  
  5         10  
  5         52  
  5         19331  
  5         10  
  5         39  
  5         25943  
  5         11  
  5         41  
  5         15932  
  5         9  
  5         48  
  5         375  
  5         9  
  5         74  
  5         1021  
  5         10  
  5         36  
  5         4965  
  5         10  
  5         44  
  5         18535  
  5         15  
  5         189  
  5         22  
  5         12  
  5         151  
  5         21  
  5         6  
  5         226  
  5         20  
  5         8  
  5         658  
  5         40  
  5         18704  
  5         91  
  5         685  
  5         15389  
11              
12 5     5   55476 use Module::Load;
  5         5599  
  5         27  
13 5     5   262 use Carp 'croak';
  5         8  
  5         1074  
14              
15 5         82 has filepath => (
16             is => 'ro',
17             isa => File,
18             required => 1,
19             coerce => 1,
20             documentation => 'The textfile to parse.',
21             );
22 5         28208 has is_utf8 => (
23             is => 'ro',
24             isa => Bool,
25             default => 1,
26             documentation => 'Determines how the stencil file is read.'
27             );
28             has stencils => (
29             is => 'ro',
30             isa => ArrayRef[Stencil],
31             traits => ['Array'],
32 5         120 default => sub { [ ] },
33 5         16588 documentation => 'After parsing, this contains all parsed stencils.',
34             init_arg => undef,
35             handles => {
36             add_stencil => 'push',
37             all_stencils => 'elements',
38             get_stencil => 'get',
39             count_stencils => 'count',
40             has_stencils => 'count',
41             },
42             );
43             has header_lines => (
44             is => 'ro',
45             isa => ArrayRef[Str],
46             traits => ['Array'],
47 5         133 default => sub { [] },
48 5         78607 init_arg => undef,
49             documentation => 'After parsing, this contains all lines in the header.',
50             handles => {
51             add_header_line => 'push',
52             all_header_lines => 'elements',
53             },
54             );
55 5         43170 has skip_if_input_empty => (
56             is => 'ro',
57             isa => Bool,
58             default => 1,
59             documentation => 'If a stencil has no input content, skip entire stencil.',
60             );
61 5         17700 has skip_if_output_empty => (
62             is => 'ro',
63             isa => Bool,
64             default => 1,
65             documentation => 'If a stencil has no output content, skip entire stencil.',
66             );
67              
68 5 50   5   12188 around BUILDARGS($next: $class, @args) {
  5 50   5   17  
  5 50       1128  
  5 50       16507  
  5         51  
  5         24  
  5         16  
  5         459  
  5         46  
  5         9  
69 5 50 33     25 if(scalar @args == 1 && ref $args[0] eq 'HASH') {
70 0         0 $class->$next(%{ $args[0] });
  0         0  
71             }
72             else {
73 5         31 $class->$next(@args);
74             }
75             }
76              
77 5 50   5   4913 method BUILD {
  5     5   10  
  5         375  
  5         5969  
  5         21  
  5         9  
78 5         22 $self->parse;
79             }
80 5 0   5   7884 around has_stencils($next: $self) {
  5 0   0   9  
  5 0       757  
  5         873  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
81 0         0 my $count = $self->$next;
82 0   0     0 return !!$count || 0;
83             }
84              
85             method transform(Str :$plugin_name! does doc('Plugin to read contents with.'),
86             HashRef :$constructor_args? does doc('Constructor arguments for the plugin.') = {},
87             HashRef :$transform_args? does doc('Settings for the specific transformation.') = {}, ...
88             --> Str but assumed does doc('The transformed content.')
89 5 50 33 5   123311 ) {
  5 50   5   9  
  5 50   5   527  
  5 50   5   22  
  5 50   5   8  
  5 50   4   919  
  5 50       25  
  5 100       7  
  5 50       522  
  5         27  
  5         7  
  5         460  
  5         22  
  5         7  
  5         1088  
  5         3128  
  4         2247  
  4         9  
  4         8  
  4         99  
  0         0  
  4         19  
  4         14  
  4         4  
  4         17  
  4         30  
  4         5  
  4         14  
  4         25  
  4         6  
  4         13  
  4         5  
90              
91 4         12 my $plugin_class = "Stenciller::Plugin::$plugin_name";
92 4         19 Module::Load::load($plugin_class);
93 4 50       68 die sprintf "Can't load %s: %s", $plugin_class, $@ if $@;
94              
95 4 50       42 if(!$plugin_class->does('Stenciller::Transformer')) {
96 0         0 croak("[$plugin_name] doesn't do the Stenciller::Transformer role. Quitting.");
97             }
98 4         747 return $plugin_class->new(stenciller => $self, %{ $constructor_args })->transform($transform_args);
  4         38  
99             }
100              
101 5 50   5   5264 method parse {
  5     5   10  
  5         4210  
  5         1047  
  5         12  
  5         6  
102 5 50       148 my @contents = split /\v/ => $self->is_utf8 ? $self->filepath->slurp_utf8 : $self->filepath->slurp;
103              
104 5         6621 my $stencil_start = qr/^== +stencil +(\{.*\} +)?==$/;
105 5         19 my $input_start = qr/^--+input--+$/;
106 5         14 my $input_end = qr/^--+end input--+$/;
107 5         12 my $output_start = qr/^--+output--+$/;
108 5         13 my $output_end = qr/^--+end output--+$/;
109              
110 5         7 my $environment = 'header';
111 5         7 my $line_count = 0;
112              
113 5         8 my $stencil = undef;
114              
115             LINE:
116 5         10 foreach my $line (@contents) {
117 203 100       538 ++$line_count if $environment ne 'next_stencil'; # because then we are redo-ing the line
118              
119 203 100   384   611 if(any { $environment eq $_ } (qw/header next_stencil/)) {
  384 100       695  
    100          
    100          
    100          
    50          
120 28 100 50     788 $self->add_header_line($line) and next LINE if $line !~ $stencil_start;
121              
122 11         17 my $possible_hash = $1;
123 11 100 66     252 my $settings = defined $possible_hash && $possible_hash =~ m{\{.*\}}
124             ? $self->eval_to_hashref($possible_hash, $self->filepath)
125             : {}
126             ;
127              
128 11         640 $stencil = Stenciller::Stencil->new(
129             name => exists $settings->{'name'} ? delete $settings->{'name'} : $self->filepath->basename . "-$line_count",
130             loop_values => delete $settings->{'loop'},
131             line_number => $line_count,
132             maybe skip => delete $settings->{'skip'},
133 11 50       309 provided scalar keys %{ $settings }, extra_settings => $settings,
134             );
135 11         69 $environment = 'before_input';
136             }
137             elsif($environment eq 'before_input') {
138 42 100 50     266 $stencil->add_before_input($line) and next LINE if $line !~ $input_start;
139 11         28 $environment = 'input';
140             }
141             elsif($environment eq 'input') {
142 40 100 50     238 $stencil->add_input($line) and next LINE if $line !~ $input_end;
143 11         25 $environment = 'between';
144             }
145             elsif($environment eq 'between') {
146 40 100 50     224 $stencil->add_between($line) and next LINE if $line !~ $output_start;
147 11         28 $environment = 'output';
148             }
149             elsif($environment eq 'output') {
150 40 100 50     246 $stencil->add_output($line) and next LINE if $line !~ $output_end;
151 11         27 $environment = 'after_output';
152             }
153             elsif($environment eq 'after_output') {
154 13 100 50     85 $stencil->add_after_output($line) and next LINE if $line !~ $stencil_start;
155 6         19 $self->handle_completed_stencil($stencil);
156 6         44 $environment = 'next_stencil';
157 6         18 redo LINE;
158             }
159             }
160 5 50       19 if($environment ne 'after_output') {
161 0         0 croak (sprintf 'File <%s> appears malformed. Ended on <%s>', $self->filepath, $environment);
162             }
163 5         18 $self->handle_completed_stencil($stencil);
164             }
165              
166 5 50   5   14370 method handle_completed_stencil(Maybe[Stencil] $stencil) {
  5 50   5   9  
  5 50   11   704  
  5 50       21  
  5 50       9  
  5         1129  
  5         632  
  11         39  
  11         30  
  11         30  
  11         26  
  11         9  
  11         70  
  11         10  
167 11 50       35 return if !Stencil->check($stencil);
168 11 50       892 return if $stencil->skip;
169 11 100 66     369 return if !$stencil->has_input && $self->skip_if_input_empty;
170 9 50 33     349 return if !$stencil->has_output && $self->skip_if_output_empty;
171              
172 9 50       337 if(!$stencil->has_loop_values) {
173 9         346 $self->add_stencil($stencil);
174 9         216 return;
175             }
176              
177 0         0 foreach my $loop_value ($stencil->all_loop_values) {
178 0         0 my $clone = $stencil->clone_with_loop_value($loop_value);
179 0         0 $self->add_stencil($clone);
180             }
181             }
182              
183 5 50   5   5225 method max_stencil_index {
  5     4   11  
  5         421  
  5         593  
  4         33  
  4         6  
184 4         131 return $self->count_stencils - 1;
185             }
186             }
187              
188             1;
189              
190             __END__
191              
192             =pod
193              
194             =encoding UTF-8
195              
196             =head1 NAME
197              
198             Stenciller::Wrap
199              
200             =head1 VERSION
201              
202             Version 0.1212, released 2015-02-10.
203              
204             =head1 SOURCE
205              
206             L<https://github.com/Csson/p5-Stenciller>
207              
208             =head1 HOMEPAGE
209              
210             L<https://metacpan.org/release/Stenciller>
211              
212             =head1 AUTHOR
213              
214             Erik Carlsson <info@code301.com>
215              
216             =head1 COPYRIGHT AND LICENSE
217              
218             This software is copyright (c) 2015 by Erik Carlsson <info@code301.com>.
219              
220             This is free software; you can redistribute it and/or modify it under
221             the same terms as the Perl 5 programming language system itself.
222              
223             =cut