Just because it looked like fun, and so far there are no examples of horizontal word trees.
#!/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", ["xr
+ay", "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;
}
Outputs:
+ ____________________________
+_______________________________________
+ /
+ \
+ ________________________________________________________________
+_______ ______________
+ /
+ \ / \
_____________________________
+______________________________________
+ ___________ __________ zulu
/
+ \
+ / \ / \
_______________________________________
+ _______________________ t
+ango _______ whiskey _____
/ \
+ / \
+ / \ / \
_______________ _____________________
+__ november _______________
+ uniform victor xray yankee
/ \ /
+ \ / \
+
__________ _____ _________ ____
+__________ _________ ______
+
/ \ / \ / \ /
+ \ / \ / \
+
______ charlie delta echo ______ hotel ______
+ _______ _____ quebec romeo sierra
+
/ \ / \ / \
+ / \ / \
+
alpha bravo foxtrot golf indigo juli
+et kilo ____ oscar papa
+
+ / \
+
+ lima mike
By commenting out the "horizontal word" line it produces:
________________________
+_
/
+ \
____________________________ _
+_____
/ \ /
+ \
___________________________ ___ ___
+ 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