File Coverage

blib/lib/Pod/ProjectDocs.pm
Criterion Covered Total %
statement 101 105 96.1
branch 15 22 68.1
condition 9 19 47.3
subroutine 16 17 94.1
pod 1 5 20.0
total 142 168 84.5


line stmt bran cond sub pod time code
1             package Pod::ProjectDocs;
2              
3 4     4   217404 use strict;
  4         38  
  4         113  
4 4     4   20 use warnings;
  4         8  
  4         153  
5              
6             our $VERSION = '0.53'; # VERSION
7              
8 4     4   2190 use Moose;
  4         1821095  
  4         29  
9              
10 4     4   28387 use File::Spec;
  4         10  
  4         120  
11 4     4   3292 use JSON;
  4         38560  
  4         24  
12 4     4   2414 use Pod::ProjectDocs::DocManager;
  4         16  
  4         186  
13 4     4   2265 use Pod::ProjectDocs::Config;
  4         16  
  4         171  
14 4     4   2205 use Pod::ProjectDocs::Parser;
  4         29  
  4         181  
15 4     4   2537 use Pod::ProjectDocs::CSS;
  4         14  
  4         171  
16 4     4   2227 use Pod::ProjectDocs::IndexPage;
  4         14  
  4         4040  
17              
18             has 'managers' => (
19             is => 'rw',
20             isa => 'ArrayRef',
21             default => sub { [] },
22             );
23             has 'components' => (
24             is => 'rw',
25             isa => 'HashRef',
26             default => sub { {} },
27             );
28             has 'config' => (
29             is => 'ro',
30             isa => 'Object',
31             );
32              
33             sub BUILDARGS {
34 3     3 1 338 my ( $class, %args ) = @_;
35              
36 3   50     28 $args{title} ||= "MyProject's Libraries";
37 3   50     20 $args{desc} ||= "manuals and libraries";
38 3   50     55 $args{lang} ||= "en";
39              
40             # set absolute path to 'outroot'
41 3   33     9 $args{outroot} ||= File::Spec->curdir;
42             $args{outroot} = File::Spec->rel2abs( $args{outroot}, File::Spec->curdir )
43 3 50       38 unless File::Spec->file_name_is_absolute( $args{outroot} );
44              
45             # set absolute path to 'libroot'
46 3   33     13 $args{libroot} ||= File::Spec->curdir;
47 3 50       21 $args{libroot} = [ $args{libroot} ] unless ref $args{libroot};
48             $args{libroot} = [
49             map {
50 3 50       24 File::Spec->file_name_is_absolute($_)
51             ? $_
52             : File::Spec->rel2abs( $_, File::Spec->curdir )
53 3         9 } @{ $args{libroot} }
  3         12  
54             ];
55              
56             # check mtime by default, but can be overridden
57 3   50     14 $args{forcegen} ||= 0;
58              
59 3 100       15 $args{nosourcecode} = 0 if !defined $args{nosourcecode};
60              
61 3   100     16 $args{except} ||= [];
62 3 50       13 $args{except} = [ $args{except} ] unless ref $args{except};
63              
64 3         41 $args{config} = Pod::ProjectDocs::Config->new(%args);
65              
66 3         9389 return \%args;
67             }
68              
69             sub BUILD {
70 3     3 0 3352 my $self = shift;
71              
72             $self->components->{css} =
73 3         118 Pod::ProjectDocs::CSS->new( config => $self->config );
74 3         30 $self->add_manager( 'Perl Manuals', 'pod', Pod::ProjectDocs::Parser->new );
75 3         26 $self->add_manager( 'Perl Modules', 'pm', Pod::ProjectDocs::Parser->new );
76 3         28 $self->add_manager(
77             'Trigger Scripts',
78             [ 'cgi', 'pl' ],
79             Pod::ProjectDocs::Parser->new
80             );
81              
82 3         11 return;
83             }
84              
85             sub add_manager {
86 9     9 0 75327 my ( $self, $desc, $suffix, $parser ) = @_;
87 9         19 push @{ $self->managers },
  9         217  
88             Pod::ProjectDocs::DocManager->new(
89             config => $self->config,
90             desc => $desc,
91             suffix => $suffix,
92             parser => $parser,
93             );
94 9         80 return;
95             }
96              
97             sub gen {
98 3     3 0 40 my $self = shift;
99              
100 3         7 foreach my $comp_key ( keys %{ $self->components } ) {
  3         80  
101 3         68 my $comp = $self->components->{$comp_key};
102 3         18 $comp->publish();
103             }
104              
105 3         10 my %local_modules;
106              
107 3         7 foreach my $manager ( @{ $self->managers } ) {
  3         101  
108 9 100       230 next if $manager->desc !~ /^Perl/;
109 6 50       12 for my $doc ( @{ $manager->docs() || [] } ) {
  6         145  
110 5         117 my $name = $doc->name;
111 5         18 my $path = $doc->get_output_path;
112 5         18 $local_modules{$name} = $path;
113             }
114             }
115              
116 3         6 foreach my $manager ( @{ $self->managers } ) {
  3         106  
117              
118 9         291 $manager->parser->local_modules( \%local_modules );
119              
120 9 50       14 for my $doc ( @{ $manager->docs() || [] } ) {
  9         251  
121 5         145 my $html = $manager->parser->gen_html(
122             doc => $doc,
123             desc => $manager->desc,
124             components => $self->components,
125             );
126              
127 5 50 33     150 if ( $self->config->forcegen || $doc->is_modified ) {
128 5 100       124 if ( !$self->config->nosourcecode ) {
129 4         22 $doc->copy_src();
130             }
131 5         36 $doc->publish($html);
132             }
133             }
134             }
135              
136 3         77 my $index_page = Pod::ProjectDocs::IndexPage->new(
137             config => $self->config,
138             components => $self->components,
139             json => $self->get_managers_json,
140             );
141 3         6525 $index_page->publish();
142 3         15 return;
143             }
144              
145             sub get_managers_json {
146 3     3 0 8 my $self = shift;
147 3         97 my $js = JSON->new;
148 3         11 my $entries = [];
149 3         9 foreach my $manager ( @{ $self->managers } ) {
  3         84  
150 9         226 my $entry = {
151             desc => $manager->desc,
152             entries => [],
153             };
154 9         15 foreach my $doc ( @{ $manager->docs } ) {
  9         218  
155 5         10 push @{ $entry->{entries} },
  5         125  
156             {
157             path => $doc->relpath,
158             name => $doc->name,
159             title => $doc->title,
160             };
161             }
162 9 100       17 if ( scalar( @{ $entry->{entries} } ) > 0 ) {
  9         28  
163 4         8 push @$entries, $entry;
164             }
165             }
166              
167             # Use "canonical" to generate stable structures that can be added
168             # to version control systems without changing all the time.
169 3         139 return $js->canonical()->encode($entries);
170             }
171              
172             sub _croak {
173 0     0     my ( $self, $msg ) = @_;
174 0           require Carp;
175 0           Carp::croak($msg);
176 0           return;
177             }
178              
179 4     4   43 no Moose;
  4         10  
  4         22  
180              
181             1;
182             __END__
183              
184             =encoding utf-8
185              
186             =head1 NAME
187              
188             Pod::ProjectDocs - generates CPAN like project documents from pod.
189              
190             =head1 SYNOPSIS
191              
192             #!/usr/bin/perl
193              
194             use strict;
195             use warnings;
196              
197             use Pod::ProjectDocs;
198              
199             my $pd = Pod::ProjectDocs->new(
200             libroot => '/your/project/lib/root',
201             outroot => '/output/directory',
202             title => 'ProjectName',
203             );
204             $pd->gen();
205              
206             # or use pod2projdocs on your shell
207             pod2projdocs -out /output/directory -lib /your/project/lib/root
208              
209             =head1 DESCRIPTION
210              
211             This module allows you to generates CPAN like pod pages from your modules
212             for your projects. It also creates an optional index page.
213              
214             =head1 OPTIONS
215              
216             =over 4
217              
218             =item C<outroot>
219              
220             output directory for the generated documentation.
221              
222             =item C<libroot>
223              
224             your library's (source code) root directory.
225              
226             You can set single path by string, or multiple by arrayref.
227              
228             my $pd = Pod::ProjectDocs->new(
229             outroot => '/path/to/output/directory',
230             libroot => '/path/to/lib'
231             );
232              
233             or
234              
235             my $pd = Pod::ProjectDocs->new(
236             outroot => '/path/to/output/directory',
237             libroot => ['/path/to/lib1', '/path/to/lib2'],
238             );
239              
240             =item C<title>
241              
242             your project's name.
243              
244             =item C<desc>
245              
246             description for your project.
247              
248             =item C<index>
249              
250             whether you want to create an index for all generated pages (0 or 1).
251              
252             =item C<lang>
253              
254             set this language as xml:lang (default 'en')
255              
256             =item C<forcegen>
257              
258             whether you want to generate HTML document even if source files are not updated (default is 0).
259              
260             =item C<nosourcecode>
261              
262             whether to suppress inclusion of the original source code in the generated output (default is 0).
263              
264             =item C<except>
265              
266             the files matches this regex won't be parsed.
267              
268             Pod::ProjectDocs->new(
269             except => qr/^specific_dir\//,
270             ...other parameters
271             );
272              
273             Pod::ProjectDocs->new(
274             except => [qr/^specific_dir1\//, qr/^specific_dir2\//],
275             ...other parameters
276             );
277              
278             =back
279              
280             =head1 pod2projdocs
281              
282             You can use the command line script L<pod2projdocs> to generate your documentation
283             without creating a custom perl script.
284              
285             pod2projdocs -help
286              
287             =head1 SEE ALSO
288              
289             L<Pod::Simple::XHTML>
290              
291             =head1 AUTHORS
292              
293             =over 4
294              
295             =item Lyo Kato E<lt>lyo.kato@gmail.comE<gt>
296              
297             =item L<Martin Gruner|https://github.com/mgruner> (current maintainer)
298              
299             =back
300              
301             =head1 COPYRIGHT AND LICENSE
302              
303             =over 4
304              
305             =item © 2005 by Lyo Kato
306              
307             =item © 2018 by Martin Gruner
308              
309             =back
310              
311             This library is free software; you can redistribute it and/or modify
312             it under the same terms as Perl itself, either Perl version 5.8.5 or,
313             at your option, any later version of Perl 5 you may have available.
314              
315             =cut