File Coverage

blib/lib/Pod/Weaver.pm
Criterion Covered Total %
statement 78 78 100.0
branch 5 8 62.5
condition 5 9 55.5
subroutine 14 14 100.0
pod 3 5 60.0
total 105 114 92.1


line stmt bran cond sub pod time code
1             package Pod::Weaver;
2             # ABSTRACT: weave together a Pod document from an outline
3             $Pod::Weaver::VERSION = '4.017';
4 10     10   14639491 use Moose;
  10         108  
  10         86  
5 10     10   71560 use namespace::autoclean;
  10         26  
  10         119  
6              
7             #pod =head1 SYNOPSIS
8             #pod
9             #pod my $weaver = Pod::Weaver->new_with_default_config;
10             #pod
11             #pod my $document = $weaver->weave_document({
12             #pod pod_document => $pod_elemental_document,
13             #pod ppi_document => $ppi_document,
14             #pod
15             #pod license => $software_license,
16             #pod version => $version_string,
17             #pod authors => \@author_names,
18             #pod })
19             #pod
20             #pod =head1 DESCRIPTION
21             #pod
22             #pod Pod::Weaver is a system for building Pod documents from templates. It doesn't
23             #pod perform simple text substitution, but instead builds a
24             #pod Pod::Elemental::Document. Its plugins sketch out a series of sections
25             #pod that will be produced based on an existing Pod document or other provided
26             #pod information.
27             #pod
28             #pod =cut
29              
30 10     10   893 use File::Spec;
  10         24  
  10         479  
31 10     10   7468 use Log::Dispatchouli 1.100710; # proxy
  10         2407014  
  10         441  
32 10     10   94 use Pod::Elemental 0.100220;
  10         352  
  10         106  
33 10     10   4298 use Pod::Elemental::Document;
  10         23  
  10         403  
34 10     10   5650 use Pod::Weaver::Config::Finder;
  10         43  
  10         471  
35 10     10   6592 use Pod::Weaver::Role::Plugin;
  10         36  
  10         502  
36 10     10   92 use String::Flogger 1;
  10         200  
  10         84  
37              
38             #pod =attr logger
39             #pod
40             #pod This attribute stores the logger, which must provide a log method. The
41             #pod weaver's log method delegates to the logger's log method.
42             #pod
43             #pod =cut
44              
45             has logger => (
46             is => 'ro',
47             lazy => 1,
48             default => sub {
49             Log::Dispatchouli->new({
50             ident => 'Pod::Weaver',
51             to_stdout => 1,
52             log_pid => 0,
53             });
54             },
55             handles => [ qw(log log_fatal log_debug) ]
56             );
57              
58             #pod =attr plugins
59             #pod
60             #pod This attribute is an arrayref of objects that can perform the
61             #pod L<Pod::Weaver::Role::Plugin> role. In general, its contents are found through
62             #pod the C<L</plugins_with>> method.
63             #pod
64             #pod =cut
65              
66             has plugins => (
67             is => 'ro',
68             isa => 'ArrayRef[Pod::Weaver::Role::Plugin]',
69             required => 1,
70             lazy => 1,
71             init_arg => undef,
72             default => sub { [] },
73             );
74              
75             #pod =method plugins_with
76             #pod
77             #pod my $plugins_array_ref = $weaver->plugins_with('-Section');
78             #pod
79             #pod This method will return an arrayref of plugins that perform the given role, in
80             #pod the order of their registration. If the role name begins with a hyphen, the
81             #pod method will prepend C<Pod::Weaver::Role::>.
82             #pod
83             #pod =cut
84              
85             sub plugins_with {
86 178     178 1 482 my ($self, $role) = @_;
87              
88 178         896 $role =~ s/^-/Pod::Weaver::Role::/;
89 178         411 my @plugins = grep { $_->does($role) } @{ $self->plugins };
  1126         66226  
  178         5010  
90              
91 178         11800 return \@plugins;
92             }
93              
94             #pod =method weave_document
95             #pod
96             #pod my $document = $weaver->weave_document(\%input);
97             #pod
98             #pod This is the most important method in Pod::Weaver. Given a set of input
99             #pod parameters, it will weave a new document. Different section plugins will
100             #pod expect different input parameters to be present, but some common ones include:
101             #pod
102             #pod pod_document - a Pod::Elemental::Document for the original Pod document
103             #pod ppi_document - a PPI document for the source of the module being documented
104             #pod license - a Software::License object for the source module's license
105             #pod version - a version (string) to use in produced documentation
106             #pod
107             #pod The C<pod_document> should have gone through a L<Pod5
108             #pod transformer|Pod::Elemental::Transformer::Pod5>, and should probably have had
109             #pod its C<=head1> elements L<nested|Pod::Elemental::Transformer::Nester>.
110             #pod
111             #pod The method will return a new Pod::Elemental::Document. The input documents may
112             #pod be destructively altered during the weaving process. If they should be
113             #pod untouched, pass in copies.
114             #pod
115             #pod =cut
116              
117             sub weave_document {
118 36     36 1 380024 my ($self, $input) = @_;
119              
120 36         1591 my $document = Pod::Elemental::Document->new;
121              
122 36         3114 for (@{ $self->plugins_with(-Preparer) }) {
  36         255  
123 29         204 $_->prepare_input($input);
124             }
125              
126 36         108 for (@{ $self->plugins_with(-Dialect) }) {
  36         188  
127 7         68 $_->translate_dialect($input->{pod_document});
128             }
129              
130 36         110 for (@{ $self->plugins_with(-Transformer) }) {
  36         130  
131 49         1188 $_->transform_document($input->{pod_document});
132             }
133              
134 36         572 for (@{ $self->plugins_with(-Section) }) {
  36         183  
135 167         16839 $_->weave_section($document, $input);
136             }
137              
138 34         2966 for (@{ $self->plugins_with(-Finalizer) }) {
  34         162  
139 32         185 $_->finalize_document($document, $input);
140             }
141              
142 34         514 return $document;
143             }
144              
145             #pod =method new_with_default_config
146             #pod
147             #pod This method returns a new Pod::Weaver with a stock configuration by using only
148             #pod L<Pod::Weaver::PluginBundle::Default>.
149             #pod
150             #pod =cut
151              
152             sub new_with_default_config {
153 2     2 1 35886 my ($class, $arg) = @_;
154              
155 2         110 my $assembler = Pod::Weaver::Config::Assembler->new;
156              
157 2         69 my $root = $assembler->section_class->new({ name => '_' });
158 2         5221 $assembler->sequence->add_section($root);
159              
160 2         682 $assembler->change_section('@Default');
161 2         1591 $assembler->end_section;
162              
163 2         7467 return $class->new_from_config_sequence($assembler->sequence, $arg);
164             }
165              
166             sub new_from_config {
167 1     1 0 17239 my ($class, $arg, $new_arg) = @_;
168              
169 1   50     6 my $root = $arg->{root} || '.';
170 1         22 my $name = File::Spec->catfile($root, 'weaver');
171 1         47 my ($sequence) = Pod::Weaver::Config::Finder->new->read_config($name);
172              
173 1         34 return $class->new_from_config_sequence($sequence, $new_arg);
174             }
175              
176             sub new_from_config_sequence {
177 36     36 0 96941 my ($class, $seq, $arg) = @_;
178 36   100     305 $arg ||= {};
179              
180 36   50     290 my $merge = $arg->{root_config} || {};
181              
182 36 50 33     355 confess("config must be a Config::MVP::Sequence")
183             unless $seq and $seq->isa('Config::MVP::Sequence');
184              
185 36         145 my $core_config = $seq->section_named('_')->payload;
186              
187 36         3925 my $self = $class->new({
188             %$merge,
189             %$core_config,
190             });
191              
192 36         181 for my $section ($seq->sections) {
193 268 100       11549 next if $section->name eq '_';
194              
195 232         6810 my ($name, $plugin_class, $arg) = (
196             $section->name,
197             $section->package,
198             $section->payload,
199             );
200              
201 232         14916 $self->log_debug("initializing plugin $name ($plugin_class)");
202              
203             confess "arguments attempted to override 'plugin_name'"
204 232 50       4974 if defined $arg->{plugin_name};
205              
206             confess "arguments attempted to override 'weaver'"
207 232 50       591 if defined $arg->{weaver};
208              
209 232         367 push @{ $self->plugins },
  232         5413  
210             $plugin_class->new({
211             %$arg,
212             plugin_name => $name,
213             weaver => $self,
214             });
215             }
216              
217 36         1737 return $self;
218             }
219              
220             __PACKAGE__->meta->make_immutable;
221             1;
222              
223             __END__
224              
225             =pod
226              
227             =encoding UTF-8
228              
229             =head1 NAME
230              
231             Pod::Weaver - weave together a Pod document from an outline
232              
233             =head1 VERSION
234              
235             version 4.017
236              
237             =head1 SYNOPSIS
238              
239             my $weaver = Pod::Weaver->new_with_default_config;
240              
241             my $document = $weaver->weave_document({
242             pod_document => $pod_elemental_document,
243             ppi_document => $ppi_document,
244              
245             license => $software_license,
246             version => $version_string,
247             authors => \@author_names,
248             })
249              
250             =head1 DESCRIPTION
251              
252             Pod::Weaver is a system for building Pod documents from templates. It doesn't
253             perform simple text substitution, but instead builds a
254             Pod::Elemental::Document. Its plugins sketch out a series of sections
255             that will be produced based on an existing Pod document or other provided
256             information.
257              
258             =head1 ATTRIBUTES
259              
260             =head2 logger
261              
262             This attribute stores the logger, which must provide a log method. The
263             weaver's log method delegates to the logger's log method.
264              
265             =head2 plugins
266              
267             This attribute is an arrayref of objects that can perform the
268             L<Pod::Weaver::Role::Plugin> role. In general, its contents are found through
269             the C<L</plugins_with>> method.
270              
271             =head1 METHODS
272              
273             =head2 plugins_with
274              
275             my $plugins_array_ref = $weaver->plugins_with('-Section');
276              
277             This method will return an arrayref of plugins that perform the given role, in
278             the order of their registration. If the role name begins with a hyphen, the
279             method will prepend C<Pod::Weaver::Role::>.
280              
281             =head2 weave_document
282              
283             my $document = $weaver->weave_document(\%input);
284              
285             This is the most important method in Pod::Weaver. Given a set of input
286             parameters, it will weave a new document. Different section plugins will
287             expect different input parameters to be present, but some common ones include:
288              
289             pod_document - a Pod::Elemental::Document for the original Pod document
290             ppi_document - a PPI document for the source of the module being documented
291             license - a Software::License object for the source module's license
292             version - a version (string) to use in produced documentation
293              
294             The C<pod_document> should have gone through a L<Pod5
295             transformer|Pod::Elemental::Transformer::Pod5>, and should probably have had
296             its C<=head1> elements L<nested|Pod::Elemental::Transformer::Nester>.
297              
298             The method will return a new Pod::Elemental::Document. The input documents may
299             be destructively altered during the weaving process. If they should be
300             untouched, pass in copies.
301              
302             =head2 new_with_default_config
303              
304             This method returns a new Pod::Weaver with a stock configuration by using only
305             L<Pod::Weaver::PluginBundle::Default>.
306              
307             =head1 AUTHOR
308              
309             Ricardo SIGNES <rjbs@cpan.org>
310              
311             =head1 CONTRIBUTORS
312              
313             =for stopwords Alex Peters Apocalypse Blabos de Blebe Caleb Cushing Christian Walde Christopher J. Madsen Chris Weyl Dave Houston Rolsky David E. Wheeler Golden Miguel Susano Pinto Zurborg Doug Bell Florian Ragwitz Jonathan "Duke" Leto Joshua Keroes Karen Etheridge Kent Fredric Kivanc Yazan Marcel Gruenauer Randy Stauner Ricardo Signes Sam Graham Shlomi Fish
314              
315             =over 4
316              
317             =item *
318              
319             Alex Peters <lxp@cpan.org>
320              
321             =item *
322              
323             Apocalypse <perl@0ne.us>
324              
325             =item *
326              
327             Blabos de Blebe <blabos@cpan.org>
328              
329             =item *
330              
331             Caleb Cushing <xenoterracide@gmail.com>
332              
333             =item *
334              
335             Christian Walde <walde.christian@googlemail.com>
336              
337             =item *
338              
339             Christopher J. Madsen <perl@cjmweb.net>
340              
341             =item *
342              
343             Chris Weyl <cweyl@alumni.drew.edu>
344              
345             =item *
346              
347             Dave Houston <dave.houston@gmail.com>
348              
349             =item *
350              
351             Dave Rolsky <autarch@urth.org>
352              
353             =item *
354              
355             David E. Wheeler <david@justatheory.com>
356              
357             =item *
358              
359             David Golden <dagolden@cpan.org>
360              
361             =item *
362              
363             David Miguel Susano Pinto <carandraug+dev@gmail.com>
364              
365             =item *
366              
367             David Zurborg <post@david-zurb.org>
368              
369             =item *
370              
371             Doug Bell <doug@preaction.me>
372              
373             =item *
374              
375             Florian Ragwitz <rafl@debian.org>
376              
377             =item *
378              
379             Jonathan "Duke" Leto <jonathan@leto.net>
380              
381             =item *
382              
383             Joshua Keroes <joshua.keroes@integratelecom.com>
384              
385             =item *
386              
387             Karen Etheridge <ether@cpan.org>
388              
389             =item *
390              
391             Kent Fredric <kentfredric@gmail.com>
392              
393             =item *
394              
395             Kivanc Yazan <kyzn@cpan.org>
396              
397             =item *
398              
399             Marcel Gruenauer <hanekomu@gmail.com>
400              
401             =item *
402              
403             Randy Stauner <randy@magnificent-tears.com>
404              
405             =item *
406              
407             Ricardo Signes <rjbs@semiotic.systems>
408              
409             =item *
410              
411             Sam Graham <git@illusori.co.uk>
412              
413             =item *
414              
415             Shlomi Fish <shlomif@shlomifish.org>
416              
417             =back
418              
419             =head1 COPYRIGHT AND LICENSE
420              
421             This software is copyright (c) 2021 by Ricardo SIGNES.
422              
423             This is free software; you can redistribute it and/or modify it under
424             the same terms as the Perl 5 programming language system itself.
425              
426             =cut