File Coverage

blib/lib/Pod/Weaver/Section/Name.pm
Criterion Covered Total %
statement 50 52 96.1
branch 5 10 50.0
condition 3 5 60.0
subroutine 14 14 100.0
pod 0 1 0.0
total 72 82 87.8


line stmt bran cond sub pod time code
1             package Pod::Weaver::Section::Name 4.020;
2             # ABSTRACT: add a NAME section with abstract (for your Perl module)
3              
4 9     9   42600 use Moose;
  9         53  
  9         94  
5             with 'Pod::Weaver::Role::Section',
6             'Pod::Weaver::Role::StringFromComment';
7              
8             # BEGIN BOILERPLATE
9 9     9   80318 use v5.20.0;
  9         35  
10 9     9   62 use warnings;
  9         16  
  9         625  
11 9     9   94 use utf8;
  9         23  
  9         98  
12 9     9   498 no feature 'switch';
  9         20  
  9         1845  
13 9     9   74 use experimental qw(postderef postderef_qq); # This experiment gets mainlined.
  9         15  
  9         99  
14             # END BOILERPLATE
15              
16             #pod =head1 OVERVIEW
17             #pod
18             #pod This section plugin will produce a hunk of Pod giving the name of the document
19             #pod as well as an abstract, like this:
20             #pod
21             #pod =head1 NAME
22             #pod
23             #pod Some::Document - a document for some
24             #pod
25             #pod It will determine the name and abstract by inspecting the C<ppi_document> which
26             #pod must be given. It looks for comments in the form:
27             #pod
28             #pod
29             #pod # ABSTRACT: a document for some
30             #pod # PODNAME: Some::Package::Name
31             #pod
32             #pod If no C<PODNAME> comment is present, but a package declaration can be found,
33             #pod the package name will be used as the document name.
34             #pod
35             #pod =attr header
36             #pod
37             #pod The title of the header to be added.
38             #pod (default: "NAME")
39             #pod
40             #pod =cut
41              
42             has header => (
43             is => 'ro',
44             isa => 'Str',
45             default => 'NAME',
46             );
47              
48 9     9   1286 use Pod::Elemental::Element::Pod5::Command;
  9         18  
  9         503  
49 9     9   81 use Pod::Elemental::Element::Pod5::Ordinary;
  9         21  
  9         415  
50 9     9   58 use Pod::Elemental::Element::Nested;
  9         26  
  9         7178  
51              
52             sub _get_docname_via_statement {
53 27     27   105 my ($self, $ppi_document) = @_;
54              
55 27         119 my $pkg_node = $ppi_document->find_first('PPI::Statement::Package');
56 27 50       8192 return unless $pkg_node;
57 27         183 return $pkg_node->namespace;
58             }
59              
60             sub _get_docname_via_comment {
61 29     29   90 my ($self, $ppi_document) = @_;
62              
63 29         212 return $self->_extract_comment_content($ppi_document, 'PODNAME');
64             }
65              
66             sub _get_docname {
67 29     29   90 my ($self, $input) = @_;
68              
69 29         73 my $ppi_document = $input->{ppi_document};
70              
71 29   66     147 my $docname = $self->_get_docname_via_comment($ppi_document)
72             || $self->_get_docname_via_statement($ppi_document);
73              
74 29         1385 return $docname;
75             }
76              
77             sub _get_abstract {
78 29     29   92 my ($self, $input) = @_;
79              
80 29         150 my $comment = $self->_extract_comment_content($input->{ppi_document}, 'ABSTRACT');
81              
82 29 50       147 return $comment if $comment;
83              
84             # If that failed, fall back to searching the whole document
85             my ($abstract)
86 0         0 = $input->{ppi_document}->serialize =~ /^\s*#+\s*ABSTRACT:\s*(.+)$/m;
87              
88 0         0 return $abstract;
89             }
90              
91             sub weave_section {
92 29     29 0 116 my ($self, $document, $input) = @_;
93              
94 29   50     239 my $filename = $input->{filename} || 'file';
95              
96 29         289 my $docname = $self->_get_docname($input);
97 29         129 my $abstract = $self->_get_abstract($input);
98              
99 29 50       136 Carp::croak sprintf "couldn't determine document name for %s\nAdd something like this to %s:\n# PODNAME: bobby_tables.pl", $filename, $filename
100             unless $docname;
101              
102 29 50       95 $self->log([ "couldn't find abstract in %s", $filename ]) unless $abstract;
103              
104 29         65 my $name = $docname;
105 29 50       157 $name .= " - $abstract" if $abstract;
106              
107 29         260 $self->log_debug(qq{setting NAME to "$name"});
108              
109 29         2943 my $name_para = Pod::Elemental::Element::Nested->new({
110             command => 'head1',
111             content => $self->header,
112             children => [
113             Pod::Elemental::Element::Pod5::Ordinary->new({ content => $name }),
114             ],
115             });
116              
117 29         19478 push $document->children->@*, $name_para;
118             }
119              
120             __PACKAGE__->meta->make_immutable;
121             1;
122              
123             __END__
124              
125             =pod
126              
127             =encoding UTF-8
128              
129             =head1 NAME
130              
131             Pod::Weaver::Section::Name - add a NAME section with abstract (for your Perl module)
132              
133             =head1 VERSION
134              
135             version 4.020
136              
137             =head1 OVERVIEW
138              
139             This section plugin will produce a hunk of Pod giving the name of the document
140             as well as an abstract, like this:
141              
142             =head1 NAME
143              
144             Some::Document - a document for some
145              
146             It will determine the name and abstract by inspecting the C<ppi_document> which
147             must be given. It looks for comments in the form:
148              
149             # ABSTRACT: a document for some
150             # PODNAME: Some::Package::Name
151              
152             If no C<PODNAME> comment is present, but a package declaration can be found,
153             the package name will be used as the document name.
154              
155             =head1 PERL VERSION
156              
157             This module should work on any version of perl still receiving updates from
158             the Perl 5 Porters. This means it should work on any version of perl
159             released in the last two to three years. (That is, if the most recently
160             released version is v5.40, then this module should work on both v5.40 and
161             v5.38.)
162              
163             Although it may work on older versions of perl, no guarantee is made that the
164             minimum required version will not be increased. The version may be increased
165             for any reason, and there is no promise that patches will be accepted to
166             lower the minimum required perl.
167              
168             =head1 ATTRIBUTES
169              
170             =head2 header
171              
172             The title of the header to be added.
173             (default: "NAME")
174              
175             =head1 AUTHOR
176              
177             Ricardo SIGNES <cpan@semiotic.systems>
178              
179             =head1 COPYRIGHT AND LICENSE
180              
181             This software is copyright (c) 2024 by Ricardo SIGNES.
182              
183             This is free software; you can redistribute it and/or modify it under
184             the same terms as the Perl 5 programming language system itself.
185              
186             =cut