No solution to this problem can be perfectly general. Automating the style is not necessarily better (or worse) than Sandy G's excellent manual structuring of the trees. This answer aims to be more automatic, slightly more robust and to avoid minor formatting issues, but there is no guarantee it will not eat your chocolate or steal your sock.
Caveat emptor
This is a modification of Sandy G's excellent answer. The fundamental idea is the same, with the following changes.
- The style is more automated.
- It avoids typesetting multiple copies of the same node content, which is responsible for the fake-bold effect in nodes sprouting subtrees in multiple directions. (But there are easier ways by far if this is your only concern.)
- It tries to be potentially slightly more robust by integrating one of the changes in Sašo Živanović's yet-more-excellent answer. (This does not mean it will work with
folder style - I haven't even tried it!)
The output should be the same as using Sandy G's answer (modulo apparent font weight). Only the specification of the trees differs.

Only two keys are really of interest in specifying the trees.
subtree grow=<growth direction>
subtree grow'=<growth direction>
These are intended to be precisely analogous to grow subtree and grow subtree'.
The main difference is that this is all we need to do. There is no need to insert additional nodes or to specify any style for the tree as a whole. subtree grow and subtree grow' activate the required style, which inserts any additional nodes required.
Taking Sandy G's examples for demonstration purposes, the first can be specified as simply
\begin{forest}
[root
[child 1
[a][b]
]
[child 2, subtree grow=150
[c][d][e]
]
[child 3, subtree grow'=30
[f][g]
]
]
\end{forest}
There is, of course, a downside to this simplicity. In some trees, we have to type more precisely because we don't have an additional fake node to set the growth direction for an entire subtree. Instead, we must specify the growth direction for every child which should not grow in the default direction determined by the parent. Hence, Sandy G's second tree requires six uses of subtree grow/subtree grow', whereas it required only two of grow subtree/grow subtree'.
[If the previous example was the swings, I assume we're on the roundabouts by now.]
\begin{forest}
for tree={minimum height=4ex, anchor=center},
forked edges,
[R
[1, subtree grow'=east
[a][b]
]
[2, subtree grow'=east
[c][d]
]
[3, subtree grow'=east
[e][f]
]
[4, subtree grow=west
[g][h]
]
[5, subtree grow=west
[i][j]
]
[6, subtree grow=west
[k][l]
]
]
\end{forest}
For the third example, we need two uses of subtree grow', but since we don't have to insert extra nodes or add to the preamble, this is still a bit more concise.
\begin{forest}
for tree={minimum width=2.5em, anchor=center, circle, draw},
[c
[a, subtree grow'=north
[a1][a2]
]
[b, subtree grow'=north
[b1][b2]
]
[d
[d1][d2]
]
[e
[e1][e2]
]
]
\end{forest}
Similarly, the fourth example involves a good balance of swings and roundabouts, but the payoff for multiple growth specifications is a clearer structure (at least at the level of input syntax - the actual tree is a different matter).
\begin{forest}
for tree={anchor=center},
forked edges,
[0
[1, subtree grow=west
[1a][1b]
]
[2, subtree grow=west
[2a][2b]
]
[3, subtree grow'=east
[3a][3b]
]
[4, subtree grow'=east
[4a]
[4b
[x, subtree grow'=east[x1][x2]]
[y, subtree grow=south[y1][y2]]
]
]
]
\end{forest}
Under the hood, both subtree grow and subtree grow' call a style called wild branching.
subtree grow/.style={%
wild branching={grow=#1},
},
subtree grow'/.style={%
wild branching={grow'=#1},
},
wild branching does nothing you couldn't do for yourself with Sandy G's code and a couple of tweaks. It uses a variety of custom Forest options and registers (for those unfamiliar with this terminology an 'option' is a setting for a node in a tree, while a 'register' applies to the entire tree).
Options:
declare boolean={wild children}{0},
declare boolean={wild child}{0},
declare keylist={tame ones}{},
declare keylist={wild siblings}{},
declare boolean={wild leader}{0},
The final argument is the initial value for all nodes in all trees.
Registers:
declare boolean register={wild tree},
wild tree=0,
We also need a few simple styles:
append me/.style={append={!id=#1},do dynamics},
prepend me/.style={prepend={!id=#1},do dynamics},
wild phantom/.style={%
node options/.option=!u.node options,
content/.process={Ow{!u.content}{\phantom{##1}}},
child anchor/.option=!1.child anchor,
anchor/.option=!1.anchor,
parent anchor/.option=!1.parent anchor,
opacity=0,
no edge,
},
and I used a custom step
define long step={wild children by growth}{}{%
sort by={>O{grow}},sort'={filter={children}{>O{wild child}}}
},
I split up the styling into parts as it was getting a bit long. wild branching calls do tameness and do wildness as appropriate.
do tameness inserts an additional node for subtrees growing in the default direction, when one of their siblings uses subtree grow or subtree grow'.
do tameness/.style={%
where wild children={%
tempboola=0,
for children={%
if wild child={}{%
if tempboola={%
!u.tame ones+/.option=id,
}{%
tempboola,
replace by={%
[,
append,
delay={%
if={>O_={!u.tame ones}{}}{}{%
split option={!u.tame ones}{,}{append me},
},
wild phantom,
},
]%
},
},
},
},
}{},
},
do wildness figures out when to create a new additional node for a new growth direction and when the subtree should be added to an existing addition. This is where the custom step defined above gets used: it ensures we visit the siblings in order of their directions of growth, which makes it easier to compile lists of which ones belong together.
do wildness/.style={%
where wild children={%
tempcounta'=9999,
for wild children by growth={%
if={>OR= {grow}{tempcounta} }
{%
tempkeylista'=,
for children={%
tempkeylista+/.option=id,
},
for nodewalk={%
until={>O{wild leader}}{next},
if wild siblings={}{%
wild siblings/.register=tempkeylista
}{%
wild siblings+/.register=tempkeylista
}%
}{%
},
before packing={remove},
}{%
wild leader,
tempcounta/.option=grow,
before packing={%
if wild siblings={}{}{%
split option={wild siblings}{,}{prepend me},
},
},
},
},
}{},
},
This method creates more nodes than Sandy G's, but the extras get deleted before the tree is packed. Nonetheless, the structure of the final tree differs because wild branching alters l and s before the parent node is packed. Theoretically, this should lead to fewer situations requiring manual intervention. But theory is not, as we all know, practice.
wild branching/.style={%
if id=1{for tree={#1}}{%
!u.wild children,
delay={%
replace by={%
[,
wild child,
append,
delay={%
wild phantom,
for tree={#1},
},
]%
},
},
if wild tree={}{%
wild tree,
!root.before typesetting nodes={%
do tameness,
do wildness,
},
!root.before packing={%
delay={
where wild children={%
after packing node={%
for children={l'=0pt,s'=0pt},
},
}{},
},
},
},
},
},
wild branching/.default={},
Note that subtree grow/subtree grow' aren't designed to be set for the root node. If they are, wild branching simply applies grow or grow' to the tree, without invoking anything special.
wild branching probably shouldn't have a .default setting, but for some reason I can't now remember, I've defined one.
Code:
\documentclass[a4paper,landscape]{article}
\usepackage[scale=.8]{geometry}
% ateb: https://tex.stackexchange.com/a/705635/ addaswyd o ateb Sandy G: https://tex.stackexchange.com/a/643061/
\usepackage{forest}
\useforestlibrary{edges}
\forestset{% https://tex.stackexchange.com/a/705635/
declare boolean={wild children}{0},
declare boolean={wild child}{0},
declare keylist={tame ones}{},
declare keylist={wild siblings}{},
declare boolean={wild leader}{0},
declare boolean register={wild tree},
wild tree=0,
append me/.style={append={!id=#1},do dynamics},
prepend me/.style={prepend={!id=#1},do dynamics},
wild phantom/.style={%
node options/.option=!u.node options,
content/.process={Ow{!u.content}{\phantom{##1}}},
child anchor/.option=!1.child anchor,
anchor/.option=!1.anchor,
parent anchor/.option=!1.parent anchor,
opacity=0,
no edge,
},
define long step={wild children by growth}{}{%
sort by={>O{grow}},sort'={filter={children}{>O{wild child}}}
},
do tameness/.style={%
where wild children={%
tempboola=0,
for children={%
if wild child={}{%
if tempboola={%
!u.tame ones+/.option=id,
}{%
tempboola,
replace by={%
[,
append,
delay={%
if={>O_={!u.tame ones}{}}{}{%
split option={!u.tame ones}{,}{append me},
},
wild phantom,
},
]%
},
},
},
},
}{},
},
do wildness/.style={%
where wild children={%
tempcounta'=9999,
for wild children by growth={%
if={>OR= {grow}{tempcounta} }
{%
tempkeylista'=,
for children={%
tempkeylista+/.option=id,
},
for nodewalk={%
until={>O{wild leader}}{next},
if wild siblings={}{%
wild siblings/.register=tempkeylista
}{%
wild siblings+/.register=tempkeylista
}%
}{%
},
before packing={remove},
}{%
wild leader,
tempcounta/.option=grow,
before packing={%
if wild siblings={}{}{%
split option={wild siblings}{,}{prepend me},
},
},
},
},
}{},
},
wild branching/.style={%
if id=1{for tree={#1}}{%
!u.wild children,
delay={%
replace by={%
[,
wild child,
append,
delay={%
wild phantom,
for tree={#1},
},
]%
},
},
if wild tree={}{%
wild tree,
!root.before typesetting nodes={%
do tameness,
do wildness,
},
!root.before packing={%
delay={
where wild children={%
after packing node={%
for children={l'=0pt,s'=0pt},
},
}{},
},
},
},
},
},
wild branching/.default={},
subtree grow/.style={%
wild branching={grow=#1},
},
subtree grow'/.style={%
wild branching={grow'=#1},
},
}
\pagestyle{empty}
\begin{document}
\centering
\begin{forest}
[root
[child 1
[a][b]
]
[child 2, subtree grow=150
[c][d][e]
]
[child 3, subtree grow'=30
[f][g]
]
]
\end{forest}
\begin{forest}
for tree={minimum height=4ex, anchor=center},
forked edges,
[R
[1, subtree grow'=east
[a][b]
]
[2, subtree grow'=east
[c][d]
]
[3, subtree grow'=east
[e][f]
]
[4, subtree grow=west
[g][h]
]
[5, subtree grow=west
[i][j]
]
[6, subtree grow=west
[k][l]
]
]
\end{forest}
\begin{forest}
for tree={minimum width=2.5em, anchor=center, circle, draw},
[c
[a, subtree grow'=north
[a1][a2]
]
[b, subtree grow'=north
[b1][b2]
]
[d
[d1][d2]
]
[e
[e1][e2]
]
]
\end{forest}
\begin{forest}
for tree={anchor=center},
forked edges,
[0
[1, subtree grow=west
[1a][1b]
]
[2, subtree grow=west
[2a][2b]
]
[3, subtree grow'=east
[3a][3b]
]
[4, subtree grow'=east
[4a]
[4b
[x, subtree grow'=east[x1][x2]]
[y, subtree grow=south[y1][y2]]
]
]
]
\end{forest}
\end{document}
forestwhich prevent overlaps and ensure neat packing. That's not a criticism of your code - I doubt a general solution is possible here. If you were going to use this a lot, you could modify the code to make it a bit speedier. Note that!c.contentseems pointless: why not justcontent?content/.option=!u.contentwould be simpler and faster.l'=0pt, s'=0ptwould be quicker thanl=0,s=0. For speed, avoidpgfmathwhenever possible! :) – cfr Jul 25 '23 at 01:03