package Pod::ProjectDocs;
use strict;
use warnings;
our $VERSION = '0.51'; # VERSION
use Moose;
use File::Spec;
use JSON;
use Pod::ProjectDocs::DocManager;
use Pod::ProjectDocs::Config;
use Pod::ProjectDocs::Parser;
use Pod::ProjectDocs::CSS;
use Pod::ProjectDocs::IndexPage;
has 'managers' => (
is => 'rw',
isa => 'ArrayRef',
default => sub { [] },
);
has 'components' => (
is => 'rw',
isa => 'HashRef',
default => sub { {} },
);
has 'config' => (
is => 'ro',
isa => 'Object',
);
sub BUILDARGS {
my ( $class, %args ) = @_;
$args{title} ||= "MyProject's Libraries";
$args{desc} ||= "manuals and libraries";
$args{lang} ||= "en";
# set absolute path to 'outroot'
$args{outroot} ||= File::Spec->curdir;
$args{outroot} = File::Spec->rel2abs( $args{outroot}, File::Spec->curdir )
unless File::Spec->file_name_is_absolute( $args{outroot} );
# set absolute path to 'libroot'
$args{libroot} ||= File::Spec->curdir;
$args{libroot} = [ $args{libroot} ] unless ref $args{libroot};
$args{libroot} = [
map {
File::Spec->file_name_is_absolute($_)
? $_
: File::Spec->rel2abs( $_, File::Spec->curdir )
} @{ $args{libroot} }
];
# check mtime by default, but can be overridden
$args{forcegen} ||= 0;
$args{nosourcecode} = 0 if !defined $args{nosourcecode};
$args{except} ||= [];
$args{except} = [ $args{except} ] unless ref $args{except};
$args{config} = Pod::ProjectDocs::Config->new(%args);
return \%args;
}
sub BUILD {
my $self = shift;
$self->components->{css} =
Pod::ProjectDocs::CSS->new( config => $self->config );
$self->add_manager( 'Perl Manuals', 'pod', Pod::ProjectDocs::Parser->new );
$self->add_manager( 'Perl Modules', 'pm', Pod::ProjectDocs::Parser->new );
$self->add_manager(
'Trigger Scripts',
[ 'cgi', 'pl' ],
Pod::ProjectDocs::Parser->new
);
return;
}
sub add_manager {
my ( $self, $desc, $suffix, $parser ) = @_;
push @{ $self->managers },
Pod::ProjectDocs::DocManager->new(
config => $self->config,
desc => $desc,
suffix => $suffix,
parser => $parser,
);
return;
}
sub gen {
my $self = shift;
foreach my $comp_key ( keys %{ $self->components } ) {
my $comp = $self->components->{$comp_key};
$comp->publish();
}
my %local_modules;
foreach my $manager ( @{ $self->managers } ) {
next if $manager->desc !~ /Perl Modules/;
for my $doc ( @{ $manager->docs() || [] } ) {
my $name = $doc->name;
my $path = $doc->get_output_path;
if ( $manager->desc eq 'Perl Modules' ) {
$local_modules{$name} = $path;
}
}
}
foreach my $manager ( @{ $self->managers } ) {
$manager->parser->local_modules( \%local_modules );
for my $doc ( @{ $manager->docs() || [] } ) {
my $html = $manager->parser->gen_html(
doc => $doc,
desc => $manager->desc,
components => $self->components,
);
if ( $self->config->forcegen || $doc->is_modified ) {
if ( !$self->config->nosourcecode ) {
$doc->copy_src();
}
$doc->publish($html);
}
}
}
my $index_page = Pod::ProjectDocs::IndexPage->new(
config => $self->config,
components => $self->components,
json => $self->get_managers_json,
);
$index_page->publish();
return;
}
sub get_managers_json {
my $self = shift;
my $js = JSON->new;
my $records = [];
foreach my $manager ( @{ $self->managers } ) {
my $record = {
desc => $manager->desc,
records => [],
};
foreach my $doc ( @{ $manager->docs } ) {
push @{ $record->{records} },
{
path => $doc->relpath,
name => $doc->name,
title => $doc->title,
};
}
if ( scalar( @{ $record->{records} } ) > 0 ) {
push @$records, $record;
}
}
# Use "canonical" to generate stable structures that can be added
# to version control systems without changing all the time.
return $js->canonical()->encode($records);
}
sub _croak {
my ( $self, $msg ) = @_;
require Carp;
Carp::croak($msg);
return;
}
1;
__END__
=encoding utf-8
=head1 NAME
Pod::ProjectDocs - generates CPAN like project documents from pod.
=head1 SYNOPSIS
#!/usr/bin/perl
use strict;
use warnings;
use Pod::ProjectDocs;
my $pd = Pod::ProjectDocs->new(
libroot => '/your/project/lib/root',
outroot => '/output/directory',
title => 'ProjectName',
);
$pd->gen();
# or use pod2projdocs on your shell
pod2projdocs -out /output/directory -lib /your/project/lib/root
=head1 DESCRIPTION
This module allows you to generates CPAN like pod pages from your modules
for your projects. It also creates an optional index page.
=head1 OPTIONS
=over 4
=item C<outroot>
output directory for the generated documentation.
=item C<libroot>
your library's (source code) root directory.
You can set single path by string, or multiple by arrayref.
my $pd = Pod::ProjectDocs->new(
outroot => '/path/to/output/directory',
libroot => '/path/to/lib'
);
or
my $pd = Pod::ProjectDocs->new(
outroot => '/path/to/output/directory',
libroot => ['/path/to/lib1', '/path/to/lib2'],
);
=item C<title>
your project's name.
=item C<desc>
description for your project.
=item C<index>
whether you want to create an index for all generated pages (0 or 1).
=item C<lang>
set this language as xml:lang (default 'en')
=item C<forcegen>
whether you want to generate HTML document even if source files are not updated (default is 0).
=item C<nosourcecode>
whether to suppress inclusion of the original source code in the generated output (default is 0).
=item C<except>
the files matches this regex won't be parsed.
Pod::ProjectDocs->new(
except => qr/^specific_dir\//,
...other parameters
);
Pod::ProjectDocs->new(
except => [qr/^specific_dir1\//, qr/^specific_dir2\//],
...other parameters
);
=back
=head1 pod2projdocs
You can use the command line script L<pod2projdocs> to generate your documentation
without creating a custom perl script.
pod2projdocs -help
=head1 SEE ALSO
L<Pod::Simple::XHTML>
=head1 AUTHORS
=over 4
=item Lyo Kato E<lt>lyo.kato@gmail.comE<gt>
=item L<Martin Gruner|https://github.com/mgruner> (current maintainer)
=back
=head1 COPYRIGHT AND LICENSE
=over 4
=item © 2005 by Lyo Kato
=item © 2018 by Martin Gruner
=back
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.5 or,
at your option, any later version of Perl 5 you may have available.
=cut