File Coverage

blib/lib/Pod/Weaver/Section/Collect.pm
Criterion Covered Total %
statement 62 62 100.0
branch 11 12 91.6
condition 2 3 66.6
subroutine 14 14 100.0
pod 0 2 0.0
total 89 93 95.7


line stmt bran cond sub pod time code
1             package Pod::Weaver::Section::Collect 4.018;
2             # ABSTRACT: a section that gathers up specific commands
3              
4 5     5   43283 use Moose;
  5         15  
  5         45  
5             with 'Pod::Weaver::Role::Section',
6             'Pod::Weaver::Role::Transformer';
7              
8             # BEGIN BOILERPLATE
9 5     5   33458 use v5.20.0;
  5         18  
10 5     5   30 use warnings;
  5         11  
  5         214  
11 5     5   36 use utf8;
  5         9  
  5         63  
12 5     5   169 no feature 'switch';
  5         8  
  5         643  
13 5     5   65 use experimental qw(postderef postderef_qq); # This experiment gets mainlined.
  5         14  
  5         59  
14             # END BOILERPLATE
15              
16             #pod =head1 OVERVIEW
17             #pod
18             #pod Given the configuration:
19             #pod
20             #pod [Collect / METHODS]
21             #pod command = method
22             #pod
23             #pod This plugin will start off by gathering and nesting any C<=method> commands
24             #pod found in the C<pod_document>. Those commands, along with their nestable
25             #pod content, will be collected under a C<=head1 METHODS> header and placed in the
26             #pod correct location in the output stream. Their order will be preserved as it was
27             #pod in the source document.
28             #pod
29             #pod =cut
30              
31 5     5   586 use Pod::Elemental::Element::Pod5::Region;
  5         14  
  5         244  
32 5     5   32 use Pod::Elemental::Selectors -all;
  5         13  
  5         58  
33 5     5   2925 use List::Util 1.33 'any';
  5         94  
  5         1045  
34              
35             #pod =attr command
36             #pod
37             #pod The command that will be collected (e.g. C<attr> or C<method>).
38             #pod (required)
39             #pod
40             #pod =attr new_command
41             #pod
42             #pod The command to be used in the output instead of the collected command.
43             #pod (default: C<head2>)
44             #pod
45             #pod =attr header_command
46             #pod
47             #pod The section command for the section to be added.
48             #pod (default: C<head1>)
49             #pod
50             #pod =attr header
51             #pod
52             #pod The title of the section to be added.
53             #pod (default: the plugin name)
54             #pod
55             #pod =cut
56              
57             has command => (
58             is => 'ro',
59             isa => 'Str',
60             required => 1,
61             );
62              
63             has new_command => (
64             is => 'ro',
65             isa => 'Str',
66             required => 1,
67             default => 'head2',
68             );
69              
70             has header_command => (
71             is => 'ro',
72             isa => 'Str',
73             required => 1,
74             default => 'head1',
75             );
76              
77             has header => (
78             is => 'ro',
79             isa => 'Str',
80             lazy => 1,
81             required => 1,
82             default => sub { $_[0]->plugin_name },
83             );
84              
85 5     5   2952 use Pod::Elemental::Transformer::Gatherer;
  5         158782  
  5         204  
86 5     5   42 use Pod::Elemental::Transformer::Nester;
  5         13  
  5         3434  
87              
88             has __used_container => (is => 'rw');
89              
90             sub transform_document {
91 20     20 0 57 my ($self, $document) = @_;
92              
93 20         641 my $command = $self->command;
94 20         73 my $selector = s_command($command);
95              
96 20         695 my $children = $document->children;
97 20 100   126   220 unless (any { $selector->($_) } @$children) {
  126         8438  
98 13         1238 $self->log_debug("no $command commands in pod to collect");
99 13         379 return;
100             }
101              
102 7         701 $self->log_debug("transforming $command commands into standard pod");
103              
104 7         480 my $nester = Pod::Elemental::Transformer::Nester->new({
105             top_selector => $selector,
106             content_selectors => [
107             s_command([ qw(head3 head4 over item back) ]),
108             s_flat,
109             ],
110             });
111              
112             # try and find array position of suitable host
113             my ( $container_id ) = grep {
114 7         907 my $c = $children->[$_];
  55         100  
115 55 100 66     1060 $c->isa("Pod::Elemental::Element::Nested")
116             and $c->command eq $self->header_command and $c->content eq $self->header;
117             } 0 .. $#$children;
118              
119 7 100       83 my $container = $container_id
120             ? splice @$children, $container_id, 1 # excise host
121             : Pod::Elemental::Element::Nested->new({ # synthesize new host
122             command => $self->header_command,
123             content => $self->header,
124             });
125              
126 7         417 $self->__used_container($container);
127              
128 7         295 my $gatherer = Pod::Elemental::Transformer::Gatherer->new({
129             gather_selector => $selector,
130             container => $container,
131             });
132              
133 7         1564 $nester->transform_node($document);
134 7         13564 my @children = $container->children->@*; # rescue children
135 7         86 $gatherer->transform_node($document); # insert host at position of first adopt-child and inject it with adopt-children
136 7         8507 foreach my $child ($container->children->@*) {
137 7 50       264 $child->command( $self->new_command ) if $child->command eq $command;
138             }
139 7         344 unshift $container->children->@*, @children; # give original children back to host
140             }
141              
142             sub weave_section {
143 20     20 0 49 my ($self, $document, $input) = @_;
144              
145 20 100       574 return unless $self->__used_container;
146              
147 7         194 my $in_node = $input->{pod_document}->children;
148              
149             my @found = grep {
150 7         66 my ($i, $para) = ($_, $in_node->[$_]);
  21         50  
151 21 100       596 ($para == $self->__used_container)
152             && $self->__used_container->children->@*;
153             } (0 .. $#$in_node);
154              
155 7         260 push $document->children->@*, map { splice @$in_node, $_, 1 } reverse @found;
  7         102  
156             }
157              
158             __PACKAGE__->meta->make_immutable;
159             1;
160              
161             __END__
162              
163             =pod
164              
165             =encoding UTF-8
166              
167             =head1 NAME
168              
169             Pod::Weaver::Section::Collect - a section that gathers up specific commands
170              
171             =head1 VERSION
172              
173             version 4.018
174              
175             =head1 OVERVIEW
176              
177             Given the configuration:
178              
179             [Collect / METHODS]
180             command = method
181              
182             This plugin will start off by gathering and nesting any C<=method> commands
183             found in the C<pod_document>. Those commands, along with their nestable
184             content, will be collected under a C<=head1 METHODS> header and placed in the
185             correct location in the output stream. Their order will be preserved as it was
186             in the source document.
187              
188             =head1 PERL VERSION SUPPORT
189              
190             This module has the same support period as perl itself: it supports the two
191             most recent versions of perl. (That is, if the most recently released version
192             is v5.40, then this module should work on both v5.40 and v5.38.)
193              
194             Although it may work on older versions of perl, no guarantee is made that the
195             minimum required version will not be increased. The version may be increased
196             for any reason, and there is no promise that patches will be accepted to lower
197             the minimum required perl.
198              
199             =head1 ATTRIBUTES
200              
201             =head2 command
202              
203             The command that will be collected (e.g. C<attr> or C<method>).
204             (required)
205              
206             =head2 new_command
207              
208             The command to be used in the output instead of the collected command.
209             (default: C<head2>)
210              
211             =head2 header_command
212              
213             The section command for the section to be added.
214             (default: C<head1>)
215              
216             =head2 header
217              
218             The title of the section to be added.
219             (default: the plugin name)
220              
221             =head1 AUTHOR
222              
223             Ricardo SIGNES <rjbs@semiotic.systems>
224              
225             =head1 COPYRIGHT AND LICENSE
226              
227             This software is copyright (c) 2021 by Ricardo SIGNES.
228              
229             This is free software; you can redistribute it and/or modify it under
230             the same terms as the Perl 5 programming language system itself.
231              
232             =cut