package Pod::Elemental::Transformer::Gatherer;
# ABSTRACT: gather related paragraphs under a shared header
$Pod::Elemental::Transformer::Gatherer::VERSION = '0.103005';
use Moose;
with 'Pod::Elemental::Transformer';
use namespace::autoclean;
use MooseX::Types::Moose qw(CodeRef);
use Pod::Elemental::Node;
#pod =head1 OVERVIEW
#pod
#pod Like the Nester transformer, this Gatherer produces structure and containment
#pod in a Pod document. Unlike that Nester, it does not find top-level elements,
#pod but instead produces them.
#pod
#pod It looks for all elements matching the C<gather_selector>. They are removed
#pod from the node. In the place of the first found element, the C<container> node
#pod is placed into the transformed node, and all the gathered elements are made
#pod children of the container.
#pod
#pod So, given this document:
#pod
#pod Document
#pod =head1 Foo
#pod =over 4
#pod =item * xyzzy
#pod =item * abcdef
#pod =back
#pod =head1 Bar
#pod =over 4
#pod =item * 1234
#pod =item * 8765
#pod =back
#pod
#pod ...and this nester...
#pod
#pod my $gatherer = Pod::Elemental::Transformer::Gatherer->new({
#pod gather_selector => s_command( [ qw(over item back) ] ),
#pod container => Pod::Elemental::Element::Pod5::Command->new({
#pod command => 'head1',
#pod content => "LISTS\n",
#pod }),
#pod });
#pod
#pod Then this:
#pod
#pod $nester->transform_node($document);
#pod
#pod Will result in this document:
#pod
#pod Document
#pod =head1 Foo
#pod =head1 LISTS
#pod =over 4
#pod =item * xyzzy
#pod =item * abcdef
#pod =back
#pod =over 4
#pod =item * 1234
#pod =item * 8765
#pod =back
#pod =head1 Bar
#pod
#pod =attr gather_selector
#pod
#pod This is a coderef (a predicate) used to find the paragraphs to gather up.
#pod
#pod =cut
has gather_selector => (
is => 'ro',
isa => CodeRef,
required => 1,
);
#pod =attr container
#pod
#pod This is a Pod::Elemental::Node that will be inserted into the node, containing
#pod all gathered elements.
#pod
#pod =cut
has container => (
is => 'ro',
does => 'Pod::Elemental::Node',
required => 1,
);
sub transform_node {
my ($self, $node) = @_;
my @indexes;
for my $i (0 .. @{ $node->children } - 1) {
push @indexes, $i if $self->gather_selector->($node->children->[ $i ]);
}
my @paras;
for my $idx (reverse @indexes) {
unshift @paras, splice @{ $node->children }, $idx, 1;
}
$self->container->children(\@paras);
splice @{ $node->children }, $indexes[0], 0, $self->container;
return $node;
}
__PACKAGE__->meta->make_immutable;
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Pod::Elemental::Transformer::Gatherer - gather related paragraphs under a shared header
=head1 VERSION
version 0.103005
=head1 OVERVIEW
Like the Nester transformer, this Gatherer produces structure and containment
in a Pod document. Unlike that Nester, it does not find top-level elements,
but instead produces them.
It looks for all elements matching the C<gather_selector>. They are removed
from the node. In the place of the first found element, the C<container> node
is placed into the transformed node, and all the gathered elements are made
children of the container.
So, given this document:
Document
=head1 Foo
=over 4
=item * xyzzy
=item * abcdef
=back
=head1 Bar
=over 4
=item * 1234
=item * 8765
=back
...and this nester...
my $gatherer = Pod::Elemental::Transformer::Gatherer->new({
gather_selector => s_command( [ qw(over item back) ] ),
container => Pod::Elemental::Element::Pod5::Command->new({
command => 'head1',
content => "LISTS\n",
}),
});
Then this:
$nester->transform_node($document);
Will result in this document:
Document
=head1 Foo
=head1 LISTS
=over 4
=item * xyzzy
=item * abcdef
=back
=over 4
=item * 1234
=item * 8765
=back
=head1 Bar
=head1 ATTRIBUTES
=head2 gather_selector
This is a coderef (a predicate) used to find the paragraphs to gather up.
=head2 container
This is a Pod::Elemental::Node that will be inserted into the node, containing
all gathered elements.
=head1 AUTHOR
Ricardo SIGNES <rjbs@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2020 by Ricardo SIGNES.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut