use strict; 
use warnings;

for my $test ( split /^(?=
  {
  my ( $id, $outline ) = $test =~ /(\V*?\n)(.*)/s;
  my $sorted = validateandsort( $outline, $id =~ /descend/ );
  print $test, '=' x 20, " answer:\n$sorted\n";
  }

sub validateandsort
  {
  my ($outline, $descend) = @_;
  $outline =~ /^\h*(?: \t|\t )/m and
    return "ERROR: mixed tab and space indentaion\n";
  my $adjust = 0;
  $adjust++ while $outline =~ s/^(\h*)\H.*\n\1\K\h(?=\H)//m
    or $outline =~ s/^(\h*)(\h)\H.*\n\1\K(?=\H)/$2/m;
  $adjust and print "WARNING: adjusting indentation on some lines\n";
  return levelsort($outline, $descend);
  }

sub levelsort       
  {
  my ($section, $descend) = @_;
  my @parts;
  while( $section =~ / ((\h*) .*\n) ( (?:\2\h.*\n)* )/gx )
    {
    my ($head, $rest) = ($1, $3);
    push @parts, $head . ( $rest and levelsort($rest, $descend) );
    }
  join '', $descend ? reverse sort @parts : sort @parts;
  }

__DATA__

zeta
    beta
    gamma
        lambda
        kappa
        mu
    delta
alpha
    theta
    iota
    epsilon

zeta
    beta
    gamma
        lambda
        kappa
        mu
    delta
alpha
    theta
    iota
    epsilon


alpha
    epsilon
  iota
    theta
zeta
    beta
    delta
    gamma
      kappa
        lambda
        mu

zeta
    beta
   gamma
        lambda
         kappa
        mu
    delta
alpha
    theta
    iota
    epsilon