Pod-Abstract
view release on metacpan or search on metacpan
lib/Pod/Abstract/Tree.pm view on Meta::CPAN
return $node;
}
=head2 insert_before
$tree->insert_before($target,$node);
Insert C<$node> before C<$target>. Both must be children of C<$tree>
=cut
sub insert_before {
my $self = shift;
my $target = shift;
my $node = shift;
my $idx = $self->{id_map}{$target->serial};
return 0 unless defined $idx;
splice(@{$self->{nodes}}, $idx, 0, $node);
$self->{id_map}{$node->serial} = $idx;
# Push all following nodes forwards by 1.
my $length = scalar @{$self->{nodes}};
for( my $i = $idx + 1; $i < $length; $i ++) {
my $s = $self->{nodes}[$i]->serial;
$self->{id_map}{$s} ++;
}
return 1;
}
=head2 insert_after
$tree->insert_after($target,$node);
Insert C<$node> after C<$target>. Both must be children of C<$tree>
=cut
sub insert_after {
my $self = shift;
my $target = shift;
my $node = shift;
my $idx = $self->{id_map}{$target->serial};
die $target->serial, " not in index ", join(", ", keys %{$self->{id_map}})
unless defined $idx;
my $last_idx = $#{$self->{nodes}};
if($idx == $last_idx) {
return $self->push($node);
} else {
my $before_target = $self->{nodes}[$idx + 1];
return $self->insert_before($before_target, $node);
}
}
=head2 unshift
Remove the first node from the node list and return it.
Unshift takes linear time - it has to relocate every other element in
id_map so that they stay in line.
=cut
sub unshift {
my $self = shift;
my $node = shift;
if($node->attached) {
$node->detach;
warn "Implicit detach of node on unshift";
}
my $s = $node->serial;
foreach my $k (keys %{$self->{id_map}}) {
$self->{id_map}{$k} ++;
}
unshift @{$self->{nodes}}, $node;
$self->{id_map}{$s} = 0;
return 1;
}
=head2 children
Returns the in-order node list.
=cut
sub children {
my $self = shift;
return @{$self->{nodes}};
}
=head2 index_relative
my $node = $tree->index_relative($target, $offset);
This method will return a node at an offset of $offset (which may be
negative) from this tree structure. If there is no such node, undef
will be returned. For example, an offset of 1 will give the following
element of $node.
=cut
sub index_relative {
my $self = shift;
my $node = shift;
my $index = shift;
my $serial = $node->serial;
die "index_relative called with unattached node"
unless $node->attached;
my $node_idx = $self->{id_map}{$serial};
die "index_relative called with node not present in tree"
unless defined $node_idx;
my $real_index = $node_idx + $index;
my $n_nodes = scalar @{$self->{nodes}};
if($real_index >= 0 && $real_index < $n_nodes) {
return $self->{nodes}[$real_index];
} else {
( run in 0.727 second using v1.01-cache-2.11-cpan-71847e10f99 )