App-FuguWeb
view release on metacpan or search on metacpan
lib/App/FuguWeb/Config.pm view on Meta::CPAN
return;
}
package App::FuguWeb::Config::Group;
our $VERSION = '0.2.0';
# App::FuguWeb::Config::Group - one group of the manual index.
#
# A group is a heading, an anchor, and a directory. It never holds a
# list of manuals: it reads the directory, so a manual that is added
# reaches the site with no edit anywhere.
#
# A manuals group globs mdoc sources. A modules group finds POD
# sidecars below the directory, and the file that names the directory
# itself: lib/App/FuguWeb.pod is the umbrella of lib/App/FuguWeb/.
# The sections that a manuals group globs, in the order the index
# shows them.
my @SECTIONS = qw(1 3p 5 8);
# App::FuguWeb::Config::Group->new(%args):
# kind => 'manuals'|'modules'
# heading => $string the h2 of the group
# anchor => $string the id of the h2
# dir => $path the directory it reads
# namespace => $string the prefix of a manuals name
# module_root => $path the prefix a module name drops
sub new ( $class, %args )
{
return bless {
kind => $args{kind},
heading => $args{heading},
anchor => $args{anchor},
dir => $args{dir},
namespace => $args{namespace},
module_root => $args{module_root},
}, $class;
}
sub kind ($self) { return $self->{kind}; }
sub heading ($self) { return $self->{heading}; }
sub anchor ($self) { return $self->{anchor}; }
sub namespace ($self) { return $self->{namespace}; }
# $self->manuals:
# The manuals of the group, in the order the index shows them.
# The method reads the directory once and keeps the answer.
sub manuals ($self)
{
$self->{manuals} //=
$self->{kind} eq 'manuals'
? [ $self->_mdoc_manuals ]
: [ $self->_pod_manuals ];
return @{ $self->{manuals} };
}
# $self->_mdoc_manuals:
# Every mdoc source in the directory, by section in the order 1,
# 3p, 5, 8, and then by file name. The sort compares bytes and
# never reads the locale of the builder: a site must not depend
# on the machine that built it.
#
# The method reads the directory rather than globs it. Perl's
# glob splits its pattern on whitespace and reads [ ] { } ? ~, so
# a project whose path holds one of them would lose its manuals
# or collect a sibling directory's. It also matches a directory,
# and a directory named tool.1 is not a manual.
sub _mdoc_manuals ($self)
{
my $names = App::FuguWeb::list_dir( $self->{dir} ) or return ();
my @names = grep { !/^\./ } @$names;
my @manuals;
for my $section (@SECTIONS) {
for my $name (@names) {
next unless $name =~ /\.\Q$section\E$/;
next unless -f "$self->{dir}/$name";
push @manuals,
App::FuguWeb::Manual->from_mdoc(
"$self->{dir}/$name", $self );
}
}
return @manuals;
}
# $self->_pod_manuals:
# Every POD sidecar below the directory, and the sidecar that
# names the directory itself, by path. Sorting by the whole path
# keeps Store.pod before Store/Memory.pod, because a dot sorts
# before a slash.
sub _pod_manuals ($self)
{
my @paths;
push @paths, "$self->{dir}.pod" if -f "$self->{dir}.pod";
File::Find::find( {
no_chdir => 1,
wanted => sub {
push @paths, $File::Find::name
if /\.pod$/ && -f $File::Find::name;
},
},
$self->{dir} );
return map {
App::FuguWeb::Manual->from_pod( $_, $self,
$self->{module_root} )
} sort @paths;
}
1;
( run in 0.461 second using v1.01-cache-2.11-cpan-a5162978ef8 )