To parse and reformat Perl code, you should use PPI.
This is the same tool that Perl::Criticand Perl::Tidyuse to perform all their deeds.
PPI::Dumper, , , PPI,
, . , pod whitespace , .
use strict;
use warnings;
use PPI;
use Data::Dump;
my $src = do { local $/; <DATA> };
my $doc = PPI::Document->new( \$src );
my @group = ();
my @subs = ();
for my $i ( 0 .. $#{ $doc->{children} } ) {
my $child = $doc->{children}[$i];
my ( $subtype, $subname )
= $child->isa('PPI::Statement::Sub')
? grep { $_->isa('PPI::Token::Word') } @{ $child->{children} }
: ( '', '' );
my $is_related = ($subtype eq 'sub') || grep { $child->isa("PPI::Token::$_") } qw(Whitespace Comment Pod);
if ( my $range = $is_related .. ( !$is_related || ( $i == $#{ $doc->{children} } ) ) ) {
if ($is_related) {
push @group, $child;
if ( $subtype ) {
push @subs, { name => "$subname", children => [@group] };
@group = ();
}
}
if ( $range =~ /E/ ) {
@group = ();
if (@subs) {
my @sorted = map { @{ $_->{children} } } sort { $a->{name} cmp $b->{name} } @subs;
my $min_index = $i - $range + 1;
@{ $doc->{children} }[ $min_index .. $min_index + $#sorted ] = @sorted;
@subs = ();
}
}
}
}
print $doc->serialize;
1;
__DATA__
package A;
use warnings;
use strict;
=comment
Pod describing subC
=cut
sub subC {
print "C\n";
}
INIT {
print "Hello World";
}
sub subB {
print "B\n";
}
# Hello subA comment
sub subA {
print "A\n";
}
1;
:
package A;
use warnings;
use strict;
sub subC {
print "C\n";
}
INIT {
print "Hello World";
}
sub subA {
print "A\n";
}
sub subB {
print "B\n";
}
1;