JeT
Trying to formalize a long question about (a kind) of validation of my workflow, I realized a good tree would actually summarize well my thoughts.
So... before asking for a proof of concept of this method to generate easily loads of content from one source, I'd like to formalize it visually (this question is a good pretext for me to formalize my thoughts and discover forest).

**My question**
How can I grow a second tree starting from courses, going left with a simple structure on 2 levels below courses like

* Courses
- chap01
- sec01_01
- sec01_02
- chap02
- sec02_01
- sec02_02
- sec02_03
- ...
- chap30
- sec30_01
- sec30_02

and having the same system of columns on the left hand side. The option grow'=180 enables me to switch correctly but I need on **both sides** (on the left, for chap and sec, on the right hand side of the tree as it is now) ?

Adapted from https://tex.stackexchange.com/questions/567434/tikz-tree-diagram-classification-with-functional-levels/567923#567923 I have the following (looong) tree...  (not so MWE but it'll be the key to my next post)

![TAQuestionTree0.png](/image?hash=6fc824a027aa0f87fb07622205412e711c61112f448656bb61d8d49408e4a2f1)

and the other side of the tree

...that is the direct application of

**How to wrap a frame in a tcolorbox when using \mode<article>**

(show frames in beamer ans tcolorboxes in beamerarticle)

**How to wrap floats in tcolorbox ?**

(extend the previous to definition, examples, blocs... to tcolorboxes in beamerarticle)

**ignoreframe option (kind of) in Beamerarticle?**

**Pass pgfkeys arguments to a document to produce multiple outputs**
(to generate easily multiple outputs based on pgf keys)

**How to use pgfkeys to (elegantly) parameter my document**

**Flag the lectures you want to compile for a course**
(smart filter of chapters/lectures to produce courses)

**PS** : I have already fantastic results to produce with a simple latexmk   consistent content between different formats that fit the needs of each audience (prof, student, administration, publication, printing, etc all styles using the combination of keys).

**PPS** : The same system of choice would be made on the left hand side to describe which chapters/lectures or sections to use to build the content. The formatting is taken care of by the styles on the right hand side.

**PPPS** : I am probably reinventing the wheel here, but the path was nice :)


\documentclass{standalone}
\usepackage[edges]{forest}

\forestset{
% This is the style that should be applied in the tree preamble. See the tree
% for what argument it takes.
categorized citations/.style={
delay={
for tree={
% The assumption is that all the nodes without a "tier" option belong
% to the tree on the left. The names of the tiers that citation nodes
% live on will end up to be consecutive numbers.
if tier={}{
% These styles can be adjusted by the user.
common node options,
tree node options,
}{% We assume that anything on a tier is a citation node.
citation format,
% Split the content of the node (separator is ",") and format the
% parts --- if desired.
if citation node autoformat={
split option={content}{,}{format first citation entry, format citation entry},
}{},
% The tier situation is atypical in these trees. There are multiple
% tiers, but there is no hierarchical relation between them --- all
% nodes on tiers are just children of the nodes in the tree.  So we
% need to give forest a nudge to get tiers right. This has two parts.
%
% Tiers, part 1. Here we solve the problem of a node in the
% tree with several tier nodes (i.e. citations).  The citation nodes
% are siblings, so forest will push them apart in the s (y) dimension
% --- this is so because tier alignment happens later.  But if we
% make the l (x) coordinates of the nodes different enough, the nodes
% will not "bump" and will happily end up with the same s (y) coordinate.
% We try to make them minimally different (and thus small), so that
% we don't accidentally push them too much to the right.
l=\forestregister{citation boxes offset}+(tier()-1)*(\forestregister{citation node text width}+2*\pgfkeysvalueof{/pgf/inner xsep}+2*\pgfkeysvalueof{/pgf/outer xsep}+0.1pt),
},
},
% Tiers, part 2.
% Here we tell forest about the relative order of tiers (and thus boxes
% on the right). We need to do this because when we write down the tree,
% we just put the citation nodes next to each other (as siblings).  The
% idea here is to create a dummy node on each tier, with structure
% [1[2[3...]]], and remove them all once they do their job. This "tier
% header" is created automatically from the argument to "folders with
% citation blocks" style.
temptoksa={}, % This will hold the argument to "prepend".
% This will hold a call of "draw tier box" for each tier box (in reverse
% order):
draw tier boxes/.style={},
tempcounta'=0, % The current tier number.
temptoksb={}, % The closing brackets to append to temptoksa.
% Insert the closing brackets.
temptoksa+/.register=temptoksb,
% The tier header specification is constructed, let's put it in the tree!
prepend/.register=temptoksa,
},
% After all nodes are positioned, we define style "draw tier box" which
% draws a citation box and its contents.
before drawing tree={% #1 = tier name
% Remember the topmost and the bottommost position in the entire tree
% (folders and citations):
tempdimya/.max={y()+max_y()}{tree},
tempdimyb/.min={y()+min_y()}{tree},
% The first argument of this style is a tier name; in the code, it is
% referred to by ####1, due to being embedded in .process
draw tier box/.style/.process=R2w2{tempdimya}{tempdimyb}{
% ##1, ##2 = tempdimya, tempdimyb
% Get the leftmost and the right position in the citation box (i.e the
% given tier):
tempdimxa/.max={x()+max_x()}{filter={tree}{strequal(tier(),"####1")}},
tempdimxb/.min={x()+min_x()}{filter={tree}{strequal(tier(),"####1")}},
% "draw tier box" style is called from the "draw tree method", so we
% just draw the citation box directly.
TeX/.process=R2ORw4
{tempdimxa}{tempdimxb}{####1.content}{citation box label position}{
% ########1, ########2 = tempdimxa, tempdimxb
% ########3 = the content of the dummy tier node
% ########4 = "citation box label position" register
\node[
fit={(########1,##1) (########2,##2)},
citation box options,
% The box is labeled by the content of the dummy tier header node.
label={[citation box label options]########4:########3}]{};
},
% Draw the citation nodes of this box (i.e. on this tier), and their edges.
for filter={tree}{strequal(tier(),"####1")}{draw tree node, draw tree edge},
},
},
% We need to draw stuff in a very particular order, so that the edges from
% citation nodes on tier 2 go behind citation box 1, etc.
draw tree method/.style={
% Draw the tree on the left (nodes and edges).
for filter={tree}{strequal(tier(),"")}{draw tree node, draw tree edge},
% Draw the citation boxes (and their contents) --- in reverse order!
draw tier boxes,
% Finally, draw any decorations.
for tree=draw tree tikz,
},
},
% How should the nodes in the blocks on the right look like?
citation format/.style={
% Don't change "text width" directly. We need to remember it for later (see
% Tiers, part 1), so use "citation node text width" register.
text width/.register=citation node text width,
% Adjust these styles for other options.
common node options,
citation node options,
},
% We use these two styles when splitting the citation box specification (the
% argument of "categorized citations").
% Get rid of the dummy citation nodes after they have done their job.
temptoksa+={, before computing xy=remove},
},
tempcounta'+=1, % Increase the tier number.
% Add the dummy citation specification. We put it on tier 1/2/3..., give it
% the same name (just in case we want to format them independently), and
% apply the standard citation node format.
temptoksa+/.process=Rw{tempcounta}{[#1, tier=##1, name=##1, citation format%]
},
% Well need an extra closing bracket at the end:
temptoksb+=%[
],
% Prepend the command to draw this particular citation box to "draw tier
% boxes".  We *pre*pend because it is crucial that citation boxes are drawn
% in reverse order: the idea is that a citation box gets drawn on top of
% any edges coming from citation boxes further away from the tree; in
% effect, the edges to citations will go below intermediate citation boxes.
draw tier boxes/.prefix style/.process=Rw{tempcounta}{draw tier box=##1},
},
% An update to the "folder" style from the "edges" library. It (or something
% like it) will be included in the next release of forest.
folder v2/.style={
calign=child,
calign primary child=1,
% This is necessary for "tempdims" calculation below to work properly.
anchor=parent,
after packing node={
if n children=0{}{
tempdiml=l_sep()-l("!1"),  % l-shift
tempdims={abs(max_s("",""))+abs(min_s("!1",""))+s_sep()}, % s-shift
for children={
l+=tempdiml,
s+=tempdims()*(0.5-reversed())*2,
edge={rotate/.option=!parent.grow},
% We don't use the values of "parent anchor" and "child anchor" here
% (we use ".-children last" and ".parent" directly), because the user
% might want to use those otherwise if the folder is embedded in a
% larger tree.
edge path'/.expanded={
([xshift=\forestregister{folder indent}]!u.-children last) |- (.parent)
},
},
fit=band, % to avoid overlapping nodes with their (greatgreat...)uncles.
},
},
},
% In "folder with cites", we separate category and citation nodes, and pack
% them separately. So this style really does all the work in "before/after
% packing node": separate category and citation nodes just before packing, and
% put them back together after packing.
%
% This is just a temporary node we'll need to store a copy of the parent
% folder node into. We need it because somebody didn't implement "create" to
% accept a relative node name and thus act as a copying operation. To be done.-
create'={[,name=folder@temp]},
folder with cites/.style={
before packing node={
% Make a copy of the parent folder node (without the subtree).
for name/.process=_Ow{folder@temp}{id}{
append''={!{id=##1}},
},
% Here I don't follow my own advice (from the forest manual) and call the
% experimental "do dynamics" from within "process keylist(')" (well, not
% explicitly, effectively so, because "before/after packing node" are
% internally called as if by "process keylist'"). The bad news is that
% "do dynamics" in fact does not work as expected here ...
do dynamics,
% ... but the good news is that I now know at least one thing that is
% wrong with it: it fails to set "last dynamic node". This will be
% investigated ... until then, a workaround:
for group={name=folder@temp,last}{alias=folder@temp@parent},
% In fact, there was another problem with "do dynamics". It did not
% update all the node options containing the hierarchical information
% about the tree. So this key now grew (the new definition below; to be
% included in the next release of forest) an argument: a relative node
% name instructing it which nodes to update after doing the dynamic
% thing. (Note that we can safely use "do dynamics" twice; no dynamic
% operations are performed the second time, as the dynamic queue is
% empty, but the info will get updated.)
do dynamics=folder@temp@parent,
% Move all citation nodes (i.e. a nodes with non-empty tier option) into
% the copy of the parent.
for children={
if tier={}{}{
for name/.process=_Ow{folder@temp@parent}{id}{
append={!{id=##1}},
},
},
},
% Do the dynamic operations immediately --- ahh yes, we must do this
% because we're in the middle of packing a node!
do dynamics, do dynamics=folder@temp@parent,
},
% Apply the (updated) folder style to whatever children remained in the
% original parent.
folder v2,
after packing node={
alias=folder@temp@current,
for name={folder@temp@parent}{
for children={
% We do this because gdjgfjdfgsdj ... remove the line and see what
% happens to the tall adjacent citations on tier 2 (children of
% "Crank and slider" and "Bell crank").
l+={abs(max_l("",""))+abs(min_l("!u",""))+l_sep("!u")},
},
% calign/.register=citation nodes calign,
% How should we calign the citation nodes after packing them?
citation nodes calign,
% Pack the citation nodes within the copy of the parent ...
pack',
% ... and then put them back into the original parent. It does not
% really matter where to put them, so we just append.
for children={
for name/.process=_Ow{folder@temp@current}{id}{
append={!{id=##1}},
},
},
},
% For the final time ...
do dynamics,
},
},
declare dimen register=citation node text width,
declare dimen register=citation boxes offset,
declare boolean register=citation node autoformat,
declare toks register=citation box label position,
}

\makeatletter
\forestset{
% Let's patch up "do dynamics" --- to be included in the next release of forest.
do dynamics/.code={%
\the\forest@do@dynamics
\forest@do@dynamics{}%
\forest@forthis{%
\forest@nameandgo{#1}%
\forest@node@Compute@numeric@ts@info{\forest@cn}%
}%
},
do dynamics/.default=!{root'},
}
\makeatother

% These are the formatting options and should be (reasonably) safe to adjust.
\forestset{
common node options/.style={
% "grow" will only work for 0 and 180. For other directions, the "draw tier
% box" style would need to be generalized.
grow'=0,
},
% This style is applied to all the category nodes, i.e. the nodes on the
% left.
tree node options/.style={
% Some basic stuff ...
draw, /tikz/align=center,
% For single citation nodes connected to a tree nodes, it even works
% without this (assuming that the default parent anchor is center). But for
% the fancy "forked edge" calignment of citation nodes, this is necessary.
parent anchor=children,
% The shift of the parent anchor for the folder node (a register applying
% to all folder nodes):
folder indent=1em,
% Nodes on levels 0, 1 and 2 are drawn with "forked edge"s.
% Nodes on levels 2, 3, ... are folders. There is no limit on the
% number of levels.
%
% Feel free to change the level where the transition from forked edge to
% folders occurs, or even to mix them. Note that key "forked edge" sets the
% type of the edge towards the parent node; it must be set for each child.  Key
% "folder" (either the original, v2, or "folder with cites"), on the other hand,
% influences the positions and edges of its children; it must be only used on
% the parent node.
%
% We also set text widths, opacities etc. for each level here. The
% color is set in the tree itself.
if level=0{
fill opacity=0.45, text width=3.5cm, rounded corners=3pt,
}{if level=1{
fill opacity=0.45, text width=2.5cm, rounded corners=3pt,
forked edge,
}{
if level=2{
fill opacity=0.30, text width=2.0cm, rounded corners=3pt,
forked edge,
% The "l sep" (here and below) influences both the folder--file
% distance and the distance to citation nodes.
folder with cites, l sep+=1em,
}{
if level=3{
fill opacity=0.30, text width=1.5cm, rounded corners=2pt,
folder with cites, l sep+=1em,
}{% level >= 4
fill opacity=0.15, text width=1.5cm, rounded corners=2pt,
folder with cites, l sep+=1em,
},
},
},
},
},
% The width of the citation nodes.
citation node text width=1.5cm,
% Other options applying to citation nodes (don't change "text width" here!):
citation node options/.style={
draw, /tikz/align=center, rounded corners=2pt,
fill=brown, fill opacity=0.6,
% This sets the separation between the citation boxes:
l sep=2em,
% The "anchor" key specifies center vertical alignment to the parent.  The
% "child anchor" says that's where the edge will start too. We
% most probably want to keep these as they are.
anchor=parent, child anchor=parent,
},
% How shall we align citations in the unlikely case that we have more than
% one citation node belonging to a category node on a single tier (see the blue
% "citation" in the example tree)? Let's have a very fancy setup, center
% caligned with forked edges, by default.
citation nodes calign/.style={
calign=center, forked edges, for children={fork sep=2em},
},
% We can push the citation boxes a bit further away from the tree. By
% default, the "l sep" of the parents of citations nodes is in effect.
citation boxes offset=0em,
% How should a citation box look like? Note that we want "fill opacity=1"
% (the default) here, because we want the citation box to partially hide the
% edges from citations to the folders.
/tikz/citation box options/.style={
fill=blue!20, draw=red, thick,
},
% Format the citation box labels:
/tikz/citation box label options/.style={
},
% Where should the citation box labels appear?
citation box label position=north,
% These two keys are used to automatically format the list of references in a
% citation node.
format first citation entry/.style={content'=\mbox{[#1]}},
format citation entry/.style={content+'=\discretionary{}{}{}\mbox{[#1]}},
% A register saying whether we want to autoformat citations:
citation node autoformat=true,
}

\begin{document}
\begin{forest}
% Style "categorized citations" takes an argument specifying the
% (comma-separated) labels of citation boxes.  Each citation block will reside
% on its own tier, the tiers numbered 1,2,3... So to put a citation into
% block A/B/C, write "tier=1/2/3" into the citation node.  The number of
% labels given here must match the number of tiers used below, i.e. an empty
% citation box will lead to an error.  If you list too few labels here, the
% extra tiers will be ignored (without producing an error).
categorized citations={standard,prof,student}
[Courses, fill=gray
[common, for tree={fill=blue}
[class
[book]
[beamer]
[article]
[exam]
[...]
]
[Author related
[author]
[title]
[subtitle]
]
[cover-image
[cover Course1]
[cover Course2]
[cover Course3]
[cover Course4]
[...]
[error-handler]
[tikzexternalize
[yes
[,tier=1]
[,tier=2]
]
[no
[,tier=3]
]
]
]
[University
[institute]
[department]
[logo
[standard]
[Transparent]
[BW]
]
]
]
[notes, for tree={fill=brown}
[page-format
[standard
[,tier=1]
]
[wide
[,tier=2]
]
[tufte like
[,tier=3]
]
]
[simple
[,tier=1]
]
[fancy
[,tier=2]
[,tier=3]
]
]
[fonts
[Garamond
[,tier=1]
]
[Euler]
[Times]
[Avant
[,tier=2]
[,tier=3]
]
]
[caption]
[float-counters]
[frames in tcb
[yes
[,tier=1]
[,tier=2]
]
[no
[,tier=3]
]
]
[env in tcb
[example
[,tier=1]
[,tier=2]
]
[definition
[,tier=1]
[,tier=2]
]
[block
[,tier=1]
[,tier=2]
]
[,tier=1]
[,tier=2]
]
]
[multipage
[2 on 1
[,tier=2]
]
[4 on 1]
[block]
]
[tocdepth
[4,tier=1]
[4,tier=2]
[2,tier=3]
]
[section depth
[4,tier=1]
[4,tier=2]
[3,tier=3]
]
[extract
[yes
[,tier=1]
[,tier=2]
]
[no
[,tier=3]
]
]
]
[beamer,
% An easy way to set the color of the entire subtree. The opacity is set,
% per-level, in "tree node options".
for tree={fill=red},
[theme
[Simple
[,tier=1]
]
[Cambridge
[,tier=2]
]
[Hannover
[,tier=3]
]
]
[colortheme
[no color
[,tier=1]
]
[beetle
[,tier=2]
]
[crane
[,tier=3]
]
]
[font
[,tier=1]
[,tier=2]
[professionalfonts,tier=3]
[page-format
[normal
[,tier=1]
]
[show only notes
[,tier=2]
]
[show notes on second screen=right
[,tier=3]
]
]
]
[university colors
]
[tocdepth
[2,tier=1]
[2,tier=2]
[2,tier=3]
]
]
%
]
\end{forest}
\end{document}


as for my poor attempt to describe left tree


\documentclass{standalone}
\usepackage[edges]{forest}

\forestset{
% This is the style that should be applied in the tree preamble. See the tree
% for what argument it takes.
categorized citations/.style={
delay={
for tree={
% The assumption is that all the nodes without a "tier" option belong
% to the tree on the left. The names of the tiers that citation nodes
% live on will end up to be consecutive numbers.
if tier={}{
% These styles can be adjusted by the user.
common node options,
tree node options,
}{% We assume that anything on a tier is a citation node.
citation format,
% Split the content of the node (separator is ",") and format the
% parts --- if desired.
if citation node autoformat={
split option={content}{,}{format first citation entry, format citation entry},
}{},
% The tier situation is atypical in these trees. There are multiple
% tiers, but there is no hierarchical relation between them --- all
% nodes on tiers are just children of the nodes in the tree.  So we
% need to give forest a nudge to get tiers right. This has two parts.
%
% Tiers, part 1. Here we solve the problem of a node in the
% tree with several tier nodes (i.e. citations).  The citation nodes
% are siblings, so forest will push them apart in the s (y) dimension
% --- this is so because tier alignment happens later.  But if we
% make the l (x) coordinates of the nodes different enough, the nodes
% will not "bump" and will happily end up with the same s (y) coordinate.
% We try to make them minimally different (and thus small), so that
% we don't accidentally push them too much to the right.
l=\forestregister{citation boxes offset}+(tier()-1)*(\forestregister{citation node text width}+2*\pgfkeysvalueof{/pgf/inner xsep}+2*\pgfkeysvalueof{/pgf/outer xsep}+0.1pt),
},
},
% Tiers, part 2.
% Here we tell forest about the relative order of tiers (and thus boxes
% on the right). We need to do this because when we write down the tree,
% we just put the citation nodes next to each other (as siblings).  The
% idea here is to create a dummy node on each tier, with structure
% [1[2[3...]]], and remove them all once they do their job. This "tier
% header" is created automatically from the argument to "folders with
% citation blocks" style.
temptoksa={}, % This will hold the argument to "prepend".
% This will hold a call of "draw tier box" for each tier box (in reverse
% order):
draw tier boxes/.style={},
tempcounta'=0, % The current tier number.
temptoksb={}, % The closing brackets to append to temptoksa.
% Insert the closing brackets.
temptoksa+/.register=temptoksb,
% The tier header specification is constructed, let's put it in the tree!
prepend/.register=temptoksa,
},
% After all nodes are positioned, we define style "draw tier box" which
% draws a citation box and its contents.
before drawing tree={% #1 = tier name
% Remember the topmost and the bottommost position in the entire tree
% (folders and citations):
tempdimya/.max={y()+max_y()}{tree},
tempdimyb/.min={y()+min_y()}{tree},
% The first argument of this style is a tier name; in the code, it is
% referred to by ####1, due to being embedded in .process
draw tier box/.style/.process=R2w2{tempdimya}{tempdimyb}{
% ##1, ##2 = tempdimya, tempdimyb
% Get the leftmost and the right position in the citation box (i.e the
% given tier):
tempdimxa/.max={x()+max_x()}{filter={tree}{strequal(tier(),"####1")}},
tempdimxb/.min={x()+min_x()}{filter={tree}{strequal(tier(),"####1")}},
% "draw tier box" style is called from the "draw tree method", so we
% just draw the citation box directly.
TeX/.process=R2ORw4
{tempdimxa}{tempdimxb}{####1.content}{citation box label position}{
% ########1, ########2 = tempdimxa, tempdimxb
% ########3 = the content of the dummy tier node
% ########4 = "citation box label position" register
\node[
fit={(########1,##1) (########2,##2)},
citation box options,
% The box is labeled by the content of the dummy tier header node.
label={[citation box label options]########4:########3}]{};
},
% Draw the citation nodes of this box (i.e. on this tier), and their edges.
for filter={tree}{strequal(tier(),"####1")}{draw tree node, draw tree edge},
},
},
% We need to draw stuff in a very particular order, so that the edges from
% citation nodes on tier 2 go behind citation box 1, etc.
draw tree method/.style={
% Draw the tree on the left (nodes and edges).
for filter={tree}{strequal(tier(),"")}{draw tree node, draw tree edge},
% Draw the citation boxes (and their contents) --- in reverse order!
draw tier boxes,
% Finally, draw any decorations.
for tree=draw tree tikz,
},
},
% How should the nodes in the blocks on the right look like?
citation format/.style={
% Don't change "text width" directly. We need to remember it for later (see
% Tiers, part 1), so use "citation node text width" register.
text width/.register=citation node text width,
% Adjust these styles for other options.
common node options,
citation node options,
},
% We use these two styles when splitting the citation box specification (the
% argument of "categorized citations").
% Get rid of the dummy citation nodes after they have done their job.
temptoksa+={, before computing xy=remove},
},
tempcounta'+=1, % Increase the tier number.
% Add the dummy citation specification. We put it on tier 1/2/3..., give it
% the same name (just in case we want to format them independently), and
% apply the standard citation node format.
temptoksa+/.process=Rw{tempcounta}{[#1, tier=##1, name=##1, citation format%]
},
% Well need an extra closing bracket at the end:
temptoksb+=%[
],
% Prepend the command to draw this particular citation box to "draw tier
% boxes".  We *pre*pend because it is crucial that citation boxes are drawn
% in reverse order: the idea is that a citation box gets drawn on top of
% any edges coming from citation boxes further away from the tree; in
% effect, the edges to citations will go below intermediate citation boxes.
draw tier boxes/.prefix style/.process=Rw{tempcounta}{draw tier box=##1},
},
% An update to the "folder" style from the "edges" library. It (or something
% like it) will be included in the next release of forest.
folder v2/.style={
calign=child,
calign primary child=1,
% This is necessary for "tempdims" calculation below to work properly.
anchor=parent,
after packing node={
if n children=0{}{
tempdiml=l_sep()-l("!1"),  % l-shift
tempdims={abs(max_s("",""))+abs(min_s("!1",""))+s_sep()}, % s-shift
for children={
l+=tempdiml,
s+=tempdims()*(0.5-reversed())*2,
edge={rotate/.option=!parent.grow},
% We don't use the values of "parent anchor" and "child anchor" here
% (we use ".-children last" and ".parent" directly), because the user
% might want to use those otherwise if the folder is embedded in a
% larger tree.
edge path'/.expanded={
([xshift=\forestregister{folder indent}]!u.-children last) |- (.parent)
},
},
fit=band, % to avoid overlapping nodes with their (greatgreat...)uncles.
},
},
},
% In "folder with cites", we separate category and citation nodes, and pack
% them separately. So this style really does all the work in "before/after
% packing node": separate category and citation nodes just before packing, and
% put them back together after packing.
%
% This is just a temporary node we'll need to store a copy of the parent
% folder node into. We need it because somebody didn't implement "create" to
% accept a relative node name and thus act as a copying operation. To be done.-
create'={[,name=folder@temp]},
folder with cites/.style={
before packing node={
% Make a copy of the parent folder node (without the subtree).
for name/.process=_Ow{folder@temp}{id}{
append''={!{id=##1}},
},
% Here I don't follow my own advice (from the forest manual) and call the
% experimental "do dynamics" from within "process keylist(')" (well, not
% explicitly, effectively so, because "before/after packing node" are
% internally called as if by "process keylist'"). The bad news is that
% "do dynamics" in fact does not work as expected here ...
do dynamics,
% ... but the good news is that I now know at least one thing that is
% wrong with it: it fails to set "last dynamic node". This will be
% investigated ... until then, a workaround:
for group={name=folder@temp,last}{alias=folder@temp@parent},
% In fact, there was another problem with "do dynamics". It did not
% update all the node options containing the hierarchical information
% about the tree. So this key now grew (the new definition below; to be
% included in the next release of forest) an argument: a relative node
% name instructing it which nodes to update after doing the dynamic
% thing. (Note that we can safely use "do dynamics" twice; no dynamic
% operations are performed the second time, as the dynamic queue is
% empty, but the info will get updated.)
do dynamics=folder@temp@parent,
% Move all citation nodes (i.e. a nodes with non-empty tier option) into
% the copy of the parent.
for children={
if tier={}{}{
for name/.process=_Ow{folder@temp@parent}{id}{
append={!{id=##1}},
},
},
},
% Do the dynamic operations immediately --- ahh yes, we must do this
% because we're in the middle of packing a node!
do dynamics, do dynamics=folder@temp@parent,
},
% Apply the (updated) folder style to whatever children remained in the
% original parent.
folder v2,
after packing node={
alias=folder@temp@current,
for name={folder@temp@parent}{
for children={
% We do this because gdjgfjdfgsdj ... remove the line and see what
% happens to the tall adjacent citations on tier 2 (children of
% "Crank and slider" and "Bell crank").
l+={abs(max_l("",""))+abs(min_l("!u",""))+l_sep("!u")},
},
% calign/.register=citation nodes calign,
% How should we calign the citation nodes after packing them?
citation nodes calign,
% Pack the citation nodes within the copy of the parent ...
pack',
% ... and then put them back into the original parent. It does not
% really matter where to put them, so we just append.
for children={
for name/.process=_Ow{folder@temp@current}{id}{
append={!{id=##1}},
},
},
},
% For the final time ...
do dynamics,
},
},
declare dimen register=citation node text width,
declare dimen register=citation boxes offset,
declare boolean register=citation node autoformat,
declare toks register=citation box label position,
}

\makeatletter
\forestset{
% Let's patch up "do dynamics" --- to be included in the next release of forest.
do dynamics/.code={%
\the\forest@do@dynamics
\forest@do@dynamics{}%
\forest@forthis{%
\forest@nameandgo{#1}%
\forest@node@Compute@numeric@ts@info{\forest@cn}%
}%
},
do dynamics/.default=!{root'},
}
\makeatother

% These are the formatting options and should be (reasonably) safe to adjust.
\forestset{
common node options/.style={
% "grow" will only work for 0 and 180. For other directions, the "draw tier
% box" style would need to be generalized.
grow'=180,
},
% This style is applied to all the category nodes, i.e. the nodes on the
% left.
tree node options/.style={
% Some basic stuff ...
draw, /tikz/align=center,
% For single citation nodes connected to a tree nodes, it even works
% without this (assuming that the default parent anchor is center). But for
% the fancy "forked edge" calignment of citation nodes, this is necessary.
parent anchor=children,
% The shift of the parent anchor for the folder node (a register applying
% to all folder nodes):
folder indent=1em,
% Nodes on levels 0, 1 and 2 are drawn with "forked edge"s.
% Nodes on levels 2, 3, ... are folders. There is no limit on the
% number of levels.
%
% Feel free to change the level where the transition from forked edge to
% folders occurs, or even to mix them. Note that key "forked edge" sets the
% type of the edge towards the parent node; it must be set for each child.  Key
% "folder" (either the original, v2, or "folder with cites"), on the other hand,
% influences the positions and edges of its children; it must be only used on
% the parent node.
%
% We also set text widths, opacities etc. for each level here. The
% color is set in the tree itself.
if level=0{
fill opacity=0.45, text width=3.5cm, rounded corners=3pt,
}{if level=1{
fill opacity=0.45, text width=2.5cm, rounded corners=3pt,
forked edge,
}{
if level=2{
fill opacity=0.30, text width=2.0cm, rounded corners=3pt,
forked edge,
% The "l sep" (here and below) influences both the folder--file
% distance and the distance to citation nodes.
folder with cites, l sep+=1em,
}{
if level=3{
fill opacity=0.30, text width=1.5cm, rounded corners=2pt,
folder with cites, l sep+=1em,
}{% level >= 4
fill opacity=0.15, text width=1.5cm, rounded corners=2pt,
folder with cites, l sep+=1em,
},
},
},
},
},
% The width of the citation nodes.
citation node text width=1.5cm,
% Other options applying to citation nodes (don't change "text width" here!):
citation node options/.style={
draw, /tikz/align=center, rounded corners=2pt,
fill=brown, fill opacity=0.6,
% This sets the separation between the citation boxes:
l sep=2em,
% The "anchor" key specifies center vertical alignment to the parent.  The
% "child anchor" says that's where the edge will start too. We
% most probably want to keep these as they are.
anchor=parent, child anchor=parent,
},
% How shall we align citations in the unlikely case that we have more than
% one citation node belonging to a category node on a single tier (see the blue
% "citation" in the example tree)? Let's have a very fancy setup, center
% caligned with forked edges, by default.
citation nodes calign/.style={
calign=center, forked edges, for children={fork sep=2em},
},
% We can push the citation boxes a bit further away from the tree. By
% default, the "l sep" of the parents of citations nodes is in effect.
citation boxes offset=0em,
% How should a citation box look like? Note that we want "fill opacity=1"
% (the default) here, because we want the citation box to partially hide the
% edges from citations to the folders.
/tikz/citation box options/.style={
fill=blue!20, draw=red, thick,
},
% Format the citation box labels:
/tikz/citation box label options/.style={
},
% Where should the citation box labels appear?
citation box label position=north,
% These two keys are used to automatically format the list of references in a
% citation node.
format first citation entry/.style={content'=\mbox{[#1]}},
format citation entry/.style={content+'=\discretionary{}{}{}\mbox{[#1]}},
% A register saying whether we want to autoformat citations:
citation node autoformat=true,
}

\begin{document}
\begin{forest}
% Style "categorized citations" takes an argument specifying the
% (comma-separated) labels of citation boxes.  Each citation block will reside
% on its own tier, the tiers numbered 1,2,3... So to put a citation into
% block A/B/C, write "tier=1/2/3" into the citation node.  The number of
% labels given here must match the number of tiers used below, i.e. an empty
% citation box will lead to an error.  If you list too few labels here, the
% extra tiers will be ignored (without producing an error).
categorized citations={chapters/lectures,sections,}
[Courses, fill=gray
[chap01, for tree={fill=blue}
[sec01-01]
[sec01-02]
[...]
[sec01-n]
]
[chap02, for tree={fill=blue}
[sec02-01]
[sec02-02]
[...]
[sec02-n]
]
[chap03, for tree={fill=blue}
[sec03-01]
[sec03-02]
[...]
[sec03-n]
]
[...]
[chap30,for tree={fill=red},
[sec30-01
[,tier=1]
[sec30-02
[,tier=2]
]
[sec03-03
[,tier=2]
]
]
]
]
\end{forest}
\end{document}


marmot
This is not really an answer, just some simpleminded approach. One can store one branch in a savebox. And one can measure the x and y coordinates of the root in this saved tree. This allows us to postion the root precisely on top of the root of another tree that grows in the opposite direction.

\documentclass{standalone}
\usepackage[edges]{forest}
\newsavebox\ForestR
\sbox\ForestR{\begin{forest}
forked edges,
for tree={grow'=0,draw=red,dashed,rounded corners}
[R,alias=R
[A
[1]
[2]
[3]
]
[B
[1]
[2]
]
[C
[1]
[2]
]
[D
[1]
[2]
]
]
\path[overlay] let \p1=($(current bounding box.north west)-(R.north west)$)
in \pgfextra{\xdef\JeTy{\y1}\xdef\JeTx{\x1}};
\end{forest}}
\begin{document}
\begin{forest}
forked edges,
for tree={grow'=180,draw,rounded corners}
[R,alias=R'
[A
[1]
[2]
]
[B
[1]
[2]
[3]
]
[C
[1]
[2]
[3]
]
[D
[1]
[2]
]
]
\path (R'.north west) node[anchor=north west,
xshift=-\JeTx-\pgfkeysvalueof{/pgf/inner xsep}-\pgfkeysvalueof{/pgf/outer xsep},
yshift=\JeTy+\pgfkeysvalueof{/pgf/inner ysep}+\pgfkeysvalueof{/pgf/outer ysep}
]{\usebox\ForestR};
\end{forest}
\end{document}

![Screen Shot 2020-10-22 at 9.54.59 PM.png](/image?hash=0a3a2d88f34a06507e9e2063bd3101ba338ba57d808e9c19df7bdb3ecf1a6b98)

I used red dashes to show that the roots really end up at the same positions.

![Screen Shot 2020-10-22 at 9.55.22 PM.png](/image?hash=fbfab8bac2fd9559a06c5402c7d4af1b3901f862ff57cae53e69ac091d408b6e)

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.