File Coverage

blib/lib/Stenciller/Stencil.pm
Criterion Covered Total %
statement 37 46 80.4
branch 2 2 100.0
condition 3 3 100.0
subroutine 11 14 78.5
pod 0 2 0.0
total 53 67 79.1


line stmt bran cond sub pod time code
1 7     7   84 use 5.10.1;
  7         20  
2 7     7   78 use strict;
  7         12  
  7         134  
3 7     7   29 use warnings;
  7         11  
  7         223  
4              
5             package Stenciller::Stencil;
6              
7 7     7   52 use Moose;
  7         12  
  7         52  
8 7     7   42406 use MooseX::AttributeDocumented;
  7         13  
  7         56  
9 7     7   21137 use namespace::autoclean;
  7         15  
  7         63  
10              
11 7     7   540 use Types::Standard qw/ArrayRef CodeRef HashRef Str Bool Int/;
  7         13  
  7         53  
12              
13             our $VERSION = '0.1400'; # VERSION:
14             # ABSTRACT: One part of a file
15              
16             my @attrs = qw/before_input input between output after_output/;
17              
18             my $order = 1;
19             foreach my $attr (@attrs) {
20             has $attr => (
21             is => 'ro',
22             isa => ArrayRef[Str],
23             default => sub { [] },
24             traits => ['Array'],
25             #init_arg => undef,
26             documentation_order => ++$order,
27             documentation => sprintf ('Holds all lines of the %s section.', $attr),
28             handles => {
29             "has_$attr" => 'count',
30             "add_$attr" => 'push',
31             "all_$attr" => 'elements',
32             "map_$attr" => 'map',
33             "get_$attr" => 'get',
34             "count_$attr" => 'count',
35             },
36             );
37             }
38             has skip => (
39             is => 'ro',
40             isa => Bool,
41             default => 0,
42             documentation => 'Should the Stencil not be included in the result?',
43             );
44             has line_number => (
45             is => 'ro',
46             isa => Int,
47             documentation => 'Can be referenced in the output for easier backtracking.',
48             );
49             has stencil_name => (
50             is => 'ro',
51             isa => Str,
52             documentation => q{Can be given in the stencil hash with 'name'. Depends on used plugins if it is necessary/useful.},
53             documentation_default => '[filename]_[linenumber]',
54             );
55             has extra_settings => (
56             is => 'ro',
57             isa => HashRef,
58             default => sub { { } },
59             traits => ['Hash'],
60             documentation => 'Any extra key-value pairs in the stencil header.',
61             handles => {
62             get_extra_setting => 'get',
63             set_extra_setting => 'set',
64             keys_extra_settings => 'keys',
65             },
66             );
67             has loop_values => (
68             is => 'ro',
69             isa => ArrayRef,
70             default => sub { [] },
71             traits => ['Array'],
72             documentation_order => 0,
73             handles => {
74             has_loop_values => 'count',
75             add_loop_value => 'get',
76             all_loop_values => 'elements',
77             },
78             );
79              
80             around BUILDARGS => sub {
81             my $orig = shift;
82             my $class = shift;
83             my @args = @_;
84              
85             my %args = @args;
86             $args{'loop_values'} = [] if !defined $args{'loop_values'};
87              
88             return $class->$orig(%args);
89             };
90              
91             # Remove all empty lines for each group until we have a line with content, then keep everything
92             around add_before_input => sub {
93             my $orig = shift;
94             my $self = shift;
95             my $text = shift;
96             return $self->ensure_content($orig, $self->has_before_input, $text);
97             };
98             around add_input => sub {
99             my $orig = shift;
100             my $self = shift;
101             my $text = shift;
102             return $self->ensure_content($orig, $self->has_input, $text);
103             };
104             around add_between => sub {
105             my $orig = shift;
106             my $self = shift;
107             my $text = shift;
108             return $self->ensure_content($orig, $self->has_between, $text);
109             };
110             around add_output => sub {
111             my $orig = shift;
112             my $self = shift;
113             my $text = shift;
114             return $self->ensure_content($orig, $self->has_output, $text);
115             };
116             around add_after_output => sub {
117             my $orig = shift;
118             my $self = shift;
119             my $text = shift;
120             return $self->ensure_content($orig, $self->has_after_output, $text);
121             };
122             sub ensure_content {
123 172     172 0 219 my $self = shift;
124 172         185 my $orig = shift; # CodeRef
125 172         186 my $already_have = shift; # Bool
126 172         220 my $text = shift;
127              
128 172 100 100     3400 $self->$orig($text) if $already_have || $text !~ m{^\s*$};
129 172         891 return $self;
130             }
131              
132             sub clone_with_loop_value {
133 2     2 0 3 my $self = shift;
134 2         3 my $loop_value = shift;
135              
136             my $clone = Stenciller::Stencil->new(
137 0     0   0 before_input => [$self->map_before_input( sub { my $text = $_; $text =~ s{ \[ var \] }{$loop_value}x; $text })],
  0         0  
  0         0  
138 2     2   4 input => [$self->map_input( sub { my $text = $_; $text =~ s{ \[ var \] }{$loop_value}x; $text })],
  2         8  
  2         70  
139 0     0   0 between => [$self->map_between( sub { my $text = $_; $text =~ s{ \[ var \] }{$loop_value}x; $text })],
  0         0  
  0         0  
140 2     2   4 output => [$self->map_output( sub { my $text = $_; $text =~ s{ \[ var \] }{$loop_value}x; $text })],
  2         8  
  2         69  
141 0     0   0 after_output => [$self->map_after_output( sub { my $text = $_; $text =~ s{ \[ var \] }{$loop_value}x; $text })],
  0         0  
  0         0  
142             stencil_name => $self->stencil_name . "_$loop_value",
143 2         5 (map { $_ => $self->$_ } qw/line_number extra_settings/)
  4         95  
144             );
145              
146 2         14 return $clone;
147             }
148              
149             __PACKAGE__->meta->make_immutable;
150              
151             1;
152              
153             __END__
154              
155             =pod
156              
157             =encoding UTF-8
158              
159             =head1 NAME
160              
161             Stenciller::Stencil - One part of a file
162              
163             =head1 VERSION
164              
165             Version 0.1400, released 2016-02-03.
166              
167              
168              
169             =head1 SYNOPSIS
170              
171             # In a plugin (this is pretty similar to what ToUnparsedText does)
172             sub render {
173             my $self = shift;
174             my @out = ();
175              
176             STENCIL:
177             foreach my $stencil ($self->stenciller->all_stencils) {
178             push @out => join "\n" => $stencil->all_before_input;
179             push @out => join "\n" => $stencil->all_input;
180             push @out => join "\n" => $stencil->all_between;
181             push @out => join "\n" => $stencil->all_output;
182             push @out => join "\n" => $stencil->all_after_output;
183             }
184             return join "\n" => @out;
185             }
186              
187             =head1 DESCRIPTION
188              
189             A C<Stencil> is one section of the file format defined in L<Stenciller>.
190              
191             =head1 ATTRIBUTES
192              
193              
194             =head2 before_input
195              
196             =begin HTML
197              
198             <table cellpadding="0" cellspacing="0">
199             <tr>
200             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#ArrayRef">ArrayRef</a> [ <a href="https://metacpan.org/pod/Types::Standard#Str">Str</a> ]</td>
201             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
202             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
203             </tr>
204             </table>
205              
206             <p>Holds all lines of the before_input section.</p>
207              
208             =end HTML
209              
210             =begin markdown
211              
212             <table cellpadding="0" cellspacing="0">
213             <tr>
214             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#ArrayRef">ArrayRef</a> [ <a href="https://metacpan.org/pod/Types::Standard#Str">Str</a> ]</td>
215             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
216             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
217             </tr>
218             </table>
219              
220             <p>Holds all lines of the before_input section.</p>
221              
222             =end markdown
223              
224             =head2 input
225              
226             =begin HTML
227              
228             <table cellpadding="0" cellspacing="0">
229             <tr>
230             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#ArrayRef">ArrayRef</a> [ <a href="https://metacpan.org/pod/Types::Standard#Str">Str</a> ]</td>
231             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
232             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
233             </tr>
234             </table>
235              
236             <p>Holds all lines of the input section.</p>
237              
238             =end HTML
239              
240             =begin markdown
241              
242             <table cellpadding="0" cellspacing="0">
243             <tr>
244             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#ArrayRef">ArrayRef</a> [ <a href="https://metacpan.org/pod/Types::Standard#Str">Str</a> ]</td>
245             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
246             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
247             </tr>
248             </table>
249              
250             <p>Holds all lines of the input section.</p>
251              
252             =end markdown
253              
254             =head2 between
255              
256             =begin HTML
257              
258             <table cellpadding="0" cellspacing="0">
259             <tr>
260             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#ArrayRef">ArrayRef</a> [ <a href="https://metacpan.org/pod/Types::Standard#Str">Str</a> ]</td>
261             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
262             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
263             </tr>
264             </table>
265              
266             <p>Holds all lines of the between section.</p>
267              
268             =end HTML
269              
270             =begin markdown
271              
272             <table cellpadding="0" cellspacing="0">
273             <tr>
274             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#ArrayRef">ArrayRef</a> [ <a href="https://metacpan.org/pod/Types::Standard#Str">Str</a> ]</td>
275             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
276             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
277             </tr>
278             </table>
279              
280             <p>Holds all lines of the between section.</p>
281              
282             =end markdown
283              
284             =head2 output
285              
286             =begin HTML
287              
288             <table cellpadding="0" cellspacing="0">
289             <tr>
290             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#ArrayRef">ArrayRef</a> [ <a href="https://metacpan.org/pod/Types::Standard#Str">Str</a> ]</td>
291             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
292             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
293             </tr>
294             </table>
295              
296             <p>Holds all lines of the output section.</p>
297              
298             =end HTML
299              
300             =begin markdown
301              
302             <table cellpadding="0" cellspacing="0">
303             <tr>
304             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#ArrayRef">ArrayRef</a> [ <a href="https://metacpan.org/pod/Types::Standard#Str">Str</a> ]</td>
305             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
306             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
307             </tr>
308             </table>
309              
310             <p>Holds all lines of the output section.</p>
311              
312             =end markdown
313              
314             =head2 after_output
315              
316             =begin HTML
317              
318             <table cellpadding="0" cellspacing="0">
319             <tr>
320             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#ArrayRef">ArrayRef</a> [ <a href="https://metacpan.org/pod/Types::Standard#Str">Str</a> ]</td>
321             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
322             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
323             </tr>
324             </table>
325              
326             <p>Holds all lines of the after_output section.</p>
327              
328             =end HTML
329              
330             =begin markdown
331              
332             <table cellpadding="0" cellspacing="0">
333             <tr>
334             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#ArrayRef">ArrayRef</a> [ <a href="https://metacpan.org/pod/Types::Standard#Str">Str</a> ]</td>
335             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
336             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
337             </tr>
338             </table>
339              
340             <p>Holds all lines of the after_output section.</p>
341              
342             =end markdown
343              
344             =head2 extra_settings
345              
346             =begin HTML
347              
348             <table cellpadding="0" cellspacing="0">
349             <tr>
350             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#HashRef">HashRef</a></td>
351             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
352             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
353             </tr>
354             </table>
355              
356             <p>Any extra key-value pairs in the stencil header.</p>
357              
358             =end HTML
359              
360             =begin markdown
361              
362             <table cellpadding="0" cellspacing="0">
363             <tr>
364             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#HashRef">HashRef</a></td>
365             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default is a <code>coderef</code></td>
366             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
367             </tr>
368             </table>
369              
370             <p>Any extra key-value pairs in the stencil header.</p>
371              
372             =end markdown
373              
374             =head2 line_number
375              
376             =begin HTML
377              
378             <table cellpadding="0" cellspacing="0">
379             <tr>
380             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#Int">Int</a></td>
381             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional</td>
382             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
383             </tr>
384             </table>
385              
386             <p>Can be referenced in the output for easier backtracking.</p>
387              
388             =end HTML
389              
390             =begin markdown
391              
392             <table cellpadding="0" cellspacing="0">
393             <tr>
394             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#Int">Int</a></td>
395             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional</td>
396             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
397             </tr>
398             </table>
399              
400             <p>Can be referenced in the output for easier backtracking.</p>
401              
402             =end markdown
403              
404             =head2 skip
405              
406             =begin HTML
407              
408             <table cellpadding="0" cellspacing="0">
409             <tr>
410             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#Bool">Bool</a></td>
411             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default: <code>0</code></td>
412             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
413             </tr>
414             </table>
415              
416             <p>Should the Stencil not be included in the result?</p>
417              
418             =end HTML
419              
420             =begin markdown
421              
422             <table cellpadding="0" cellspacing="0">
423             <tr>
424             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#Bool">Bool</a></td>
425             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional, default: <code>0</code></td>
426             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
427             </tr>
428             </table>
429              
430             <p>Should the Stencil not be included in the result?</p>
431              
432             =end markdown
433              
434             =head2 stencil_name
435              
436             =begin HTML
437              
438             <table cellpadding="0" cellspacing="0">
439             <tr>
440             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#Str">Str</a></td>
441             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional</td>
442             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
443             </tr>
444             </table>
445              
446             <p>Can be given in the stencil hash with 'name'. Depends on used plugins if it is necessary/useful.</p>
447              
448             =end HTML
449              
450             =begin markdown
451              
452             <table cellpadding="0" cellspacing="0">
453             <tr>
454             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;"><a href="https://metacpan.org/pod/Types::Standard#Str">Str</a></td>
455             <td style="padding-right: 6px; padding-left: 6px; border-right: 1px solid #b8b8b8; white-space: nowrap;">optional</td>
456             <td style="padding-left: 6px; padding-right: 6px; white-space: nowrap;">read-only</td>
457             </tr>
458             </table>
459              
460             <p>Can be given in the stencil hash with 'name'. Depends on used plugins if it is necessary/useful.</p>
461              
462             =end markdown
463              
464             =head1 SOURCE
465              
466             L<https://github.com/Csson/p5-Stenciller>
467              
468             =head1 HOMEPAGE
469              
470             L<https://metacpan.org/release/Stenciller>
471              
472             =head1 AUTHOR
473              
474             Erik Carlsson <info@code301.com>
475              
476             =head1 COPYRIGHT AND LICENSE
477              
478             This software is copyright (c) 2016 by Erik Carlsson.
479              
480             This is free software; you can redistribute it and/or modify it under
481             the same terms as the Perl 5 programming language system itself.
482              
483             =cut