#!/usr/bin/perl
use strict;
use warnings; # https://perlmonks.org/?node_id=998803
my $tree = [ [ [[[[["a", "b"], "c"], ["d", "e"]], [[["f", "g"], "h"], [["i", "j"], ["k", ["l", "m"]]]]], ["n", [[["o", "p"], "q"], ["r", "s"]]]], ["t", ["u", "v"]] ], [["w", ["x", "y"]], "z"] ];
$tree = [ [ [[[[["alpha", "bravo"], "charlie"], ["delta", "echo"]], [[["foxtrot", "golf"], "hotel"], [["indigo", "juliet"], ["kilo", ["lima", "mike"]]]]], ["november", [[["oscar", "papa"], "quebec"], ["romeo", "sierra"]]]], ["tango", ["uniform", "victor"]] ], [["whiskey", ["xray", "yankee"]], "zulu"] ];
print tree( $tree );
sub half { ' ' x ( length(shift) >> 1 ) }
sub tree
{
my $tree = shift;
ref $tree or return "$tree\n" =~ s/ +/ /gr; # horizontal word
ref $tree or return $tree =~ s/./$&\n/gr; # vertical word
my ($padl, $padr) = map $_->[0] =~ tr// /cr, # pads
my ($left, $right) = map [ tree($_) =~ /.+/g ], @$tree;
use List::AllUtils qw( pairwise );
local $_ = join '', pairwise # paste two blocks side by side
{ "@{[($a // $padl)]} @{[($b // $padr)]}\n" } @$left, @$right;
return s{^(?=( *)(\S.*?) {2,}(\S.*?)( *\n))}{
my $span = ' ' x ($+[3] - $-[2] - 2 - length half($2) . half($3));
"$1 " . half($2) . $span =~ tr/ /_/r . half($3) . " $4"
. $1 . half($2) . "/$span\\" . half($3) . $4
}er;
}
####
___________________________________________________________________
/ \
_______________________________________________________________________ ______________
/ \ / \
___________________________________________________________________ ___________ __________ zulu
/ \ / \ / \
_______________________________________ _______________________ tango _______ whiskey _____
/ \ / \ / \ / \
_______________ _______________________ november _______________ uniform victor xray yankee
/ \ / \ / \
__________ _____ _________ ______________ _________ ______
/ \ / \ / \ / \ / \ / \
______ charlie delta echo ______ hotel ______ _______ _____ quebec romeo sierra
/ \ / \ / \ / \ / \
alpha bravo foxtrot golf indigo juliet kilo ____ oscar papa
/ \
lima mike
####
_________________________
/ \
____________________________ ______
/ \ / \
___________________________ ___ ___ z
/ \ / \ / \ u
________________ _________ t __ w __ l
/ \ / \ a / \ h / \ u
_____ _________ n _____ n u v i x y
/ \ / \ o / \ g n i s r a
___ __ ___ _____ v ___ __ o i c k a n
/ \ / \ / \ / \ e / \ / \ f t e y k
__ c d e __ h __ ___ m __ q r s o o y e
/ \ h e c / \ o / \ / \ b / \ u o i r r e
a b a l h f g t i j k __ e o p e m e m
l r r t o o o e n u i / \ r s a b e r
p a l a x l l d l l l m c p e o r
h v i t f i i o i i a a c a
a o e r g e m k r
o o t a e
t