60 lines
1.5 KiB
Perl
60 lines
1.5 KiB
Perl
use strict;
|
|
use warnings;
|
|
use feature 'say';
|
|
use JSON;
|
|
use Data::Printer;
|
|
|
|
my $trees = <<~END;
|
|
RosettaCode
|
|
encourages
|
|
code
|
|
diversity
|
|
comparison
|
|
discourages
|
|
golfing
|
|
trolling
|
|
emphasising execution speed
|
|
code-golf.io
|
|
encourages
|
|
golfing
|
|
discourages
|
|
comparison
|
|
END
|
|
|
|
my $level = ' ';
|
|
sub nested_to_indent { shift =~ s#^($level*)# ($1 ? length($1)/length $level : 0) . ' ' #egmr }
|
|
sub indent_to_nested { shift =~ s#^(\d+)\s*# $level x $1 #egmr }
|
|
|
|
say my $indent = nested_to_indent $trees;
|
|
my $nest = indent_to_nested $indent;
|
|
|
|
use Test::More;
|
|
is($trees, $nest, 'Round-trip');
|
|
done_testing();
|
|
|
|
# Import outline paragraph into native data structure
|
|
sub import {
|
|
my($trees) = @_;
|
|
my $level = ' ';
|
|
my $forest;
|
|
my $last = -999;
|
|
|
|
for my $branch (split /\n/, $trees) {
|
|
$branch =~ m/(($level*))*/;
|
|
my $this = $1 ? length($1)/length($level) : 0;
|
|
$forest .= do {
|
|
if ($this gt $last) { '[' . trim_and_quote($branch) }
|
|
elsif ($this lt $last) { ']'x($last-$this).',' . trim_and_quote($branch) }
|
|
else { trim_and_quote($branch) }
|
|
};
|
|
$last = $this;
|
|
}
|
|
sub trim_and_quote { shift =~ s/^\s*(.*\S)\s*$/"$1",/r }
|
|
|
|
eval $forest . ']' x (1+$last);
|
|
}
|
|
|
|
my $forest = import $trees;
|
|
say "Native data structure:\n" . np $forest;
|
|
say "\nJSON:\n" . encode_json($forest);
|