File Coverage

blib/lib/Pod/Weaver/Section/Collect.pm
Criterion Covered Total %
statement 54 54 100.0
branch 11 12 91.6
condition 2 3 66.6
subroutine 9 9 100.0
pod 0 2 0.0
total 76 80 95.0


line stmt bran cond sub pod time code
1             package Pod::Weaver::Section::Collect;
2             # ABSTRACT: a section that gathers up specific commands
3             $Pod::Weaver::Section::Collect::VERSION = '4.017';
4 5     5   46622 use Moose;
  5         14  
  5         45  
5             with 'Pod::Weaver::Role::Section';
6             with 'Pod::Weaver::Role::Transformer';
7              
8             #pod =head1 OVERVIEW
9             #pod
10             #pod Given the configuration:
11             #pod
12             #pod [Collect / METHODS]
13             #pod command = method
14             #pod
15             #pod This plugin will start off by gathering and nesting any C<=method> commands
16             #pod found in the C<pod_document>. Those commands, along with their nestable
17             #pod content, will be collected under a C<=head1 METHODS> header and placed in the
18             #pod correct location in the output stream. Their order will be preserved as it was
19             #pod in the source document.
20             #pod
21             #pod =cut
22              
23 5     5   35051 use Pod::Elemental::Element::Pod5::Region;
  5         27  
  5         218  
24 5     5   49 use Pod::Elemental::Selectors -all;
  5         11  
  5         52  
25 5     5   3005 use List::Util 1.33 'any';
  5         129  
  5         930  
26              
27             #pod =attr command
28             #pod
29             #pod The command that will be collected (e.g. C<attr> or C<method>).
30             #pod (required)
31             #pod
32             #pod =attr new_command
33             #pod
34             #pod The command to be used in the output instead of the collected command.
35             #pod (default: C<head2>)
36             #pod
37             #pod =attr header_command
38             #pod
39             #pod The section command for the section to be added.
40             #pod (default: C<head1>)
41             #pod
42             #pod =attr header
43             #pod
44             #pod The title of the section to be added.
45             #pod (default: the plugin name)
46             #pod
47             #pod =cut
48              
49             has command => (
50             is => 'ro',
51             isa => 'Str',
52             required => 1,
53             );
54              
55             has new_command => (
56             is => 'ro',
57             isa => 'Str',
58             required => 1,
59             default => 'head2',
60             );
61              
62             has header_command => (
63             is => 'ro',
64             isa => 'Str',
65             required => 1,
66             default => 'head1',
67             );
68              
69             has header => (
70             is => 'ro',
71             isa => 'Str',
72             lazy => 1,
73             required => 1,
74             default => sub { $_[0]->plugin_name },
75             );
76              
77 5     5   3162 use Pod::Elemental::Transformer::Gatherer;
  5         171505  
  5         207  
78 5     5   43 use Pod::Elemental::Transformer::Nester;
  5         13  
  5         3060  
79              
80             has __used_container => (is => 'rw');
81              
82             sub transform_document {
83 20     20 0 64 my ($self, $document) = @_;
84              
85 20         627 my $command = $self->command;
86 20         69 my $selector = s_command($command);
87              
88 20         747 my $children = $document->children;
89 20 100   126   244 unless (any { $selector->($_) } @$children) {
  126         8596  
90 13         1238 $self->log_debug("no $command commands in pod to collect");
91 13         415 return;
92             }
93              
94 7         731 $self->log_debug("transforming $command commands into standard pod");
95              
96 7         474 my $nester = Pod::Elemental::Transformer::Nester->new({
97             top_selector => $selector,
98             content_selectors => [
99             s_command([ qw(head3 head4 over item back) ]),
100             s_flat,
101             ],
102             });
103              
104             # try and find array position of suitable host
105             my ( $container_id ) = grep {
106 7         926 my $c = $children->[$_];
  55         98  
107 55 100 66     1163 $c->isa("Pod::Elemental::Element::Nested")
108             and $c->command eq $self->header_command and $c->content eq $self->header;
109             } 0 .. $#$children;
110              
111             my $container = $container_id
112 7 100       68 ? splice @{ $children }, $container_id, 1 # excise host
  6         21  
113             : Pod::Elemental::Element::Nested->new({ # synthesize new host
114             command => $self->header_command,
115             content => $self->header,
116             });
117              
118 7         473 $self->__used_container($container);
119              
120 7         336 my $gatherer = Pod::Elemental::Transformer::Gatherer->new({
121             gather_selector => $selector,
122             container => $container,
123             });
124              
125 7         1664 $nester->transform_node($document);
126 7         14090 my @children = @{$container->children}; # rescue children
  7         187  
127 7         97 $gatherer->transform_node($document); # insert host at position of first adopt-child and inject it with adopt-children
128 7         8888 foreach my $child (@{ $container->children }) {
  7         182  
129 7 50       311 $child->command( $self->new_command ) if $child->command eq $command;
130             }
131 7         208 unshift @{$container->children}, @children; # give original children back to host
  7         203  
132             }
133              
134             sub weave_section {
135 20     20 0 65 my ($self, $document, $input) = @_;
136              
137 20 100       593 return unless $self->__used_container;
138              
139 7         186 my $in_node = $input->{pod_document}->children;
140              
141             my @found = grep {
142 7         73 my ($i, $para) = ($_, $in_node->[$_]);
  21         58  
143             ($para == $self->__used_container)
144 21 100       612 && @{ $self->__used_container->children };
  7         227  
145             } (0 .. $#$in_node);
146              
147 7         97 push @{ $document->children }, map { splice @$in_node, $_, 1 } reverse @found;
  7         187  
  7         98  
148             }
149              
150             __PACKAGE__->meta->make_immutable;
151             1;
152              
153             __END__
154              
155             =pod
156              
157             =encoding UTF-8
158              
159             =head1 NAME
160              
161             Pod::Weaver::Section::Collect - a section that gathers up specific commands
162              
163             =head1 VERSION
164              
165             version 4.017
166              
167             =head1 OVERVIEW
168              
169             Given the configuration:
170              
171             [Collect / METHODS]
172             command = method
173              
174             This plugin will start off by gathering and nesting any C<=method> commands
175             found in the C<pod_document>. Those commands, along with their nestable
176             content, will be collected under a C<=head1 METHODS> header and placed in the
177             correct location in the output stream. Their order will be preserved as it was
178             in the source document.
179              
180             =head1 ATTRIBUTES
181              
182             =head2 command
183              
184             The command that will be collected (e.g. C<attr> or C<method>).
185             (required)
186              
187             =head2 new_command
188              
189             The command to be used in the output instead of the collected command.
190             (default: C<head2>)
191              
192             =head2 header_command
193              
194             The section command for the section to be added.
195             (default: C<head1>)
196              
197             =head2 header
198              
199             The title of the section to be added.
200             (default: the plugin name)
201              
202             =head1 AUTHOR
203              
204             Ricardo SIGNES <rjbs@cpan.org>
205              
206             =head1 COPYRIGHT AND LICENSE
207              
208             This software is copyright (c) 2021 by Ricardo SIGNES.
209              
210             This is free software; you can redistribute it and/or modify it under
211             the same terms as the Perl 5 programming language system itself.
212              
213             =cut