Skip to content

Instantly share code, notes, and snippets.

@sebkirche
Created May 2, 2024 16:33
Show Gist options
  • Save sebkirche/a3fa8dec8a1214806214dd3e2b094013 to your computer and use it in GitHub Desktop.
Save sebkirche/a3fa8dec8a1214806214dd3e2b094013 to your computer and use it in GitHub Desktop.
Pretty print a tree structure in ascii using box drawing chars
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
# Pretty print a tree structure
# Constants for drawing lines and spaces
my $_cross = "├─";
my $_corner = "└─";
my $_vertical = "│ ";
my $_space = " ";
# test struct
my $struct = { node => 'Top level',
childs => [
{ node => 'prequel', childs => [
{ node => 'first',
childs => [
{ node => 'one' },
{ node => 'two' , childs => [{ node => 'brol'}]},
{ node => 'three' }
]
},
{ node => 'second'
},
{ node => 'third',
childs => [{ node => 'foo'}]
}
]},
{ node => 'sequel' }
]
};
# $struct = { node => 'alone', childs => [ { node => 'single'}] };
say(show_tree(prefix => '', data => $struct, islast => 1));
sub show_tree {
my %args = @_;
my $ret = '';
# my $sub_indent;
my $indent = $args{indent} // '';
my $level = $args{level} // 0;
# prefix
$ret = $args{prefix};
# indent
$ret .= $indent;
if ($args{islast}){
$ret .= $_corner if $level > 0; # only for non-top (avoid corner for top level)
$indent .= $_space if $level > 0;
} else {
$ret .= $_cross if $level > 0; # only for non-top (avoid corner for top level)
$indent .= $_vertical;
}
$ret .= $args{data}->{node};
$ret .= "\n";
return $ret unless exists $args{data}->{childs};
my $child_count = scalar @{$args{data}->{childs}};
for (my $i = 0; $i < $child_count; $i++){
my $child = $args{data}->{childs}->[$i];
my $islast = ($i == $child_count - 1);
$ret .= show_tree(prefix => $args{prefix}, data => $child, indent => $indent, islast => $islast, level => $level + 1);
}
return $ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment