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.019;
2             # ABSTRACT: add a NAME section with abstract (for your Perl module)
3              
4 9     9   33009 use Moose;
  9         29  
  9         73  
5             with 'Pod::Weaver::Role::Section',
6             'Pod::Weaver::Role::StringFromComment';
7              
8             # BEGIN BOILERPLATE
9 9     9   64135 use v5.20.0;
  9         45  
10 9     9   63 use warnings;
  9         20  
  9         377  
11 9     9   66 use utf8;
  9         40  
  9         93  
12 9     9   339 no feature 'switch';
  9         31  
  9         1145  
13 9     9   72 use experimental qw(postderef postderef_qq); # This experiment gets mainlined.
  9         36  
  9         93  
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   1418 use Pod::Elemental::Element::Pod5::Command;
  9         27  
  9         454  
49 9     9   102 use Pod::Elemental::Element::Pod5::Ordinary;
  9         28  
  9         383  
50 9     9   64 use Pod::Elemental::Element::Nested;
  9         21  
  9         5698  
51              
52             sub _get_docname_via_statement {
53 27     27   91 my ($self, $ppi_document) = @_;
54              
55 27         97 my $pkg_node = $ppi_document->find_first('PPI::Statement::Package');
56 27 50       6967 return unless $pkg_node;
57 27         207 return $pkg_node->namespace;
58             }
59              
60             sub _get_docname_via_comment {
61 29     29   85 my ($self, $ppi_document) = @_;
62              
63 29         256 return $self->_extract_comment_content($ppi_document, 'PODNAME');
64             }
65              
66             sub _get_docname {
67 29     29   81 my ($self, $input) = @_;
68              
69 29         97 my $ppi_document = $input->{ppi_document};
70              
71 29   66     126 my $docname = $self->_get_docname_via_comment($ppi_document)
72             || $self->_get_docname_via_statement($ppi_document);
73              
74 29         994 return $docname;
75             }
76              
77             sub _get_abstract {
78 29     29   96 my ($self, $input) = @_;
79              
80 29         124 my $comment = $self->_extract_comment_content($input->{ppi_document}, 'ABSTRACT');
81              
82 29 50       165 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 102 my ($self, $document, $input) = @_;
93              
94 29   50     188 my $filename = $input->{filename} || 'file';
95              
96 29         165 my $docname = $self->_get_docname($input);
97 29         113 my $abstract = $self->_get_abstract($input);
98              
99 29 50       90 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       100 $self->log([ "couldn't find abstract in %s", $filename ]) unless $abstract;
103              
104 29         78 my $name = $docname;
105 29 50       123 $name .= " - $abstract" if $abstract;
106              
107 29         251 $self->log_debug(qq{setting NAME to "$name"});
108              
109 29         2064 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         15945 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.019
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 released
159             in the last two to three years. (That is, if the most recently released
160             version is v5.40, then this module should work on both v5.40 and v5.38.)
161              
162             Although it may work on older versions of perl, no guarantee is made that the
163             minimum required version will not be increased. The version may be increased
164             for any reason, and there is no promise that patches will be accepted to lower
165             the minimum required perl.
166              
167             =head1 ATTRIBUTES
168              
169             =head2 header
170              
171             The title of the header to be added.
172             (default: "NAME")
173              
174             =head1 AUTHOR
175              
176             Ricardo SIGNES <cpan@semiotic.systems>
177              
178             =head1 COPYRIGHT AND LICENSE
179              
180             This software is copyright (c) 2023 by Ricardo SIGNES.
181              
182             This is free software; you can redistribute it and/or modify it under
183             the same terms as the Perl 5 programming language system itself.
184              
185             =cut