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 )