File Coverage

blib/lib/Pod/Elemental/Transformer/Stenciller.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1 1     1   904423 use Stenciller::Standard;
  0            
  0            
2             use strict;
3             use warnings;
4              
5             our $VERSION = '0.0100'; # VERSION:
6             # PODNAME: Pod::Elemental::Transformer::Stenciller
7             # ABSTRACT: Injects content from textfiles transformed with Stenciller
8             use Stenciller;
9              
10             class Pod::Elemental::Transformer::Stenciller
11             using Moose
12             with Pod::Elemental::Transformer, Stenciller::Utils :ro {
13              
14             use Carp 'croak';
15             use Module::Loader;
16              
17             has directory => (
18             is => 'ro',
19             isa => Dir,
20             coerce => 1,
21             required => 1,
22             documentation => 'Path to directory where the stencil files are.'
23             );
24             has settings => (
25             isa => HashRef,
26             traits => ['Hash'],
27             default => sub { {} },
28             documentation_default => '{ }',
29             documentation_order => 0,
30             documentation => 'If a plugin takes more attributes..',
31             handles => {
32             get_setting => 'get',
33             set_setting => 'set',
34             all_settings => 'elements',
35             },
36             );
37             has plugins => (
38             isa => HashRef,
39             default => sub { {} },
40             documentation_default => '{ }',
41             documentation_order => 0,
42             init_arg => undef,
43             traits => ['Hash'],
44             handles => {
45             get_plugin => 'get',
46             set_plugin => 'set',
47             },
48             );
49             has stencillers => (
50             is => 'ro',
51             isa => HashRef,
52             traits => ['Hash'],
53             handles => {
54             get_stenciller_for_filename => 'get',
55             set_stenciller_for_filename => 'set',
56             },
57             documentation_order => 0,
58             );
59             has loader => (
60             is => 'ro',
61             isa => Object,
62             init_arg => undef,
63             default => sub { Module::Loader->new },
64             documentation_order => 0,
65             );
66             around BUILDARGS($next: $class, @args) {
67             my $args = ref $args[0] eq 'HASH' ? $args[0] : { @args };
68              
69             $class->$next(
70             directory => delete $args->{'directory'},
71             settings => $args
72             );
73             }
74              
75             method transform_node($main_node) {
76              
77             NODE:
78             foreach my $node (@{ $main_node->children }) {
79             my $content = $node->content;
80             my $start = substr($content, 0, 11, '');
81             next NODE if $start ne ':stenciller';
82              
83             $content =~ s{^\h+}{}; # remove leading whitespace
84             next if $content !~ m{([^\h\v]+)}; # the next sequence of non-space is the wanted plugin name
85              
86             my $wanted_plugin = $1;
87             my $plugin_name = $self->ensure_plugin($wanted_plugin);
88              
89             (undef, my($filename, $possible_hash)) = split /\h+/ => $content, 3;
90             chomp $filename;
91             my $node_settings = defined $possible_hash && $possible_hash =~ m{\{.*\}} ? $self->eval_to_hashref($possible_hash, $filename) : {};
92              
93             my $stenciller = $self->get_stenciller_for_filename($filename);
94              
95             if(!Stenciller->check($stenciller)) {
96             $stenciller = Stenciller::->new(filepath => path($self->directory)->child($filename));
97             carp sprintf '! no stencils in %s/%s - skipping', $self->directory, $filename and return '' if !$stenciller->has_stencils;
98              
99             $self->set_stenciller_for_filename($filename => $stenciller);
100             }
101              
102             my $transformed_content = $stenciller->transform(plugin_name => $plugin_name,
103             constructor_args => $self->settings,
104             transform_args => $node_settings
105             );
106             $transformed_content =~ s{[\v\h]+$}{};
107             $node->content($transformed_content);
108              
109             }
110             }
111             method ensure_plugin(Str $plugin_name) {
112             return $self->get_plugin($plugin_name) if $self->get_plugin($plugin_name);
113              
114             my $plugin_class = sprintf 'Stenciller::Plugin::%s', $plugin_name;
115             $self->loader->load($plugin_class);
116              
117             if(!$plugin_class->does('Stenciller::Transformer')) {
118             croak("[$plugin_name] doesn't do the Stenciller::Transformer role. Quitting.");
119             }
120             $self->set_plugin($plugin_name => $plugin_name);
121             return $plugin_name;
122             }
123             }
124              
125             1;
126              
127             __END__
128              
129             =pod
130              
131             =encoding UTF-8
132              
133             =head1 NAME
134              
135             Pod::Elemental::Transformer::Stenciller - Injects content from textfiles transformed with Stenciller
136              
137             =head1 VERSION
138              
139             Version 0.0100, released 2015-02-07.
140              
141             =head1 SYNOPSIS
142              
143             # in weaver.ini
144             [-Transformer / Stenciller]
145             transformer = Stenciller
146             directory = path/to/stencildir
147              
148             =head1 DESCRIPTION
149              
150             This transformer uses a special command in pod files to inject content from elsewhere via a L<Stenciller> transformer plugin.
151              
152             =head2 Example
153              
154             1. Start with the C<weaver.ini> from the L</"synopsis">.
155              
156             2. Add a textfile, in C<path/to/stencildir/file-with-stencils.stencil>:
157              
158             == stencil { } ==
159              
160             Header text
161              
162             --input--
163              
164             Input text
165              
166             --end input--
167              
168             Between text
169              
170             --output--
171              
172             Output text
173              
174             --end output--
175              
176             Footer text
177              
178             3. Add a Perl module:
179              
180             package A::Test::Module;
181              
182             1;
183              
184             __END__
185              
186             =pod
187              
188             =head1 NAME
189              
190             =head1 DESCRIPTION
191              
192             :stenciller ToUnparsedText file-with-stencils.stencil
193              
194             The last line in the Perl module will cause the textfile to be parsed with L<Stenciller>, and then transformed using the L<Stenciller::Plugin::ToUnparsedText> plugin.
195              
196             It would be rendered like this (between I<begin> and I<end>):
197              
198             I<begin>
199              
200             Header text
201              
202             Input text
203              
204             Between text
205              
206             Output text
207              
208             Footer text
209              
210             I<end>
211              
212              
213              
214             =head1 SEE ALSO
215              
216             =over 4
217              
218             =item *
219              
220             L<Stenciller>
221              
222             =item *
223              
224             L<Stenciller::Plugin::ToUnparsedText>
225              
226             =item *
227              
228             L<Pod::Weaver>
229              
230             =back
231              
232             =head1 SOURCE
233              
234             L<https://github.com/Csson/p5-Pod-Elemental-Transformer-Stenciller>
235              
236             =head1 HOMEPAGE
237              
238             L<https://metacpan.org/release/Pod-Elemental-Transformer-Stenciller>
239              
240             =head1 AUTHOR
241              
242             Erik Carlsson <info@code301.com>
243              
244             =head1 COPYRIGHT AND LICENSE
245              
246             This software is copyright (c) 2015 by Erik Carlsson <info@code301.com>.
247              
248             This is free software; you can redistribute it and/or modify it under
249             the same terms as the Perl 5 programming language system itself.
250              
251             =cut